|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // uPD7201(MPSC) と Z8530(SCC) の共通部分 (シリアルポート1個つき)
9: //
10:
11: #pragma once
12:
13: #include "device.h"
14: #include "message.h"
15: #include <array>
16:
17: #if defined(MPSCC_SIO_LOG_HACK)
18: // SIO で SR0 のログ表示に細工をするため、
19: // SIO, MPSCC で putlog() マクロを再定義している。
20: #undef putlog
21: #define putlog(lv, fmt...) do { \
22: if (__predict_false(loglevel >= (lv))) { \
23: putlogn(fmt); \
24: sr0_logphase = 0; \
25: } \
26: } while (0)
27: #endif
28:
29: class HostCOMDevice;
1.1.1.3 root 30: class InterruptDevice;
1.1 root 31:
32: // 1チャンネル分の共通部分
1.1.1.8 root 33: class MPSCCChan final
1.1 root 34: {
35: public:
36: MPSCCChan();
1.1.1.8 root 37: ~MPSCCChan();
1.1 root 38:
39: void Init(int id_);
40:
41: // プロパティっぽいもの
42: int id {}; // チャンネル番号 (0 or 1)
43: char name {}; // チャンネル名 ('A' or 'B')
44: const char *desc {}; // チャンネルの用途(モニタ表示用)
45: uint32 ctrladdr {}; // 制御ポートのアドレス (モニタ表示用)
46: uint32 dataaddr {}; // データポートのアドレス (モニタ表示用)
47:
48: // ここから内部構造
49:
50: // CR0/WR0 付近
51: uint8 crc_cmd {}; // CRC
52: uint8 cmd {}; // Command
53: uint ptr {}; // Pointer (uPD7201 は 3bit、Z8530 は実質 4bit)
54:
55: // CR1/WR1 付近
56: bool wait_enable {}; // b7
57: bool wait_func {}; // b6; Z8530 Only
58: bool wait_on_rx {}; // b5
59: bool txint_enable {}; // b1
60: bool esint_enable {}; // b0
61:
62: // Z8530 では割り込みモード3種類とパリティエラーを Sp.Rx に含むかどうかが
63: // 独立して選択できるため、組み合わせは 3 * 2 (+ Disable 1通り) = 7通り。
64: // uPD7201 ではこれに相当する設定は RXINT の 2bit しかなく、Disable を除く
65: // 3通りはこのうち 3つがプリセットされたような感じ。
66: // (もちろん歴史的経緯はこの逆だろうけど)
67: //
68: // RXInt SP 割込モード Parity Error を Sp.Rx に含むか
69: // ----------------- ------------ ------------------------------
70: // 0 0 - : Disable -
71: // uPD7201 0 1 - : 1stChar no
72: // uPD7201 1 0 - : AllChar yes
73: // uPD7201 1 1 - : AllChar no
74: // Z8530 0 1 0 : 1stChar no
75: // Z8530 0 1 1 : 1stChar yes
76: // Z8530 1 0 0 : AllChar no
77: // Z8530 1 0 1 : AllChar yes
78: // Z8530 1 1 0 : SpOnly no
79: // Z8530 1 1 1 : SpOnly yes
80: static const uint RXINT_DISABLE = 0x00;
81: static const uint RXINT_1STCHAR = 0x01;
82: static const uint RXINT_ALLCHAR = 0x02;
83: static const uint RXINT_SPONLY = 0x03; // Z8530 Only
84: uint rxint_mode {};
85: bool sp_parity {};
86:
87: // SR0/RR0 付近
88: bool break_detected {};
89: bool tx_underrun {};
90: bool nCTS {};
91: bool nSYNC {};
92: bool nDCD {};
93:
94: // これらのレジスタは uPD7201/Z8530 で共通
95:
1.1.1.2 root 96: // CR3/WR3 付近
1.1.1.5 root 97: uint rxbits {}; // 受信データビット数 (レジスタ値ではない)
1.1.1.2 root 98: uint8 cr3_sync {}; // SyncMode でだけ使う bit4-1 を保存
99: bool auto_enable {};
1.1 root 100: bool rx_enable {};
1.1.1.2 root 101:
102: // CR4/WR4 付近
1.1.1.5 root 103: uint clkrate {}; // クロック倍率 (レジスタ値ではない)
1.1.1.2 root 104: uint8 syncmode {}; // bit5,4 を保存
105: uint8 stopbits {}; // STOPBITS_*
106: bool parity_even {};
107: int parity_enable {}; // パリティ有効 (追加するビット数 0 か 1 で保持)
108:
109: // CR5/WR5 付近
110: bool nDTR {}; // ~DTR
1.1.1.5 root 111: uint txbits {}; // 送信データビット数 (レジスタ値ではない)
1.1.1.2 root 112: bool sendbreak {};
1.1 root 113: bool tx_enable {};
1.1.1.2 root 114: bool crc16 {};
115: bool nRTS {}; // ~RTS
116: bool txcrc_en {};
117:
1.1 root 118: uint8 cr6 {};
119: uint8 cr7 {};
120: uint8 sr1 {};
121:
1.1.1.2 root 122: // いずれもレジスタイメージとして保存
123: uint8 old_cr3 {};
124: uint8 old_cr4 {};
125: uint8 old_cr5 {};
126:
1.1 root 127: // Z8530 専用のレジスタだけど継承とかは面倒なので結局ここに置く
128: uint8 wr10 {};
129: uint8 wr11 {};
130: uint16 tc {}; // WR12, WR13
131: uint8 wr14 {};
132: uint8 wr15 {};
133: uint8 rr10 {};
134:
135: // ここからその他の内部状態
136:
137: bool es_latched {}; // E/S ビットがラッチされているか
138:
139: // 受信バッファは短いので先頭からの FIFO とし、
140: // 取り出したら前にずらす
141: uint8 rxbuf[3] {}; // 受信バッファ(FIFO)
142: int rxlen {}; // 受信バッファの有効バイト数
143:
144: uint8 txbuf {}; // 送信バッファ
145: int txlen {}; // 送信バッファの有効バイト数
146: uint8 tx_shiftreg {}; // 送信シフトレジスタ相当品
147:
148: // First Char 用のフラグで、この受信で割り込みを起こすなら true。
149: // ALL なら常に true。FIRSTCHAR の時は最初が true で1文字目の受信
150: // 割り込みを出したところで false にする。
151: bool all_or_first {};
152:
153: // Tx 割り込み発火用のフラグ。
154: // Tx 割り込みは
155: // 1) Tx 割り込みが有効で
156: // 2) 送信バッファに書き込まれるか Reset Tx INT/DMA Pending コマンドが
157: // 発行されるかした後
158: // 3) 送信バッファが空になった
159: // 場合に発生する。チャンネルリセットとハードリセットで送信バッファが
160: // 空になった場合には発生しない。
161: // ので、ここの 2) を満たす場合 txint_ready = true とする。
162: bool txint_ready {};
163:
164: // 割り込みペンディング (MPSCC::INTPEND_*)
165: //
166: // Z8530 の RR3A レジスタは個別の割り込みペンディング状態が読み出せる。
167: // uPD7201 にも内部に同じだけの状態を持っているが個別に読み出す方法はなく
168: // すべてを OR したペンディングの有無を SR0A b1 で読み出すことが出来る。
169: uint intpend {};
170:
171: // ボーレート (表示用)
172: // Z8530 なら tc から求められる
173: double baudrate {};
174:
175: // 1フレームあたりの送受信のビット数 (表示用)
1.1.1.5 root 176: uint txframebits {};
177: uint rxframebits {};
1.1.1.2 root 178:
179: // LUNA の場合は TxC, RxC ピンに供給されているクロック。
180: // X68030 の場合は Z8530 内部で生成されている基準クロック。
1.1.1.9 ! root 181: // 誤差を減らすため 12 ビット分の時間 [tsec] としている。
! 182: uint64 xc12_tsec {};
1.1.1.2 root 183:
1.1.1.9 ! root 184: // 実際の 12 ビットの通信にかかる時間。xc12_tsec に倍率をかけたもの。
! 185: uint64 bit12_tsec {};
1.1 root 186: };
187:
188: class MPSCC
189: {
190: public:
191: // レジスタ定義
192:
193: // b7 b6 b5 b4 b3 b2 b1 b0
194: // +---------+--------------+--------------+
195: // CR0 | CRC | Command | Pointer |
196: // WR0 +---------+--------------+--------------+
197: //
198: static const uint8 CR0_CRC = 0xc0;
199: static const uint8 CR0_CMD = 0x38;
200: static const uint8 CR0_PTR = 0x07;
201: // Z8530 ではコマンド %000 と %001 がレジスタ切り替えなので、
202: // CMD が 0x38、PTR が 0x0f とあえて被せてある。
203: static const uint8 WR0_CRC = CR0_CRC;
204: static const uint8 WR0_CMD = CR0_CMD;
205: static const uint8 WR0_PTR = 0x0f;
206:
207: // b7 b6 b5 b4 b3 b2 b1 b0
208: // +----+----+----+---------+----+----+----+
209: // CR1 | WE | 0 | WR | RX Int | SAV| TE | ES |
210: // +----+----+----+---------+----+----+----+
211: // | | | | | +---- E/S Int Enable
212: // | | | | +--------- TX INT/DMA Enable
213: // | | | +-------------- Status Affects Vec.(Ch.B)
214: // | | +--------------------- RX Int Mode
215: // | +----------------------------- Wait on RX(=%1),TX(=%0)
216: // +--------------------------------------- Wait Enable
217: //
218: static const uint8 CR1_WAIT_EN = 0x80; // Wait Enable
219: static const uint8 CR1_WAIT_RX = 0x20; // Wait on RX
220: static const uint8 CR1_RXINT = 0x18; // Rx Interrupt Mode
221: static const uint8 CR1_RXINT_DISABLE = 0x00; // Disable
222: static const uint8 CR1_RXINT_1STCHAR = 0x08; // 1st Char
223: static const uint8 CR1_RXINT_ALLCHAR = 0x10; // All Chars
224: static const uint8 CR1_RXINT_ALL_BUT_PE = 0x18; // All Chars exclude P.E.
225: static const uint8 CR1_SAV = 0x04; // Status Affects Vector (Ch.B)
226: static const uint8 CR1_TXINT_EN = 0x02; // Tx Int/DMA Enable
227: static const uint8 CR1_ESINT_EN = 0x01; // E/S Interrupt Enable
228: //
229: // b7 b6 b5 b4 b3 b2 b1 b0
230: // +----+----+----+---------+----+----+----+
231: // WR1 | WE | WF | WR | RX Int | SP | TE | ES |
232: // +----+----+----+---------+----+----+----+
233: // | +-------------- Sp includes Parity Err
234: // +---------------------------------- Wait Function
235: //
236: static const uint8 WR1_WAIT_EN = CR1_WAIT_EN;
237: static const uint8 WR1_WAIT_FUNC = 0x40; // Wait Function
238: static const uint8 WR1_WAIT_RX = CR1_WAIT_RX;
239: static const uint8 WR1_RXINT = CR1_RXINT;
240: static const uint8 WR1_RXINT_DISABLE = 0x00; // Disable
241: static const uint8 WR1_RXINT_1STCHAR = 0x08; // 1st Char or Sp.Cond.
242: static const uint8 WR1_RXINT_ALLCHAR = 0x10; // All Chars or Sp.Cond.
243: static const uint8 WR1_RXINT_SPONLY = 0x18; // Special Conditoin Only
244: static const uint8 WR1_SP_INC_PE = 0x04; // Sp. Condition includes P.E.
245: static const uint8 WR1_TXINT_EN = CR1_TXINT_EN;
246: static const uint8 WR1_ESINT_EN = CR1_ESINT_EN;
247:
248: // b7 b6 b5 b4 b3 b2 b1 b0
249: // +----+----+----+---------+----+---------+
250: // CR2A | R/S| 0 | VM | IntMode | PS | Int/DMA |
251: // +----+----+----+---------+----+---------+
252: // | | | | +------ INT/DMA Mode
253: // | | | +-------------- Priority Select
254: // | | +--------------------- Interrupt Mode -> VIS
255: // | +----------------------------- Vector Mode
256: // +--------------------------------------- ~RTSB/~SYNCB Select
257: //
258: static const uint8 CR2_SYNCB = 0x80; // ~RTSB/~SYNCB Select
259: static const uint8 CR2_VM = 0x20; // Vector Mode
260: static const uint8 CR2_INT = 0x18; // Interrupt Mode -> VIS
261: static const uint8 CR2_PRIOSEL = 0x04; // Priority Select
262: static const uint8 CR2_INTDMA = 0x03; // Int/DMA Mode
263:
264: // b7 b6 b5 b4 b3 b2 b1 b0
265: // +---------+----+-------------------+----+
266: // CR3 | RX bits | AE | (For sync mode) | RE |
267: // WR3 +---------+----+-------------------+----+
268: // | | +---- RX Enable
269: // | +----------------------------- Auto Enable
270: // +------------------------------------ RX bits
271: //
272: static const uint8 CR3_RXBITS = 0xc0; // Rx Bits
273: static const uint8 CR3_AUTO_EN = 0x40; // Auto Enable
1.1.1.2 root 274: static const uint8 CR3_SYNC_MASK = 0x1e;
1.1 root 275: static const uint8 CR3_RX_EN = 0x01; // Rx Enable
276: // WR3
277: static const uint8 WR3_RXBITS = CR3_RXBITS;
278: static const uint8 WR3_AUTO_EN = CR3_AUTO_EN;
279: static const uint8 WR3_RX_EN = CR3_RX_EN;
280:
281: // 並び順が 5, 6, 7, 8 でないので注意
282: static const uint8 RXBITS_5 = 0x00;
283: static const uint8 RXBITS_7 = 0x40;
284: static const uint8 RXBITS_6 = 0x80;
285: static const uint8 RXBITS_8 = 0xc0;
286:
287: // b7 b6 b5 b4 b3 b2 b1 b0
288: // +---------+---------+---------+----+----+
289: // CR4 | ClkRate | SyncMode| StopBits| PEV| PEN|
290: // WR4 +---------+---------+---------+----+----+
291: // | | | | +---- Parity Enable(%1)
292: // | | | +--------- Parity Even(%1)
293: // | | +---------------- Stop Bits
294: // | +-------------------------- Sync Mode
295: // +------------------------------------ Clock Rate
296: //
297: static const uint8 CR4_CLKRATE = 0xc0; // Clock Rate
298: static const uint8 CR4_SYNCMODE = 0x30; // Sync Mode
299: static const uint8 CR4_STOPBITS = 0x0c; // Stop Bits
300: static const uint8 CR4_PARITY_EVEN = 0x02; // Parity Even
301: static const uint8 CR4_PARITY_EN = 0x01; // Parity Enable
302: // WR4
303: static const uint8 WR4_CLKRATE = CR4_CLKRATE;
304: static const uint8 WR4_SYNCMODE = CR4_SYNCMODE;
305: static const uint8 WR4_STOPBITS = CR4_STOPBITS;
306: static const uint8 WR4_PARITY_EVEN = CR4_PARITY_EVEN;
307: static const uint8 WR4_PARITY_EN = CR4_PARITY_EN;
308:
1.1.1.2 root 309: static const uint8 CLKRATE_1 = 0x00;
310: static const uint8 CLKRATE_16 = 0x40;
311: static const uint8 CLKRATE_32 = 0x80;
312: static const uint8 CLKRATE_64 = 0xc0;
313:
314: static const uint8 STOPBITS_SYNC = (0x00 >> 2);
315: static const uint8 STOPBITS_1 = (0x04 >> 2);
316: static const uint8 STOPBITS_1_5 = (0x08 >> 2);
317: static const uint8 STOPBITS_2 = (0x0c >> 2);
1.1 root 318:
319: // b7 b6 b5 b4 b3 b2 b1 b0
320: // +----+---------+----+----+----+----+----+
321: // CR5 |~DTR| TX bits | SB | TE | CRC|~RTS| TCE|
322: // WR5 +----+---------+----+----+----+----+----+
323: // | | | | +---- TX CRC Enable
324: // | | | +-------------- CRC-16/CCITT
325: // | | +------------------- TX Enable
326: // | +------------------------ Send Break
327: // +------------------------------- TX Bits
328: static const uint8 CR5_nDTR = 0x80; // ~DTR
329: static const uint8 CR5_TXBITS = 0x60; // Tx Bits
330: static const uint8 CR5_SENDBREAK = 0x10; // Send Break
331: static const uint8 CR5_TX_EN = 0x08; // Tx Enable
332: static const uint8 CR5_CRC16 = 0x04; // CRC-16/CCITT
333: static const uint8 CR5_nRTS = 0x02; // ~RTS
334: static const uint8 CR5_TXCRC_EN = 0x01; // Tx CRC Enable
335: // WR5
336: static const uint8 WR5_nDTR = CR5_nDTR;
337: static const uint8 WR5_TXBITS = CR5_TXBITS;
338: static const uint8 WR5_SENDBREAK = CR5_SENDBREAK;
339: static const uint8 WR5_TX_EN = CR5_TX_EN;
340: static const uint8 WR5_CRC16 = CR5_CRC16;
341: static const uint8 WR5_nRTS = CR5_nRTS;
342: static const uint8 WR5_TXCRC_EN = CR5_TXCRC_EN;
343:
344: // 並び順が 5, 6, 7, 8 でないので注意
345: static const uint8 TXBITS_5 = 0x00;
346: static const uint8 TXBITS_7 = 0x20;
347: static const uint8 TXBITS_6 = 0x40;
348: static const uint8 TXBITS_8 = 0x60;
349:
350: // b7 b6 b5 b4 b3 b2 b1 b0
351: // +---------+----+----+----+----+----+----+
352: // WR9A | Reset | 0 |SHSL| MIE| DLC| NV | VIS|
353: // WR9B +---------+----+----+----+----+----+----+
354: // | | | | | +---- Vector Includes Status
355: // | | | | +--------- No Vector Mode
356: // | | | +-------------- Disable Lower Chain
357: // | | +------------------- Master Interrupt Enable
358: // | +------------------------ StatusHigh / StatusLow
359: // +------------------------------------ Reset Command
360: // Reset Command は CR0 のコマンドも参照のこと。
361: //
362: static const uint8 WR9_RESET_CMD = 0xc0; // Reset Command
363: static const uint8 WR9_SHSL = 0x10; // Status High / Status Low
364: static const uint8 WR9_MIE = 0x08; // Master Interrupt Enable
365: static const uint8 WR9_DLC = 0x04; // Disable Lower Chain
366: static const uint8 WR9_NV = 0x02; // No Vector Mode
367: static const uint8 WR9_VIS = 0x01; // Vector Includes Status
368:
369: // b7 b6 b5 b4 b3 b2 b1 b0
370: // +----+----+----+----+----+----+----+----+
371: // SR0 | B/A| T/E|~CTS|~S/H|~DCD| TE | IP | RA |
372: // +----+----+----+----+----+----+----+----+
373: // | | | | | +---- Rx Char. Available
374: // | | | | +--------- Interrupt Pending
375: // | | | +-------------- Tx Buffer Empty
376: // | | +------------------------ ~SYNC/Hunt
377: // | +---------------------------------- Tx Underrun/EOM
378: // +--------------------------------------- Break/Abort
379: //
380: static const uint8 SR0_BREAK = 0x80; // Break/Abort
381: static const uint8 SR0_TXUNDER = 0x40; // Tx Underrun/EOM
382: static const uint8 SR0_nCTS = 0x20; // ~CTS
383: static const uint8 SR0_nSYNC = 0x10; // ~SYNC/Hunt
384: static const uint8 SR0_nDCD = 0x08; // ~DCD
385: static const uint8 SR0_TXEMPTY = 0x04; // Tx Buffer Empty
386: static const uint8 SR0_INTPEND = 0x02; // Interrupt Pending
387: static const uint8 SR0_RXAVAIL = 0x01; // Rx Character Available
388: //
389: // +----+----+----+----+----+----+----+----+
390: // RR0 | B/A| T/E|~CTS|~S/H|~DCD| TE | ZC | RA |
391: // +----+----+----+----+----+----+----+----+
392: // +--------- Zero Count
393: //
394: static const uint8 RR0_BREAK = SR0_BREAK;
395: static const uint8 RR0_TXUNDER = SR0_TXUNDER;
396: static const uint8 RR0_nCTS = SR0_nCTS;
397: static const uint8 RR0_nSYNC = SR0_nSYNC;
398: static const uint8 RR0_nDCD = SR0_nDCD;
399: static const uint8 RR0_TXEMPTY = SR0_TXEMPTY;
400: static const uint8 RR0_ZEROCNT = 0x02; // Zero Count
401: static const uint8 RR0_RXAVAIL = SR0_RXAVAIL;
402:
403: // b7 b6 b5 b4 b3 b2 b1 b0
404: // +----+----+----+----+--------------+----+
405: // SR1 | EF | FRE| RO | PE | ResidueCode | AS |
406: // RR1 +----+----+----+----+--------------+----+
407: //
408: static const uint8 SR1_ENDOFFRAME = 0x80; // End of Frame
409: static const uint8 SR1_FRAMEERROR = 0x40; // Framing/CRC Error
410: static const uint8 SR1_RXOVERRUN = 0x20; // Rx Overrun
411: static const uint8 SR1_PARITYERROR = 0x10; // Parity Error
412: static const uint8 SR1_RESIDUEMASK = 0x0e; // Residue Code 2-0
413: static const uint8 SR1_ALL_SENT = 0x01; // All Sent
414: // RR1
415: static const uint8 RR1_ENDOFFRAME = SR1_ENDOFFRAME;
416: static const uint8 RR1_FRAMEERROR = SR1_FRAMEERROR;
417: static const uint8 RR1_RXOVERRUN = SR1_RXOVERRUN;
418: static const uint8 RR1_PARITYERROR = SR1_PARITYERROR;
419: static const uint8 RR1_RESIDUEMASK = SR1_RESIDUEMASK;
420: static const uint8 RR1_ALL_SENT = SR1_ALL_SENT;
421:
422: // b7 b6 b5 b4 b3 b2 b1 b0
423: // +---------+----+----+----+----+----+----+
424: // RR3A | 0 | RxA| TxA| ESA| RxB| TxB| ESB|
425: // +---------+----+----+----+----+----+----+
426: static const uint8 RR3_RXA = 0x20; // Channel A Rx Int. Pending
427: static const uint8 RR3_TXA = 0x10; // Channel A Tx Int. Pending
428: static const uint8 RR3_ESA = 0x08; // Channel A E/S Int. Pending
429: static const uint8 RR3_RXB = 0x04; // Channel B Rx Int. Pending
430: static const uint8 RR3_TXB = 0x02; // Channel B Tx Int. Pending
431: static const uint8 RR3_ESB = 0x01; // Channel B E/S Int. Pending
432:
433: public:
434: // 2チャンネル分
435: std::array<MPSCCChan, 2> chan {};
436:
437: // CR2 付近
438: uint8 intdma_mode {};
439: static const uint8 INTDMA_INT_INT = 0; // Both channel INT
440: static const uint8 INTDMA_DMA_INT = 1; // ChA DMA, ChB INT
441: static const uint8 INTDMA_DMA_DMA = 2; // Both channel DMA
442: bool priority_select {};
443: uint8 int_mode {};
444: static const uint8 INTMODE_85_1 = 0;
445: static const uint8 INTMODE_85_2 = 1;
446: static const uint8 INTMODE_86 = 2;
447: // 割り込み時にベクタを出力するなら true。
448: // CR2A の VM は出力なら %1、WR9 の NV(Non Vector) は出力しない時 %1。
449: bool vectored_mode {};
450: bool syncb {};
451:
452: // WR9 付近
453: uint8 wr9_cmd {}; // WR9 の b6,7
454: bool sav_vis {}; // uPD7201 なら CR1 SAV、Z8530 なら WR9 VIS
455: bool disable_lower_chain {};
456: bool master_int_enable {};
457: bool status_high_low {};
458:
459: // ベクタに割り込み要因(3bit) を入れるかどうかは、
460: // CR1 なら Status Affects Vector、
461: // WR9 なら Vector Includes Status が担当。
462: // どこに (どの順で) 入れるかは CR2A INT Mode か WR9 bit4 で指定する。
463: enum {
464: VIS_FIXED = 0,
465: VIS_432, // uPD7201: SAV = %1 && CR2A INT Mode = %00 or %01
466: VIS_210, // uPD7201: SAV = %1 && CR2A INT Mode = %10
467: VIS_321, // Z8530: VIS = %1 && WR9 SHSL = %0
468: VIS_456, // Z8530: VIS = %1 && WR9 SHSL = %1 (456; 向きに注意)
469: } vis {};
470:
471: // b7 b6 b5 b4 b3 b2 b1 b0
472: // +---------------------------------------+
473: // CR2B | Vector |
474: // WR2 +---------------------------------------+
475: //
476: // b7 b6 b5 b4 b3 b2 b1 b0
477: // +---------------------------------------+
478: // RR2A | Vector (WR2 に書いた値) |
479: // +---------------------------------------+
480: //
481: // +---------------------------------------+
482: // SR2B | Vector (割り込み要因で変化した値) |
483: // RR2B +---------------------------------------+
484: uint vector {};
485:
486: // 割り込み要因
487: static const uint VS_TxB = 0;
488: static const uint VS_ESB = 1;
489: static const uint VS_RxB = 2;
490: static const uint VS_SPB = 3;
491: static const uint VS_TxA = 4;
492: static const uint VS_ESA = 5;
493: static const uint VS_RxA = 6;
494: static const uint VS_SPA = 7;
495: static const uint VS_none = 8; // 割り込みなし
496: };
497:
498: class MPSCCDevice : public IODevice
499: {
500: using inherited = IODevice;
501: protected:
502: // 割り込みペンディングビット。chan.intpend で使用する。
503: static const uint INTPEND_TX = 0x01;
504: static const uint INTPEND_ES = 0x02;
505: static const uint INTPEND_RX = 0x04;
506: static const uint INTPEND_SP = 0x08;
507:
508: // 今のところ SIO, SCC どちらもシリアルポートはチャンネル 0
509: static const int COM_CH = 0;
510:
511: public:
1.1.1.3 root 512: MPSCCDevice();
1.1 root 513: ~MPSCCDevice() override;
514:
515: bool Create() override;
516: void SetLogLevel(int loglevel_) override;
517: bool Init() override;
518:
519: // 1バイト受信 (送信側デバイスが呼ぶ)
520: virtual bool Rx(int ch, uint32 data);
521:
522: protected:
523: // 指定のレジスタ名を返す
1.1.1.5 root 524: virtual const char *CRName(const MPSCCChan&, uint n) const = 0;
525: virtual const char *SRName(const MPSCCChan&, uint n) const = 0;
1.1 root 526: // 現在のレジスタ名を返す
527: const char *CRName(const MPSCCChan& chan) const {
528: return CRName(chan, chan.ptr);
529: }
530: const char *SRName(const MPSCCChan& chan) const {
531: return SRName(chan, chan.ptr);
532: }
533:
534: // チャンネルリセットの共通部
535: void ResetChannelCommon(MPSCCChan&);
536:
1.1.1.5 root 537: // BusIO インタフェース
538: static const uint32 NPORT = 4;
539: bool PokePort(uint32 offset, uint32 data);
540:
1.1 root 541: // レジスタアクセス
1.1.1.2 root 542: static uint8 GetCR0(const MPSCCChan&);
543: static void SetCR3(MPSCCChan&, uint32 data);
544: static uint8 GetCR3(const MPSCCChan&);
545: static void SetCR4(MPSCCChan&, uint32 data);
546: static uint8 GetCR4(const MPSCCChan&);
547: static void SetCR5(MPSCCChan&, uint32 data);
548: static uint8 GetCR5(const MPSCCChan&);
1.1 root 549: uint8 GetSR2B() const;
550: void WriteCR3(MPSCCChan&, uint32 data);
551: void WriteCR4(MPSCCChan&, uint32 data);
552: void WriteCR5(MPSCCChan&, uint32 data);
553: void WriteCR6(MPSCCChan&, uint32 data);
554: void WriteCR7(MPSCCChan&, uint32 data);
555:
556: uint8 ReadData(MPSCCChan&);
557: void WriteData(MPSCCChan&, uint32 data);
558: uint8 PeekData(const MPSCCChan&) const;
559:
560: void SendAbort(MPSCCChan&);
561: void ResetESIntr(MPSCCChan&);
562: void EnableIntrOnNextRx(MPSCCChan&);
563: void ResetTxIntrPending(MPSCCChan&);
564: void ErrorReset(MPSCCChan&);
565: void ResetHighestIUS(MPSCCChan&);
566:
567: // 1バイト送信
568: virtual void Tx(int ch, uint32 data) = 0;
569:
570: // シリアルから1バイト受信のメッセージとイベントコールバック
1.1.1.7 root 571: void HostRxCallback(uint32);
1.1.1.4 root 572: void RxMessage(MessageID, uint32);
1.1.1.8 root 573: void RxCallback(Event *);
1.1 root 574:
575: // 送受信関連
576: void TrySend(MPSCCChan&);
577: void SetTxPeriod(MPSCCChan&);
578: void SetRxPeriod(MPSCCChan&);
1.1.1.8 root 579: void TxCallback(Event *);
1.1 root 580:
581: // 割り込み
582: void ChangeInterrupt();
583: // ペンディングのうち最も優先度の高い割り込み要因 (VS_*) を返す
584: virtual uint GetHighestInt() const = 0;
585:
586: // "9600,N,8,1" みたいなのを返す
587: std::string GetParamStr(const MPSCCChan& chan) const;
588:
1.1.1.2 root 589: void ChangeBaudrate(MPSCCChan&);
590: static int GetClkRate(uint8);
591: int AdditionalBits(MPSCCChan&, bool enable);
592: int GetStopBits(MPSCCChan&, bool enable);
593:
1.1 root 594: // モニタの下請け
1.1.1.9 ! root 595: int MonitorScreenCR345(TextScreen&, int x, int y, uint8, uint8, uint8);
! 596: void MonitorScreenSR1(TextScreen&, int x, int y, uint8 sr1);
1.1 root 597: void MonitorReg(TextScreen&, int x, int y,
598: uint32 reg, const char * const *names);
599:
600: MPSCC mpscc {};
601:
602: // 送受信用イベント
1.1.1.8 root 603: std::array<Event *, 2> txevent {};
604: std::array<Event *, 2> rxevent {};
1.1 root 605:
606: // シリアルポート。
607: // 本当は共通層でやることではないがどう考えても同じコードになるので。
608: std::unique_ptr<HostCOMDevice> hostcom /*{}*/;
609:
610: // SR0 のログ対策 (sio.cpp::ReadCtrl 参照)
611: int sr0_logphase {};
612: uint32 sr0_lastread {};
1.1.1.3 root 613:
614: InterruptDevice *interrupt {};
615:
1.1.1.6 root 616: // モニタ
617: Monitor *monitor {};
1.1 root 618: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.