Annotation of nono/vm/upd7201.cpp, revision 1.1.1.4

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #include "upd7201.h"
                      8: 
                      9: // コンストラクタ
                     10: uPD7201Device::uPD7201Device()
                     11: {
1.1.1.4 ! root       12:        monitor_size = nnSize(48, 19);
1.1       root       13:        cr.chan[0].id = 0;
                     14:        cr.chan[0].name = "A";
                     15:        cr.chan[1].id = 1;
                     16:        cr.chan[1].name = "B";
                     17: 
                     18:        cr.chan[0].desc = NULL;
                     19:        cr.chan[1].desc = NULL;
                     20: }
                     21: 
                     22: // デストラクタ
                     23: uPD7201Device::~uPD7201Device()
                     24: {
                     25: }
                     26: 
                     27: // リセット
                     28: // どのタイミングで呼ばれるかは上位による
                     29: void
                     30: uPD7201Device::Reset()
                     31: {
                     32:        putlog(2, "リセット");
                     33: 
                     34:        // CR2A はチップリセットで bit6 以外を '0' に
                     35:        cr.cr2a &= ~0xbf;
                     36: 
                     37:        // チャンネルリセット
                     38:        ResetChannel(&cr.chan[0]);
                     39:        ResetChannel(&cr.chan[1]);
                     40: }
                     41: 
                     42: // チャンネルリセット
                     43: void
                     44: uPD7201Device::ResetChannel(struct SIO::channel *chan)
                     45: {
                     46:        putlog(2, "チャンネル %s リセット", chan->name);
                     47: 
                     48:        // CR0 b2-0
                     49:        chan->cr0 &= ~SIO::CR0_PTR;
                     50:        chan->ptr = 0;
                     51: 
                     52:        // CR1 b0,1,3,4,7
                     53:        chan->cr1 &= ~(SIO::CR1_WAIT_EN | SIO::CR1_RXINT |
                     54:                       SIO::CR1_TXINT_EN | SIO::CR1_ESINT_EN);
                     55: 
                     56:        // CR3 b0-7
                     57:        chan->cr3 = 0;
                     58: 
                     59:        // CR5 b1,2,3,4,7
                     60:        chan->cr5 &= ~(SIO::CR5_DTR | SIO::CR5_SENDBREAK | SIO::CR5_TX_EN |
                     61:                       SIO::CR5_CRC16 | SIO::CR5_RTS);
                     62: 
                     63:        // SR0 は b0,1 が '0'、b2,6 が '1'、残りは不定
                     64:        chan->sr0 &= ~(SIO::SR0_INTPEND | SIO::SR0_RXAVAIL);
                     65:        chan->sr0 |= (SIO::SR0_TXUNDER | SIO::SR0_TXEMPTY);
                     66: 
                     67:        // SR1 は b4-7 が '0'
                     68:        chan->sr1 &= ~(SIO::SR1_ENDOFFRAME | SIO::SR1_CRCERROR |
                     69:                       SIO::SR1_RXOVERRUN | SIO::SR1_PARITYERROR);
                     70: 
                     71:        // E/S ラッチ解除
                     72:        chan->es_ratched = false;
                     73: 
                     74:        // 受信バッファをクリア
                     75:        memset(chan->rxbuf, 0, sizeof(chan->rxbuf));
                     76:        chan->rxlen = 0;
                     77: }
                     78: 
                     79: // 制御ポートの読み込み
                     80: uint8
                     81: uPD7201Device::ReadCtrl(struct SIO::channel *chan)
                     82: {
                     83:        uint8 data;
                     84: 
                     85:        switch (chan->ptr) {
                     86:         case 0:        // SR0
1.1.1.2   root       87:                data = ReadSR0(chan);
1.1       root       88:                putlog(2, "SR%d%s -> $%02x", chan->ptr, chan->name, data);
                     89:                // アクセス後は SR0 へ戻す
                     90:                chan->ptr = 0;
                     91:                break;
                     92: 
                     93:         case 1:        // SR1
1.1.1.2   root       94:                data = ReadSR1(chan);
1.1       root       95:                putlog(2, "SR%d%s -> $%02x", chan->ptr, chan->name, data);
                     96:                // アクセス後は SR0 へ戻す
                     97:                chan->ptr = 0;
                     98:                break;
                     99: 
                    100:         case 2:
                    101:                // SR2B はベクタの読み出し
                    102:                if (chan->id == 1) {
                    103:                        data = cr.vector;
                    104:                        putlog(2, "SR%d%s -> $%02x", chan->ptr, chan->name, data);
                    105:                        // アクセス後は SR0 へ戻す
                    106:                        chan->ptr = 0;
                    107:                        break;
                    108:                }
                    109: 
                    110:                // SR2A はない
                    111:                FALLTHROUGH;
                    112: 
                    113:         default:
                    114:                putlog(0, "未実装レジスタ読み込み SR%d%s",
                    115:                        chan->ptr, chan->name);
                    116:                // SR0 へ戻る?
                    117:                chan->ptr = 0;
                    118:                return 0xff;
                    119:        }
                    120:        return data;
                    121: }
                    122: 
                    123: // 制御ポートの書き込み
                    124: void
                    125: uPD7201Device::WriteCtrl(struct SIO::channel *chan, uint32 data)
                    126: {
                    127:        uint cmd;
                    128: 
                    129:        switch (chan->ptr) {
                    130:         case 0:        // CR0
                    131:                // XXX b7,b6 は未対応。
                    132:                // b5,b4,b3 がコマンド。
                    133:                // b2,b1,b0 が次にアクセスするレジスタ(chan->ptr)の切り替え。
                    134:                chan->cr0 = data;
                    135:                chan->ptr = (chan->cr0 & SIO::CR0_PTR);
                    136: 
                    137:                cmd = (chan->cr0 & SIO::CR0_CMD) >> 3;
                    138:                if (cmd == 0) {
                    139:                        // コマンド0 ならレジスタ切り替え
                    140:                        putlog(3, "CR0%s <- $%02x (ptr=%d)", chan->name, data, chan->ptr);
                    141:                } else {
                    142:                        // 0 以外ならコマンド発行
                    143:                        putlog(2, "CR0%s <- $%02x", chan->name, data);
                    144:                }
                    145:                switch (cmd) {
                    146:                 case 0:        // No operation
                    147:                        break;
                    148:                 case 1:        // Send Abort
                    149:                        if (chan->mode == SIO::Mode::HDLC) {
                    150:                                putlog(0, "CR0: Send Abort 未実装");
                    151:                        } else {
                    152:                                // XXX Send Abort コマンドは「HDLC モードのみ有効」と書いて
                    153:                                //     あるがそれ以外の時にどうなるか不明。
                    154:                                putlog(0, "CR0: 未定義コマンド %d", cmd);
                    155:                        }
                    156:                        break;
                    157:                 case 2:        // Reset External/Status Interrupt
                    158:                        putlog(3, "E/S ラッチ解除");
                    159:                        chan->es_ratched = false;
                    160:                        break;
                    161:                 case 3:        // Channel Reset
                    162:                        putlog(1, "チャンネル%sリセット", chan->name);
                    163:                        ResetChannel(chan);
                    164:                        break;
                    165:                 case 4:        // Enable Interrupt On Next Receive Character
                    166:                        putlog(0, "CR0: 未実装コマンド %d", cmd);
                    167:                        break;
                    168:                 case 5:        // Reset Transmitter Interrupt/DMA Pending
                    169:                        // 本来これは上がっている Tx 割り込みを落とすためのようだが、
                    170:                        // SIO から MPU への割り込み通知はもう終わっていて下げる必要は
                    171:                        // ないので、何もすることはない。
                    172:                        break;
                    173:                 case 6:        // Error Reset
                    174:                 case 7:        // End of Interrupt
                    175:                        putlog(0, "CR0: 未実装コマンド %d", cmd);
                    176:                        break;
                    177:                 default:
                    178:                        __unreachable();
                    179:                }
                    180:                break;
                    181: 
                    182:         case 1:        // CR1
                    183:                chan->cr1 = data;
                    184:                putlog(2, "CR%d%s <- $%02x", chan->ptr, chan->name, data);
                    185:                // アクセス後は CR0 へ戻す
                    186:                chan->ptr = 0;
                    187:                break;
                    188: 
                    189:         case 2:
                    190:                if (chan->id == 0) {    // CR2A
                    191:                        putlog(2, "CR2A <- $%02x 書き込み(b7-2未実装)", data);
                    192:                        cr.cr2a = data;
                    193:                } else {                                // CR2B
                    194:                        putlog(2, "CR2B <- $%02x ベクタ設定", data);
                    195:                        cr.vector = data;
                    196:                }
                    197:                // アクセス後は CR0 へ戻す
                    198:                chan->ptr = 0;
                    199:                break;
                    200: 
                    201:         case 3:        // CR3
                    202:                chan->cr3 = data;
                    203:                putlog(2, "CR%d%s <- $%02x", chan->ptr, chan->name, data);
                    204:                putlog(1, "チャンネル%s RX %s, %dbits",
                    205:                        chan->name,
                    206:                        (chan->cr3 & SIO::CR3_RX_EN) ? "Enable" : "Disable",
                    207:                        bits_per_char[(chan->cr3 & SIO::CR3_RXBITS) >> 6]);
                    208:                // アクセス後は CR0 へ戻す
                    209:                chan->ptr = 0;
                    210:                break;
                    211: 
                    212:         case 4:        // CR4
                    213:         {
                    214:                chan->cr4 = data;
                    215:                putlog(2, "CR%d%s <- $%02x", chan->ptr, chan->name, data);
                    216:                uint8 stopbits = (chan->cr4 & SIO::CR4_STOPBITS);
                    217:                uint8 syncmode = (chan->cr4 & SIO::CR4_SYNCMODE);
                    218: 
                    219:                // モード分け、優先順位は分からない
                    220:                if (stopbits == SIO::SYNC_MODE) {
                    221:                        if (syncmode == SIO::SYNC_HDLC) {
                    222:                                chan->mode = SIO::Mode::HDLC;
                    223:                                putlog(2, "チャンネル%s HDLC モード", chan->name);
                    224:                        } else {
                    225:                                chan->mode = SIO::Mode::SYNC;
                    226:                                const char *sm[] = { "8bit", "16bit", "HDLC?", "Ext" };
                    227:                                putlog(2, "チャンネル%s Sync (%s) モード",
                    228:                                        chan->name, sm[syncmode >> 4]);
                    229:                        }
                    230:                } else {
                    231:                        chan->mode = SIO::Mode::ASYNC;
                    232:                        const char *cm[] = { "x1", "x16", "x32", "x64" };
                    233:                        const char *sm[] = { "?", "1", "1.5", "2" };
                    234:                        putlog(2, "チャンネル%s Async (%s clock, stopbit %s) モード",
                    235:                                chan->name,
                    236:                                cm[(chan->cr4 & SIO::CR4_CLKRATE) >> 6],
                    237:                                sm[stopbits >> 2]);
                    238:                }
                    239: 
                    240:                // アクセス後は CR0 へ戻す
                    241:                chan->ptr = 0;
                    242:                break;
                    243:         }
                    244: 
                    245:         case 5:        // CR5
                    246:         {
                    247:                chan->cr5 = data;
                    248:                putlog(2, "CR%d%s <- $%02x", chan->ptr, chan->name, data);
                    249:                putlog(1, "チャンネル%s TX %s, %dbits",
                    250:                        chan->name,
                    251:                        (chan->cr5 & SIO::CR5_TX_EN) ? "Enable" : "Disable",
                    252:                        bits_per_char[(chan->cr5 & SIO::CR5_TXBITS) >> 5]);
                    253:                // アクセス後は CR0 へ戻す
                    254:                chan->ptr = 0;
                    255:                break;
                    256:         }
                    257: 
                    258:         case 6:        // CR6
                    259:                putlog(0, "CR6%s <- $%02x 書き込み(未実装)", chan->name, data);
                    260:                chan->cr6 = data;
                    261:                // アクセス後は CR0 へ戻す
                    262:                chan->ptr = 0;
                    263:                break;
                    264: 
                    265:         case 7:        // CR7
                    266:                putlog(0, "CR7%s <- $%02x 書き込み(未実装)", chan->name, data);
                    267:                chan->cr7 = data;
                    268:                // アクセス後は CR0 へ戻す
                    269:                chan->ptr = 0;
                    270:                break;
                    271: 
                    272:         default:
                    273:                putlog(0, "未実装レジスタ書き込み CR%d%s <- $%02x",
                    274:                        chan->ptr, chan->name, data);
                    275:                break;
                    276:        }
                    277: }
                    278: 
