--- nono/vm/upd7201.h 2026/04/29 17:04:36 1.1.1.3 +++ nono/vm/upd7201.h 2026/04/29 17:04:50 1.1.1.6 @@ -81,7 +81,7 @@ struct SIO // | | +---------------- Stop Bits // | +-------------------------- Sync Mode // +------------------------------------ Clock Rate - // + // static const int CR4_CLKRATE = 0xc0; static const int CR4_SYNCMODE = 0x30; static const int CR4_STOPBITS = 0x0c; @@ -171,6 +171,43 @@ struct SIO static const int RR1_RESIDUEMASK= SR1_RESIDUEMASK; static const int RR1_ALL_SENT = SR1_ALL_SENT; + // 割り込みベクタ ChB ChA + // Tx Buffer Empty %000 %100 + // External/Status Change %001 %101 + // Rx Character Available %010 %110 + // Special Rx Condition %011 %111 + // (この 3bit が V4-V2 か V2-V0 のところに出力される) + static const uint INTR_TX = (1U << 0); + static const uint INTR_ES = (1U << 1); + static const uint INTR_RX = (1U << 2); + static const uint INTR_SP = (1U << 3); + + // 割り込みあたりのロジック (uPD7201/7201A Figure 3-2 より INT 分のみ) + // + // Rx Disable (CR1:b1) *1 -----------------+ *1: Rx Enable (CR3:b0) + // | じゃなくて? + // +---+ | + // * RxCharAvailable ---->| | | + // | AND )--+ | +---+ + // All/First RxChar --->| | | +---+ +->| | + // +---+ +->) | | AND )--+ + // ) OR )-->| | | + // * Special Rx Condition ----------->) | +---+ | +-+ + // +---+ +->) | + // ) | --- + // * External/Status -------------------------------------->) OR |o-> INT + // ) | + // +---+ +->) | + // * Tx Buffer Empty ---------------->| | +----+ | +-+ + // | | | | | + // (Reset TxIntPend Cmd) --------->o| AND )-->| | | + // | | | | | + // Tx INT/DMA Enable (CR1:b1) ----->| | | AND )--+ + // +---+ | | + // | | + // INT DMA Mode (CR2A b1-0) ----------------->| | + // +----+ + int cr2a; // CR2A int vector; struct channel { @@ -182,6 +219,8 @@ struct SIO Mode mode; // CR4 で決まるモード // uPD7201 レジスタ + // CR0 の下位 3bit (PTR 部分) は読み出し時には使わないこと (代わりに + // ptr を使用する)。書き込み時は書き込んでよい(書き捨て)。 uint8 cr0; uint8 cr1; // CR2 は特殊なのでここにはない @@ -195,6 +234,7 @@ struct SIO uint8 sr1; // ここから Z8530 拡張 + uint8 wr10; // WR10 uint8 wr11; // WR11 uint16 tc; // WR12, WR13 uint8 wr14; // WR14 @@ -207,7 +247,18 @@ struct SIO // 取り出したら前にずらす? uint8 rxbuf[3]; // 受信バッファ(FIFO) int rxlen; // 受信バッファの有効バイト数 - bool rxrecved; // 1文字でも受信したら true (FirstCharIntr用) + + // First Char 用のフラグで、この受信で割り込みを起こすなら true。 + // ALL なら常に true。FIRSTCHAR の時は最初が true で1文字目の受信 + // 割り込みを出したところで false にする。 + bool all_or_first; + + // Reset Tx Interrupt/DMA Pending コマンドによる Tx 割り込み抑制。 + // 通常 true にしておき、コマンドが発行されたら false にする。 + // XXX 解除するのはリセットでええんかな? + bool reset_txint_pend; + + uint int_asserted; // 割り込み要因を保持 } chan[2]; }; @@ -217,9 +268,10 @@ class uPD7201Device using inherited = IODevice; public: uPD7201Device(); - ~uPD7201Device() override; + virtual ~uPD7201Device() override; - bool MonitorUpdate() override; + void ResetHard() override; + void MonitorUpdate(TextScreen&) override; // 受信 bool Rx(int ch, uint32 data); @@ -244,9 +296,18 @@ class uPD7201Device static const int bits_per_char[4]; private: - uint8 ReadSR0(const struct SIO::channel *chan) const; - uint8 ReadSR1(const struct SIO::channel *chan) const; - - void MonitorUpdateCh(int ch, int xbase, int ybase); - void MonitorReg(int, int, uint32 reg, const char * const *names); + void WriteCR0(struct SIO::channel *chan, uint32 data); + void WriteCR1(struct SIO::channel *chan, uint32 data); + void WriteCR2(struct SIO::channel *chan, uint32 data); + void WriteCR3(struct SIO::channel *chan, uint32 data); + void WriteCR4(struct SIO::channel *chan, uint32 data); + void WriteCR5(struct SIO::channel *chan, uint32 data); + void WriteCR6(struct SIO::channel *chan, uint32 data); + void WriteCR7(struct SIO::channel *chan, uint32 data); + + void ChangeInterrupt(); + + void MonitorUpdateCh(TextScreen&, int ch, int xbase, int ybase); + void MonitorReg(TextScreen&, + int, int, uint32 reg, const char * const *names); };