Annotation of nono/vm/xiospace.cpp, revision 1.1.1.10

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.10! root        7: //
        !             8: // X68030 のメイン空間 ($000000-$FFFFFF) 担当
        !             9: //
        !            10: 
1.1.1.3   root       11: #include "xiospace.h"
1.1       root       12: #include "areaset.h"
1.1.1.2   root       13: #include "busio.h"
1.1       root       14: #include "crtc.h"
                     15: #include "dmac.h"
                     16: #include "fdc.h"
                     17: #include "gvram.h"
                     18: #include "mfp.h"
1.1.1.5   root       19: #include "opm.h"
                     20: #include "pedec.h"
1.1.1.2   root       21: #include "pio.h"
1.1.1.3   root       22: #include "pluto.h"
1.1       root       23: #include "printer.h"
                     24: #include "ram.h"
1.1.1.2   root       25: #include "romimg_x68k.h"
1.1       root       26: #include "rp5c15.h"
                     27: #include "scc.h"
                     28: #include "spc.h"
                     29: #include "sprite.h"
                     30: #include "sram.h"
                     31: #include "sysport.h"
                     32: #include "tvram.h"
1.1.1.3   root       33: #include "videoctlr.h"
1.1       root       34: 
                     35: //
                     36: // 1つの 8KB ブロックを複数のデバイスで共有する場合
1.1.1.10! root       37: //
1.1.1.8   root       38: class MuxDevice : public IODevice
1.1       root       39: {
1.1.1.3   root       40:        using inherited = IODevice;
1.1       root       41:  public:
                     42:        MuxDevice();
1.1.1.5   root       43:        virtual ~MuxDevice() override;
1.1       root       44: 
1.1.1.5   root       45:        uint64 Read8(uint32 addr) override;
                     46:        uint64 Read16(uint32 addr) override;
                     47:        uint64 Write8(uint32 addr, uint32 data) override;
                     48:        uint64 Write16(uint32 addr, uint32 data) override;
                     49:        uint64 Peek8(uint32 addr) override;
1.1       root       50: 
1.1.1.2   root       51:        IODevice *SearchDevice(uint32 addr) const;
1.1       root       52: 
                     53:        void AddDevice(IODevice *dev);
                     54: 
                     55:        std::vector<IODevice*> devlist;
                     56: };
                     57: 
1.1.1.10! root       58: // コンストラクタ
1.1       root       59: MuxDevice::MuxDevice()
1.1.1.8   root       60:        : inherited("MuxDevice")
1.1       root       61: {
                     62: }
                     63: 
1.1.1.10! root       64: // デストラクタ
1.1       root       65: MuxDevice::~MuxDevice()
                     66: {
                     67: }
                     68: 
1.1.1.3   root       69: // デバイスを追加する。
                     70: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root       71: void
                     72: MuxDevice::AddDevice(IODevice *dev)
                     73: {
1.1.1.10! root       74:        assertmsg(dev->devlen != 0, "MuxDevice::AddDevice '%s'",
        !            75:                dev->GetName().c_str());
        !            76: 
1.1       root       77:        devlist.push_back(dev);
                     78: }
                     79: 
                     80: IODevice *
1.1.1.2   root       81: MuxDevice::SearchDevice(uint32 addr) const
1.1       root       82: {
                     83:        for (const auto& d : devlist) {
                     84:                if (d->devaddr <= addr && addr < d->devaddr + d->devlen) {
                     85:                        return d;
                     86:                }
                     87:        }
                     88:        return nullptr;
                     89: }
                     90: 
                     91: uint64
                     92: MuxDevice::Read8(uint32 addr)
                     93: {
                     94:        IODevice *d = SearchDevice(addr);
                     95:        if (d == nullptr) {
                     96:                return (uint64)-1;
                     97:        }
                     98:        return d->Read8(addr);
                     99: }
                    100: 
                    101: uint64
                    102: MuxDevice::Read16(uint32 addr)
                    103: {
                    104:        IODevice *d = SearchDevice(addr);
                    105:        if (d == nullptr) {
                    106:                return (uint64)-1;
                    107:        }
                    108:        return d->Read16(addr);
                    109: }
                    110: 
                    111: uint64
                    112: MuxDevice::Write8(uint32 addr, uint32 data)
                    113: {
                    114:        IODevice *d = SearchDevice(addr);
                    115:        if (d == nullptr) {
                    116:                return (uint64)-1;
                    117:        }
                    118:        return d->Write8(addr, data);
                    119: }
                    120: 
                    121: uint64
                    122: MuxDevice::Write16(uint32 addr, uint32 data)
                    123: {
                    124:        IODevice *d = SearchDevice(addr);
                    125:        if (d == nullptr) {
                    126:                return (uint64)-1;
                    127:        }
                    128:        return d->Write16(addr, data);
                    129: }
                    130: 
                    131: uint64
                    132: MuxDevice::Peek8(uint32 addr)
                    133: {
                    134:        IODevice *d = SearchDevice(addr);
                    135:        if (d == nullptr) {
                    136:                return (uint64)-1;
                    137:        }
                    138:        return d->Peek8(addr);
                    139: }
                    140: 
                    141: 
