--- nono/vm/scc.cpp 2026/04/29 17:04:36 1.1.1.3 +++ nono/vm/scc.cpp 2026/04/29 17:04:59 1.1.1.8 @@ -5,7 +5,10 @@ // #include "scc.h" -#include "mpu680x0.h" +#include "bitops.h" +#include "interrupt.h" +#include "keyboard.h" +#include "mpu.h" // IODevice // | @@ -20,14 +23,16 @@ std::unique_ptr gSCC; SCCDevice::SCCDevice() + : inherited("SCC") { - logname = "scc"; - devname = "SCC"; devaddr = baseaddr; devlen = 0x2000; cr.chan[0].desc = "Serial Port"; cr.chan[1].desc = "Mouse"; + + // X680x0 では SCC と呼ぶほうが通りがいい。 + monitor.Regist(ID_MONITOR_SCC); } SCCDevice::~SCCDevice() @@ -37,23 +42,18 @@ SCCDevice::~SCCDevice() // Z8530 は RD と WR を同時に Low にするとリセットがかかる。 // 回路図からは PEDEC から繋がってるという以上のことは分からないけど // 普通に考えればハードリセットでリセットされるよな。 -void -SCCDevice::ResetHard() -{ - Reset(); -} uint64 -SCCDevice::Read(uint32 addr) +SCCDevice::Read(uint32 offset) { - switch (addr) { + gMPU->AddCycle(41); // InsideOut p.135 + + switch (offset) { case 0: // $E98001 return ReadCtrl(&cr.chan[1]); case 1: // $E98003 - // マウス非接続は 0x00 ? - putlog(0, "ChB データレジスタ読み込み (未実装)"); - return 0x00; + return ReadData(&cr.chan[1]); case 2: // $E98005 return ReadCtrl(&cr.chan[0]); @@ -66,9 +66,11 @@ SCCDevice::Read(uint32 addr) } uint64 -SCCDevice::Write(uint32 addr, uint32 data) +SCCDevice::Write(uint32 offset, uint32 data) { - switch (addr) { + gMPU->AddCycle(49); // InsideOut p.135 + + switch (offset) { case 0: // $E98001 WriteCtrl(&cr.chan[1], data); return 0; @@ -89,15 +91,14 @@ SCCDevice::Write(uint32 addr, uint32 dat } uint64 -SCCDevice::Peek(uint32 addr) +SCCDevice::Peek(uint32 offset) { - switch (addr) { + switch (offset) { case 0: // $E98001 return PeekCtrl(&cr.chan[1]); case 1: // $E98003 - // マウス非接続は 0x00 ? - return 0x00; + return PeekData(&cr.chan[1]); case 2: // $E98005 return PeekCtrl(&cr.chan[0]); @@ -187,7 +188,7 @@ SCCDevice::WriteCtrl(struct SIO::channel ResetChannel(&cr.chan[1]); break; case 3: // Force Hardware Reset - Reset(); + ResetHard(); break; default: __unreachable(); @@ -196,6 +197,13 @@ SCCDevice::WriteCtrl(struct SIO::channel chan->ptr = 0; break; + case 10: // WR10 + putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data); + chan->wr10 = data; + // アクセス後は WR0 へ戻す + chan->ptr = 0; + break; + case 11: // WR11 putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data); chan->wr11 = data; @@ -238,10 +246,29 @@ SCCDevice::WriteCtrl(struct SIO::channel } } +void +SCCDevice::WriteCR5(struct SIO::channel *chan, uint32 data) +{ + bool rts = bit_falling(chan->cr5, data, SIO::CR5_RTS); + + inherited::WriteCR5(chan, data); + + if (chan->id == 1 && rts) { + gKeyboard->MouseSendStart(); + } +} + // 割り込みを上げる void SCCDevice::Interrupt() { putlog(0, "割り込み(未実装)"); - gMPU680x0->Interrupt(this, 5, 0x50/*XXX*/); +// gInterrupt->Raise(this); +} + +// 割り込みアクノリッジ +int +SCCDevice::InterruptAcknowledge() +{ + return 0x50; /* XXX 実際は WR2 とか要因で変わる */ }