1.1.1.2   root      279: // 制御ポートの Peek
                    280: uint8
                    281: uPD7201Device::PeekCtrl(const struct SIO::channel *chan) const
                    282: {
                    283:        switch (chan->ptr) {
                    284:         case 0:        // SR0
                    285:                return ReadSR0(chan);
                    286: 
                    287:         case 1:        // SR1
                    288:                return ReadSR1(chan);
                    289: 
                    290:         case 2:        // SR2
                    291:                // SR2A はない。SR2B はベクタの読み出し
                    292:                if (chan->id == 1) {
                    293:                        return cr.vector;
                    294:                }
                    295:                FALLTHROUGH;
                    296: 
                    297:         default:
                    298:                // 未調査
                    299:                return 0xff;
                    300:        }
                    301: }
                    302: 
                    303: // SR0 の読み込み (Read, Peek 共通)
                    304: uint8
                    305: uPD7201Device::ReadSR0(const struct SIO::channel *chan) const
                    306: {
                    307:        uint32 data;
                    308: 
                    309:        // 送信バッファは常に空
                    310:        data = SIO::SR0_TXEMPTY;
                    311:        // 受信データがあるか
                    312:        if (chan->rxlen > 0) {
                    313:                data |= SIO::SR0_RXAVAIL;
                    314:        }
                    315:        return data;
                    316: }
                    317: 
                    318: // SR1 の読み込み (Read, Peek 共通)
                    319: uint8
                    320: uPD7201Device::ReadSR1(const struct SIO::channel *chan) const
                    321: {
                    322:        // エラーとか起きてないという状態だけ再現。
                    323:        return SIO::SR1_ALL_SENT;
                    324: }
                    325: 
                    326: 
