Annotation of nono/vm/scc.cpp, revision 1.1.1.8

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 "scc.h"
1.1.1.8 ! root        8: #include "bitops.h"
1.1.1.5   root        9: #include "interrupt.h"
1.1.1.8 ! root       10: #include "keyboard.h"
1.1.1.5   root       11: #include "mpu.h"
1.1       root       12: 
                     13: //          IODevice
                     14: //              |
                     15: //              v
                     16: //        upd7201Device  (uPD7201 と Z8530 の共通部分)
                     17: //              |
                     18: //    +---------+----------+
                     19: //    v                    v
                     20: // SIODevice           SCCDevice
                     21: // (LUNA, uPD7201)     (X68030, Z8530)
                     22: 
1.1.1.2   root       23: std::unique_ptr<SCCDevice> gSCC;
                     24: 
1.1       root       25: SCCDevice::SCCDevice()
1.1.1.7   root       26:        : inherited("SCC")
1.1       root       27: {
                     28:        devaddr = baseaddr;
                     29:        devlen  = 0x2000;
1.1.1.2   root       30: 
                     31:        cr.chan[0].desc = "Serial Port";
                     32:        cr.chan[1].desc = "Mouse";
1.1.1.7   root       33: 
                     34:        // X680x0 では SCC と呼ぶほうが通りがいい。
                     35:        monitor.Regist(ID_MONITOR_SCC);
1.1       root       36: }
                     37: 
                     38: SCCDevice::~SCCDevice()
                     39: {
                     40: }
                     41: 
                     42: // Z8530 は RD と WR を同時に Low にするとリセットがかかる。
                     43: // 回路図からは PEDEC から繋がってるという以上のことは分からないけど
                     44: // 普通に考えればハードリセットでリセットされるよな。
                     45: 
                     46: uint64
1.1.1.6   root       47: SCCDevice::Read(uint32 offset)
1.1       root       48: {
1.1.1.4   root       49:        gMPU->AddCycle(41);     // InsideOut p.135
                     50: 
1.1.1.6   root       51:        switch (offset) {
1.1.1.3   root       52:         case 0:        // $E98001
1.1       root       53:                return ReadCtrl(&cr.chan[1]);
                     54: 
1.1.1.3   root       55:         case 1:        // $E98003
1.1.1.8 ! root       56:                return ReadData(&cr.chan[1]);
1.1       root       57: 
1.1.1.3   root       58:         case 2:        // $E98005
1.1       root       59:                return ReadCtrl(&cr.chan[0]);
                     60: 
1.1.1.3   root       61:         case 3:        // $E98007
1.1       root       62:                putlog(0, "ChA データレジスタ読み込み (未実装)");
1.1.1.2   root       63:                return ReadData(&cr.chan[0]);
1.1       root       64:        }
1.1.1.3   root       65:        __unreachable();
1.1       root       66: }
                     67: 
                     68: uint64
1.1.1.6   root       69: SCCDevice::Write(uint32 offset, uint32 data)
1.1       root       70: {
1.1.1.4   root       71:        gMPU->AddCycle(49);     // InsideOut p.135
                     72: 
1.1.1.6   root       73:        switch (offset) {
1.1.1.3   root       74:         case 0:        // $E98001
1.1       root       75:                WriteCtrl(&cr.chan[1], data);
                     76:                return 0;
                     77: 
1.1.1.3   root       78:         case 1:        // $E98003
1.1       root       79:                WriteData(&cr.chan[1], data);
                     80:                return 0;
                     81: 
1.1.1.3   root       82:         case 2:        // $E98005
1.1       root       83:                WriteCtrl(&cr.chan[0], data);
                     84:                return 0;
                     85: 
1.1.1.3   root       86:         case 3:        // $E98007
1.1       root       87:                WriteData(&cr.chan[0], data);
                     88:                return 0;
                     89:        }
1.1.1.3   root       90:        __unreachable();
1.1       root       91: }
                     92: 
                     93: uint64
