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

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.3   root        7: #include "xiospace.h"
1.1       root        8: #include "areaset.h"
1.1.1.2   root        9: #include "busio.h"
1.1       root       10: #include "crtc.h"
                     11: #include "dmac.h"
                     12: #include "fdc.h"
                     13: #include "gvram.h"
                     14: #include "mfp.h"
1.1.1.5   root       15: #include "opm.h"
                     16: #include "pedec.h"
1.1.1.2   root       17: #include "pio.h"
1.1.1.3   root       18: #include "pluto.h"
1.1       root       19: #include "printer.h"
                     20: #include "ram.h"
1.1.1.2   root       21: #include "romimg_x68k.h"
1.1       root       22: #include "rp5c15.h"
                     23: #include "scc.h"
                     24: #include "spc.h"
                     25: #include "sprite.h"
                     26: #include "sram.h"
                     27: #include "sysport.h"
                     28: #include "tvram.h"
1.1.1.3   root       29: #include "videoctlr.h"
1.1       root       30: #include "vm.h"
1.1.1.3   root       31: #include <typeinfo>
1.1       root       32: 
                     33: //
                     34: // X68030 のメイン空間 ($000000-$FFFFFF) 担当。
                     35: //
                     36: 
                     37: // 1つの 8KB ブロックを複数のデバイスで共有する場合
                     38: class MuxDevice
                     39:        : public IODevice
                     40: {
1.1.1.3   root       41:        using inherited = IODevice;
1.1       root       42:  public:
                     43:        MuxDevice();
1.1.1.5   root       44:        virtual ~MuxDevice() override;
1.1       root       45: 
1.1.1.5   root       46:        uint64 Read8(uint32 addr) override;
                     47:        uint64 Read16(uint32 addr) override;
                     48:        uint64 Write8(uint32 addr, uint32 data) override;
                     49:        uint64 Write16(uint32 addr, uint32 data) override;
                     50:        uint64 Peek8(uint32 addr) override;
1.1       root       51: 
1.1.1.2   root       52:        IODevice *SearchDevice(uint32 addr) const;
1.1       root       53: 
                     54:        void AddDevice(IODevice *dev);
                     55: 
                     56:        std::vector<IODevice*> devlist;
                     57: };
                     58: 
                     59: MuxDevice::MuxDevice()
                     60: {
                     61:        logname = "none";
                     62: }
                     63: 
                     64: MuxDevice::~MuxDevice()
                     65: {
                     66: }
                     67: 
1.1.1.3   root       68: // デバイスを追加する。
                     69: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root       70: void
                     71: MuxDevice::AddDevice(IODevice *dev)
                     72: {
                     73:        if (dev->devlen == 0) {
1.1.1.3   root       74:                printf("MuxDevice::AddDevice: '%s' devlen not set!\n",
                     75:                        dev->devname.c_str());
1.1       root       76:                exit(1);
                     77:        }
                     78:        devlist.push_back(dev);
                     79: }
                     80: 
                     81: IODevice *
1.1.1.2   root       82: MuxDevice::SearchDevice(uint32 addr) const
1.1       root       83: {
                     84:        for (const auto& d : devlist) {
                     85:                if (d->devaddr <= addr && addr < d->devaddr + d->devlen) {
                     86:                        return d;
                     87:                }
                     88:        }
                     89:        return nullptr;
                     90: }
                     91: 
                     92: uint64
                     93: MuxDevice::Read8(uint32 addr)
                     94: {
                     95:        IODevice *d = SearchDevice(addr);
                     96:        if (d == nullptr) {
                     97:                return (uint64)-1;
                     98:        }
                     99:        return d->Read8(addr);
                    100: }
                    101: 
                    102: uint64
                    103: MuxDevice::Read16(uint32 addr)
                    104: {
                    105:        IODevice *d = SearchDevice(addr);
                    106:        if (d == nullptr) {
                    107:                return (uint64)-1;
                    108:        }
                    109:        return d->Read16(addr);
                    110: }
                    111: 
                    112: uint64
                    113: MuxDevice::Write8(uint32 addr, uint32 data)
                    114: {
                    115:        IODevice *d = SearchDevice(addr);
                    116:        if (d == nullptr) {
                    117:                return (uint64)-1;
                    118:        }
                    119:        return d->Write8(addr, data);
                    120: }
                    121: 
                    122: uint64
                    123: MuxDevice::Write16(uint32 addr, uint32 data)
                    124: {
                    125:        IODevice *d = SearchDevice(addr);
                    126:        if (d == nullptr) {
                    127:                return (uint64)-1;
                    128:        }
                    129:        return d->Write16(addr, data);
                    130: }
                    131: 
                    132: uint64
                    133: MuxDevice::Peek8(uint32 addr)
                    134: {
                    135:        IODevice *d = SearchDevice(addr);
                    136:        if (d == nullptr) {
                    137:                return (uint64)-1;
                    138:        }
                    139:        return d->Peek8(addr);
                    140: }
                    141: 
                    142: 
