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

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

unix.superglobalmegacorp.com

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