1.1.1.6   root       94: SCCDevice::Peek(uint32 offset)
1.1       root       95: {
1.1.1.6   root       96:        switch (offset) {
1.1.1.3   root       97:         case 0:        // $E98001
1.1.1.2   root       98:                return PeekCtrl(&cr.chan[1]);
                     99: 
1.1.1.3   root      100:         case 1:        // $E98003
1.1.1.8 ! root      101:                return PeekData(&cr.chan[1]);
1.1.1.2   root      102: 
1.1.1.3   root      103:         case 2:        // $E98005
1.1.1.2   root      104:                return PeekCtrl(&cr.chan[0]);
                    105: 
1.1.1.3   root      106:         case 3:        // $E98007
1.1.1.2   root      107:                return PeekData(&cr.chan[0]);
                    108:        }
1.1.1.3   root      109:        __unreachable();
1.1       root      110: }
                    111: 
                    112: // Z8530 制御ポート読み込み
                    113: uint8
                    114: SCCDevice::ReadCtrl(struct SIO::channel *chan)
                    115: {
                    116:        return inherited::ReadCtrl(chan);
                    117: }
                    118: 
                    119: // Z8530 制御ポート書き込み
                    120: void
                    121: SCCDevice::WriteCtrl(struct SIO::channel *chan, uint32 data)
                    122: {
                    123:        switch (chan->ptr) {
                    124:         case 0:        // WR0
                    125:                chan->cr0 = data;
                    126: 
                    127:                switch ((chan->cr0 & SIO::WR0_CMD) >> 3) {
                    128:                 case 0:
                    129:                 case 1:
                    130:                        // コマンド 0、1 がレジスタ切り替え
                    131:                        chan->ptr = chan->cr0 & SIO::WR0_PTR;
                    132:                        putlog(3, "WR0%s <- $%02x (ptr=%d)", chan->name, data, chan->ptr);
                    133:                        break;
                    134: 
                    135:                 case 2:        // Reset Ext/Status Interrupts
                    136:                        putlog(0, "WR0 Reset Ext/Status Interrupts 未実装");
                    137:                        break;
                    138:                 case 3:        // Send Abort
                    139:                        putlog(0, "WR0 Send Abort 未実装");
                    140:                        break;
                    141:                 case 4:        // Enable Int on Next Rx Character
                    142:                        putlog(0, "WR0 Enable Int on Next Rx Character 未実装");
                    143:                        break;
                    144:                 case 5:        // Reset Tx Int Pending
                    145:                        putlog(0, "WR0 Reset Tx Int Pending 未実装");
                    146:                        break;
                    147:                 case 6:        // Error Reset
                    148:                        putlog(0, "WR0 Error Reset 未実装");
                    149:                        break;
                    150:                 case 7:        // Reset Highest IUS
                    151:                        putlog(0, "WR0 Reset Highest IUS");
                    152:                        break;
                    153:                }
                    154:                break;
                    155: 
                    156:         case 2:        // WR2
                    157:                // Z8530 の WR2 は A/B 共通でベクタ設定
                    158:                putlog(2, "WR2 <- $%02x ベクタ設定", data);
                    159:                cr.vector = data;
                    160:                // アクセス後は WR0 へ戻す
                    161:                chan->ptr = 0;
                    162:                break;
                    163: 
                    164:         case 1:        // WR1
                    165:         case 3:
                    166:         case 4:
                    167:         case 5:
                    168:         case 6:
                    169:         case 7:
                    170:                inherited::WriteCtrl(chan, data);
                    171:                break;
                    172: 
                    173:         case 8:        // WR8
                    174:                WriteData(chan, data);
                    175:                // アクセス後は WR0 へ戻す
                    176:                chan->ptr = 0;
                    177:                break;
                    178: 
                    179:         case 9:        // WR9
                    180:                putlog(2, "WR%d%s <- $%02x", chan->ptr, chan->name, data);
                    181:                switch ((data & 0xc0) >> 6) {
                    182:                 case 0:        // No Reset
                    183:                        break;
                    184:                 case 1:        // Channel Reset A
                    185:                        ResetChannel(&cr.chan[0]);
                    186:                        break;
                    187:                 case 2:        // Channel Reset B
                    188:                        ResetChannel(&cr.chan[1]);
                    189:                        break;
                    190:                 case 3:        // Force Hardware Reset
1.1.1.6   root      191:                        ResetHard();
1.1       root      192:                        break;
                    193:                 default:
                    194:                        __unreachable();
                    195:                }
                    196:                // アクセス後は WR0 へ戻す
                    197:                chan->ptr = 0;
                    198:                break;
                    199: 
1.1.1.5   root      200:         case 10:       // WR10
                    201:                putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
                    202:                chan->wr10 = data;
                    203:                // アクセス後は WR0 へ戻す
                    204:                chan->ptr = 0;
                    205:                break;
                    206: 
1.1       root      207:         case 11:       // WR11
                    208:                putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
                    209:                chan->wr11 = data;
                    210:                // アクセス後は WR0 へ戻す
                    211:                chan->ptr = 0;
                    212:                break;
                    213: 
                    214:         case 12:       // WR12
                    215:                chan->tc = (chan->tc & 0xff00) | data;
                    216:                putlog(2, "WR%d%s TC(L)=%04x", chan->ptr, chan->name, chan->tc);
                    217:                // アクセス後は WR0 へ戻す
                    218:                chan->ptr = 0;
                    219:                break;
                    220: 
                    221:         case 13:       // WR13
                    222:                chan->tc = (chan->tc & 0x00ff) | (data << 8);
                    223:                putlog(2, "WR%d%s TC(H)=%04x", chan->ptr, chan->name, chan->tc);
                    224:                // アクセス後は WR0 へ戻す
                    225:                chan->ptr = 0;
                    226:                break;
                    227: 
                    228:         case 14:       // WR14
                    229:                putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
                    230:                chan->wr14 = data;
                    231:                // アクセス後は WR0 へ戻す
                    232:                chan->ptr = 0;
                    233:                break;
                    234: 
                    235:         case 15:       // WR15
                    236:                putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
                    237:                chan->wr15 = data;
                    238:                // アクセス後は WR0 へ戻す
                    239:                chan->ptr = 0;
                    240:                break;
                    241: 
                    242:         default:
                    243:                PANIC("未実装レジスタ書き込み WR%d%s <- $%02x",
                    244:                        chan->ptr, chan->name, data);
                    245:                break;
                    246:        }
                    247: }
                    248: 
1.1.1.8 ! root      249: void
        !           250: SCCDevice::WriteCR5(struct SIO::channel *chan, uint32 data)
        !           251: {
        !           252:        bool rts = bit_falling(chan->cr5, data, SIO::CR5_RTS);
        !           253: 
        !           254:        inherited::WriteCR5(chan, data);
        !           255: 
        !           256:        if (chan->id == 1 && rts) {
        !           257:                gKeyboard->MouseSendStart();
        !           258:        }
        !           259: }
        !           260: 
1.1       root      261: // 割り込みを上げる
                    262: void
                    263: SCCDevice::Interrupt()
                    264: {
                    265:        putlog(0, "割り込み(未実装)");
1.1.1.5   root      266: //     gInterrupt->Raise(this);
                    267: }
                    268: 
                    269: // 割り込みアクノリッジ
                    270: int
                    271: SCCDevice::InterruptAcknowledge()
                    272: {
                    273:        return 0x50;    /* XXX 実際は WR2 とか要因で変わる */
1.1       root      274: }

unix.superglobalmegacorp.com

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