Annotation of nono/vm/mainbus_x68k.cpp, revision 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.