--- nono/vm/videoctlr.h 2026/04/29 17:05:24 1.1.1.9 +++ nono/vm/videoctlr.h 2026/04/29 17:05:59 1.1.1.14 @@ -12,19 +12,71 @@ #include "device.h" #include "bitmap.h" -#include "color.h" -#include "event.h" -#include "planevram.h" #include +#include -class Renderer; +class GVRAMDevice; +class PlaneVRAMDevice; +class VideoRenderer; +class UIMessage; -class VideoCtlrDevice : public IODevice +class VideoCtlr +{ + public: + // f e d c b a 9 8 7 6 5 4 3 2 1 0 + // +--------------------------------------+--+-----+ + // R0 | |SZ| COL | + // +--------------------------------------+--+-----+ + static constexpr uint32 R0_SIZ = 0x0004; + static constexpr uint32 R0_COL = 0x0003; + + // f e d c b a 9 8 7 6 5 4 3 2 1 0 + // +-----+-----+-----+-----+-----+-----+-----+-----+ + // R1 | %00 | SP | TX | GR | GP3 | GP2 | GP1 | GP0 | + // +-----+-----+-----+-----+-----+-----+-----+-----+ + static constexpr uint32 R1_SP = 0x3000; // スプライト優先度 + static constexpr uint32 R1_TX = 0x0c00; // テキスト画面優先度 + static constexpr uint32 R1_GR = 0x0300; // グラフィック画面優先度 + static constexpr uint32 R1_G3 = 0x00c0; // GP3 優先度 + static constexpr uint32 R1_G2 = 0x0030; // GP2 優先度 + static constexpr uint32 R1_G1 = 0x000c; // GP1 優先度 + static constexpr uint32 R1_G0 = 0x0003; // GP0 優先度 + + // f e d c b a 9 8 7 6 5 4 3 2 1 0 + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // R2 |YS|AH|VH|EX|HP|BP|GG|GT| |SO|TO|GO|G3|G2|G1|G0| + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + static constexpr uint32 R2_YS = 0x8000; + static constexpr uint32 R2_AH = 0x4000; + static constexpr uint32 R2_VH = 0x2000; + static constexpr uint32 R2_EX = 0x1000; + static constexpr uint32 R2_HP = 0x0800; + static constexpr uint32 R2_BP = 0x0400; + static constexpr uint32 R2_GG = 0x0200; + static constexpr uint32 R2_GT = 0x0100; + static constexpr uint32 R2_SP_ON = 0x0040; // スプライトオン + static constexpr uint32 R2_TX_ON = 0x0020; // テキスト画面オン + static constexpr uint32 R2_GR_ON = 0x0010; // グラフィック画面オン + static constexpr uint32 R2_G3_ON = 0x0008; // グラフィック(P3)オン + static constexpr uint32 R2_G2_ON = 0x0004; // グラフィック(P2)オン + static constexpr uint32 R2_G1_ON = 0x0002; // グラフィック(P1)オン + static constexpr uint32 R2_G0_ON = 0x0001; // グラフィック(P0)オン +}; + +class VideoCtlrDevice : public IODevice, public VideoCtlr { using inherited = IODevice; static const uint32 baseaddr = 0xe82000; + // 描画順のための描画フラグ + static constexpr uint32 SORDER_NONE = 0x0; + static constexpr uint32 SORDER_SP = 0x1; + static constexpr uint32 SORDER_TX = 0x2; + static constexpr uint32 SORDER_GR = 0x3; + static constexpr uint32 SORDER_BG = 0x4; + static constexpr uint32 SORDER_BLACK = 0x5; // 仮想的な背景 + public: VideoCtlrDevice(); ~VideoCtlrDevice() override; @@ -32,34 +84,49 @@ class VideoCtlrDevice : public IODevice bool Init() override; void ResetHard(bool poweron) override; - busdata Read8(uint32 addr) override; - busdata Read16(uint32 addr) override; - busdata Write8(uint32 addr, uint32 data) override; - busdata Write16(uint32 addr, uint32 data) override; - busdata Peek8(uint32 addr) override; - bool Poke8(uint32 addr, uint32 data) override; + busdata Read(busaddr addr) override; + busdata Write(busaddr addr, uint32 data) override; + busdata Peek1(uint32 addr) override; + bool Poke1(uint32 addr, uint32 data) override; // コントラストを取得 (Peek() からも呼ぶので副作用を起こしてはいけない) - int GetContrast() const { return (int)(target_contrast / 0x11); } + uint GetContrast() const { return target_contrast / 0x11; } // コントラストを設定 - void SetContrast(int); + void SetContrast(uint); + + // 画面作成。 + void VDisp(); // 画面合成 - bool Render(BitmapRGBX& dst, ModifyInfo&); + bool Render(BitmapRGBX& dst); + + // モニタ更新(下請け) + int MonitorScreen(TextScreen&, int y, uint32 crtc_r20); + + // グラフィック画面を取得。(モニタ用) + const BitmapRGBX& GetGraphicBitmap() const { return grbmp; } - // 加工済みテキストパレットの先頭アドレスを取得 - // レンダラとかからの参照用 - const std::vector& GetHostPalette() const { return hostcolor; } + // ホストパレットを取得。(レンダラとかからの参照用) + const std::vector& GetHostPalette() const { return hostcolor; } - // 生パレットを uint32 形式にしたものを返す (GUI 用) - const std::vector GetIntPalette() const; + // ホストパレットのアドレスを取得。 + const Color *GetHostPalettePtr(int idx) const { return &hostcolor[idx]; } + + // ゲストパレットを取得。(GUI 情報表示用) + const std::vector& GetGuestPalette() const { return palette; } + + // モニタ用。CRTC からも使う。 + static const char * const siz_str[2]; + static const char * const col_str[4]; private: - inline uint32 Decoder(uint32 addr) const; - inline uint Offset2NR(uint32 offset) const; + static inline uint32 Decoder(uint32 addr); + static inline uint Offset2Rn(uint32 offset); + + uint32 Get16(uint32 offset) const; + void Set8(uint32 offset, uint32 data); + void Set16(uint32 offset, uint32 data); - uint32 GetNR(uint reg) const; - void SetNR(uint reg, uint32 data); void MakePalette(); void RenderContrast(BitmapRGBX& dst, const BitmapRGBX& src); static void RenderContrast_gen(BitmapRGBX&, const BitmapRGBX&, uint32); @@ -67,22 +134,33 @@ class VideoCtlrDevice : public IODevice static void RenderContrast_avx2(BitmapRGBX&, const BitmapRGBX&, uint32); bool enable_avx2 {}; #endif +#if defined(HAVE_NEON) + static void RenderContrast_neon(BitmapRGBX&, const BitmapRGBX&, uint32); + bool enable_neon {}; +#endif - void ContrastCallback(Event& ev); + void ContrastCallback(Event *); - // ワードレジスタ R0, R1, R2 は内部では nr0 .. nr5 というバイトレジスタ - // として扱う。 - std::array nreg {}; - - // テキスト画面 - BitmapRGBX textbmp {}; - - // メモリを確保する時のサイズ計算のため型を uint8 にしているが、 - // 運用はワードでホストバイトオーダー。 - std::array palette {}; + // ワードレジスタ R0, R1, R2 + std::array reg {}; + uint16 prev_reg1 {}; + uint16 prev_reg2 {}; + + // 各画面 + BitmapRGBX txbmp {}; + BitmapRGBX grbmp {}; + + // 合成画面 (コントラスト適用前) + BitmapRGBX mixbmp {}; + + // パレット (ホストバイトオーダー) + std::vector palette {}; // ホスト形式のテキストパレット (レンダラ用に加工したもの) - std::vector hostcolor {}; + std::vector hostcolor {}; + + // 描画順 (SORDER_* を LSB 側から4ビットずつ並べる) + uint32 screen_order {}; // 設定したコントラスト値 (0-255) uint32 target_contrast {}; @@ -93,15 +171,20 @@ class VideoCtlrDevice : public IODevice // 設定を変える時の起点 uint64 contrast_time0 {}; + // VM スレッドからレンダラスレッドへの連絡用。(0-255) + std::atomic pending_contrast {}; + // レンダリングに使っているコントラスト値 (0-255) uint32 rendering_contrast {}; - Event contrast_event { this }; + Event *contrast_event {}; + GVRAMDevice *gvram {}; PlaneVRAMDevice *planevram {}; - Renderer *renderer {}; + UIMessage *uimessage {}; + VideoRenderer *renderer {}; }; -static inline VideoCtlrDevice *GetVideoCtlrDevice() { +inline VideoCtlrDevice *GetVideoCtlrDevice() { return Object::GetObject(OBJ_VIDEOCTLR); }