|
|
1.1 root 1: //
2: // nono
1.1.1.3 ! root 3: // Copyright (C) 2020 nono project
! 4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
9: #include "device.h"
10:
11: // uPD7201/Z8530 のレジスタ
12: //
13: // uPD7201 は、書き込みが CR (Command Register) 8本、
14: // 読み込みが SR (Status Register) 2本。
15: // Z8530 は、書き込みが WR (Write Register) 16本、
16: // 読み込みが RR (Read Register) 8本。
17: //
18: // Z8530 の WR0..WR7、RR0..RR2 は (名前が異なるが)
19: // uPD7201 の CR0..CR7、SR0..SR2 とわりとよく似ている (所々違う)。
20: //
21: // そのためデバイスは uPD7201Device クラスを基底に、SIODevice
22: // (ほぼ uPD7201Device) と SCCDevice (Z8530) とに派生している。
23: // レジスタ構造体は C++ の制約的に両方のセットを持ったものを一つ
24: // 用意するほうが楽なので、こうなっている。
25: struct SIO
26: {
27: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
28: // CR0 | CRC | Command | Pointer |
29: static const int CR0_CRC = 0xc0;
30: static const int CR0_CMD = 0x38;
31: static const int CR0_PTR = 0x07;
32:
33: // Z8530 ではコマンド %000 と %001 がレジスタ切り替えなので、
34: // CMD が 0x38、PTR が 0x0f とあえて被せてある。
35: static const int WR0_CRC = CR0_CRC;
36: static const int WR0_CMD = CR0_CMD;
37: static const int WR0_PTR = 0x0f;
38:
39: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
40: // CR1 | WE | -- | WR | RX Int | -- | TE | ES |
41: // | | | | +---- E/S Int Enable
42: // | | | +--------- TX INT/DMA Enable
43: // | | +--------------------- RX Int Mode
44: // | +----------------------------- Wait on RX(=%1),TX(=%0)
45: // +--------------------------------------- Wait Enable
46: static const int CR1_WAIT_EN = 0x80;
47: static const int CR1_WAIT_RX = 0x20;
48: static const int CR1_RXINT = 0x18;
49: static const int CR1_TXINT_EN = 0x02;
50: static const int CR1_ESINT_EN = 0x01;
51:
52: static const int WR1_WAIT_EN = CR1_WAIT_EN;
53: static const int WR1_WAIT_RX = CR1_WAIT_RX;
54: static const int WR1_RXINT = CR1_RXINT;
55: static const int WR1_TXINT_EN = CR1_TXINT_EN;
56: static const int WR1_ESINT_EN = CR1_ESINT_EN;
57:
58: // CR1_RXINT
59: static const int RXINT_DISABLE = 0x00; // disabled
60: static const int RXINT_FIRSTCHAR = 0x08; // First charactoer intr.
61: static const int RXINT_ALL_INC_SPECIAL = 0x10; // All char include special
62: static const int RXINT_ALL_EXC_SPECIAL = 0x18; // All char exclude special
63:
64: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
65: // CR3 | RX bits | AE | -- -- -- -- | RE |
66: // | | +---- RX Enable
67: // | +----------------------------- Auto Enable
68: // +------------------------------------ RX bits
69: static const int CR3_RXBITS = 0xc0;
70: static const int CR3_AUTO_EN = 0x40;
71: static const int CR3_RX_EN = 0x01;
72:
73: static const int WR3_RXBITS = CR3_RXBITS;
74: static const int WR3_AUTO_EN = CR3_AUTO_EN;
75: static const int WR3_RX_EN = CR3_RX_EN;
76:
77: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
78: // CR4 | ClkRate | SyncMode| StopBits| PV | PE |
79: // | | | | +---- Parity Enable(%1)
80: // | | | +--------- Parity Even(%1)
81: // | | +---------------- Stop Bits
82: // | +-------------------------- Sync Mode
83: // +------------------------------------ Clock Rate
84: //
85: static const int CR4_CLKRATE = 0xc0;
86: static const int CR4_SYNCMODE = 0x30;
87: static const int CR4_STOPBITS = 0x0c;
88: static const int CR4_PARITY_EVEN= 0x02;
89: static const int CR4_PARITY_EN = 0x01;
90:
91: static const int WR4_CLKRATE = CR4_CLKRATE;
92: static const int WR4_SYNCMODE = CR4_SYNCMODE;
93: static const int WR4_STOPBITS = CR4_STOPBITS;
94: static const int WR4_PARITY_EVEN= CR4_PARITY_EVEN;
95: static const int WR4_PARITY_EN = CR4_PARITY_EN;
96:
97: static const int SYNC_8BIT = 0x00;
98: static const int SYNC_16BIT = 0x10;
99: static const int SYNC_HDLC = 0x20;
100: static const int SYNC_EXT = 0x30;
101:
102: static const int SYNC_MODE = 0x00;
103: static const int STOP_BITS_1 = 0x04;
104: static const int STOP_BITS_1_5 = 0x08;
105: static const int STOP_BITS_2 = 0x0c;
106:
107: enum Mode {
108: SYNC = 0,
109: ASYNC = 1,
110: HDLC = 2,
111: };
112:
113: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
114: // CR5 | DTR| TX bits | SB | TE | CRC| RTS| TC |
115: // | | | | | | +---- TX CRC Enable
116: // | | | | | +--------- ~RTS
117: // | | | | +-------------- CRC-16/CCITT
118: // | | | +------------------- TX Enable
119: // | | +------------------------ Send Break
120: // | +------------------------------- TX Bits
121: // +--------------------------------------- ~DTR
122: static const int CR5_DTR = 0x80;
123: static const int CR5_TXBITS = 0x60;
124: static const int CR5_SENDBREAK = 0x10;
125: static const int CR5_TX_EN = 0x08;
126: static const int CR5_CRC16 = 0x04;
127: static const int CR5_RTS = 0x02;
128: static const int CR5_TXCRC_EN = 0x01;
129:
130: static const int WR5_DTR = CR5_DTR;
131: static const int WR5_TXBITS = CR5_TXBITS;
132: static const int WR5_SENDBREAK = CR5_SENDBREAK;
133: static const int WR5_TX_EN = CR5_TX_EN;
134: static const int WR5_CRC16 = CR5_CRC16;
135: static const int WR5_RTS = CR5_RTS;
136: static const int WR5_TXCRC_EN = CR5_TXCRC_EN;
137:
138: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
139: // SR0 | BA | TU | CTS| SY | DCD| TE | IP | RA |
140: static const int SR0_BREAK = 0x80; // Break/Abort
141: static const int SR0_TXUNDER = 0x40; // Tx Underrun
142: static const int SR0_CTS = 0x20; // CTS
143: static const int SR0_SYNC = 0x10; // SYNC
144: static const int SR0_DCD = 0x08; // DCD
145: static const int SR0_TXEMPTY = 0x04; // Tx Buffer Empty
146: static const int SR0_INTPEND = 0x02; // Interrupt Pending
147: static const int SR0_RXAVAIL = 0x01; // Rx Character Available
148:
149: static const int RR0_BREAK = SR0_BREAK;
150: static const int RR0_TXUNDER = SR0_TXUNDER;
151: static const int RR0_CTS = SR0_CTS;
152: static const int RR0_SYNC = SR0_SYNC;
153: static const int RR0_DCD = SR0_DCD;
154: static const int RR0_TXEMPTY = SR0_TXEMPTY;
155: static const int RR0_INTPEND = SR0_INTPEND;
156: static const int RR0_RXAVAIL = SR0_RXAVAIL;
157:
158: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
159: // SR1 | EF | CRC| RO | PE | ResidueCode | AS |
160: static const int SR1_ENDOFFRAME = 0x80; // End of Frame
161: static const int SR1_CRCERROR = 0x40; // CRC/Framing Error
162: static const int SR1_RXOVERRUN = 0x20; // Rx Overrun
163: static const int SR1_PARITYERROR= 0x10; // Parity Error
164: static const int SR1_RESIDUEMASK= 0x0e; // Residue Code 2-0
165: static const int SR1_ALL_SENT = 0x01; // All Sent
166:
167: static const int RR1_ENDOFFRAME = SR1_ENDOFFRAME;
168: static const int RR1_CRCERROR = SR1_CRCERROR;
169: static const int RR1_RXOVERRUN = SR1_RXOVERRUN;
170: static const int RR1_PARITYERROR= SR1_PARITYERROR;
171: static const int RR1_RESIDUEMASK= SR1_RESIDUEMASK;
172: static const int RR1_ALL_SENT = SR1_ALL_SENT;
173:
174: int cr2a; // CR2A
175: int vector;
176: struct channel {
177: // 二次変数など
178: int ptr; // CR0 で決まるレジスタ選択ポインタ
179: int id; // チャンネル番号。0 か 1
180: const char *name; // チャンネル名。"A" か "B"
181: const char *desc; // チャンネルの用途(モニタ表示用)
182: Mode mode; // CR4 で決まるモード
183:
184: // uPD7201 レジスタ
185: uint8 cr0;
186: uint8 cr1;
187: // CR2 は特殊なのでここにはない
188: uint8 cr3;
189: uint8 cr4;
190: uint8 cr5;
191: uint8 cr6; // CR6 (未実装)
192: uint8 cr7; // CR7 (未実装)
193:
194: uint8 sr0;
195: uint8 sr1;
196:
197: // ここから Z8530 拡張
198: uint8 wr11; // WR11
199: uint16 tc; // WR12, WR13
200: uint8 wr14; // WR14
201: uint8 wr15; // WR15
202:
203: // ここからその他の内部状態
204: bool es_ratched; // E/S ビットがラッチされているか
205:
206: // 受信バッファは短いので先頭からの FIFO とし、
207: // 取り出したら前にずらす?
208: uint8 rxbuf[3]; // 受信バッファ(FIFO)
209: int rxlen; // 受信バッファの有効バイト数
210: bool rxrecved; // 1文字でも受信したら true (FirstCharIntr用)
211: } chan[2];
212: };
213:
214: class uPD7201Device
215: : public IODevice
216: {
1.1.1.3 ! root 217: using inherited = IODevice;
1.1 root 218: public:
219: uPD7201Device();
1.1.1.3 ! root 220: ~uPD7201Device() override;
1.1 root 221:
1.1.1.3 ! root 222: bool MonitorUpdate() override;
1.1 root 223:
224: // 受信
225: bool Rx(int ch, uint32 data);
226:
227: protected:
228: // チップリセット
229: void Reset();
230:
231: void ResetChannel(struct SIO::channel *chan);
232: virtual uint8 ReadCtrl(struct SIO::channel *chan);
1.1.1.2 root 233: uint8 ReadData(struct SIO::channel *chan);
1.1 root 234: virtual void WriteCtrl(struct SIO::channel *chan, uint32 data);
235: void WriteData(struct SIO::channel *chan, uint32 data);
1.1.1.2 root 236: uint8 PeekCtrl(const struct SIO::channel *chan) const;
237: uint8 PeekData(const struct SIO::channel *chan) const;
1.1 root 238:
239: // 割り込みを上げる (上位デバイスで用意する)
240: virtual void Interrupt() = 0;
241:
242: struct SIO cr {};
243:
244: static const int bits_per_char[4];
245:
246: private:
1.1.1.2 root 247: uint8 ReadSR0(const struct SIO::channel *chan) const;
248: uint8 ReadSR1(const struct SIO::channel *chan) const;
249:
1.1 root 250: void MonitorUpdateCh(int ch, int xbase, int ybase);
251: void MonitorReg(int, int, uint32 reg, const char * const *names);
252: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.