--- nono/vm/upd7201.cpp 2026/04/29 17:04:28 1.1 +++ nono/vm/upd7201.cpp 2026/04/29 17:04:36 1.1.1.3 @@ -1,6 +1,7 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "upd7201.h" @@ -83,20 +84,14 @@ uPD7201Device::ReadCtrl(struct SIO::chan switch (chan->ptr) { case 0: // SR0 - // 送信バッファは常に空 - data = SIO::SR0_TXEMPTY; - // 受信データがあるか - if (chan->rxlen > 0) { - data |= SIO::SR0_RXAVAIL; - } + data = ReadSR0(chan); putlog(2, "SR%d%s -> $%02x", chan->ptr, chan->name, data); // アクセス後は SR0 へ戻す chan->ptr = 0; break; case 1: // SR1 - // エラーとか起きてないという状態だけ再現。 - data = SIO::SR1_ALL_SENT; + data = ReadSR1(chan); putlog(2, "SR%d%s -> $%02x", chan->ptr, chan->name, data); // アクセス後は SR0 へ戻す chan->ptr = 0; @@ -281,11 +276,58 @@ uPD7201Device::WriteCtrl(struct SIO::cha } } +// 制御ポートの Peek +uint8 +uPD7201Device::PeekCtrl(const struct SIO::channel *chan) const +{ + switch (chan->ptr) { + case 0: // SR0 + return ReadSR0(chan); + + case 1: // SR1 + return ReadSR1(chan); + + case 2: // SR2 + // SR2A はない。SR2B はベクタの読み出し + if (chan->id == 1) { + return cr.vector; + } + FALLTHROUGH; + + default: + // 未調査 + return 0xff; + } +} + +// SR0 の読み込み (Read, Peek 共通) +uint8 +uPD7201Device::ReadSR0(const struct SIO::channel *chan) const +{ + uint32 data; + + // 送信バッファは常に空 + data = SIO::SR0_TXEMPTY; + // 受信データがあるか + if (chan->rxlen > 0) { + data |= SIO::SR0_RXAVAIL; + } + return data; +} + +// SR1 の読み込み (Read, Peek 共通) +uint8 +uPD7201Device::ReadSR1(const struct SIO::channel *chan) const +{ + // エラーとか起きてないという状態だけ再現。 + return SIO::SR1_ALL_SENT; +} + + // データポートの読み込み uint8 -uPD7201Device::ReadData(int ch) +uPD7201Device::ReadData(struct SIO::channel *chan) { - struct SIO::channel *chan = &cr.chan[ch]; uint8 data; if (chan->rxlen > 0) { @@ -330,7 +372,20 @@ uPD7201Device::WriteData(struct SIO::cha } } -// TX/RX の bits/char のレジスタ値を実際の bits/char の値に変換します。 +// データポートの Peek +uint8 +uPD7201Device::PeekData(const struct SIO::channel *chan) const +{ + if (chan->rxlen > 0) { + // 受信バッファにデータがあれば先頭バイトが見える + return chan->rxbuf[0]; + } else { + // 空の時は? + return 0xff; + } +} + +// TX/RX の bits/char のレジスタ値を実際の bits/char の値に変換する。 /* static */ const int uPD7201Device::bits_per_char[] = { 5, 7, 6, 8 }; @@ -522,11 +577,10 @@ uPD7201Device::MonitorReg(int x, int y, { for (int i = 0; i < 8; i++) { if (strcmp(names[i], "----") == 0) { - monitor.Print(x + i * 5, y, TA::Disable, "%s", names[i]); + monitor.Puts(x + i * 5, y, TA::Disable, names[i]); } else { bool b = reg & (1 << (7 - i)); - uint attr = b ? TA::On : TA::Off; - monitor.Print(x + i * 5, y, attr, "%s", names[i]); + monitor.Puts(x + i * 5, y, TA::OnOff(b), names[i]); } } }