--- nono/vm/videoctlr.h 2026/04/29 17:04:39 1.1.1.2 +++ nono/vm/videoctlr.h 2026/04/29 17:05:32 1.1.1.11 @@ -4,52 +4,113 @@ // Licensed under nono-license.txt // +// +// ビデオコントローラ +// + #pragma once #include "device.h" +#include "bitmap.h" +#include "color.h" +#include "event.h" +#include +#include -class VideoCtlrDevice - : public IODevice +class PlaneVRAMDevice; +class Renderer; + +class VideoCtlrDevice : public IODevice { using inherited = IODevice; - private: - static const int baseaddr = 0xe82000; - struct videoctlr { - uint16 r0; - uint16 r1; - uint16 r2; - }; + static const uint32 baseaddr = 0xe82000; public: VideoCtlrDevice(); ~VideoCtlrDevice() override; + bool Init() override; + void ResetHard(bool poweron) 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() からも呼ぶので副作用を起こしてはいけない) + uint GetContrast() const { return target_contrast / 0x11; } + // コントラストを設定 + void SetContrast(uint); + + // 画面作成。 + void VDisp(); + + // 画面合成 + bool Render(BitmapRGBX& dst); + // 加工済みテキストパレットの先頭アドレスを取得 // レンダラとかからの参照用 - const uint32 *GetCookedPalette() const { return cooked_palette; } + const std::vector& GetHostPalette() const { return hostcolor; } - protected: - // BusIO インタフェース - static const uint NPORT = 4096; - uint64 Read(uint32 addr); - uint64 Write(uint32 addr, uint32 data); - uint64 Peek(uint32 addr); + // 生パレットを uint32 形式にしたものを返す (GUI 用) + const std::vector GetIntPalette() const; private: - void SetR0(uint32 data); - void SetR1(uint32 data); - void SetR2(uint32 data); + 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); + void MakePalette(); + void RenderContrast(BitmapRGBX& dst, const BitmapRGBX& src); + static void RenderContrast_gen(BitmapRGBX&, const BitmapRGBX&, uint32); +#if defined(HAVE_AVX2) + 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); + + // ワードレジスタ R0, R1, R2 + std::array reg {}; + + // テキスト画面 + BitmapRGBX textbmp {}; + + // パレット (ホストバイトオーダー) + std::array palette {}; + + // ホスト形式のテキストパレット (レンダラ用に加工したもの) + std::vector hostcolor {}; + + // 設定したコントラスト値 (0-255) + uint32 target_contrast {}; + // 現在の (遷移中かもしれない) コントラスト値 (0-255) + uint32 running_contrast {}; + // 設定を変える時の初期値 (0-255) + uint32 initial_contrast {}; + // 設定を変える時の起点 + uint64 contrast_time0 {}; + + // VM スレッドからレンダラスレッドへの連絡用。(0-255) + std::atomic pending_contrast {}; + + // レンダリングに使っているコントラスト値 (0-255) + uint32 rendering_contrast {}; - struct videoctlr videoctlr {}; - union { - uint8 b[1024]; - uint16 w[512]; - } palette {}; + Event contrast_event { this }; - // xBGR32 形式のテキストパレット (レンダラ用に加工したもの) - uint32 cooked_palette[16]; + PlaneVRAMDevice *planevram {}; + Renderer *renderer {}; }; -extern std::unique_ptr gVideoCtlr; +static inline VideoCtlrDevice *GetVideoCtlrDevice() { + return Object::GetObject(OBJ_VIDEOCTLR); +}