1.1       root      327: // データポートの読み込み
                    328: uint8
1.1.1.2   root      329: uPD7201Device::ReadData(struct SIO::channel *chan)
1.1       root      330: {
                    331:        uint8 data;
                    332: 
                    333:        if (chan->rxlen > 0) {
                    334:                data = chan->rxbuf[0];
                    335:                chan->rxlen--;
                    336:                // 少ないので毎回前詰めしちゃえ
                    337:                if (chan->rxlen > 0) {
                    338:                        memmove(chan->rxbuf + 1, chan->rxbuf, chan->rxlen);
                    339:                }
                    340:        } else {
                    341:                // XXX 何が読めるか
                    342:                data = 0xff;
                    343:        }
                    344: 
                    345:        return data;
                    346: }
                    347: 
                    348: // データポートの書き込み
                    349: void
                    350: uPD7201Device::WriteData(struct SIO::channel *chan, uint32 data)
                    351: {
                    352:        char charbuf[4];
                    353: 
                    354:        if (isprint((int)data)) {
                    355:                snprintf(charbuf, sizeof(charbuf), "'%c'", data);
                    356:        } else {
                    357:                charbuf[0] = '\0';
                    358:        }
                    359:        putlog(1, "Ch%s データレジスタ書き込み $%02x %s",
                    360:                chan->name, data, charbuf);
                    361: 
                    362:        // 1文字送信
                    363: 
                    364:        // 今のところ内部バッファがなく常に送信できるので
                    365:        // 必ず Tx Buffer Empty が発生する。
                    366:        chan->sr0 |= SIO::SR0_TXEMPTY;
                    367: 
                    368:        // 割り込みをあげる
                    369:        if ((chan->cr1 & SIO::CR1_TXINT_EN)) {
                    370:                putlog(2, "割り込み (TX Empty)");
                    371:                Interrupt();
                    372:        }
                    373: }
                    374: 
