Annotation of nono/vm/mpscc.h, revision 1.1.1.3

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.