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