1.1.1.2   root      375: // データポートの Peek
                    376: uint8
                    377: uPD7201Device::PeekData(const struct SIO::channel *chan) const
                    378: {
                    379:        if (chan->rxlen > 0) {
                    380:                // 受信バッファにデータがあれば先頭バイトが見える
                    381:                return chan->rxbuf[0];
                    382:        } else {
                    383:                // 空の時は?
                    384:                return 0xff;
                    385:        }
                    386: }
                    387: 
1.1.1.3   root      388: // TX/RX の bits/char のレジスタ値を実際の bits/char の値に変換する。
1.1       root      389: /* static */
                    390: const int
                    391: uPD7201Device::bits_per_char[] = { 5, 7, 6, 8 };
                    392: 
                    393: // 1バイト受信する。
                    394: // 受理されれば true を返す。
                    395: bool
                    396: uPD7201Device::Rx(int ch, uint32 data)
                    397: {
                    398:        struct SIO::channel *chan = &cr.chan[ch];
                    399: 
                    400:        // Rx Enable でなければ受け取らない?
                    401:        if ((chan->cr3 & SIO::CR3_RX_EN) == 0) {
                    402:                return false;
                    403:        }
                    404: 
                    405:        // バッファが一杯なら Rx Overrun Error
                    406:        if (chan->rxlen == sizeof(chan->rxbuf)) {
                    407:                putlog(2, "Rx Overrun");
                    408:                chan->sr1 |= SIO::SR1_RXOVERRUN;
                    409:                return false;
                    410:        }
                    411: 
                    412:        // 受信
                    413:        chan->rxbuf[chan->rxlen++] = data;
                    414: 
                    415:        // 必要なら割り込みを上げる
                    416:        if ((chan->cr1 & SIO::CR1_RXINT) == SIO::RXINT_FIRSTCHAR) {
                    417:                // First character interrupt モードなら最初の1バイトでだけ割り込み
                    418:                if (chan->rxrecved == false) {
                    419:                        Interrupt();
                    420:                }
                    421:                chan->rxrecved = true;
                    422:        } else if ((chan->cr1 & SIO::CR1_RXINT) >= SIO::RXINT_ALL_INC_SPECIAL) {
                    423:                // All character interrupt モード (Special のことはちょっと置いとく)
                    424:                chan->rxrecved = true;
                    425:                Interrupt();
                    426:        }
                    427: 
                    428:        return true;
                    429: }
                    430: 
                    431: // モニター
