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

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"
1.1.1.3 ! root       34: #include "monitor.h"
1.1       root       35: #include "x68kio.h"
                     36: 
                     37: // コンストラクタ
                     38: X68kMainbus::X68kMainbus()
                     39:        : inherited(OBJ_MAINBUS)
                     40: {
                     41:        // デバイス
                     42:        NEWDV(Interrupt, new X68030Interrupt());
                     43:        NEWDV(X68kIO, new X68kIODevice());
                     44:        NEWDV(ExtRAM, new ExtRAMDevice());
                     45: 
                     46:        // デバイスの割り当ては Init() で行っている。
                     47: 
1.1.1.3 ! root       48:        monitor = gMonitorManager->Regist(ID_MONITOR_MAINBUS, this);
        !            49:        monitor->func = ToMonitorCallback(&X68kMainbus::MonitorUpdate);
        !            50:        monitor->SetSize(75, 33);
1.1       root       51: 
1.1.1.3 ! root       52:        accstat_monitor->func =
1.1       root       53:                ToMonitorCallback(&X68kMainbus::MonitorUpdateAccStat);
1.1.1.3 ! root       54:        accstat_monitor->SetSize(80, 2 + 32 + 3);
1.1       root       55: }
                     56: 
                     57: // デストラクタ
                     58: X68kMainbus::~X68kMainbus()
                     59: {
                     60: }
                     61: 
                     62: // 初期化
                     63: bool
                     64: X68kMainbus::Init()
                     65: {
                     66:        if (inherited::Init() == false) {
                     67:                return false;
                     68:        }
                     69: 
                     70:        for (int i = 0; i < bankram.size(); i++) {
                     71:                bankram[i] = gMainApp.FindObject<BankRAMDevice>(OBJ_BANKRAM(i));
                     72:        }
                     73: 
                     74:        return true;
                     75: }
                     76: 
                     77: // メインバスの初期化
                     78: bool
                     79: X68kMainbus::InitMainbus()
                     80: {
1.1.1.2   root       81:        int extstart;
                     82:        int extsize;
                     83: 
1.1       root       84:        // 拡張メモリはサイズが確定した後のここで配置。
                     85:        extsize = pExtRAM->GetSizeMB();
                     86: 
                     87:        // 上位8ビット全域を一旦全部内蔵空間にしてから
                     88:        std::fill(is_intio.begin(), is_intio.end(), true);
                     89: 
                     90:        if (extsize == 16) {
                     91:                // TS-6BE16 互換 (16MB) なら $01 の 16MB。
                     92:                extstart = 16;
                     93:                is_intio[1] = false;
                     94:        } else {
                     95:                // 060turbo 互換なら $10 から。
                     96:                extstart = 256;
                     97:                for (int i = 0x10, end = i + (extsize / 16); i < end; i++) {
                     98:                        is_intio[i] = false;
                     99:                }
                    100:        }
                    101: 
                    102:        // 親子構造になっている。
                    103:        if (pX68kIO->InitMainbus() == false) {
                    104:                return false;
                    105:        }
                    106: 
1.1.1.2   root      107:        // アクセス統計のデバイスがある領域。
                    108:        accstat_avail[0] = 0x80;
                    109:        for (int i = extstart / 16; i < (extstart + extsize) / 16; i++) {
                    110:                accstat_avail[i / 8] |= 0x80U >> (i % 8);
                    111:        }
                    112: 
1.1       root      113:        return true;
                    114: }
                    115: 
                    116: // リセット
                    117: void
                    118: X68kMainbus::ResetHard(bool poweron)
                    119: {
                    120:        inherited::ResetHard(poweron);
                    121: 
                    122:        std::fill(accstat_read.begin(), accstat_read.end(), 0);
                    123:        std::fill(accstat_write.begin(), accstat_write.end(), 0);
                    124: }
                    125: 
                    126: // リセットについて。
                    127: //
                    128: //           PWRRESET
                    129: // 電源オン ----------+--> VIPS
                    130: // (7505)             +--> VideoCtlr
                    131: //                    +--> OSCIAN2
                    132: //                    |
                    133: //                    |   +------+
                    134: //                    +-->|      |
                    135: // 本体      SWRESET      | YUKI |
                    136: // リセット ------------->|      |
                    137: // スイッチ               +------+
                    138: //                         | IPLRESET
                    139: //                         |
                    140: //                         +--> FPU
                    141: //                         |
                    142: //                         ▽
                    143: //                   RESET |
                    144: //                         |<-> MPU (68030)
                    145: //                         +--> PPI (8255)
                    146: //                         +--> SPC (MB89352)
                    147: //                         +--> ADPCM (MSM6258)
                    148: //                         +--> FDC (uPD72065B)
                    149: //                         +--> MFP (MC68901)
                    150: //                         |
                    151: //                         |   +-------+
                    152: //                         +-->| PEDEC |
                    153: //                         |   +-------+
                    154: //                         |     |
                    155: //                         |     +-- OPMIC -----> OPM(YM2151)
                    156: //                         |     +-- SCCRD/WR --> SCC(Z8530)
                    157: //                         |
                    158: //                         |      EXRESET
                    159: //                         +---|>-----------> 外部バス
                    160: //                         ▽
                    161: //                SYSRESET |
                    162: //                         |<-> SAKI  ---+
                    163: //                         |             | BEC0,BEC1
                    164: //                         +--> DMAC  <--+
                    165: //                         +--> CYNTHIA
                    166: // リセットされない?
                    167: // o CACHY
                    168: 
                    169: // MPU の RESET 命令によるリセット
                    170: void
                    171: X68kMainbus::ResetByMPU()
                    172: {
                    173:        std::vector<int> ids {
                    174:                OBJ_ADPCM,
                    175:                OBJ_BANKRAM0,
                    176:                OBJ_BANKRAM1,
                    177:                OBJ_DMAC,
                    178:                OBJ_ETHERNET0,
                    179:                OBJ_ETHERNET1,
                    180:                OBJ_FDC,
                    181:                OBJ_MFP,
                    182:                OBJ_OPM,
                    183:                OBJ_PEDEC,
                    184:                OBJ_PLUTO,
                    185:                OBJ_PPI,
                    186:                OBJ_MPSCC,
                    187:                OBJ_SPC,
                    188:                OBJ_WINDRV,
                    189:        };
                    190:        for (auto id : ids) {
                    191:                auto dev = gMainApp.FindObject<IODevice>(id);
                    192:                if (dev) {
                    193:                        dev->ResetHard(false);
                    194:                }
                    195:        }
                    196: }
                    197: 
                    198: inline bool
                    199: X68kMainbus::IsIntio(uint32 addr) const
                    200: {
                    201:        return is_intio[(addr >> 24) & 0xff];
                    202: }
                    203: 
