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