1.1.1.4 ! root      432: void
        !           433: uPD7201Device::MonitorUpdate(TextScreen& monitor)
1.1       root      434: {
                    435:        monitor.Clear();
                    436:        for (int i = 0; i < 2; i++) {
                    437:                int x = 0;
                    438:                int y = i * 10;
1.1.1.4 ! root      439:                MonitorUpdateCh(monitor, i, x, y);
1.1       root      440:        }
                    441: }
                    442: 
                    443: // モニター (1チャンネル)
                    444: void
1.1.1.4 ! root      445: uPD7201Device::MonitorUpdateCh(TextScreen& monitor,
        !           446:        int ch, int xbase, int ybase)
1.1       root      447: {
                    448:        struct SIO::channel *chan = &cr.chan[ch];
                    449:        uint cr0;
                    450:        uint cr1;
                    451:        uint cr3;
                    452:        uint cr4;
                    453:        uint cr5;
                    454:        uint sr0;
                    455:        uint sr1;
                    456:        uint rxlen;
                    457:        int x;
                    458:        int y;
                    459: 
                    460:        cr0 = chan->cr0;
                    461:        cr1 = chan->cr1;
                    462:        cr3 = chan->cr3;
                    463:        cr4 = chan->cr4;
                    464:        cr5 = chan->cr5;
                    465:        sr0 = chan->sr0;
                    466:        sr1 = chan->sr1;
                    467:        rxlen = chan->rxlen;
                    468: 
                    469:        // 0         1         2         3         4         5         6
                    470:        // 012345678901234567890123456789012345678901234567890123456789012345
                    471:        //          0123 0123 0123 0123 0123 0123 0123 0123
                    472:        // CR0:$xx  CRC=x     CMD=x          PTR=x
                    473:        // CR1:$xx  WE   0    WR   RXInt=x   0    TXEn ESEn
                    474: 
                    475:        x = xbase;
                    476:        y = ybase;
                    477:        monitor.Print(x, y++, "Channel %s: %s", chan->name, chan->desc);
                    478:        monitor.Print(x, y++, "CR0:$%02x", cr0);
                    479:        monitor.Print(x, y++, "CR1:$%02x", cr1);
                    480:        monitor.Print(x, y++, "CR3:$%02x", cr3);
                    481:        monitor.Print(x, y++, "CR4:$%02x", cr4);
                    482:        monitor.Print(x, y++, "CR5:$%02x", cr5);
                    483:        monitor.Print(x, y++, "SR0:$%02x", sr0);
                    484:        monitor.Print(x, y++, "SR1:$%02x", sr1);
                    485:        monitor.Print(x, y,   "RXbuf:%d", rxlen);
                    486:        int i;
                    487:        for (i = 0; i < rxlen; i++) {
                    488:                monitor.Print(x + 8 + i * 4, y, "$%02x", chan->rxbuf[i]);
                    489:        }
                    490:        for (; i < sizeof(chan->rxbuf); i++) {
                    491:                monitor.Print(x + 8 + i * 4, y, "---");
                    492:        }
                    493: 
                    494:        y = ybase + 1;
                    495:        x = xbase;
                    496:        // CR0
                    497:        monitor.Print(x + 9, y, "CRC=%d", (cr0 >> 6));
                    498:        static const char * const cmd_str[] = {
                    499:        //   0123456789012345
                    500:                "No operation",
                    501:                "Send Abort",
                    502:                "Reset E/S Int",
                    503:                "Channel Reset",
                    504:                "Enable IntNextCh",
                    505:                "Reset TxIntPend",
                    506:                "Error Reset",
                    507:                "End of Interrupt",
                    508:        };
                    509:        uint cmd = (cr0 >> 3) & 7;
                    510:        monitor.Print(x + 19, y, "CMD=%d(%s)", cmd, cmd_str[cmd]);
                    511:        monitor.Print(x + 43, y, "PTR=%d", (cr0 & 7));
                    512:        y++;
                    513: 
                    514:        // CR1
                    515:        static const char * const cr1_str[] = {
                    516:                "WaEn", "----", "WaRx", "", "", "----", "TxIE", "ESEn"
                    517:        };
1.1.1.4 ! root      518:        MonitorReg(monitor, x + 9, y, cr1, cr1_str);
1.1       root      519:        monitor.Print(x + 24, y, "RXInt=%d", (cr1 >> 3) & 3);
                    520:        y++;
                    521: 
                    522:        // CR3
                    523:        static const char * const cr3_str[] = {
                    524:                "", "", "AuEn", "----", "----", "----", "----", "RXEn"
                    525:        };
1.1.1.4 ! root      526:        MonitorReg(monitor, x + 9, y, cr3, cr3_str);
1.1       root      527:        monitor.Print(x + 9, y, "RXbits=%d", 5 + ((cr3 >> 6) & 3));
                    528:        y++;
                    529: 
                    530:        // CR4
                    531:        static const char * const cr4_str[] = {
                    532:                "", "", "", "", "", "", "PaEv", "PaEn"
                    533:        };
1.1.1.4 ! root      534:        MonitorReg(monitor, x + 9, y, cr4, cr4_str);
1.1       root      535: 
                    536:        static const char * const clkrate_str[] = {
                    537:                "1", "16", "32", "64"
                    538:        };
                    539:        monitor.Print(x + 9, y, "Rate=x%s", clkrate_str[(cr4 >> 6) & 3]);
                    540:        static const char * const syncmode_str[] = {
                    541:                "Mono", "Bi", "HDLC", "Ext"
                    542:        };
                    543:        monitor.Print(x + 19, y, "Sync=%s", syncmode_str[(cr4 >> 4) & 3]);
                    544:        static const char * const stopbit_str[] = {
                    545:                "Sync", "1", "1.5", "2"
                    546:        };
                    547:        monitor.Print(x + 29, y, "Stop=%s", stopbit_str[(cr4 >> 2) & 3]);
                    548:        y++;
                    549: 
                    550:        // CR5
                    551:        static const char * const cr5_str[] = {
                    552:                "DTR", "", "", "SBrk", "TXEn", "CRC", "!RTS", "TCEn"
                    553:        };
1.1.1.4 ! root      554:        MonitorReg(monitor, x + 9, y, cr5, cr5_str);
1.1       root      555:        monitor.Print(x + 14, y, "TXbits=%d", 5 + ((cr5 >> 5) & 3));
                    556:        y++;
                    557: 
                    558:        // SR0
                    559:        static const char * const sr0_str[] = {
                    560:                "BrAb", "TxUn", "CTS", "SYNC", "DCD", "TxEm", "IntP", "RxAv"
                    561:        };
1.1.1.4 ! root      562:        MonitorReg(monitor, x + 9, y, sr0, sr0_str);
1.1       root      563:        y++;
                    564: 
                    565:        // SR1
                    566:        static const char * const sr1_str[] = {
                    567:                "EOF", "CRCE", "RxOv", "PaEr", "", "", "", "Sent"
                    568:        };
1.1.1.4 ! root      569:        MonitorReg(monitor, x + 9, y, sr1, sr1_str);
1.1       root      570:        monitor.Print(x + 29, y, "ResidueCode=%d", (sr1 >> 1) & 7);
                    571:        y++;
                    572: }
                    573: 
                    574: // レジスタをビットごとに表示する。MonitorUpdate の下請け。
                    575: void
1.1.1.4 ! root      576: uPD7201Device::MonitorReg(TextScreen& monitor,
        !           577:        int x, int y, uint32 reg, const char * const *names)
1.1       root      578: {
                    579:        for (int i = 0; i < 8; i++) {
                    580:                if (strcmp(names[i], "----") == 0) {
1.1.1.3   root      581:                        monitor.Puts(x + i * 5, y, TA::Disable, names[i]);
1.1       root      582:                } else {
                    583:                        bool b = reg & (1 << (7 - i));
1.1.1.3   root      584:                        monitor.Puts(x + i * 5, y, TA::OnOff(b), names[i]);
1.1       root      585:                }
                    586:        }
                    587: }

unix.superglobalmegacorp.com

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