1.1.1.6 ! root      143: std::unique_ptr<XIOSpaceDevice> gXIOSpace;
        !           144: 
1.1       root      145: // コンストラクタ
                    146: XIOSpaceDevice::XIOSpaceDevice()
                    147: {
                    148:        logname = "xiospace";
                    149:        devname = "IOSpace";
                    150: 
                    151: #define ADD_DEVICE(varname, clsname)   do {    \
1.1.1.2   root      152:        varname.reset(new clsname);     \
                    153:        AddDevice(varname.get());       \
1.1       root      154: } while (0)
                    155: 
                    156:        // デバイスクラス作成 (順序に注意)
1.1.1.6 ! root      157:        ADD_DEVICE(gAreaSet, AreaSetDevice());
1.1.1.4   root      158:        ADD_DEVICE(gCGROM, CGROMDevice());
1.1.1.3   root      159:        ADD_DEVICE(gCRTC, BusIO_W<CRTCDevice>());
                    160:        ADD_DEVICE(gDMAC, BusIO_B<DMACDevice>());
1.1.1.5   root      161:        ADD_DEVICE(gFDC, BusIO_EB<FDCDevice>());
1.1       root      162:        ADD_DEVICE(gGVRAM, GVRAMDevice());
1.1.1.5   root      163:        ADD_DEVICE(gPEDEC, BusIO_EB<PEDECDevice>());
1.1.1.4   root      164:        ADD_DEVICE(gIPLROM1, IPLROM1Device());
                    165:        ADD_DEVICE(gIPLROM2, IPLROM2Device());
1.1.1.3   root      166:        ADD_DEVICE(gMFP, BusIO_EB<MFPDevice>());
1.1.1.6 ! root      167:        ADD_DEVICE(gPluto, PlutoDevice());
        !           168:        ADD_DEVICE(gPPI, BusIO_EB<PPIDevice>());
        !           169:        ADD_DEVICE(gPrinter, PrinterDevice());
1.1.1.3   root      170:        ADD_DEVICE(gRTC, BusIO_EB<RP5C15Device>());
                    171:        ADD_DEVICE(gSCC, BusIO_EB<SCCDevice>());
1.1.1.4   root      172:        ADD_DEVICE(gSRAM, SRAMDevice());                                // Required by SPC
1.1.1.2   root      173:        ADD_DEVICE(gSPC, BusIO_X68kSPC<SPCDevice>());
1.1.1.6 ! root      174:        ADD_DEVICE(gSprite, SpriteDevice());
        !           175:        ADD_DEVICE(gSysport, BusIO_FB<SysportDevice>());