1.1.1.10! root      142: //
        !           143: // X68030 のメイン空間担当
        !           144: //
        !           145: 
        !           146: // グローバル参照用
        !           147: XIOSpaceDevice *gXIOSpace;
1.1.1.6   root      148: 
1.1       root      149: // コンストラクタ
                    150: XIOSpaceDevice::XIOSpaceDevice()
1.1.1.8   root      151:        : inherited("IOSpace")
1.1       root      152: {
1.1.1.10! root      153: #define ADD_DEVICE(NAME, NEW_CTOR)     do {    \
        !           154:        NEWDV(NAME, NEW_CTOR);  \
        !           155:        AddDevice(dynamic_cast<IODevice *>(__CONCAT(p,NAME).get()));    \
1.1       root      156: } while (0)
                    157: 
                    158:        // デバイスクラス作成 (順序に注意)
1.1.1.10! root      159:        ADD_DEVICE(AreaSet, new AreaSetDevice());
        !           160:        ADD_DEVICE(CGROM, new CGROMDevice());
        !           161:        ADD_DEVICE(CRTC, new BusIO_W<CRTCDevice>());
        !           162:        ADD_DEVICE(DMAC, new BusIO_B<DMACDevice>());
        !           163:        ADD_DEVICE(FDC, new BusIO_EB<FDCDevice>());
        !           164:        ADD_DEVICE(GVRAM, new GVRAMDevice());
        !           165:        ADD_DEVICE(PEDEC, new BusIO_EB<PEDECDevice>());
        !           166:        ADD_DEVICE(IPLROM1, new IPLROM1Device());
        !           167:        ADD_DEVICE(IPLROM2, new IPLROM2Device());
        !           168:        ADD_DEVICE(MFP, new BusIO_EB<MFPDevice>());
        !           169:        ADD_DEVICE(PlaneVRAM, new TVRAMDevice());
        !           170:        ADD_DEVICE(Pluto, new PlutoDevice());
        !           171:        ADD_DEVICE(PPI, new BusIO_EB<PPIDevice>());
        !           172:        ADD_DEVICE(Printer, new PrinterDevice());
        !           173:        ADD_DEVICE(RTC, new BusIO_EB<RP5C15Device>());
        !           174:        ADD_DEVICE(SCC, new BusIO_EB<SCCDevice>());
        !           175:        ADD_DEVICE(SRAM, new SRAMDevice());                             // Required by SPC
        !           176:        ADD_DEVICE(SPC, new BusIO_X68kSPC<SPCDevice>());
        !           177:        ADD_DEVICE(Sprite, new SpriteDevice());
        !           178:        ADD_DEVICE(Sysport, new BusIO_FB<SysportDevice>());
        !           179:        ADD_DEVICE(VideoCtlr, new BusIO_W<VideoCtlrDevice>());
        !           180:        ADD_DEVICE(OPM, new BusIO_EB<OPMDevice>());
1.1.1.4   root      181: }
                    182: 
                    183: // デストラクタ
                    184: XIOSpaceDevice::~XIOSpaceDevice()
                    185: {
1.1.1.10! root      186:        gXIOSpace = NULL;
1.1.1.4   root      187: }
                    188: 
                    189: bool
                    190: XIOSpaceDevice::Init()
                    191: {
                    192:        // RAM のみ RamDevice::Init() で ram_size が決定してから行う。
1.1.1.6   root      193:        int ram_size = gRAM->GetSize();
1.1.1.4   root      194:        for (int i = 0; i < ram_size / 8192; i++) {
1.1.1.10! root      195:                table[i] = gRAM;
1.1.1.4   root      196:        }
                    197: 
                    198:        // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを
1.1.1.7   root      199:        // BusErr に差し替える。
1.1.1.4   root      200:        for (auto&& d : table) {
                    201:                if (d == nullptr) {
1.1.1.10! root      202:                        d = gBusErr;
1.1.1.4   root      203:                }
                    204:        }
1.1       root      205: 
                    206:        // デバッグ表示
                    207:        if (0) {
1.1.1.9   root      208:                for (int i = 1536; i < table.size(); i++) {
                    209:                        printf("[%3d] $%06x ", i, i * 8192);
1.1.1.4   root      210:                        assert(table[i]);
                    211:                        if (dynamic_cast<MuxDevice*>(table[i])) {
1.1       root      212:                                printf("MuxDevice\n");
1.1.1.4   root      213:                        } else {
1.1.1.8   root      214:                                printf("%s\n", table[i]->GetName().c_str());
1.1       root      215:                        }
                    216:                }
                    217:        }
                    218: 
1.1.1.4   root      219:        return true;
1.1       root      220: }
                    221: 
                    222: // デバイステーブルに dev を追加する。
