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

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

unix.superglobalmegacorp.com

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