Annotation of nono/vm/mainbus_x68k.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // メインバス (X68030)
                      9: //
                     10: 
                     11: // IODevice
                     12: //   +-- MainbusBaseDevice (InitMainbus() と FC アクセスを持つ)
                     13: //   |    +-- MainbusDevice (これがメインバス、システムに1つ)
                     14: //   |    |    +-- Mainbus24Device (上位8ビットがテーブルで表せるメインバス)
                     15: //   |    |    |    +-- LunaMainbus
                     16: //   |    |    |    |    +-- Luna1Mainbus
                     17: //   |    |    |    |    +-- Luna88kMainbus
                     18: //   |    |    |    +-- NewsMainbus
                     19: //   |    |    |    +-- Virt68kMainbus
                     20: //   |    |    |
                     21: //   |    |    |  +-------------+
                     22: //   |    |    +--| X68kMainbus |(上位8ビットが IODevice で表せないため)
                     23: //   |    |       +-------------+
                     24: //   |    |
                     25: //   |    +-- X68kIODevice (FC を受け取るため)
                     26: //   |
                     27: //   +-- XPbusDevice
                     28: 
                     29: #include "mainbus_x68k.h"
                     30: #include "bankram.h"
                     31: #include "extram.h"
                     32: #include "interrupt.h"
                     33: #include "mainapp.h"
                     34: #include "x68kio.h"
                     35: 
                     36: // コンストラクタ
                     37: X68kMainbus::X68kMainbus()
                     38:        : inherited(OBJ_MAINBUS)
                     39: {
                     40:        // デバイス
                     41:        NEWDV(Interrupt, new X68030Interrupt());
                     42:        NEWDV(X68kIO, new X68kIODevice());
                     43:        NEWDV(ExtRAM, new ExtRAMDevice());
                     44: 
                     45:        // デバイスの割り当ては Init() で行っている。
                     46: 
                     47:        // モニタの表示外観は Mainbus24 と同じ。
                     48:        monitor.func = ToMonitorCallback(&X68kMainbus::MonitorUpdate);
                     49:        monitor.SetSize(75, 33);
                     50:        monitor.Regist(ID_MONITOR_MAINBUS);
                     51: 
                     52:        monitor_accstat.func =
                     53:                ToMonitorCallback(&X68kMainbus::MonitorUpdateAccStat);
                     54:        monitor_accstat.SetSize(80, 2 + 16 + 3);
                     55:        monitor_accstat.Regist(ID_MONITOR_ACCSTAT);
                     56: }
                     57: 
                     58: // デストラクタ
                     59: X68kMainbus::~X68kMainbus()
                     60: {
                     61: }
                     62: 
                     63: // 初期化
                     64: bool
                     65: X68kMainbus::Init()
                     66: {
                     67:        if (inherited::Init() == false) {
                     68:                return false;
                     69:        }
                     70: 
                     71:        for (int i = 0; i < bankram.size(); i++) {
                     72:                bankram[i] = gMainApp.FindObject<BankRAMDevice>(OBJ_BANKRAM(i));
                     73:        }
                     74: 
                     75:        return true;
                     76: }
                     77: 
                     78: // メインバスの初期化
                     79: bool
                     80: X68kMainbus::InitMainbus()
                     81: {
                     82:        // 拡張メモリはサイズが確定した後のここで配置。
                     83:        extsize = pExtRAM->GetSizeMB();
                     84: 
                     85:        // 上位8ビット全域を一旦全部内蔵空間にしてから
                     86:        std::fill(is_intio.begin(), is_intio.end(), true);
                     87: 
                     88:        if (extsize == 16) {
                     89:                // TS-6BE16 互換 (16MB) なら $01 の 16MB。
                     90:                extstart = 16;
                     91:                is_intio[1] = false;
                     92:        } else {
                     93:                // 060turbo 互換なら $10 から。
                     94:                extstart = 256;
                     95:                for (int i = 0x10, end = i + (extsize / 16); i < end; i++) {
                     96:                        is_intio[i] = false;
                     97:                }
                     98:        }
                     99: 
                    100:        // 親子構造になっている。
                    101:        if (pX68kIO->InitMainbus() == false) {
                    102:                return false;
                    103:        }
                    104: 
                    105:        return true;
                    106: }
                    107: 
                    108: // リセット
                    109: void
                    110: X68kMainbus::ResetHard(bool poweron)
                    111: {
                    112:        inherited::ResetHard(poweron);
                    113: 
                    114:        std::fill(accstat_read.begin(), accstat_read.end(), 0);
                    115:        std::fill(accstat_write.begin(), accstat_write.end(), 0);
                    116: }
                    117: 
                    118: // リセットについて。
                    119: //
                    120: //           PWRRESET
                    121: // 電源オン ----------+--> VIPS
                    122: // (7505)             +--> VideoCtlr
                    123: //                    +--> OSCIAN2
                    124: //                    |
                    125: //                    |   +------+
                    126: //                    +-->|      |
                    127: // 本体      SWRESET      | YUKI |
                    128: // リセット ------------->|      |
                    129: // スイッチ               +------+
                    130: //                         | IPLRESET
                    131: //                         |
                    132: //                         +--> FPU
                    133: //                         |
                    134: //                         ▽
                    135: //                   RESET |
                    136: //                         |<-> MPU (68030)
                    137: //                         +--> PPI (8255)
                    138: //                         +--> SPC (MB89352)
                    139: //                         +--> ADPCM (MSM6258)
                    140: //                         +--> FDC (uPD72065B)
                    141: //                         +--> MFP (MC68901)
                    142: //                         |
                    143: //                         |   +-------+
                    144: //                         +-->| PEDEC |
                    145: //                         |   +-------+
                    146: //                         |     |
                    147: //                         |     +-- OPMIC -----> OPM(YM2151)
                    148: //                         |     +-- SCCRD/WR --> SCC(Z8530)
                    149: //                         |
                    150: //                         |      EXRESET
                    151: //                         +---|>-----------> 外部バス
                    152: //                         ▽
                    153: //                SYSRESET |
                    154: //                         |<-> SAKI  ---+
                    155: //                         |             | BEC0,BEC1
                    156: //                         +--> DMAC  <--+
                    157: //                         +--> CYNTHIA
                    158: // リセットされない?
                    159: // o CACHY
                    160: 
                    161: // MPU の RESET 命令によるリセット
                    162: void
                    163: X68kMainbus::ResetByMPU()
                    164: {
                    165:        std::vector<int> ids {
                    166:                OBJ_ADPCM,
                    167:                OBJ_BANKRAM0,
                    168:                OBJ_BANKRAM1,
                    169:                OBJ_DMAC,
                    170:                OBJ_ETHERNET0,
                    171:                OBJ_ETHERNET1,
                    172:                OBJ_FDC,
                    173:                OBJ_MFP,
                    174:                OBJ_OPM,
                    175:                OBJ_PEDEC,
                    176:                OBJ_PLUTO,
                    177:                OBJ_PPI,
                    178:                OBJ_MPSCC,
                    179:                OBJ_SPC,
                    180:                OBJ_WINDRV,
                    181:        };
                    182:        for (auto id : ids) {
                    183:                auto dev = gMainApp.FindObject<IODevice>(id);
                    184:                if (dev) {
                    185:                        dev->ResetHard(false);
                    186:                }
                    187:        }
                    188: }
                    189: 
                    190: inline bool
                    191: X68kMainbus::IsIntio(uint32 addr) const
                    192: {
                    193:        return is_intio[(addr >> 24) & 0xff];
                    194: }
                    195: 
                    196: #define READ(NN)       do {    \
                    197:        uint32 pa = addr.Addr();        \
                    198:        if (IsIntio(pa)) {      \
                    199:                /* 内蔵 16MB を 1MB 単位で */     \
                    200:                accstat_read[(pa >> 20) & 0x0f] = ACC_READ;     \
                    201:                return pX68kIO->__CONCAT(Read,NN)(addr);        \
                    202:        } else {        \
                    203:                /* 拡張メモリのアドレスは折り返しは起きない */      \
                    204:                accstat_read[pa >> 20] = ACC_READ;      \
                    205:                return pExtRAM->__CONCAT(Read,NN)(pa);  \
                    206:        }       \
                    207: } while (0)
                    208: 
                    209: #define WRITE(NN)      do {    \
                    210:        uint32 pa = addr.Addr();        \
                    211:        if (IsIntio(pa)) {      \
                    212:                /* 内蔵 16MB を 1MB 単位で */     \
                    213:                accstat_write[(pa >> 20) & 0x0f] = ACC_WRITE;   \
                    214:                return pX68kIO->__CONCAT(Write,NN)(addr, data); \
                    215:        } else {        \
                    216:                /* 拡張メモリのアドレスは折り返しは起きない */      \
                    217:                accstat_write[pa >> 20] = ACC_WRITE;    \
                    218:                return pExtRAM->__CONCAT(Write,NN)(pa, data);   \
                    219:        }       \
                    220: } while (0)
                    221: 
                    222: busdata
                    223: X68kMainbus::Read8(busaddr addr)
                    224: {
                    225:        READ(8);
                    226: }
                    227: 
                    228: busdata
                    229: X68kMainbus::Read16(busaddr addr)
                    230: {
                    231:        READ(16);
                    232: }
                    233: 
                    234: busdata
                    235: X68kMainbus::Read32(busaddr addr)
                    236: {
                    237:        READ(32);
                    238: }
                    239: 
                    240: busdata
                    241: X68kMainbus::Write8(busaddr addr, uint32 data)
                    242: {
                    243:        WRITE(8);
                    244: }
                    245: 
                    246: busdata
                    247: X68kMainbus::Write16(busaddr addr, uint32 data)
                    248: {
                    249:        WRITE(16);
                    250: }
                    251: 
                    252: busdata
                    253: X68kMainbus::Write32(busaddr addr, uint32 data)
                    254: {
                    255:        WRITE(32);
                    256: }
                    257: 
                    258: busdata
                    259: X68kMainbus::Peek8(uint32 addr)
                    260: {
                    261:        if (IsIntio(addr)) {
                    262:                return pX68kIO->Peek8(addr);
                    263:        } else {
                    264:                return pExtRAM->Peek8(addr);
                    265:        }
                    266: }
                    267: 
                    268: bool
                    269: X68kMainbus::Poke8(uint32 addr, uint32 data)
                    270: {
                    271:        if (IsIntio(addr)) {
                    272:                return pX68kIO->Poke8(addr, data);
                    273:        } else {
                    274:                return pExtRAM->Poke8(addr, data);
                    275:        }
                    276: }
                    277: 
                    278: void
                    279: X68kMainbus::MonitorUpdate(Monitor *, TextScreen& screen)
                    280: {
                    281:        screen.Clear();
                    282: 
                    283:        // 012345678901234567890
                    284:        // $0000'0000: 1234567
                    285: 
                    286:        for (int i = 0; i < 8; i++) {
                    287:                screen.Print(12 + i * 8, 0, "+$0%x", i);
                    288:        }
                    289: 
                    290:        auto xioname = FormatDevName(pX68kIO.get()).first;
                    291:        auto extname = FormatDevName(pExtRAM.get()).first;
                    292: 
                    293:        int idx = 0;
                    294:        for (int i = 0; i < is_intio.size() / 8; i++) {
                    295:                screen.Print(0, i + 1, "$%02x00'0000:", idx);
                    296:                for (int j = 0; j < 8; j++) {
                    297:                        screen.Print(12 + j * 8, i + 1, "%s",
                    298:                                (is_intio[idx] ? xioname : extname).c_str());
                    299:                        idx++;
                    300:                }
                    301:        }
                    302: }
                    303: 
                    304: void
                    305: X68kMainbus::MonitorUpdateAccStat(Monitor *, TextScreen& screen)
                    306: {
                    307:        std::array<uint8, 1024> acc;
                    308:        std::array<uint8, 16 + 16> accbank;
                    309: 
                    310:        // R|W をマージしながらコピー。
                    311:        for (int i = 0, iend = acc.size(); i < iend; i += 4) {
                    312:                uint32 tmp = 0;
                    313:                tmp |= *(uint32 *)&accstat_read[i];
                    314:                tmp |= *(uint32 *)&accstat_write[i];
                    315:                *(uint32 *)&acc[i] = tmp;
                    316:        }
                    317: 
                    318:        // 読んだのでリセット。
                    319:        std::fill(accstat_read.begin(), accstat_read.end(), 0);
                    320:        std::fill(accstat_write.begin(), accstat_write.end(), 0);
                    321: 
                    322:        // バンクメモリ。
                    323:        for (int n = 0; n < bankram.size(); n++) {
                    324:                if (bankram[n]) {
                    325:                        bankram[n]->FetchAccStat(&accbank[n * 16]);
                    326:                }
                    327:        }
                    328: 
                    329:        screen.Clear();
                    330:        screen.Print(0, 0,
                    331:                "Shows only the first 1GB. 1MB/char. "
                    332:                "'R':Read, 'W':Write, 'A':Read+Write");
                    333:        screen.Print(12, 1, "0123456789ABCDEF");
                    334:        for (int i = 1; i < 4; i++) {
                    335:                screen.Print(12 + 17 * i, 1, "+$0%x", i);
                    336:        }
                    337:        for (int y = 0; y < acc.size() / 64; y++) {
                    338:                screen.Print(0, y + 2, "$%02x00'0000:", y * 0x04);
                    339:        }
                    340: 
                    341:        // 拡張メモリ部分。
                    342:        for (int i = extstart, end = extstart + extsize; i < end; i++) {
                    343:                uint op = acc[i] & 3;
                    344:                uint8 ch = ".RWA"[op];
                    345:                int y = 2 + i / 64;
                    346:                int x = 12 + (i % 64) + ((i % 64) / 16)/*区切りの空白分*/;
                    347:                screen.Putc(x, y, ch);
                    348:        }
                    349: 
                    350:        // 内蔵I/O 部分。
                    351:        {
                    352:                std::array<char, 16 + 1> buf;
                    353:                char *d = &buf[0];
                    354:                for (int i = 0; i < 16; i++) {
                    355:                        uint op = acc[i] & 3;
                    356:                        *d++ = ".RWA"[op];
                    357:                }
                    358:                *d = '\0';
                    359:                screen.Puts(12, 2, &buf[0]);
                    360:        }
                    361: 
                    362:        // バンクメモリ。
                    363:        for (int n = 0; n < 2; n++) {
                    364:                screen.Print(0, 19 + n, "BankMem #%d:", n);
                    365:                if (bankram[n]) {
                    366:                        for (int i = 0; i < 16; i++) {
                    367:                                uint op = accbank[n * 16 + i] & 3;
                    368:                                uint8 ch = ".RWA"[op];
                    369:                                screen.Putc(12 + i, 19 + n, ch);
                    370:                        }
                    371:                }
                    372:        }
                    373: }
                    374: 
                    375: // ブートページを切り替える。
                    376: void
                    377: X68kMainbus::SwitchBootPage(bool isrom)
                    378: {
                    379:        // X68030 ではすべて X68kIO が担当している
                    380:        pX68kIO->SwitchBootPage(isrom);
                    381: }

unix.superglobalmegacorp.com

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