--- nono/vm/sio.cpp 2026/04/29 17:05:13 1.1.1.10 +++ nono/vm/sio.cpp 2026/04/29 17:05:59 1.1.1.18 @@ -10,18 +10,19 @@ #define MPSCC_SIO_LOG_HACK #include "sio.h" +#include "event.h" #include "hostcom.h" #include "keyboard.h" #include "mainapp.h" -// グローバル参照用 -SIODevice *gSIO; - // コンストラクタ SIODevice::SIODevice() - : inherited("SIO") + : inherited() { - devaddr = 0x51000000; + SetName("SIO"); + ClearAlias(); + AddAlias("SIO"); + AddAlias("MPSCC"); mpscc.chan[0].desc = "Serial Console"; mpscc.chan[1].desc = "Keyboard"; @@ -30,7 +31,7 @@ SIODevice::SIODevice() // デバイス自身は自分が配置されるアドレスを知らなくてよい構造になって // いるが、直接アクセスしたりする場合などに毎回アドレスを確認するのが // 面倒なので(全機種で向きと間隔が異なる)、モニタで表示されてほしい。 - if (gMainApp.GetVMType() == VMType::LUNA1) { + if (gMainApp.IsLUNA1()) { mpscc.chan[0].dataaddr = 0x51000000; mpscc.chan[0].ctrladdr = 0x51000002; mpscc.chan[1].dataaddr = 0x51000004; @@ -44,26 +45,40 @@ SIODevice::SIODevice() // 153.6kHz = 6.510416...usec / bit; // 12bit = 78.125usec - mpscc.chan[0].xc12_ns = 78.125_usec; - mpscc.chan[1].xc12_ns = 78.125_usec; + mpscc.chan[0].xc12_tsec = 78.125_usec; + mpscc.chan[1].xc12_tsec = 78.125_usec; + + monitor = gMonitorManager->Regist(ID_MONITOR_SIO, this); + monitor->SetCallback(&SIODevice::MonitorScreen); + monitor->SetSize(70, 24); +} + +// デストラクタ +SIODevice::~SIODevice() +{ +} + +// 初期化 +bool +SIODevice::Init() +{ + if (inherited::Init() == false) { + return false; + } + + hostcom->SetPortName("SIO Ch.A"); + + keyboard = GetKeyboard(); // LUNA では SIO と呼ぶほうが通りがいい。 // イベントの登録は親クラスで行ってある。 for (int ch = 0; ch < txevent.size(); ch++) { auto& chan = mpscc.chan[ch]; - txevent[ch].SetName(string_format("SIO Ch%c TX", chan.name)); - rxevent[ch].SetName(string_format("SIO Ch%c RX", chan.name)); + txevent[ch]->SetName(string_format("SIO Ch%c TX", chan.name)); + rxevent[ch]->SetName(string_format("SIO Ch%c RX", chan.name)); } - monitor.func = ToMonitorCallback(&SIODevice::MonitorUpdate); - monitor.SetSize(70, 24); - monitor.Regist(ID_MONITOR_SIO); -} - -// デストラクタ -SIODevice::~SIODevice() -{ - gSIO = NULL; + return true; } // リセット @@ -123,10 +138,10 @@ SIODevice::ResetChannel(MPSCCChan& chan) ResetChannelCommon(chan); } -uint64 -SIODevice::Read(uint32 offset) +busdata +SIODevice::ReadPort(uint32 offset) { - uint64 data; + busdata data; switch (offset) { case 0: @@ -142,13 +157,15 @@ SIODevice::Read(uint32 offset) data = ReadCtrl(mpscc.chan[1]); break; default: - __unreachable(); + VMPANIC("corrupted offset=%u", offset); } + // XXX wait? + data |= BusData::Size1; return data; } -uint64 -SIODevice::Write(uint32 offset, uint32 data) +busdata +SIODevice::WritePort(uint32 offset, uint32 data) { switch (offset) { case 0: @@ -164,13 +181,15 @@ SIODevice::Write(uint32 offset, uint32 d WriteCtrl(mpscc.chan[1], data); break; default: - __unreachable(); + VMPANIC("corrupted offset=%u", offset); } - return 0; + // XXX wait? + busdata r = BusData::Size1; + return r; } -uint64 -SIODevice::Peek(uint32 offset) +busdata +SIODevice::PeekPort(uint32 offset) { uint64 data; @@ -188,27 +207,28 @@ SIODevice::Peek(uint32 offset) data = PeekCtrl(mpscc.chan[1]); break; default: - __unreachable(); + data = 0xff; + break; } return data; } // 書き込みレジスタ名を返す const char * -SIODevice::CRName(const MPSCCChan& chan, int ptr_) const +SIODevice::CRName(const MPSCCChan& chan, uint ptr_) const { assert(ptr_ < 8); - int idx = ptr_ * 2 + chan.id; + uint idx = ptr_ * 2 + chan.id; assert(idx < countof(crnames)); return crnames[idx]; } // 読み込みレジスタ名を返す const char * -SIODevice::SRName(const MPSCCChan& chan, int ptr_) const +SIODevice::SRName(const MPSCCChan& chan, uint ptr_) const { assert(ptr_ < 8); - int idx = ptr_ * 2 + chan.id; + uint idx = ptr_ * 2 + chan.id; assert(idx < countof(srnames)); return srnames[idx]; } @@ -335,7 +355,7 @@ SIODevice::WriteCtrl(MPSCCChan& chan, ui WriteCR7(chan, data); break; default: - __unreachable(); + VMPANIC("corrupted chan.ptr=%u", chan.ptr); } // アクセス後は CR0 へ戻す chan.ptr = 0; @@ -453,13 +473,13 @@ SIODevice::WriteCR0(MPSCCChan& chan, uin chan.ptr = data & MPSCC::CR0_PTR; if (chan.crc_cmd != 0) { - putlog(0, "%s crc_cmd %d (NOT IMPLEMENTED)", + putlog(0, "%s crc_cmd %u (NOT IMPLEMENTED)", CRName(chan, 0), chan.crc_cmd); } if (chan.cmd == 0) { // コマンド0 ならレジスタ切り替え - putlog(3, "%s <- $%02x (ptr=%d)", CRName(chan, 0), data, chan.ptr); + putlog(3, "%s <- $%02x (ptr=%u)", CRName(chan, 0), data, chan.ptr); } else { // 0 以外ならコマンド発行 putlog(2, "%s <- $%02x", CRName(chan, 0), data); @@ -497,7 +517,7 @@ SIODevice::WriteCR0(MPSCCChan& chan, uin } break; default: - __unreachable(); + VMPANIC("corrupted chan.cmd=%u", chan.cmd); } } @@ -533,6 +553,7 @@ SIODevice::WriteCR1(MPSCCChan& chan, uin chan.rxint_mode = MPSCCChan::RXINT_ALLCHAR; chan.sp_parity = true; chan.all_or_first = true; + break; default: __unreachable(); } @@ -583,7 +604,7 @@ SIODevice::SetVIS() // モニター void -SIODevice::MonitorUpdate(Monitor *, TextScreen& screen) +SIODevice::MonitorScreen(Monitor *, TextScreen& screen) { uint cr2a; uint cr2b; @@ -598,7 +619,7 @@ SIODevice::MonitorUpdate(Monitor *, Text for (int i = 0; i < 2; i++) { int x = 0; y = i * 11; - MonitorUpdateCh(screen, i, x, y); + MonitorScreenCh(screen, i, x, y); } // CR2A @@ -618,7 +639,7 @@ SIODevice::MonitorUpdate(Monitor *, Text } screen.Print(34, y, TA::OnOff((cr2a & MPSCC::CR2_PRIOSEL)), "PRIO"); // bit1,0 はよく分からん - screen.Print(39, y, "INT/DMA=%d", (cr2a & MPSCC::CR2_INTDMA)); + screen.Print(39, y, "INT/DMA=%u", (cr2a & MPSCC::CR2_INTDMA)); y++; // CR2B @@ -627,7 +648,7 @@ SIODevice::MonitorUpdate(Monitor *, Text // モニター (1チャンネル) void -SIODevice::MonitorUpdateCh(TextScreen& screen, int ch, int xbase, int ybase) +SIODevice::MonitorScreenCh(TextScreen& screen, int ch, int xbase, int ybase) { const MPSCCChan& chan = mpscc.chan[ch]; uint cr0; @@ -673,7 +694,7 @@ SIODevice::MonitorUpdateCh(TextScreen& s screen.Print(x, y++, "CR7/CR6: $%02x%02x", cr7, cr6); screen.Print(x, y++, "SR0: $%02x", sr0); screen.Print(x, y++, "SR1: $%02x", sr1); - screen.Print(x, y, "RXbuf: %d", rxlen); + screen.Print(x, y, "RXbuf: %u", rxlen); int i; for (i = 0; i < rxlen; i++) { screen.Print(x + 9 + i * 4, y, "$%02x", chan.rxbuf[i]); @@ -691,7 +712,7 @@ SIODevice::MonitorUpdateCh(TextScreen& s y = ybase + 1; x = xbase; // CR0 - screen.Print(x + 9, y, "CRC=%d", (cr0 >> 6)); + screen.Print(x + 9, y, "CRC=%u", (cr0 >> 6)); static const char * const cmd_str[] = { // 0123456789012345 "No operation", @@ -704,8 +725,8 @@ SIODevice::MonitorUpdateCh(TextScreen& s "End of Interrupt", }; uint cmd = (cr0 >> 3) & 7; - screen.Print(x + 19, y, "CMD=%d(%s)", cmd, cmd_str[cmd]); - screen.Print(x + 43, y, "PTR=%d", (cr0 & 7)); + screen.Print(x + 19, y, "CMD=%u(%s)", cmd, cmd_str[cmd]); + screen.Print(x + 43, y, "PTR=%u", (cr0 & 7)); y++; // CR1 @@ -730,7 +751,7 @@ SIODevice::MonitorUpdateCh(TextScreen& s y++; // CR3,CR4,CR5 - y = MonitorUpdateCR345(screen, x, y, cr3, cr4, cr5); + y = MonitorScreenCR345(screen, x, y, cr3, cr4, cr5); // CR6,CR7 y++; @@ -747,7 +768,7 @@ SIODevice::MonitorUpdateCh(TextScreen& s y++; // SR1 - MonitorUpdateSR1(screen, x, y, sr1); + MonitorScreenSR1(screen, x, y, sr1); y++; // 右列 @@ -756,9 +777,9 @@ SIODevice::MonitorUpdateCh(TextScreen& s screen.Print(x, y++, "DataAddr: $%08x", chan.dataaddr); screen.Print(x, y++, "CtrlAddr: $%08x", chan.ctrladdr); y++; - screen.Print(x, y++, "Param: %12s", GetParamStr(chan).c_str()); - screen.Print(x, y++, "Rx Bits/Frame: %2d", chan.rxframebits); - screen.Print(x, y++, "Tx Bits/Frame: %2d", chan.txframebits); + screen.Print(x, y++, "Param:%13s", GetParamStr(chan).c_str()); + screen.Print(x, y++, "Rx Bits/Frame: %2u", chan.rxframebits); + screen.Print(x, y++, "Tx Bits/Frame: %2u", chan.txframebits); } // ペンディングのうち最も優先度の高い割り込み要因を返す @@ -786,7 +807,6 @@ SIODevice::GetHighestInt() const if ((mpscc.chan[1].intpend & INTPEND_TX)) return MPSCC::VS_TxB; if ((mpscc.chan[0].intpend & INTPEND_ES)) return MPSCC::VS_ESA; if ((mpscc.chan[1].intpend & INTPEND_ES)) return MPSCC::VS_ESB; - } else { if ((mpscc.chan[0].intpend & INTPEND_SP)) return MPSCC::VS_SPA; if ((mpscc.chan[0].intpend & INTPEND_RX)) return MPSCC::VS_RxA; @@ -809,10 +829,10 @@ SIODevice::Tx(int ch, uint32 data) hostcom->Tx(data); break; case 1: - gKeyboard->Command(data); + keyboard->Command(data); break; default: - __unreachable(); + VMPANIC("corrupted ch=%u", ch); } }