1.1.1.2   root      204: // 内蔵 16MB 分で折り返す
                    205: #define ACCSTAT_INTIO(pa)      \
                    206:        (((pa) >> AccStat::SHIFT) & ((1U << (24 - AccStat::SHIFT)) - 1))
1.1       root      207: 
                    208: busdata
1.1.1.2   root      209: X68kMainbus::Read(busaddr addr)
1.1       root      210: {
1.1.1.2   root      211:        uint32 pa = addr.Addr();
                    212:        if (IsIntio(pa)) {
                    213:                // 内蔵 16MB を 2MB 単位で
                    214:                accstat_read[ACCSTAT_INTIO(pa)] = AccStat::READ;
                    215:                return pX68kIO->Read(addr);
                    216:        } else {
                    217:                // 拡張メモリのアドレスは折り返しは起きない
                    218:                accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
                    219:                return pExtRAM->Read(addr);
                    220:        }
1.1       root      221: }
                    222: 
                    223: busdata
1.1.1.2   root      224: X68kMainbus::Write(busaddr addr, uint32 data)
1.1       root      225: {
1.1.1.2   root      226:        uint32 pa = addr.Addr();
                    227:        if (IsIntio(pa)) {
                    228:                // 内蔵 16MB を 2MB 単位で
                    229:                accstat_write[ACCSTAT_INTIO(pa)] = AccStat::WRITE;
                    230:                return pX68kIO->Write(addr, data);
                    231:        } else {        \
                    232:                // 拡張メモリのアドレスは折り返しは起きない
                    233:                accstat_write[pa >> AccStat::SHIFT] = AccStat::WRITE;
                    234:                return pExtRAM->Write(addr, data);
                    235:        }
1.1       root      236: }
                    237: 
                    238: busdata
