Annotation of nono/hd64180/hd647180io.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // HD647180 I/O アクセス
                      9: //
                     10: 
                     11: #include "mpu64180.h"
                     12: #include "hd647180.h"
                     13: #include "pio.h"
                     14: #include "scheduler.h"
                     15: #include "xpbus.h"
                     16: 
                     17: //#define ENABLE_SERIAL_LOG
                     18: //#define ENABLE_SSG_LOG
                     19: 
                     20: uint32
                     21: MPU64180Device::ReadIO(uint32 addr)
                     22: {
                     23:        CYCLE(iowait);
                     24: 
                     25:        // 内蔵 I/O
                     26:        if (io_address <= addr && addr < io_address + 0x80) {
                     27:                return ReadInternalIO(addr - io_address);
                     28:        }
                     29: 
                     30:        return ReadExternalIO(addr);
                     31: }
                     32: 
                     33: uint32
                     34: MPU64180Device::ReadInternalIO(uint32 offset)
                     35: {
                     36:        uint32 data = -1;
                     37: 
                     38:        switch (offset) {
                     39:         case 0x00:                                     // IO_CNTLA0
                     40:         case 0x01:                                     // IO_CNTLA1
                     41:                data = 0x10;
                     42: #if defined(ENABLE_SERIAL_LOG)
                     43:                putlog(0, "%s -> $%02x (NOT IMPLEMENTED)",
                     44:                        IOName(offset).c_str(), data);
                     45: #endif
                     46:                return data;
                     47:         case 0x02:                                     // IO_CNTLB0
                     48:         case 0x03:                                     // IO_CNTLB1
                     49:                break;
                     50:         case 0x04:                                     // IO_STAT0
                     51:         case 0x05:                                     // IO_STAT1
                     52:                data = 0x02;
                     53: #if defined(ENABLE_SERIAL_LOG)
                     54:                putlog(0, "%s -> $%02x (NOT IMPLEMENTED)",
                     55:                        IOName(offset).c_str(), data);
                     56: #endif
                     57:                return data;
                     58:         case 0x06:                                     // IO_TDR0
                     59:         case 0x07:                                     // IO_TDR1
                     60:         case 0x08:                                     // IO_TSR0
                     61:         case 0x09:                                     // IO_TSR1
                     62:         case 0x0a:                                     // IO_CNTR
                     63:         case 0x0b:                                     // IO_TRDR
                     64:                break;
                     65: 
                     66:         case 0x0c:                                     // IO_TMDR0L
                     67:                data = ReadTMDRL(0);
                     68:                break;
                     69:         case 0x0d:                                     // IO_TMDR0H
                     70:                data = ReadTMDRH(0);
                     71:                break;
                     72:         case 0x0e:                                     // IO_RLDR0L
                     73:                data = PeekRLDRL(0);
                     74:                break;
                     75:         case 0x0f:                                     // IO_RLDR0H
                     76:                data = PeekRLDRH(0);
                     77:                break;
                     78:         case 0x10:                                     // IO_TCR
                     79:                data = ReadTCR();
                     80:                break;
                     81:         case 0x14:                                     // IO_TMDR1L
                     82:                data = ReadTMDRL(1);
                     83:                break;
                     84:         case 0x15:                                     // IO_TMDR1H
                     85:                data = ReadTMDRH(1);
                     86:                break;
                     87:         case 0x16:                                     // IO_RLDR1L
                     88:                data = PeekRLDRH(0);
                     89:                break;
                     90:         case 0x17:                                     // IO_RLDR1H
                     91:                data = PeekRLDRH(1);
                     92:                break;
                     93:         case 0x18:                                     // IO_FRC
                     94:                data = PeekFRC();
                     95:                break;
                     96: 
                     97:         case 0x20:                                     // IO_SAR0L
                     98:         case 0x21:                                     // IO_SAR0H
                     99:         case 0x22:                                     // IO_SAR0B
                    100:         case 0x23:                                     // IO_DAR0L
                    101:         case 0x24:                                     // IO_DAR0H
                    102:         case 0x25:                                     // IO_DAR0B
                    103:         case 0x26:                                     // IO_BCR0L
                    104:         case 0x27:                                     // IO_BCR0H
                    105:         case 0x28:                                     // IO_MAR1L
                    106:         case 0x29:                                     // IO_MAR1H
                    107:         case 0x2a:                                     // IO_MAR1B
                    108:         case 0x2b:                                     // IO_IAR1L
                    109:         case 0x2c:                                     // IO_IAR1H
                    110:         case 0x2e:                                     // IO_BCR1L
                    111:         case 0x2f:                                     // IO_BCR1H
                    112:         case 0x30:                                     // IO_DSTAT
                    113:         case 0x31:                                     // IO_DMODE
                    114:                break;
                    115:         case 0x32:                                     // IO_DCNTL
                    116:                data = PeekDCNTL();
                    117:                break;
                    118: 
                    119:         case 0x33:                                     // IO_IL
                    120:                data = PeekIL();
                    121:                break;
                    122:         case 0x34:                                     // IO_ITC
                    123:                data = PeekITC();
                    124:                break;
                    125:         case 0x36:                                     // IO_RCR
                    126:                data = PeekRCR();
                    127:                break;
                    128: 
                    129:         case 0x38:                                     // IO_CBR
                    130:                data = PeekCBR();
                    131:                break;
                    132: 
                    133:         case 0x39:                                     // IO_BBR
                    134:                data = PeekBBR();
                    135:                break;
                    136: 
                    137:         case 0x3a:                                     // IO_CBAR
                    138:                data = PeekCBAR();
                    139:                break;
                    140: 
                    141:         case 0x3e:                                     // IO_OMCR
                    142:                break;
                    143:         case 0x3f:                                     // IO_ICR
                    144:                data = PeekICR();
                    145:                break;
                    146: 
                    147:         case 0x40:                                     // IO_T2FRCL
                    148:         case 0x41:                                     // IO_T2FRCH
                    149:         case 0x42:                                     // IO_T2OCR1L
                    150:         case 0x43:                                     // IO_T2OCR1H
                    151:         case 0x44:                                     // IO_T2OCR2L
                    152:         case 0x45:                                     // IO_T2OCR2H
                    153:         case 0x46:                                     // IO_T2ICRL
                    154:         case 0x47:                                     // IO_T2ICRH
                    155:         case 0x48:                                     // IO_T2CSR1
                    156:         case 0x49:                                     // IO_T2CSR2
                    157:                break;
                    158: 
                    159:         case 0x50:                                     // IO_CCSR
                    160:                break;
                    161:         case 0x51:                                     // IO_RMCR
                    162:                data = PeekRMCR();
                    163:                break;
                    164: 
                    165:         case 0x53:                                     // IO_DERA
                    166:                break;
                    167:         case 0x60:                                     // IO_IODRA
                    168:                data = 0xff;
                    169: #if defined(ENABLE_SERIAL_LOG)
                    170:                putlog(0, "%s -> $%02x (NOT IMPLEMENTED)",
                    171:                        IOName(offset).c_str(), data);
                    172: #endif
                    173:                return data;
                    174:         case 0x61:                                     // IO_IODRB
                    175:         case 0x62:                                     // IO_IODRC
                    176:         case 0x63:                                     // IO_IODRD
                    177:         case 0x64:                                     // IO_IODRE
                    178:         case 0x65:                                     // IO_IODRF
                    179:         case 0x66:                                     // IO_IDRG
                    180:         case 0x70:                                     // IO_DDRA
                    181:         case 0x71:                                     // IO_DDRB
                    182:         case 0x72:                                     // IO_DDRC
                    183:         case 0x73:                                     // IO_DDRD
                    184:         case 0x74:                                     // IO_DDRE
                    185:         case 0x75:                                     // IO_DDRF
                    186:                break;
                    187: 
                    188:         default:
                    189:                break;
                    190:        }
                    191: 
                    192:        // 表示して値を返す部分はだいたいほぼ共通なので。
                    193:        if ((int32)data < 0) {
                    194:                // data が (32bitで) 負なら未実装ポート。
                    195:                data = 0xff;
                    196:                putlog(0, "ReadInternalIO %s -> $%02x (NOT IMPLEMENTED)",
                    197:                        IOName(offset).c_str(), data);
                    198:        } else {
                    199:                putlog(2, "%s -> $%02x", IOName(offset).c_str(), data);
                    200:        }
                    201:        return data;
                    202: }
                    203: 
                    204: uint32
                    205: MPU64180Device::ReadExternalIO(uint32 addr)
                    206: {
                    207:        uint32 data = -1;
                    208: 
                    209:        // LUNA の外部 I/O はアドレスの上位バイト不問
                    210:        switch (addr & 0xff) {
                    211:         case 0x82:                                     // SSG
                    212:         case 0x83:                                     // SSG
                    213: #if !defined(ENABLE_SSG_LOG)
                    214:                data = 0xff;
                    215: #endif
                    216:                break;
                    217: 
                    218:         case 0x90:                                     // INT0 ネゲート
                    219:                // 読み込みでも (というかアクセスがあっただけで) ネゲート。
                    220:                putlog(1, "%s Negate INT0", IOName(addr).c_str());
                    221:                NegateINT0();
                    222:                // 実際何が読めるかは不明だが。
                    223:                return 0xff;
                    224: 
                    225:         case 0xa0:                                     // レベル5 割り込み要求
                    226:         case 0xb0:                                     // レベル1 割り込み要求
                    227:                // 読み込みでも割り込み上げそうだがとりあえず未実装へ回しておく。
                    228:                break;
                    229: 
                    230:         default:
                    231:                break;
                    232:        }
                    233: 
                    234:        // 表示して値を返す部分はだいたいほぼ共通なので。
                    235:        if ((int32)data < 0) {
                    236:                // data が (32bitで) 負なら未実装ポート。
                    237:                data = 0xff;
                    238:                putlog(0, "ReadExternalIO %s -> $%02x (NOT IMPLEMENTED)",
                    239:                        IOName(addr).c_str(), data);
                    240:        } else {
                    241:                putlog(2, "%s -> $%02x", IOName(addr).c_str(), data);
                    242:        }
                    243:        return data;
                    244: }
                    245: 
                    246: uint32
                    247: MPU64180Device::ReadTMDRL(int ch)
                    248: {
                    249:        auto& t = timer[ch];
                    250: 
                    251:        // TDR 読み出しで割り込みフラグクリアの実績を解除
                    252:        t.tif &= ~0x02;
                    253:        ChangeTimerInterrupt();
                    254: 
                    255:        // L の読み出しで count を tmp にラッチ
                    256:        t.tmpcount = t.count;
                    257: 
                    258:        // でラッチした L を読み出す
                    259:        return t.tmpcount & 0xff;
                    260: }
                    261: 
                    262: uint32
                    263: MPU64180Device::ReadTMDRH(int ch)
                    264: {
                    265:        auto& t = timer[ch];
                    266: 
                    267:        // TDR 読み出しで割り込みフラグクリアの実績を解除
                    268:        t.tif &= ~0x02;
                    269:        ChangeTimerInterrupt();
                    270: 
                    271:        // L 読み出し時にラッチしたやつを読み出す。
                    272:        return t.tmpcount >> 8;
                    273: }
                    274: 
                    275: uint32
                    276: MPU64180Device::ReadTCR()
                    277: {
                    278:        // TCR 読み出しで割り込みフラグクリアの実績を解除
                    279:        timer[0].tif &= ~0x01;
                    280:        timer[1].tif &= ~0x01;
                    281:        ChangeTimerInterrupt();
                    282: 
                    283:        return PeekTCR();
                    284: }
                    285: 
                    286: uint32
                    287: MPU64180Device::WriteIO(uint32 addr, uint32 data)
                    288: {
                    289:        CYCLE(iowait);
                    290: 
                    291:        // 内蔵 I/O
                    292:        if (io_address <= addr && addr < io_address + 0x80) {
                    293:                return WriteInternalIO(addr - io_address, data);
                    294:        }
                    295: 
                    296:        return WriteExternalIO(addr, data);
                    297: }
                    298: 
                    299: uint32
                    300: MPU64180Device::WriteInternalIO(uint32 offset, uint32 data)
                    301: {
                    302:        switch (offset) {
                    303:         case 0x00:                                     // IO_CNTLA0
                    304:         case 0x01:                                     // IO_CNTLA1
                    305: #if defined(USE_XPSERIAL)
                    306:                putlog(0, "%s <- $%02x (NOT IMPLEMENTED)",
                    307:                        IOName(offset).c_str(), data);
                    308: #endif
                    309:                return 0;
                    310:         case 0x02:                                     // IO_CNTLB0
                    311:         case 0x03:                                     // IO_CNTLB1
                    312:         case 0x04:                                     // IO_STAT0
                    313:         case 0x05:                                     // IO_STAT1
                    314:         case 0x06:                                     // IO_TDR0
                    315:         case 0x07:                                     // IO_TDR1
                    316:         case 0x08:                                     // IO_TSR0
                    317:         case 0x09:                                     // IO_TSR1
                    318:         case 0x0a:                                     // IO_CNTR
                    319:         case 0x0b:                                     // IO_TRDR
                    320:                break;
                    321: 
                    322:         case 0x0c:                                     // IO_TMDR0L
                    323:                return WriteTMDRL(0, data);
                    324:         case 0x0d:                                     // IO_TMDR0H
                    325:                return WriteTMDRH(0, data);
                    326:         case 0x0e:                                     // IO_RLDR0L
                    327:                return WriteRLDRL(0, data);
                    328:         case 0x0f:                                     // IO_RLDR0H
                    329:                return WriteRLDRH(0, data);
                    330:         case 0x10:                                     // IO_TCR
                    331:                return WriteTCR(data);
                    332:         case 0x14:                                     // IO_TMDR1L
                    333:                return WriteTMDRL(1, data);
                    334:         case 0x15:                                     // IO_TMDR1H
                    335:                return WriteTMDRH(1, data);
                    336:         case 0x16:                                     // IO_RLDR1L
                    337:                return WriteRLDRL(1, data);
                    338:         case 0x17:                                     // IO_RLDR1H
                    339:                return WriteRLDRH(1, data);
                    340:         case 0x18:                                     // IO_FRC
                    341:                // 書き込みは出来るけど、してはいけないっぽい。
                    342:                // たぶん現在値が変わるだけだと思うけど未対応。
                    343:                break;
                    344: 
                    345:         case 0x20:                                     // IO_SAR0L
                    346:         case 0x21:                                     // IO_SAR0H
                    347:         case 0x22:                                     // IO_SAR0B
                    348:         case 0x23:                                     // IO_DAR0L
                    349:         case 0x24:                                     // IO_DAR0H
                    350:         case 0x25:                                     // IO_DAR0B
                    351:         case 0x26:                                     // IO_BCR0L
                    352:         case 0x27:                                     // IO_BCR0H
                    353:         case 0x28:                                     // IO_MAR1L
                    354:         case 0x29:                                     // IO_MAR1H
                    355:         case 0x2a:                                     // IO_MAR1B
                    356:         case 0x2b:                                     // IO_IAR1L
                    357:         case 0x2c:                                     // IO_IAR1H
                    358:         case 0x2e:                                     // IO_BCR1L
                    359:         case 0x2f:                                     // IO_BCR1H
                    360:         case 0x30:                                     // IO_DSTAT
                    361:         case 0x31:                                     // IO_DMODE
                    362:                break;
                    363:         case 0x32:                                     // IO_DCNTL
                    364:                return WriteDCNTL(data);
                    365:                break;
                    366: 
                    367:         case 0x33:                                     // IO_IL
                    368:                return WriteIL(data);
                    369:         case 0x34:                                     // IO_ITC
                    370:                return WriteITC(data);
                    371:         case 0x36:                                     // IO_RCR
                    372:                return WriteRCR(data);
                    373: 
                    374:         case 0x38:                                     // IO_CBR
                    375:                return WriteCBR(data);
                    376:         case 0x39:                                     // IO_BBR
                    377:                return WriteBBR(data);
                    378:         case 0x3a:                                     // IO_CBAR
                    379:                return WriteCBAR(data);
                    380: 
                    381:         case 0x3e:                                     // IO_OMCR
                    382:                break;
                    383:         case 0x3f:                                     // IO_ICR
                    384:                return WriteICR(data);
                    385: 
                    386:         case 0x40:                                     // IO_T2FRCL
                    387:         case 0x41:                                     // IO_T2FRCH
                    388:         case 0x42:                                     // IO_T2OCR1L
                    389:         case 0x43:                                     // IO_T2OCR1H
                    390:         case 0x44:                                     // IO_T2OCR2L
                    391:         case 0x45:                                     // IO_T2OCR2H
                    392:         case 0x46:                                     // IO_T2ICRL
                    393:         case 0x47:                                     // IO_T2ICRH
                    394:         case 0x48:                                     // IO_T2CSR1
                    395:         case 0x49:                                     // IO_T2CSR2
                    396:                break;
                    397: 
                    398:         case 0x50:                                     // IO_CCSR
                    399:                break;
                    400:         case 0x51:                                     // IO_RMCR
                    401:                return WriteRMCR(data);
                    402: 
                    403:         case 0x53:                                     // IO_DERA
                    404:         case 0x60:                                     // IO_IODRA
                    405:         case 0x61:                                     // IO_IODRB
                    406:         case 0x62:                                     // IO_IODRC
                    407:         case 0x63:                                     // IO_IODRD
                    408:         case 0x64:                                     // IO_IODRE
                    409:         case 0x65:                                     // IO_IODRF
                    410:         case 0x66:                                     // IO_IDRG
                    411:         case 0x70:                                     // IO_DDRA
                    412:         case 0x71:                                     // IO_DDRB
                    413:         case 0x72:                                     // IO_DDRC
                    414:         case 0x73:                                     // IO_DDRD
                    415:         case 0x74:                                     // IO_DDRE
                    416:         case 0x75:                                     // IO_DDRF
                    417:                break;
                    418: 
                    419:         default:
                    420:                break;
                    421:        }
                    422: 
                    423:        putlog(0, "WriteInternalIO %s <- $%02x (NOT IMPLEMENTED)",
                    424:                IOName(offset).c_str(), data);
                    425:        return 0;
                    426: }
                    427: 
                    428: uint32
                    429: MPU64180Device::WriteExternalIO(uint32 addr, uint32 data)
                    430: {
                    431:        // LUNA の外部 I/O はアドレスの上位バイト不問
                    432:        switch (addr & 0xff) {
                    433:         case 0x82:                                     // SSG
                    434:         case 0x83:                                     // SSG
                    435: #if !defined(ENABLE_SSG_LOG)
                    436:                return 0;
                    437: #endif
                    438:                break;
                    439: 
                    440:         case 0x90:                                     // INT0 ネゲート
                    441:                putlog(1, "%s Negate INT0", IOName(addr).c_str());
                    442:                NegateINT0();
                    443:                return 0;
                    444: 
                    445:         case 0xa0:                                     // レベル5 割り込み要求
                    446:                putlog(1, "%s Interrupt High", IOName(addr).c_str());
                    447:                pio0->InterruptXPHigh();
                    448:                return 0;
                    449: 
                    450:         case 0xb0:                                     // レベル1 割り込み要求
                    451:                putlog(1, "%s Interrupt Low", IOName(addr).c_str());
                    452:                pio0->InterruptXPLow();
                    453:                return 0;
                    454: 
                    455:         default:
                    456:                break;
                    457:        }
                    458: 
                    459:        putlog(0, "WriteExternalIO %s <- $%02x (NOT IMPLEMENTED)",
                    460:                IOName(addr).c_str(), data);
                    461:        return 0;
                    462: }
                    463: 
                    464: uint32
                    465: MPU64180Device::WriteTMDRL(int ch, uint32 data)
                    466: {
                    467:        auto& t = timer[ch];
                    468:        if (t.running) {
                    469:                // タイマー動作中の更新は inhibited と書いてあるけど、実際どうなる?
                    470:                putlog(0, "Writing %s <- $%02x while timer is running! (ignored)",
                    471:                        IOName(HD647180::IO_TMDRL(ch)).c_str(), data);
                    472:        } else {
                    473:                t.count = (t.count & 0xff00) | data;
                    474:                putlog(1, "%s <- $%02x (TMDR%d = $%04x)",
                    475:                        IOName(HD647180::IO_TMDRL(ch)).c_str(), data, ch, t.count);
                    476:        }
                    477:        return 0;
                    478: }
                    479: 
                    480: uint32
                    481: MPU64180Device::WriteTMDRH(int ch, uint32 data)
                    482: {
                    483:        auto& t = timer[ch];
                    484:        if (t.running) {
                    485:                // タイマー動作中の更新は inhibited と書いてあるけど、実際どうなる?
                    486:                putlog(0, "Writing %s <- $%02x while timer is running! (ignored)",
                    487:                        IOName(HD647180::IO_TMDRH(ch)).c_str(), data);
                    488:        } else {
                    489:                t.count = (data << 8) | (t.count & 0x00ff);
                    490:                putlog(1, "%s <- $%02x (TMDR%d = $%04x)",
                    491:                        IOName(HD647180::IO_TMDRH(ch)).c_str(), data, ch, t.count);
                    492:        }
                    493:        return 0;
                    494: }
                    495: 
                    496: uint32
                    497: MPU64180Device::WriteRLDRL(int ch, uint32 data)
                    498: {
                    499:        // 動作中にも変更可能
                    500:        auto& t = timer[ch];
                    501:        t.reload = (t.reload & 0xff00) | data;
                    502:        putlog(1, "%s <- $%02x (RLDR%d = $%04x)",
                    503:                IOName(HD647180::IO_RLDRL(ch)).c_str(), data, ch, t.reload);
                    504:        return 0;
                    505: }
                    506: 
                    507: uint32
                    508: MPU64180Device::WriteRLDRH(int ch, uint32 data)
                    509: {
                    510:        // 動作中にも変更可能
                    511:        auto& t = timer[ch];
                    512:        t.reload = (data << 8) | (t.reload & 0x00ff);
                    513:        putlog(1, "%s <- $%02x (RLDR%d = $%04x)",
                    514:                IOName(HD647180::IO_RLDRH(ch)).c_str(), data, ch, t.reload);
                    515:        return 0;
                    516: }
                    517: 
                    518: uint32
                    519: MPU64180Device::WriteTCR(uint32 data)
                    520: {
                    521:        std::array<bool, 2> new_tde;
                    522:        std::string msg;
                    523: 
                    524:        timer[1].intr_enable = (data & 0x20);
                    525:        timer[0].intr_enable = (data & 0x10);
                    526:        // intr_enable を変更したので ChangeTimerInterrupt() を呼ぶのは
                    527:        // 最後に行っている。
                    528: 
                    529:        timer_toc = (data >> 2) & 3;
                    530: 
                    531:        new_tde[1] = (data & 0x02);
                    532:        new_tde[0] = (data & 0x01);
                    533:        msg = string_format("TIE1=%d TIE0=%d TOC=$%d",
                    534:                (timer[1].intr_enable ? 1 : 0),
                    535:                (timer[0].intr_enable ? 1 : 0),
                    536:                timer_toc);
                    537: 
                    538:        for (int ch = 0; ch < timer.size(); ch++) {
                    539:                auto& t = timer[ch];
                    540:                if (t.running == false && new_tde[ch] == true) {
                    541:                        // カウントダウン開始
                    542:                        t.count = t.reload;
                    543:                        t.running = true;
                    544:                        MakeActiveTimer();
                    545:                        msg += string_format(" Timer%d=Start", ch);
                    546:                        EnableTimer();
                    547:                } else if (t.running == true && new_tde[ch] == false) {
                    548:                        // カウントダウン停止
                    549: 
                    550:                        // ここではタイマーの状態を停止にするだけでよい。
                    551:                        // タイマーイベントの中で running が落ちてたら停止してくれる。
                    552:                        t.running = false;
                    553:                        MakeActiveTimer();
                    554:                        msg += string_format(" Timer%d=Stop", ch);
                    555:                } else {
                    556:                        // 変化なし
                    557:                }
                    558:        }
                    559: 
                    560:        putlog(1, "%s <- $%02x: %s",
                    561:                IOName(HD647180::IO_TCR).c_str(), data, msg.c_str());
                    562: 
                    563:        // ログの順序的に書き込みログの後で変更する
                    564:        ChangeTimerInterrupt();
                    565: 
                    566:        return 0;
                    567: }
                    568: 
                    569: uint32
                    570: MPU64180Device::WriteDCNTL(uint32 data)
                    571: {
                    572:        // メモリウェイト 0,1,2,3
                    573:        memwait = (data >> 6) & 3;
                    574: 
                    575:        // I/O ウェイトは 0,2,3,4
                    576:        iowait = (data >> 4) & 3;
                    577:        if (iowait != 0)
                    578:                iowait++;
                    579: 
                    580:        // 下位4ビット分は未実装
                    581:        dcntl = data & 0x0f;
                    582:        return 0;
                    583: }
                    584: 
                    585: uint32
                    586: MPU64180Device::WriteIL(uint32 data)
                    587: {
                    588:        // 書き込み時にマスクする
                    589:        intvec_low = data & 0xe0;
                    590:        return 0;
                    591: }
                    592: 
                    593: uint32
                    594: MPU64180Device::WriteITC(uint32 data)
                    595: {
                    596:        itc_trap = (data & 0x80);
                    597:        // UFO は ReadOnly
                    598:        itc_ite2 = (data & 0x04);
                    599:        itc_ite1 = (data & 0x02);
                    600:        itc_ite0 = (data & 0x01);
                    601: 
                    602:        // XXX 割り込み変わったら何かする?
                    603: 
                    604:        return 0;
                    605: }
                    606: 
                    607: uint32
                    608: MPU64180Device::WriteRCR(uint32 data)
                    609: {
                    610:        // 未実装
                    611:        rcr = data | 0x3c;
                    612: 
                    613:        if ((rcr & 0x80)) {
                    614:                // Refresh Enable は未実装。無効にするなら表示不要。
                    615:                putlog(0, "%s <- $%02x: Refresh Enable (NOT IMPLEMENTED)",
                    616:                        IOName(HD647180::IO_RCR).c_str(), data);
                    617:        } else {
                    618:                // ログレベル 1 なら全部表示
                    619:                putlog(1, "%s <- $%02x (NOT IMPLEMENTED)",
                    620:                        IOName(HD647180::IO_RCR).c_str(), data);
                    621:        }
                    622:        return 0;
                    623: }
                    624: 
                    625: uint32
                    626: MPU64180Device::WriteCBR(uint32 data)
                    627: {
                    628:        int lv;
                    629:        uint32 new_base = data << 12;
                    630:        if (commbase != new_base) {
                    631:                lv = 1;
                    632:                commbase = new_base;
                    633:        } else {
                    634:                lv = 2;
                    635:        }
                    636:        putlog(lv, "%s <- $%02x: Common Base Addr=$%05x",
                    637:                IOName(HD647180::IO_CBR).c_str(), data, commbase);
                    638:        return 0;
                    639: }
                    640: 
                    641: uint32
                    642: MPU64180Device::WriteBBR(uint32 data)
                    643: {
                    644:        int lv;
                    645:        uint32 new_base = data << 12;
                    646:        if (bankbase != new_base) {
                    647:                lv = 1;
                    648:                bankbase = new_base;
                    649:        } else {
                    650:                lv = 2;
                    651:        }
                    652:        putlog(lv, "%s <- $%02x: Bank Base Addr=$%05x",
                    653:                IOName(HD647180::IO_BBR).c_str(), data, bankbase);
                    654:        return 0;
                    655: }
                    656: 
                    657: uint32
                    658: MPU64180Device::WriteCBAR(uint32 data)
                    659: {
                    660:        int lv;
                    661:        uint32 new_comm = (data & 0xf0) << 8;
                    662:        uint32 new_bank = (data & 0x0f) << 12;
                    663:        if (commarea != new_comm || bankarea != new_bank) {
                    664:                lv = 1;
                    665:                commarea = new_comm;
                    666:                bankarea = new_bank;
                    667:        } else {
                    668:                lv = 2;
                    669:        }
                    670:        putlog(lv, "%s <- $%02x: CommArea=$%04x BankArea=$%04x",
                    671:                IOName(HD647180::IO_CBAR).c_str(), data, commarea, bankarea);
                    672:        return 0;
                    673: }
                    674: 
                    675: uint32
                    676: MPU64180Device::WriteICR(uint32 data)
                    677: {
                    678:        io_address = data & 0x80;
                    679:        putlog(1, "%s <- $%02x: I/O Address=$%02x",
                    680:                IOName(HD647180::IO_ICR).c_str(), data, io_address);
                    681: 
                    682:        // IOSTP は未実装
                    683:        if ((data & 0x20) != 0) {
                    684:                putlog(0, "%s IOSTP (NOT IMPLEMENTED)");
                    685:        }
                    686:        return 0;
                    687: }
                    688: 
                    689: uint32
                    690: MPU64180Device::WriteRMCR(uint32 data)
                    691: {
                    692:        xpbus->SetRMCR(data);
                    693:        putlog(1, "%s <- $%02x: RAM address=$%05x",
                    694:                IOName(HD647180::IO_RMCR).c_str(), data, xpbus->GetXPRAMAddr());
                    695:        return 0;
                    696: }
                    697: 
                    698: uint32
                    699: MPU64180Device::PeekIO(uint32 addr)
                    700: {
                    701:        // 内蔵 I/O
                    702:        if (io_address <= addr && addr < io_address + 0x80) {
                    703:                return PeekInternalIO(addr - io_address);
                    704:        }
                    705: 
                    706:        return PeekExternalIO(addr);
                    707: }
                    708: 
                    709: uint32
                    710: MPU64180Device::PeekInternalIO(uint32 offset)
                    711: {
                    712:        switch (offset) {
                    713:         case 0x00:                                     // IO_CNTLA0
                    714:         case 0x01:                                     // IO_CNTLA1
                    715:         case 0x02:                                     // IO_CNTLB0
                    716:         case 0x03:                                     // IO_CNTLB1
                    717:         case 0x04:                                     // IO_STAT0
                    718:         case 0x05:                                     // IO_STAT1
                    719:         case 0x06:                                     // IO_TDR0
                    720:         case 0x07:                                     // IO_TDR1
                    721:         case 0x08:                                     // IO_TSR0
                    722:         case 0x09:                                     // IO_TSR1
                    723:         case 0x0a:                                     // IO_CNTR
                    724:         case 0x0b:                                     // IO_TRDR
                    725:                break;
                    726: 
                    727:         case 0x0c:                                     // IO_TMDR0L
                    728:                return PeekTMDRL(0);
                    729:         case 0x0d:                                     // IO_TMDR0H
                    730:                return PeekTMDRH(0);
                    731:         case 0x0e:                                     // IO_RLDR0L
                    732:                return PeekRLDRL(0);
                    733:         case 0x0f:                                     // IO_RLDR0H
                    734:                return PeekRLDRH(0);
                    735:         case 0x10:                                     // IO_TCR
                    736:                return PeekTCR();
                    737:         case 0x14:                                     // IO_TMDR1L
                    738:                return PeekTMDRL(1);
                    739:         case 0x15:                                     // IO_TMDR1H
                    740:                return PeekTMDRH(1);
                    741:         case 0x16:                                     // IO_RLDR1L
                    742:                return PeekRLDRL(1);
                    743:         case 0x17:                                     // IO_RLDR1H
                    744:                return PeekRLDRH(1);
                    745:         case 0x18:                                     // IO_FRC
                    746:                return PeekFRC();
                    747: 
                    748:         case 0x20:                                     // IO_SAR0L
                    749:         case 0x21:                                     // IO_SAR0H
                    750:         case 0x22:                                     // IO_SAR0B
                    751:         case 0x23:                                     // IO_DAR0L
                    752:         case 0x24:                                     // IO_DAR0H
                    753:         case 0x25:                                     // IO_DAR0B
                    754:         case 0x26:                                     // IO_BCR0L
                    755:         case 0x27:                                     // IO_BCR0H
                    756:         case 0x28:                                     // IO_MAR1L
                    757:         case 0x29:                                     // IO_MAR1H
                    758:         case 0x2a:                                     // IO_MAR1B
                    759:         case 0x2b:                                     // IO_IAR1L
                    760:         case 0x2c:                                     // IO_IAR1H
                    761:         case 0x2e:                                     // IO_BCR1L
                    762:         case 0x2f:                                     // IO_BCR1H
                    763:         case 0x30:                                     // IO_DSTAT
                    764:         case 0x31:                                     // IO_DMODE
                    765:                break;
                    766:         case 0x32:                                     // IO_DCNTL
                    767:                return PeekDCNTL();
                    768: 
                    769:         case 0x33:                                     // IO_IL
                    770:                return PeekIL();
                    771:         case 0x34:                                     // IO_ITC
                    772:                return PeekITC();
                    773:         case 0x36:                                     // IO_RCR
                    774:                return PeekRCR();
                    775: 
                    776:         case 0x38:                                     // IO_CBR
                    777:                return PeekCBR();
                    778:         case 0x39:                                     // IO_BBR
                    779:                return PeekBBR();
                    780:         case 0x3a:                                     // IO_CBAR
                    781:                return PeekCBAR();
                    782: 
                    783:         case 0x3e:                                     // IO_OMCR
                    784:                break;
                    785:         case 0x3f:                                     // IO_ICR
                    786:                return PeekICR();
                    787: 
                    788:         case 0x40:                                     // IO_T2FRCL
                    789:         case 0x41:                                     // IO_T2FRCH
                    790:         case 0x42:                                     // IO_T2OCR1L
                    791:         case 0x43:                                     // IO_T2OCR1H
                    792:         case 0x44:                                     // IO_T2OCR2L
                    793:         case 0x45:                                     // IO_T2OCR2H
                    794:         case 0x46:                                     // IO_T2ICRL
                    795:         case 0x47:                                     // IO_T2ICRH
                    796:         case 0x48:                                     // IO_T2CSR1
                    797:         case 0x49:                                     // IO_T2CSR2
                    798:                break;
                    799: 
                    800:         case 0x50:                                     // IO_CCSR
                    801:                break;
                    802:         case 0x51:                                     // IO_RMCR
                    803:                return xpbus->GetRMCR();
                    804: 
                    805:         case 0x53:                                     // IO_DERA
                    806:         case 0x60:                                     // IO_IODRA
                    807:         case 0x61:                                     // IO_IODRB
                    808:         case 0x62:                                     // IO_IODRC
                    809:         case 0x63:                                     // IO_IODRD
                    810:         case 0x64:                                     // IO_IODRE
                    811:         case 0x65:                                     // IO_IODRF
                    812:         case 0x66:                                     // IO_IDRG
                    813:         case 0x70:                                     // IO_DDRA
                    814:         case 0x71:                                     // IO_DDRB
                    815:         case 0x72:                                     // IO_DDRC
                    816:         case 0x73:                                     // IO_DDRD
                    817:         case 0x74:                                     // IO_DDRE
                    818:         case 0x75:                                     // IO_DDRF
                    819:                break;
                    820: 
                    821:         default:
                    822:                break;
                    823:        }
                    824:        return 0xff;
                    825: }
                    826: 
                    827: uint32
                    828: MPU64180Device::PeekExternalIO(uint32 addr)
                    829: {
                    830:        // LUNA の外部 I/O はアドレスの上位バイト不問
                    831:        switch (addr & 0xff) {
                    832:         case 0x82:                                     // SSG
                    833:         case 0x83:                                     // SSG
                    834:                break;
                    835: 
                    836:         case 0x90:                                     // INT0 ネゲート
                    837:                break;
                    838: 
                    839:         case 0xa0:                                     // レベル5 割り込み要求
                    840:         case 0xb0:                                     // レベル1 割り込み要求
                    841:                break;
                    842: 
                    843:         default:
                    844:                break;
                    845:        }
                    846:        return 0xff;
                    847: }
                    848: 
                    849: uint32
                    850: MPU64180Device::PeekTMDRL(int ch) const
                    851: {
                    852:        return timer[ch].count & 0xff;
                    853: }
                    854: 
                    855: uint32
                    856: MPU64180Device::PeekTMDRH(int ch) const
                    857: {
                    858:        return timer[ch].count >> 8;
                    859: }
                    860: 
                    861: uint32
                    862: MPU64180Device::PeekRLDRL(int ch) const
                    863: {
                    864:        return timer[ch].reload & 0xff;
                    865: }
                    866: 
                    867: uint32
                    868: MPU64180Device::PeekRLDRH(int ch) const
                    869: {
                    870:        return timer[ch].reload >> 8;
                    871: }
                    872: 
                    873: uint32
                    874: MPU64180Device::PeekTCR() const
                    875: {
                    876:        uint32 data = (timer_toc << 2);
                    877: 
                    878:        if (timer[1].tif != 0)
                    879:                data |= 0x80;
                    880:        if (timer[0].tif != 0)
                    881:                data |= 0x40;
                    882:        if (timer[1].intr_enable)
                    883:                data |= 0x20;
                    884:        if (timer[0].intr_enable)
                    885:                data |= 0x10;
                    886:        if (timer[1].running)
                    887:                data |= 0x02;
                    888:        if (timer[0].running)
                    889:                data |= 0x01;
                    890: 
                    891:        return data;
                    892: }
                    893: 
                    894: uint32
                    895: MPU64180Device::PeekFRC() const
                    896: {
                    897:        if (opmode == OpMode::Reset) {
                    898:                return 0xff;
                    899:        } else {
                    900:                // Free Running Counter はリセット時に 0FFH で、
                    901:                // そこから 10φ ごとに1ずつ減っていく。
                    902:                // そのため、リセット時の時刻を覚えておき、経過時間から計算する。
                    903:                uint64 time = scheduler->GetVirtTime() - timer_epoch;
                    904:                return 0xff - (uint8)(time / (clock_nsec * 10));
                    905:        }
                    906: }
                    907: 
                    908: uint32
                    909: MPU64180Device::PeekDCNTL() const
                    910: {
                    911:        uint32 data;
                    912: 
                    913:        data = (memwait << 6);
                    914:        if (iowait != 0) {
                    915:                data |= (iowait - 1) << 4;
                    916:        }
                    917:        data |= dcntl;
                    918: 
                    919:        return data;
                    920: }
                    921: 
                    922: uint32
                    923: MPU64180Device::PeekIL() const
                    924: {
                    925:        return intvec_low;
                    926: }
                    927: 
                    928: uint32
                    929: MPU64180Device::PeekITC() const
                    930: {
                    931:        uint32 data = 0x38;
                    932:        if (itc_trap)
                    933:                data |= 0x80;
                    934:        if (itc_ufo)
                    935:                data |= 0x40;
                    936:        if (itc_ite2)
                    937:                data |= 0x04;
                    938:        if (itc_ite1)
                    939:                data |= 0x02;
                    940:        if (itc_ite0)
                    941:                data |= 0x01;
                    942:        return data;
                    943: }
                    944: 
                    945: uint32
                    946: MPU64180Device::PeekRCR() const
                    947: {
                    948:        return rcr;
                    949: }
                    950: 
                    951: uint32
                    952: MPU64180Device::PeekCBR() const
                    953: {
                    954:        return (commbase >> 12) & 0xff;
                    955: }
                    956: 
                    957: uint32
                    958: MPU64180Device::PeekBBR() const
                    959: {
                    960:        return (bankbase >> 12) & 0xff;
                    961: }
                    962: 
                    963: uint32
                    964: MPU64180Device::PeekCBAR() const
                    965: {
                    966:        uint32 data;
                    967: 
                    968:        data  = (commarea >>  8) & 0xf0;
                    969:        data |= (bankarea >> 12) & 0x0f;
                    970: 
                    971:        return data;
                    972: }
                    973: 
                    974: uint32
                    975: MPU64180Device::PeekICR() const
                    976: {
                    977:        // IOSTP は未実装
                    978:        return io_address | 0x5f;
                    979: }
                    980: 
                    981: uint32
                    982: MPU64180Device::PeekRMCR() const
                    983: {
                    984:        return xpbus->GetRMCR();
                    985: }
                    986: 
                    987: // アドレス (とあれば名前) を返す。
                    988: /*static*/ std::string
                    989: MPU64180Device::IOName(uint32 addr)
                    990: {
                    991:        std::string buf;
                    992: 
                    993:        if (addr < 0x100) {
                    994:                buf = string_format("%02XH", addr);
                    995:        } else {
                    996:                buf = string_format("%04XH", addr);
                    997:        }
                    998: 
                    999:        if (addr < ionames.size() && ionames[addr] != NULL) {
                   1000:                buf += '(';
                   1001:                buf += ionames[addr];
                   1002:                buf += ')';
                   1003:        }
                   1004:        return buf;
                   1005: }
                   1006: 
                   1007: /*static*/ std::vector<const char *>
                   1008: MPU64180Device::ionames = {
                   1009:        "CNTLA0",       // 00
                   1010:        "CNTLA1",       // 01
                   1011:        "CNTLB0",       // 02
                   1012:        "CNTLB1",       // 03
                   1013:        "STAT0",        // 04
                   1014:        "STAT1",        // 05
                   1015:        "TDR0",         // 06
                   1016:        "TDR1",         // 07
                   1017:        "TSR0",         // 08
                   1018:        "TSR1",         // 09
                   1019:        "CNTR",         // 0a
                   1020:        "TRDR",         // 0b
                   1021:        "TMDR0L",       // 0c
                   1022:        "TMDR0H",       // 0d
                   1023:        "RLDR0L",       // 0e
                   1024:        "RLDR0H",       // 0f
                   1025: 
                   1026:        "TCR",          // 10
                   1027:        NULL,           // 11
                   1028:        NULL,           // 12
                   1029:        NULL,           // 13
                   1030:        "TMDR1L",       // 14
                   1031:        "TMDR1H",       // 15
                   1032:        "RLDR1L",       // 16
                   1033:        "RLDR1H",       // 17
                   1034:        "FRFC",         // 18
                   1035:        NULL,           // 19
                   1036:        NULL,           // 1a
                   1037:        NULL,           // 1b
                   1038:        NULL,           // 1c
                   1039:        NULL,           // 1d
                   1040:        NULL,           // 1e
                   1041:        NULL,           // 1f
                   1042: 
                   1043:        "SAR0L",        // 20
                   1044:        "SAR0H",        // 21
                   1045:        "SAR0B",        // 22
                   1046:        "DAR0L",        // 23
                   1047:        "DAR0H",        // 24
                   1048:        "DAR0B",        // 25
                   1049:        "BCR0L",        // 26
                   1050:        "BCR0H",        // 27
                   1051:        "MAR1L",        // 28
                   1052:        "MAR1H",        // 29
                   1053:        "MAR1B",        // 2a
                   1054:        "IAR1L",        // 2b
                   1055:        "IAR1H",        // 2c
                   1056:        NULL,           // 2d
                   1057:        "BCR1L",        // 2e
                   1058:        "BCR1H",        // 2f
                   1059: 
                   1060:        "DSTAT",        // 30
                   1061:        "DMODE",        // 31
                   1062:        "DCNTL",        // 32
                   1063:        "IL",           // 33
                   1064:        "ITC",          // 34
                   1065:        NULL,           // 35
                   1066:        "RCR",          // 36
                   1067:        NULL,           // 37
                   1068:        "CBR",          // 38
                   1069:        "BBR",          // 39
                   1070:        "CBAR",         // 3a
                   1071:        NULL,           // 3b
                   1072:        NULL,           // 3c
                   1073:        NULL,           // 3d
                   1074:        "OMCR",         // 3e
                   1075:        "ICR",          // 3f
                   1076: 
                   1077:        "T2FRCL",       // 40
                   1078:        "T2FRCH",       // 41
                   1079:        "T2OCR1L",      // 42
                   1080:        "T2OCR1H",      // 43
                   1081:        "T2OCR2L",      // 44
                   1082:        "T2OCR2H",      // 45
                   1083:        "T2ICRL",       // 46
                   1084:        "T2ICRH",       // 47
                   1085:        "T2CSR1",       // 48
                   1086:        "T2CSR2",       // 49
                   1087:        NULL,           // 4a
                   1088:        NULL,           // 4b
                   1089:        NULL,           // 4c
                   1090:        NULL,           // 4d
                   1091:        NULL,           // 4e
                   1092:        NULL,           // 4f
                   1093: 
                   1094:        "CCSR",         // 50
                   1095:        "RMCR",         // 51
                   1096:        NULL,           // 52
                   1097:        "DERA",         // 53
                   1098:        NULL,           // 54
                   1099:        NULL,           // 55
                   1100:        NULL,           // 56
                   1101:        NULL,           // 57
                   1102:        NULL,           // 58
                   1103:        NULL,           // 59
                   1104:        NULL,           // 5a
                   1105:        NULL,           // 5b
                   1106:        NULL,           // 5c
                   1107:        NULL,           // 5d
                   1108:        NULL,           // 5e
                   1109:        NULL,           // 5f
                   1110: 
                   1111:        "IODRA",        // 60
                   1112:        "IODRB",        // 61
                   1113:        "IODRC",        // 62
                   1114:        "IODRD",        // 63
                   1115:        "IODRE",        // 64
                   1116:        "IODRF",        // 65
                   1117:        "IDRG",         // 66
                   1118:        NULL,           // 67
                   1119:        NULL,           // 68
                   1120:        NULL,           // 69
                   1121:        NULL,           // 6a
                   1122:        NULL,           // 6b
                   1123:        NULL,           // 6c
                   1124:        NULL,           // 6d
                   1125:        NULL,           // 6e
                   1126:        NULL,           // 6f
                   1127: 
                   1128:        "DDRA",         // 70
                   1129:        "DDRB",         // 71
                   1130:        "DDRC",         // 72
                   1131:        "DDRD",         // 73
                   1132:        "DDRE",         // 74
                   1133:        "DDRF",         // 75
                   1134: };

unix.superglobalmegacorp.com

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