--- nono/vm/scc.cpp 2026/04/29 17:05:14 1.1.1.11 +++ nono/vm/scc.cpp 2026/04/29 17:05:17 1.1.1.12 @@ -14,27 +14,43 @@ #include "keyboard.h" #include "mpu.h" -// グローバル参照用 -SCCDevice *gSCC; - // コンストラクタ SCCDevice::SCCDevice() - : inherited("SCC") + : inherited() { - devaddr = baseaddr; - devlen = 0x2000; - - mpscc.chan[0].desc = "Serial Port"; - mpscc.chan[1].desc = "Mouse"; + SetName("SCC"); + ClearAlias(); + AddAlias("SCC"); + AddAlias("MPSCC"); - // ポートアドレス。 + // チャンネル名とポートアドレスは機種ごとに異なる。 + // // デバイス自身は自分が配置されるアドレスを知らなくてよい構造になって // いるが、直接アクセスしたりする場合などに毎回アドレスを確認するのが // 面倒なので(全機種で向きと間隔が異なる)、モニタで表示されてほしい。 - mpscc.chan[1].ctrladdr = 0xe98001; - mpscc.chan[1].dataaddr = 0xe98003; - mpscc.chan[0].ctrladdr = 0xe98005; - mpscc.chan[0].dataaddr = 0xe98007; + if (gMainApp.IsX68030()) { + mpscc.chan[0].desc = "Serial Port"; + mpscc.chan[1].desc = "Mouse"; + mpscc.chan[1].ctrladdr = 0xe98001; + mpscc.chan[1].dataaddr = 0xe98003; + mpscc.chan[0].ctrladdr = 0xe98005; + mpscc.chan[0].dataaddr = 0xe98007; + + // 5MHz + pclk_ns = 200_nsec; + } else { + // NWS-1750 + mpscc.chan[0].desc = "Serial Port #0"; + mpscc.chan[1].desc = "Serial Port #1 (NotConnected)"; + mpscc.chan[1].ctrladdr = 0xe0d40000; + mpscc.chan[1].dataaddr = 0xe0d40001; + mpscc.chan[0].ctrladdr = 0xe0d40002; + mpscc.chan[0].dataaddr = 0xe0d40003; + + // たぶん 4MHz + // http://www.ceres.dti.ne.jp/~tsutsui/netbsd/port-news68k.html#19990727 + pclk_ns = 250_nsec; + } // X680x0 では SCC と呼ぶほうが通りがいい。 // イベントの登録は親クラスで行ってある。 @@ -52,7 +68,21 @@ SCCDevice::SCCDevice() // デストラクタ SCCDevice::~SCCDevice() { - gSCC = NULL; +} + +// 初期化 +bool +SCCDevice::Init() +{ + if (inherited::Init() == false) { + return false; + } + + if (gMainApp.IsX68030()) { + keyboard = GetKeyboard(); + } + + return true; } // リセット @@ -159,7 +189,7 @@ SCCDevice::Read(uint32 offset) { uint64 data; - gMPU->AddCycle(41); // InsideOut p.135 + mpu->AddCycle(41); // InsideOut p.135 switch (offset) { case 0: // $E98001 @@ -172,11 +202,10 @@ SCCDevice::Read(uint32 offset) data = ReadCtrl(mpscc.chan[0]); break; case 3: // $E98007 - putlog(0, "Read ChA Data Register (NOT IMPLEMENTED)"); data = ReadData(mpscc.chan[0]); break; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); } return data; } @@ -184,7 +213,7 @@ SCCDevice::Read(uint32 offset) uint64 SCCDevice::Write(uint32 offset, uint32 data) { - gMPU->AddCycle(49); // InsideOut p.135 + mpu->AddCycle(49); // InsideOut p.135 switch (offset) { case 0: // $E98001 @@ -200,7 +229,7 @@ SCCDevice::Write(uint32 offset, uint32 d WriteData(mpscc.chan[0], data); break; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); } return 0; } @@ -224,7 +253,8 @@ SCCDevice::Peek(uint32 offset) data = PeekData(mpscc.chan[0]); break; default: - __unreachable(); + data = 0xff; + break; } return data; } @@ -306,7 +336,7 @@ SCCDevice::ReadCtrl(MPSCCChan& chan) break; default: - __unreachable(); + VMPANIC("corrupted chan.ptr=%d", chan.ptr); } chan.ptr = 0; return data; @@ -370,7 +400,7 @@ SCCDevice::WriteCtrl(MPSCCChan& chan, ui WriteWR15(chan, data); break; default: - __unreachable(); + VMPANIC("corrupted chan.ptr=%d", chan.ptr); } // アクセス後は WR0 へ戻す chan.ptr = 0; @@ -427,7 +457,7 @@ SCCDevice::PeekCtrl(const MPSCCChan& cha break; default: - __unreachable(); + VMPANIC("corrupted chan.ptr=%d", chan.ptr); } return data; } @@ -457,7 +487,7 @@ SCCDevice::GetWR1(const MPSCCChan& chan) data |= MPSCC::WR1_RXINT_SPONLY; break; default: - __unreachable(); + VMPANIC("corrupted rxint_mode=%d", (int)chan.rxint_mode); } if (chan.sp_parity) data |= MPSCC::WR1_SP_INC_PE; @@ -570,7 +600,7 @@ SCCDevice::WriteWR0(MPSCCChan& chan, uin ResetHighestIUS(chan); break; default: - __unreachable(); + VMPANIC("corrupted chan.cmd=%d", chan.cmd); } } } @@ -613,7 +643,9 @@ SCCDevice::WriteWR5(MPSCCChan& chan, uin inherited::WriteCR5(chan, data); if (chan.id == 1 && rts) { - gKeyboard->MouseSendStart(); + if (keyboard) { + keyboard->MouseSendStart(); + } } } @@ -638,7 +670,7 @@ SCCDevice::WriteWR9(uint32 data) ResetHard(false); break; default: - __unreachable(); + VMPANIC("corrupted mpscc.wr9_cmd=%d", mpscc.wr9_cmd); } // これらはハードウェアリセットと同時に指定されたら、 @@ -962,10 +994,15 @@ SCCDevice::MonitorUpdateCh(TextScreen& s // 右列 y = ybase + 1; x = xbase + 51; - screen.Print(x, y++, "DataAddr: $%06x", chan.dataaddr); - screen.Print(x, y++, "CtrlAddr: $%06x", chan.ctrladdr); + if (chan.dataaddr > 0x01000000) { + screen.Print(x, y++, "DataAddr: $%08x", chan.dataaddr); + screen.Print(x, y++, "CtrlAddr: $%08x", chan.ctrladdr); + } else { + screen.Print(x, y++, "DataAddr: $%06x", chan.dataaddr); + screen.Print(x, y++, "CtrlAddr: $%06x", chan.ctrladdr); + } y++; - screen.Print(x, y++, "Param: %12s", GetParamStr(chan).c_str()); + screen.Print(x, y++, "Param:%13s", GetParamStr(chan).c_str()); screen.Print(x, y++, "Rx Bits/Frame: %2d", chan.rxframebits); screen.Print(x, y++, "Tx Bits/Frame: %2d", chan.txframebits); } @@ -974,9 +1011,7 @@ SCCDevice::MonitorUpdateCh(TextScreen& s void SCCDevice::SetXC(MPSCCChan& chan) { - // 5MHz = 200nsec - // 12bit = 2.4usec - chan.xc12_ns = (2 * (chan.tc + 2)) * 2.4_usec; + chan.xc12_ns = (2 * (chan.tc + 2)) * pclk_ns * 12; ChangeBaudrate(chan); } @@ -1016,7 +1051,7 @@ SCCDevice::Tx(int ch, uint32 data) // ChB はマウスだが TxD は接続されていない break; default: - __unreachable(); + VMPANIC("corrupted ch=%d", ch); } }