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

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.1.1.3   root       38: static std::unique_ptr<AreaSetDevice> areaset;
                     39: static std::unique_ptr<PlutoDevice> pluto;
                     40: static std::unique_ptr<PPIDevice> ppi;
                     41: static std::unique_ptr<PrinterDevice> printer;
                     42: static std::unique_ptr<SpriteDevice> sprite;
                     43: static std::unique_ptr<SysportDevice> sysport;
1.1       root       44: 
                     45: // 1つの 8KB ブロックを複数のデバイスで共有する場合
                     46: class MuxDevice
                     47:        : public IODevice
                     48: {
1.1.1.3   root       49:        using inherited = IODevice;
1.1       root       50:  public:
                     51:        MuxDevice();
1.1.1.5 ! root       52:        virtual ~MuxDevice() override;
1.1       root       53: 
1.1.1.5 ! root       54:        uint64 Read8(uint32 addr) override;
        !            55:        uint64 Read16(uint32 addr) override;
        !            56:        uint64 Write8(uint32 addr, uint32 data) override;
        !            57:        uint64 Write16(uint32 addr, uint32 data) override;
        !            58:        uint64 Peek8(uint32 addr) override;
1.1       root       59: 
1.1.1.2   root       60:        IODevice *SearchDevice(uint32 addr) const;
1.1       root       61: 
                     62:        void AddDevice(IODevice *dev);
                     63: 
                     64:        std::vector<IODevice*> devlist;
                     65: };
                     66: 
                     67: MuxDevice::MuxDevice()
                     68: {
                     69:        logname = "none";
                     70: }
                     71: 
                     72: MuxDevice::~MuxDevice()
                     73: {
                     74: }
                     75: 
1.1.1.3   root       76: // デバイスを追加する。
                     77: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root       78: void
                     79: MuxDevice::AddDevice(IODevice *dev)
                     80: {
                     81:        if (dev->devlen == 0) {
1.1.1.3   root       82:                printf("MuxDevice::AddDevice: '%s' devlen not set!\n",
                     83:                        dev->devname.c_str());
1.1       root       84:                exit(1);
                     85:        }
                     86:        devlist.push_back(dev);
                     87: }
                     88: 
                     89: IODevice *
1.1.1.2   root       90: MuxDevice::SearchDevice(uint32 addr) const
1.1       root       91: {
                     92:        for (const auto& d : devlist) {
                     93:                if (d->devaddr <= addr && addr < d->devaddr + d->devlen) {
                     94:                        return d;
                     95:                }
                     96:        }
                     97:        return nullptr;
                     98: }
                     99: 
                    100: uint64
                    101: MuxDevice::Read8(uint32 addr)
                    102: {
                    103:        IODevice *d = SearchDevice(addr);
                    104:        if (d == nullptr) {
                    105:                return (uint64)-1;
                    106:        }
                    107:        return d->Read8(addr);
                    108: }
                    109: 
                    110: uint64
                    111: MuxDevice::Read16(uint32 addr)
                    112: {
                    113:        IODevice *d = SearchDevice(addr);
                    114:        if (d == nullptr) {
                    115:                return (uint64)-1;
                    116:        }
                    117:        return d->Read16(addr);
                    118: }
                    119: 
                    120: uint64
                    121: MuxDevice::Write8(uint32 addr, uint32 data)
                    122: {
                    123:        IODevice *d = SearchDevice(addr);
                    124:        if (d == nullptr) {
                    125:                return (uint64)-1;
                    126:        }
                    127:        return d->Write8(addr, data);
                    128: }
                    129: 
                    130: uint64
                    131: MuxDevice::Write16(uint32 addr, uint32 data)
                    132: {
                    133:        IODevice *d = SearchDevice(addr);
                    134:        if (d == nullptr) {
                    135:                return (uint64)-1;
                    136:        }
                    137:        return d->Write16(addr, data);
                    138: }
                    139: 
                    140: uint64
                    141: MuxDevice::Peek8(uint32 addr)
                    142: {
                    143:        IODevice *d = SearchDevice(addr);
                    144:        if (d == nullptr) {
                    145:                return (uint64)-1;
                    146:        }
                    147:        return d->Peek8(addr);
                    148: }
                    149: 
                    150: 
                    151: // コンストラクタ
                    152: XIOSpaceDevice::XIOSpaceDevice()
                    153: {
                    154:        logname = "xiospace";
                    155:        devname = "IOSpace";
                    156: 
                    157: #define ADD_DEVICE(varname, clsname)   do {    \
1.1.1.2   root      158:        varname.reset(new clsname);     \
                    159:        AddDevice(varname.get());       \
1.1       root      160: } while (0)
                    161: 
                    162:        // デバイスクラス作成 (順序に注意)
                    163:        ADD_DEVICE(areaset, AreaSetDevice());
