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

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

unix.superglobalmegacorp.com

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