--- nono/vm/upd7201.cpp 2026/04/29 17:04:45 1.1.1.5 +++ nono/vm/upd7201.cpp 2026/04/29 17:04:56 1.1.1.7 @@ -8,9 +8,9 @@ #include "interrupt.h" // コンストラクタ -uPD7201Device::uPD7201Device() +uPD7201Device::uPD7201Device(const std::string& objname_) + : inherited(objname_) { - monitor_size = nnSize(48, 22); cr.chan[0].id = 0; cr.chan[0].name = "A"; cr.chan[1].id = 1; @@ -18,6 +18,10 @@ uPD7201Device::uPD7201Device() cr.chan[0].desc = NULL; cr.chan[1].desc = NULL; + + monitor.func = (MonitorCallback_t)&uPD7201Device::MonitorUpdate; + monitor.SetSize(48, 22); + // 登録は継承先で行う。機種ごとに通りのいい名前を使い分けているため。 } // デストラクタ @@ -26,9 +30,8 @@ uPD7201Device::~uPD7201Device() } // リセット -// どのタイミングで呼ばれるかは上位による void -uPD7201Device::Reset() +uPD7201Device::ResetHard() { putlog(2, "リセット"); @@ -361,8 +364,8 @@ uPD7201Device::ReadData(struct SIO::chan chan->sr0 &= ~SIO::SR0_RXAVAIL; ChangeInterrupt(); } else { - // 少ないので毎回前詰めしちゃえ - memmove(chan->rxbuf + 1, chan->rxbuf, chan->rxlen); + chan->rxbuf[0] = chan->rxbuf[1]; + chan->rxbuf[1] = chan->rxbuf[2]; } } else { // XXX 何が読めるか @@ -492,52 +495,52 @@ uPD7201Device::ChangeInterrupt() // モニター void -uPD7201Device::MonitorUpdate(TextScreen& monitor) +uPD7201Device::MonitorUpdate(Monitor *, TextScreen& screen) { int y; - monitor.Clear(); + screen.Clear(); for (int i = 0; i < 2; i++) { int x = 0; y = i * 10; - MonitorUpdateCh(monitor, i, x, y); + MonitorUpdateCh(screen, i, x, y); } // CR2A uint cr2a = cr.cr2a; y = 20; - monitor.Print(0, y, "CR2A:$%02x", cr2a); + screen.Print(0, y, "CR2A:$%02x", cr2a); if ((cr2a & 0x80)) { - monitor.Print(9, y, TA::On, "SYNC"); + screen.Print(9, y, TA::On, "SYNC"); } else { - monitor.Print(9, y, "RTSB"); + screen.Print(9, y, "RTSB"); } - monitor.Print(14, y, "----"); - monitor.Print(19, y, TA::OnOff((cr2a & 0x20)), "Vect"); + screen.Print(14, y, "----"); + screen.Print(19, y, TA::OnOff((cr2a & 0x20)), "Vect"); if ((cr2a & 0x18) == 0x10) { - monitor.Print(24, y, "IM=V4-V2"); + screen.Print(24, y, "IM=V4-V2"); } else { - monitor.Print(24, y, "IM=V2-V0"); + screen.Print(24, y, "IM=V2-V0"); } // bit2 (Priority Select) は bit0 が 0 の時だけ意味があるようだ if ((cr2a & 0x01) == 0) { if ((cr2a & 0x04)) { - monitor.Print(34, y, "RxTx"); + screen.Print(34, y, "RxTx"); } else { - monitor.Print(34, y, "A->B"); + screen.Print(34, y, "A->B"); } } // bit1,0 はよく分からん - monitor.Print(39, y, "INT/DMA=%d", (cr2a & 0x3)); + screen.Print(39, y, "INT/DMA=%d", (cr2a & 0x3)); y++; // CR2B - monitor.Print(0, y, "CR2B:$%02x", cr.vector); + screen.Print(0, y, "CR2B:$%02x", cr.vector); } // モニター (1チャンネル) void -uPD7201Device::MonitorUpdateCh(TextScreen& monitor, +uPD7201Device::MonitorUpdateCh(TextScreen& screen, int ch, int xbase, int ybase) { struct SIO::channel *chan = &cr.chan[ch]; @@ -570,33 +573,33 @@ uPD7201Device::MonitorUpdateCh(TextScree x = xbase; y = ybase; - monitor.Print(x, y++, "Channel %s: %s", chan->name, chan->desc); - monitor.Print(x, y++, "CR0: $%02x", cr0); - monitor.Print(x, y++, "CR1: $%02x", cr1); - monitor.Print(x, y++, "CR3: $%02x", cr3); - monitor.Print(x, y++, "CR4: $%02x", cr4); - monitor.Print(x, y++, "CR5: $%02x", cr5); - monitor.Print(x, y++, "SR0: $%02x", sr0); - monitor.Print(x, y++, "SR1: $%02x", sr1); - monitor.Print(x, y, "RXbuf: %d", rxlen); + screen.Print(x, y++, "Channel %s: %s", chan->name, chan->desc); + screen.Print(x, y++, "CR0: $%02x", cr0); + screen.Print(x, y++, "CR1: $%02x", cr1); + screen.Print(x, y++, "CR3: $%02x", cr3); + screen.Print(x, y++, "CR4: $%02x", cr4); + screen.Print(x, y++, "CR5: $%02x", cr5); + screen.Print(x, y++, "SR0: $%02x", sr0); + screen.Print(x, y++, "SR1: $%02x", sr1); + screen.Print(x, y, "RXbuf: %d", rxlen); int i; for (i = 0; i < rxlen; i++) { - monitor.Print(x + 9 + i * 4, y, "$%02x", chan->rxbuf[i]); + screen.Print(x + 9 + i * 4, y, "$%02x", chan->rxbuf[i]); } for (; i < sizeof(chan->rxbuf); i++) { - monitor.Print(x + 9 + i * 4, y, "---"); + screen.Print(x + 9 + i * 4, y, "---"); } // 内部割り込み状態 - monitor.Print(31, y, "Intr:"); - monitor.Print(37, y, TA::OnOff(chan->int_asserted & SIO::INTR_RX), "Rx"); - monitor.Print(40, y, TA::OnOff(chan->int_asserted & SIO::INTR_SP), "SP"); - monitor.Print(43, y, TA::OnOff(chan->int_asserted & SIO::INTR_TX), "Tx"); - monitor.Print(46, y, TA::OnOff(chan->int_asserted & SIO::INTR_ES), "ES"); + screen.Print(31, y, "Intr:"); + screen.Print(37, y, TA::OnOff(chan->int_asserted & SIO::INTR_RX), "Rx"); + screen.Print(40, y, TA::OnOff(chan->int_asserted & SIO::INTR_SP), "SP"); + screen.Print(43, y, TA::OnOff(chan->int_asserted & SIO::INTR_TX), "Tx"); + screen.Print(46, y, TA::OnOff(chan->int_asserted & SIO::INTR_ES), "ES"); y = ybase + 1; x = xbase; // CR0 - monitor.Print(x + 9, y, "CRC=%d", (cr0 >> 6)); + screen.Print(x + 9, y, "CRC=%d", (cr0 >> 6)); static const char * const cmd_str[] = { // 0123456789012345 "No operation", @@ -609,15 +612,15 @@ uPD7201Device::MonitorUpdateCh(TextScree "End of Interrupt", }; uint cmd = (cr0 >> 3) & 7; - monitor.Print(x + 19, y, "CMD=%d(%s)", cmd, cmd_str[cmd]); - monitor.Print(x + 43, y, "PTR=%d", (cr0 & 7)); + screen.Print(x + 19, y, "CMD=%d(%s)", cmd, cmd_str[cmd]); + screen.Print(x + 43, y, "PTR=%d", (cr0 & 7)); y++; // CR1 static const char * const cr1_str[] = { "WaEn", "----", "WaRx", "", "", "----", "TxIE", "ESEn" }; - MonitorReg(monitor, x + 9, y, cr1, cr1_str); + MonitorReg(screen, x + 9, y, cr1, cr1_str); static const char * const rxint_str[] = { // 2345678 "=SpOnly", @@ -625,53 +628,53 @@ uPD7201Device::MonitorUpdateCh(TextScree "=1stChr", "Disable", }; - monitor.Print(x + 24, y, "RI%s", rxint_str[(cr1 >> 3) & 3]); + screen.Print(x + 24, y, "RI%s", rxint_str[(cr1 >> 3) & 3]); y++; // CR3 static const char * const cr3_str[] = { "", "", "AuEn", "----", "----", "----", "----", "RXEn" }; - MonitorReg(monitor, x + 9, y, cr3, cr3_str); - monitor.Print(x + 9, y, "RXbits=%d", 5 + ((cr3 >> 6) & 3)); + MonitorReg(screen, x + 9, y, cr3, cr3_str); + screen.Print(x + 9, y, "RXbits=%d", 5 + ((cr3 >> 6) & 3)); y++; // CR4 static const char * const cr4_str[] = { "", "", "", "", "", "", "PaEv", "PaEn" }; - MonitorReg(monitor, x + 9, y, cr4, cr4_str); + MonitorReg(screen, x + 9, y, cr4, cr4_str); static const char * const clkrate_str[] = { "1", "16", "32", "64" }; - monitor.Print(x + 9, y, "Rate=x%s", clkrate_str[(cr4 >> 6) & 3]); + screen.Print(x + 9, y, "Rate=x%s", clkrate_str[(cr4 >> 6) & 3]); static const char * const syncmode_str[] = { "Mono", "Bi", "HDLC", "Ext" }; - monitor.Print(x + 19, y, "Sync=%s", syncmode_str[(cr4 >> 4) & 3]); + screen.Print(x + 19, y, "Sync=%s", syncmode_str[(cr4 >> 4) & 3]); static const char * const stopbit_str[] = { "Sync", "1", "1.5", "2" }; - monitor.Print(x + 29, y, "Stop=%s", stopbit_str[(cr4 >> 2) & 3]); + screen.Print(x + 29, y, "Stop=%s", stopbit_str[(cr4 >> 2) & 3]); y++; // CR5 static const char * const cr5_str[] = { "DTR", "", "", "SBrk", "TXEn", "CRC", "!RTS", "TCEn" }; - MonitorReg(monitor, x + 9, y, cr5, cr5_str); - monitor.Print(x + 14, y, "TXbits=%d", 5 + ((cr5 >> 5) & 3)); + MonitorReg(screen, x + 9, y, cr5, cr5_str); + screen.Print(x + 14, y, "TXbits=%d", 5 + ((cr5 >> 5) & 3)); y++; // SR0 static const char * const sr0_str[] = { "BrAb", "TxUn", "CTS", "SYNC", "DCD", "TxEm", "IntP", "RxAv" }; - MonitorReg(monitor, x + 9, y, sr0, sr0_str); + MonitorReg(screen, x + 9, y, sr0, sr0_str); // SR0 の bit1 (Interrupt Pending) は SR0A のみ。SR0B では 0。 if (ch == 1) { - monitor.Print(39, y, "----"); + screen.Print(39, y, "----"); } y++; @@ -679,22 +682,22 @@ uPD7201Device::MonitorUpdateCh(TextScree static const char * const sr1_str[] = { "EOF", "CRCE", "RxOv", "PaEr", "", "", "", "Sent" }; - MonitorReg(monitor, x + 9, y, sr1, sr1_str); - monitor.Print(x + 29, y, "ResidueCode=%d", (sr1 >> 1) & 7); + MonitorReg(screen, x + 9, y, sr1, sr1_str); + screen.Print(x + 29, y, "ResidueCode=%d", (sr1 >> 1) & 7); y++; } // レジスタをビットごとに表示する。MonitorUpdate の下請け。 void -uPD7201Device::MonitorReg(TextScreen& monitor, +uPD7201Device::MonitorReg(TextScreen& screen, int x, int y, uint32 reg, const char * const *names) { for (int i = 0; i < 8; i++) { if (strcmp(names[i], "----") == 0) { - monitor.Puts(x + i * 5, y, TA::Disable, names[i]); + screen.Puts(x + i * 5, y, TA::Disable, names[i]); } else { bool b = reg & (1 << (7 - i)); - monitor.Puts(x + i * 5, y, TA::OnOff(b), names[i]); + screen.Puts(x + i * 5, y, TA::OnOff(b), names[i]); } } }