--- nono/vm/crtc.cpp 2026/04/29 17:04:35 1.1.1.4 +++ nono/vm/crtc.cpp 2026/04/29 17:04:50 1.1.1.6 @@ -48,29 +48,31 @@ CRTCDevice::ResetHard() } uint64 -CRTCDevice::Read(uint32 addr) +CRTCDevice::Read(uint32 offset) { uint64 data; - if (addr < 0x400 / 2) { // CRTC レジスタ + gMPU->AddCycle(9); // InsideOut p.135 + + if (offset < 0x400 / 2) { // CRTC レジスタ // 0x40 バイトでミラー - addr &= (0x40 / 2) - 1; + offset &= (0x40 / 2) - 1; // R20, R21 のみ読み出し可能 - switch (addr) { + switch (offset) { case 20: - data = crtc.r[addr]; - putlog(2, "R%02d -> $%04x", addr, (uint32)data); + data = crtc.r[offset]; + putlog(2, "R%02d -> $%04x", offset, (uint32)data); break; case 21: // R21 へのアクセスは多いのでログレベルを上げておく - data = crtc.r[addr]; - putlog(3, "R%02d -> $%04x", addr, (uint32)data); + data = crtc.r[offset]; + putlog(3, "R%02d -> $%04x", offset, (uint32)data); break; default: // それ以外は読み出し不可 ($00 が読める) data = 0; - if (addr < countof(crtc.r)) { - putlog(3, "R%02d -> $%04x", addr, (uint32)data); + if (offset < countof(crtc.r)) { + putlog(3, "R%02d -> $%04x", offset, (uint32)data); } else { putlog(3, "$%06x -> $%04x", gMPU->GetPaddr(), (uint32)data); } @@ -78,9 +80,9 @@ CRTCDevice::Read(uint32 addr) } } else { // 動作ポート - if ((addr & (0x80 / 2)) == 0) { // +$00..+$7f + if ((offset & (0x80 / 2)) == 0) { // +$00..+$7f data = (uint64)-1; - } else { // +$80..+$ff + } else { // +$80..+$ff data = crtc.op; } } @@ -89,20 +91,22 @@ CRTCDevice::Read(uint32 addr) } uint64 -CRTCDevice::Write(uint32 addr, uint32 data) +CRTCDevice::Write(uint32 offset, uint32 data) { - if (addr < 0x400 / 2) { // CRTC レジスタ + gMPU->AddCycle(9); // InsideOut p.135 + + if (offset < 0x400 / 2) { // CRTC レジスタ // 0x40 バイトでミラー - addr &= (0x40 / 2) - 1; - if (addr < countof(crtc.r)) { - SetReg(addr, data); + offset &= (0x40 / 2) - 1; + if (offset < countof(crtc.r)) { + SetReg(offset, data); } else { // ここ何がいるんだ? putlog(2, "$%06x <- $%04x", gMPU->GetPaddr(), data); } } else { // 動作ポート - if ((addr & (0x80 / 2)) == 0) { // +$00..+$7f + if ((offset & (0x80 / 2)) == 0) { // +$00..+$7f return (uint64)-1; } else { crtc.op = data & 0x0b; @@ -114,22 +118,22 @@ CRTCDevice::Write(uint32 addr, uint32 da } uint64 -CRTCDevice::Peek(uint32 addr) +CRTCDevice::Peek(uint32 offset) { uint64 data; - if (addr < 0x400 / 2) { // CRTC レジスタ + if (offset < 0x400 / 2) { // CRTC レジスタ // 0x40 バイトでミラー - addr &= (0x40 / 2) - 1; - if (addr == 20 || addr == 21) { + offset &= (0x40 / 2) - 1; + if (offset == 20 || offset == 21) { // R20, R21 のみ読み出し可能 - data = crtc.r[addr]; + data = crtc.r[offset]; } else { data = 0; } } else { // 動作ポート - if ((addr & (0x80 / 2)) == 0) { + if ((offset & (0x80 / 2)) == 0) { data = (uint64)-1; } else { data = crtc.op; @@ -167,28 +171,31 @@ CRTCDevice::SetReg(uint32 reg, uint32 da } // 垂直表示・帰線イベント -// arg == 1 なら表示期間開始、arg == 0 なら帰線期間開始。 +// ev.code が 1 なら表示期間開始(V-disp)、0 なら帰線期間開始(V-blank)。 void -CRTCDevice::VDispCallback(int arg) +CRTCDevice::VDispCallback(Event& ev) { + int& vdisp = ev.code; + // GPIP の状態を更新 - gMFP->SetVDisp(arg); + gMFP->SetVDisp(vdisp); // 今はここで1画面まるごと作成 - if (arg) { + if (vdisp) { // Render に作画指示 gRenderer->Render(); } // 次のタイミングを計算 // XXX まだ CRTC から計算していない - if (arg) { + if (vdisp) { // 垂直表示期間 - vdisp_event.time = 16250_usec; + ev.time = 16250_usec; + ev.code = 0; } else { // 垂直帰線期間 - vdisp_event.time = 1778_usec; + ev.time = 1778_usec; + ev.code = 1; } - vdisp_event.code = 1 - arg; - vdisp_event.Start(); + ev.Start(); }