1.1.1.3   root      223: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root      224: void
                    225: XIOSpaceDevice::AddDevice(IODevice *dev)
                    226: {
1.1.1.10! root      227:        assertmsg(dev->devaddr != 0, "XIOSpaceDevice:AddDevice '%s'",
        !           228:                dev->GetName().c_str());
        !           229:        assertmsg(dev->devlen != 0, "XIOSpaceDevice:AddDevice '%s'",
        !           230:                dev->GetName().c_str());
1.1       root      231: 
                    232:        int idx = dev->devaddr / 8192;
                    233:        for (int i = idx; i < idx + (dev->devlen + 8191) /  8192; i++) {
                    234:                if (table[i] == nullptr) {
                    235:                        table[i] = dev;
                    236:                } else {
1.1.1.4   root      237:                        MuxDevice *mux = dynamic_cast<MuxDevice*>(table[i]);
                    238:                        if (mux) {
                    239:                                mux->AddDevice(dev);
                    240:                        } else {
                    241:                                MuxDevice *muxdev = new MuxDevice();
                    242:                                muxdev->AddDevice(table[i]);
                    243:                                muxdev->AddDevice(dev);
                    244:                                table[i] = muxdev;
                    245:                        }
1.1       root      246:                }
                    247:        }
                    248: }
                    249: 
                    250: uint64
                    251: XIOSpaceDevice::Read8(uint32 addr)
                    252: {
                    253:        addr &= 0x00ffffff;
                    254:        IODevice *d = SearchDevice(addr);
                    255:        return d->Read8(addr);
                    256: }
                    257: 
                    258: uint64
                    259: XIOSpaceDevice::Read16(uint32 addr)
                    260: {
                    261:        addr &= 0x00ffffff;
                    262:        IODevice *d = SearchDevice(addr);
                    263:        return d->Read16(addr);
                    264: }
                    265: 
                    266: uint64
                    267: XIOSpaceDevice::Read32(uint32 addr)
                    268: {
                    269:        addr &= 0x00ffffff;
                    270:        IODevice *d = SearchDevice(addr);
                    271:        return d->Read32(addr);
                    272: }
                    273: 
                    274: uint64
                    275: XIOSpaceDevice::Write8(uint32 addr, uint32 data)
                    276: {
                    277:        addr &= 0x00ffffff;
                    278:        IODevice *d = SearchDevice(addr);
                    279:        return d->Write8(addr, data);
                    280: }
                    281: 
                    282: uint64
                    283: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
                    284: {
                    285:        addr &= 0x00ffffff;
                    286:        IODevice *d = SearchDevice(addr);
                    287:        return d->Write16(addr, data);
                    288: }
                    289: 
                    290: uint64
                    291: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
                    292: {
                    293:        addr &= 0x00ffffff;
                    294:        IODevice *d = SearchDevice(addr);
                    295:        return d->Write32(addr, data);
                    296: }
                    297: 
                    298: uint64
                    299: XIOSpaceDevice::Peek8(uint32 addr)
                    300: {
                    301:        addr &= 0x00ffffff;
                    302:        IODevice *d = SearchDevice(addr);
                    303:        return d->Peek8(addr);
                    304: }
1.1.1.7   root      305: 
                    306: // ブートページを切り替える。
                    307: // (VM_X68030::SwitchBootPage() の下請け)
                    308: void
                    309: XIOSpaceDevice::SwitchBootPage(bool isrom)
                    310: {
                    311:        IODevice *ram;
                    312:        IODevice *rom;
                    313: 
                    314:        if (isrom) {
                    315:                // 0x000000 からの  64KB ( 8エントリ)、
                    316:                // 0xfe0000 からの 128KB (16エントリ) のどちらも IPLROM0 が担当する。
1.1.1.10! root      317:                ram = gIPLROM0;
        !           318:                rom = gIPLROM0;
1.1.1.7   root      319:        } else {
                    320:                // 0x000000 からの  64KB ( 8エントリ) に RAM を見せる。
                    321:                // 0xfe0000 からの 128KB (16エントリ) に IPLROM1 を見せる。
1.1.1.10! root      322:                ram = gRAM;
        !           323:                rom = gIPLROM1;
1.1.1.7   root      324:        }
                    325: 
                    326:        for (int i = 0; i < 8; i++) {
                    327:                table[i] = ram;
                    328:        }
                    329:        for (int i = 0; i < 16; i++) {
                    330:                table[table.size() - 16 + i] = rom;
                    331:        }
                    332: }

unix.superglobalmegacorp.com

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