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

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

unix.superglobalmegacorp.com

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