1.1.1.4   root      164:        ADD_DEVICE(gCGROM, CGROMDevice());
1.1.1.3   root      165:        ADD_DEVICE(gCRTC, BusIO_W<CRTCDevice>());
                    166:        ADD_DEVICE(gDMAC, BusIO_B<DMACDevice>());
1.1.1.5 ! root      167:        ADD_DEVICE(gFDC, BusIO_EB<FDCDevice>());
1.1       root      168:        ADD_DEVICE(gGVRAM, GVRAMDevice());
1.1.1.5 ! root      169:        ADD_DEVICE(gPEDEC, BusIO_EB<PEDECDevice>());
1.1.1.4   root      170:        ADD_DEVICE(gIPLROM1, IPLROM1Device());
                    171:        ADD_DEVICE(gIPLROM2, IPLROM2Device());
1.1.1.3   root      172:        ADD_DEVICE(gMFP, BusIO_EB<MFPDevice>());
1.1       root      173:        ADD_DEVICE(pluto, PlutoDevice());
1.1.1.2   root      174:        ADD_DEVICE(ppi, BusIO_EB<PPIDevice>());
1.1       root      175:        ADD_DEVICE(printer, PrinterDevice());
1.1.1.3   root      176:        ADD_DEVICE(gRTC, BusIO_EB<RP5C15Device>());
                    177:        ADD_DEVICE(gSCC, BusIO_EB<SCCDevice>());
1.1.1.4   root      178:        ADD_DEVICE(gSRAM, SRAMDevice());                                // Required by SPC
1.1.1.2   root      179:        ADD_DEVICE(gSPC, BusIO_X68kSPC<SPCDevice>());
1.1       root      180:        ADD_DEVICE(sprite, SpriteDevice());
1.1.1.3   root      181:        ADD_DEVICE(sysport, BusIO_FB<SysportDevice>());
1.1       root      182:        ADD_DEVICE(gTVRAM, TVRAMDevice());
1.1.1.3   root      183:        ADD_DEVICE(gVideoCtlr, BusIO_W<VideoCtlrDevice>());
1.1.1.5 ! root      184:        ADD_DEVICE(gOPM, BusIO_EB<OPMDevice>());
1.1.1.4   root      185: }
                    186: 
                    187: // デストラクタ
                    188: XIOSpaceDevice::~XIOSpaceDevice()
                    189: {
                    190: }
                    191: 
                    192: bool
                    193: XIOSpaceDevice::Init()
                    194: {
                    195:        // RAM のみ RamDevice::Init() で ram_size が決定してから行う。
                    196:        for (int i = 0; i < ram_size / 8192; i++) {
                    197:                table[i] = gRAM.get();
                    198:        }
                    199: 
                    200:        // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを
                    201:        // buserr に差し替える。
                    202:        IODevice *buserr = gVM->GetBusErrDevice();
                    203:        for (auto&& d : table) {
                    204:                if (d == nullptr) {
                    205:                        d = buserr;
                    206:                }
                    207:        }
1.1       root      208: 
                    209:        // デバッグ表示
                    210:        if (0) {
                    211:                for (int i = 0; i < 512; i++) {
                    212:                        printf("[%3d] $%06x ", i, 0xc00000 + i * 8192);
1.1.1.4   root      213:                        assert(table[i]);
                    214:                        if (dynamic_cast<MuxDevice*>(table[i])) {
1.1       root      215:                                printf("MuxDevice\n");
1.1.1.4   root      216:                        } else {
1.1.1.3   root      217:                                printf("%s\n", table[i]->devname.c_str());
1.1       root      218:                        }
                    219:                }
                    220:        }
                    221: 
1.1.1.4   root      222:        return true;
1.1       root      223: }
                    224: 
                    225: // デバイステーブルに dev を追加する。
1.1.1.3   root      226: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root      227: void
                    228: XIOSpaceDevice::AddDevice(IODevice *dev)
                    229: {
                    230:        if (dev->devaddr == 0) {
1.1.1.3   root      231:                printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n",
                    232:                        dev->devname.c_str());
1.1       root      233:                exit(1);
                    234:        }
                    235:        if (dev->devlen == 0) {
1.1.1.3   root      236:                printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n",
                    237:                        dev->devname.c_str());
1.1       root      238:                exit(1);
                    239:        }
                    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: }

unix.superglobalmegacorp.com

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