--- nono/vm/crtc2.cpp 2026/04/29 17:04:55 1.1.1.7 +++ nono/vm/crtc2.cpp 2026/04/29 17:05:24 1.1.1.11 @@ -4,26 +4,43 @@ // Licensed under nono-license.txt // +// +// CRTC-II (HD6445) +// + #include "crtc2.h" #include "renderer.h" +#include "scheduler.h" -std::unique_ptr gCRTC2; - +// コンストラクタ CRTC2Device::CRTC2Device() - : inherited("CRTC2") + : inherited(OBJ_CRTC2) { - devaddr = 0xd1000000; - - vdisp_event.func = (DeviceCallback_t)&CRTC2Device::VDispCallback; - vdisp_event.SetName("CRTC2 V-DISP"); + vdisp_event.func = ToEventCallback(&CRTC2Device::VDispCallback); + vdisp_event.Regist("CRTC2 V-DISP"); } +// デストラクタ CRTC2Device::~CRTC2Device() { } +// 初期化 +bool +CRTC2Device::Init() +{ + if (inherited::Init() == false) { + return false; + } + + renderer = GetRenderer(); + + return true; +} + +// リセット void -CRTC2Device::ResetHard() +CRTC2Device::ResetHard(bool poweron) { // リセット信号で初期化されるレジスタ (他は維持) reg[30] = 0; @@ -37,10 +54,10 @@ CRTC2Device::ResetHard() // すぐに垂直帰線期間を開始する vdisp_event.time = 0; vdisp_event.code = 1; - vdisp_event.Start(); + scheduler->RestartEvent(vdisp_event); } -uint64 +busdata CRTC2Device::Read(uint32 offset) { uint32 data; @@ -50,7 +67,7 @@ CRTC2Device::Read(uint32 offset) // アドレスレジスタは書き込み専用 // XXX 何が読めるか data = 0xff; - putlog(1, "書き込み専用レジスタ AR の読み出し"); + putlog(1, "Read write-only register AR"); break; case 1: // データレジスタ @@ -66,42 +83,44 @@ CRTC2Device::Read(uint32 offset) case 40 ... 63: // 範囲外 // 未使用レジスタの読み出しは $00 (p.17) data = 0; - putlog(1, "未使用レジスタ読み込み R%02d", ar); + putlog(1, "Read unused register R%02d", ar); break; default: // 書き込み専用レジスタ // 読み出しは 0 になる (p.112) data = 0; - putlog(1, "書き込み専用レジスタ R%02d の読み出し", ar); + putlog(1, "Read write-only register R%02d", ar); break; } break; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); } - return data; + + busdata bd = data; + // XXX wait? + return bd; } -uint64 +busdata CRTC2Device::Write(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%02d <- $%02x", ar, data); break; case 40 ... 63: // 範囲外 - putlog(1, "未使用レジスタ書き込み R%02d <- $%02x", ar, data); + putlog(1, "Write unused register R%02d <- $%02x", ar, data); break; default: // 書き込み可能レジスタ @@ -109,14 +128,18 @@ CRTC2Device::Write(uint32 offset, uint32 putlog(2, "R%02d <- $%02x", ar, data); break; } - return 0; + break; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); + break; } + + // XXX wait? + return 0; } -uint64 +busdata CRTC2Device::Peek(uint32 offset) { switch (offset) { @@ -127,7 +150,7 @@ CRTC2Device::Peek(uint32 offset) return reg[ar]; default: - __unreachable(); + return 0xff; } } @@ -141,7 +164,7 @@ CRTC2Device::VDispCallback(Event& ev) // 今はここで1画面まるごと作成 if (vdisp) { // Render に作画指示 - gRenderer->Render(); + renderer->Render(); } // 次のタイミングを計算 @@ -155,5 +178,5 @@ CRTC2Device::VDispCallback(Event& ev) ev.time = 507.328_usec; // 32*Ht ev.code = 1; } - ev.Start(); + scheduler->StartEvent(ev); }