1.1.1.2   root      239: X68kMainbus::Peek1(uint32 addr)
1.1       root      240: {
                    241:        if (IsIntio(addr)) {
1.1.1.2   root      242:                return pX68kIO->Peek1(addr);
1.1       root      243:        } else {
1.1.1.2   root      244:                return pExtRAM->Peek1(addr);
1.1       root      245:        }
                    246: }
                    247: 
                    248: bool
1.1.1.2   root      249: X68kMainbus::Poke1(uint32 addr, uint32 data)
1.1       root      250: {
                    251:        if (IsIntio(addr)) {
1.1.1.2   root      252:                return pX68kIO->Poke1(addr, data);
1.1       root      253:        } else {
1.1.1.2   root      254:                return pExtRAM->Poke1(addr, data);
1.1       root      255:        }
                    256: }
                    257: 
                    258: void
                    259: X68kMainbus::MonitorUpdate(Monitor *, TextScreen& screen)
                    260: {
                    261:        screen.Clear();
                    262: 
                    263:        // 012345678901234567890
                    264:        // $0000'0000: 1234567
                    265: 
                    266:        for (int i = 0; i < 8; i++) {
                    267:                screen.Print(12 + i * 8, 0, "+$0%x", i);
                    268:        }
                    269: 
                    270:        auto xioname = FormatDevName(pX68kIO.get()).first;
                    271:        auto extname = FormatDevName(pExtRAM.get()).first;
                    272: 
                    273:        int idx = 0;
                    274:        for (int i = 0; i < is_intio.size() / 8; i++) {
                    275:                screen.Print(0, i + 1, "$%02x00'0000:", idx);
                    276:                for (int j = 0; j < 8; j++) {
                    277:                        screen.Print(12 + j * 8, i + 1, "%s",
                    278:                                (is_intio[idx] ? xioname : extname).c_str());
                    279:                        idx++;
                    280:                }
                    281:        }
                    282: }
                    283: 
                    284: void
1.1.1.2   root      285: X68kMainbus::MonitorUpdateAccStat(Monitor *monitor_, TextScreen& screen)
1.1       root      286: {
1.1.1.2   root      287:        // メインバス空間は親クラス側の処理そのまま。
                    288:        inherited::MonitorUpdateAccStat(monitor_, screen);
1.1       root      289: 
1.1.1.2   root      290:        // バンクメモリ側の情報取得。
1.1       root      291:        for (int n = 0; n < bankram.size(); n++) {
                    292:                if (bankram[n]) {
1.1.1.2   root      293:                        bankram[n]->FetchAccStat(&accbank[n * AccStat::BANKLEN]);
1.1       root      294:                }
                    295:        }
                    296: 
1.1.1.2   root      297:        // バンクメモリ側の描画。
                    298:        for (int n = 0; n < bankram.size(); n++) {
                    299:                int y = 35 + n;
                    300:                screen.Print(0, y, "BankMem #%u:", n);
1.1       root      301:                if (bankram[n]) {
1.1.1.2   root      302:                        for (int i = 0; i < AccStat::BANKLEN; i++) {
                    303:                                uint op = accbank[n * AccStat::BANKLEN + i] & 3;
1.1       root      304:                                uint8 ch = ".RWA"[op];
1.1.1.2   root      305:                                screen.Putc(12 + i, y, ch);
1.1       root      306:                        }
                    307:                }
                    308:        }
                    309: }
                    310: 
                    311: // ブートページを切り替える。
                    312: void
                    313: X68kMainbus::SwitchBootPage(bool isrom)
                    314: {
                    315:        // X68030 ではすべて X68kIO が担当している
                    316:        pX68kIO->SwitchBootPage(isrom);
                    317: }

unix.superglobalmegacorp.com

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