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

unix.superglobalmegacorp.com

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