1.1       root      176:        ADD_DEVICE(gTVRAM, TVRAMDevice());
1.1.1.3   root      177:        ADD_DEVICE(gVideoCtlr, BusIO_W<VideoCtlrDevice>());
1.1.1.5   root      178:        ADD_DEVICE(gOPM, BusIO_EB<OPMDevice>());
1.1.1.4   root      179: }
                    180: 
                    181: // デストラクタ
                    182: XIOSpaceDevice::~XIOSpaceDevice()
                    183: {
                    184: }
                    185: 
                    186: bool
                    187: XIOSpaceDevice::Init()
                    188: {
                    189:        // RAM のみ RamDevice::Init() で ram_size が決定してから行う。
1.1.1.6 ! root      190:        int ram_size = gRAM->GetSize();
1.1.1.4   root      191:        for (int i = 0; i < ram_size / 8192; i++) {
                    192:                table[i] = gRAM.get();
                    193:        }
                    194: 
                    195:        // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを
                    196:        // buserr に差し替える。
                    197:        IODevice *buserr = gVM->GetBusErrDevice();
                    198:        for (auto&& d : table) {
                    199:                if (d == nullptr) {
                    200:                        d = buserr;
                    201:                }
                    202:        }
1.1       root      203: 
                    204:        // デバッグ表示
                    205:        if (0) {
                    206:                for (int i = 0; i < 512; i++) {
                    207:                        printf("[%3d] $%06x ", i, 0xc00000 + i * 8192);
1.1.1.4   root      208:                        assert(table[i]);
                    209:                        if (dynamic_cast<MuxDevice*>(table[i])) {
1.1       root      210:                                printf("MuxDevice\n");
1.1.1.4   root      211:                        } else {
1.1.1.3   root      212:                                printf("%s\n", table[i]->devname.c_str());
1.1       root      213:                        }
                    214:                }
                    215:        }
                    216: 
1.1.1.4   root      217:        return true;
1.1       root      218: }
                    219: 
                    220: // デバイステーブルに dev を追加する。
1.1.1.3   root      221: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root      222: void
                    223: XIOSpaceDevice::AddDevice(IODevice *dev)
                    224: {
                    225:        if (dev->devaddr == 0) {
1.1.1.3   root      226:                printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n",
                    227:                        dev->devname.c_str());
1.1       root      228:                exit(1);
                    229:        }
                    230:        if (dev->devlen == 0) {
1.1.1.3   root      231:                printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n",
                    232:                        dev->devname.c_str());
1.1       root      233:                exit(1);
                    234:        }
                    235: 
                    236:        int idx = dev->devaddr / 8192;
                    237:        for (int i = idx; i < idx + (dev->devlen + 8191) /  8192; i++) {
                    238:                if (table[i] == nullptr) {
                    239:                        table[i] = dev;
                    240:                } else {
1.1.1.4   root      241:                        MuxDevice *mux = dynamic_cast<MuxDevice*>(table[i]);
                    242:                        if (mux) {
                    243:                                mux->AddDevice(dev);
                    244:                        } else {
                    245:                                MuxDevice *muxdev = new MuxDevice();
                    246:                                muxdev->AddDevice(table[i]);
                    247:                                muxdev->AddDevice(dev);
                    248:                                table[i] = muxdev;
                    249:                        }
1.1       root      250:                }
                    251:        }
                    252: }
                    253: 
                    254: uint64
                    255: XIOSpaceDevice::Read8(uint32 addr)
                    256: {
                    257:        addr &= 0x00ffffff;
                    258:        IODevice *d = SearchDevice(addr);
                    259:        return d->Read8(addr);
                    260: }
                    261: 
                    262: uint64
                    263: XIOSpaceDevice::Read16(uint32 addr)
                    264: {
                    265:        addr &= 0x00ffffff;
                    266:        IODevice *d = SearchDevice(addr);
                    267:        return d->Read16(addr);
                    268: }
                    269: 
                    270: uint64
                    271: XIOSpaceDevice::Read32(uint32 addr)
                    272: {
                    273:        addr &= 0x00ffffff;
                    274:        IODevice *d = SearchDevice(addr);
                    275:        return d->Read32(addr);
                    276: }
                    277: 
                    278: uint64
                    279: XIOSpaceDevice::Write8(uint32 addr, uint32 data)
                    280: {
                    281:        addr &= 0x00ffffff;
                    282:        IODevice *d = SearchDevice(addr);
                    283:        return d->Write8(addr, data);
                    284: }
                    285: 
                    286: uint64
                    287: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
                    288: {
                    289:        addr &= 0x00ffffff;
                    290:        IODevice *d = SearchDevice(addr);
                    291:        return d->Write16(addr, data);
                    292: }
                    293: 
                    294: uint64
                    295: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
                    296: {
                    297:        addr &= 0x00ffffff;
                    298:        IODevice *d = SearchDevice(addr);
                    299:        return d->Write32(addr, data);
                    300: }
                    301: 
                    302: uint64
                    303: XIOSpaceDevice::Peek8(uint32 addr)
                    304: {
                    305:        addr &= 0x00ffffff;
                    306:        IODevice *d = SearchDevice(addr);
                    307:        return d->Peek8(addr);
                    308: }

unix.superglobalmegacorp.com

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