--- nono/vm/crtc2.cpp 2026/04/29 17:05:10 1.1.1.8 +++ nono/vm/crtc2.cpp 2026/04/29 17:05:54 1.1.1.17 @@ -9,26 +9,35 @@ // #include "crtc2.h" +#include "event.h" +#include "lunafb.h" #include "renderer.h" #include "scheduler.h" -// グローバル参照用 -CRTC2Device *gCRTC2; - // コンストラクタ CRTC2Device::CRTC2Device() - : inherited("CRTC2") + : inherited(OBJ_CRTC2) { - devaddr = 0xd1000000; - - vdisp_event.func = ToEventCallback(&CRTC2Device::VDispCallback); - vdisp_event.Regist("CRTC2 V-DISP"); } // デストラクタ CRTC2Device::~CRTC2Device() { - gCRTC2 = NULL; +} + +// 初期化 +bool +CRTC2Device::Init() +{ + lunafb = GetLunafbDevice(); + renderer = GetVideoRenderer(); + + auto evman = GetEventManager(); + vdisp_event = evman->Regist(this, + ToEventCallback(&CRTC2Device::VDispCallback), + "CRTC2 V-DISP"); + + return true; } // リセット @@ -45,22 +54,22 @@ CRTC2Device::ResetHard(bool poweron) // XXX 適当 // すぐに垂直帰線期間を開始する - vdisp_event.time = 0; - vdisp_event.code = 1; - gScheduler->RestartEvent(vdisp_event); + vdisp_state = 1; + vdisp_event->time = 0; + scheduler->RestartEvent(vdisp_event); } -uint64 -CRTC2Device::Read(uint32 offset) +busdata +CRTC2Device::ReadPort(uint32 offset) { - uint32 data; + busdata data; switch (offset) { case 0: // アドレスレジスタ // アドレスレジスタは書き込み専用 // XXX 何が読めるか data = 0xff; - putlog(1, "書き込み専用レジスタ AR の読み出し"); + putlog(1, "Read write-only register AR"); break; case 1: // データレジスタ @@ -70,64 +79,71 @@ CRTC2Device::Read(uint32 offset) case 33: case 36 ... 39: data = reg[ar]; - putlog(2, "R%02d -> $%02x", ar, data); + putlog(2, "R%02u -> $%02x", ar, data.Data()); break; case 40 ... 63: // 範囲外 // 未使用レジスタの読み出しは $00 (p.17) data = 0; - putlog(1, "未使用レジスタ読み込み R%02d", ar); + putlog(1, "Read unused register R%02u", ar); break; default: // 書き込み専用レジスタ // 読み出しは 0 になる (p.112) data = 0; - putlog(1, "書き込み専用レジスタ R%02d の読み出し", ar); + putlog(1, "Read write-only register R%02u", ar); break; } break; default: - __unreachable(); + VMPANIC("corrupted offset=%u", offset); } + + // XXX wait? + data |= BusData::Size1; return data; } -uint64 -CRTC2Device::Write(uint32 offset, uint32 data) +busdata +CRTC2Device::WritePort(uint32 offset, uint32 data) { switch (offset) { case 0: // アドレスレジスタ ar = data & 0x3f; - putlog(3, "アドレスレジスタ <- $%02x", ar); - return 0; + putlog(3, "Address Register <- $%02x", ar); + break; case 1: // データレジスタ switch (ar) { case 16 ... 17: // 読み出し専用レジスタ case 28: - putlog(1, "読み出し専用レジスタへの書き込み R%02d <- $%02x", - ar, data); + putlog(1, "Write read-only register R%02u <- $%02x", ar, data); break; case 40 ... 63: // 範囲外 - putlog(1, "未使用レジスタ書き込み R%02d <- $%02x", ar, data); + putlog(1, "Write unused register R%02u <- $%02x", ar, data); break; default: // 書き込み可能レジスタ reg[ar] = data; - putlog(2, "R%02d <- $%02x", ar, data); + putlog(2, "R%02u <- $%02x", ar, data); break; } - return 0; + break; default: - __unreachable(); + VMPANIC("corrupted offset=%u", offset); + break; } + + // XXX wait? + busdata r = BusData::Size1; + return r; } -uint64 -CRTC2Device::Peek(uint32 offset) +busdata +CRTC2Device::PeekPort(uint32 offset) { switch (offset) { case 0: // アドレスレジスタ @@ -137,33 +153,39 @@ CRTC2Device::Peek(uint32 offset) return reg[ar]; default: - __unreachable(); + return 0xff; } } +bool +CRTC2Device::PokePort(uint32 offset, uint32 data) +{ + return false; +} + // 垂直表示・帰線イベント -// ev.code が 1 なら表示期間開始(V-disp)、0 なら帰線期間開始(V-blank)。 +// vdisp_state が 1 なら表示期間開始(V-disp)、0 なら帰線期間開始(V-blank)。 void -CRTC2Device::VDispCallback(Event& ev) +CRTC2Device::VDispCallback(Event *ev) { - int& vdisp = ev.code; - // 今はここで1画面まるごと作成 - if (vdisp) { - // Render に作画指示 - gRenderer->Render(); + if (vdisp_state) { + // 更新の必要があれば Render に作画指示。 + if (lunafb->Snap()) { + renderer->NotifyRender(); + } } // 次のタイミングを計算 // XXX まだ CRTC から計算していない - if (vdisp) { + if (vdisp_state) { // 垂直表示期間 - ev.time = 16234.496_usec; // 1024*Ht - ev.code = 0; + ev->time = 16234.496_usec; // 1024*Ht + vdisp_state = 0; } else { // 垂直帰線期間 - ev.time = 507.328_usec; // 32*Ht - ev.code = 1; + ev->time = 507.328_usec; // 32*Ht + vdisp_state = 1; } - gScheduler->StartEvent(ev); + scheduler->StartEvent(ev); }