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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2018 [email protected]
        !             4: //
        !             5: 
        !             6: #include <typeinfo>
        !             7: #include "areaset.h"
        !             8: #include "crtc.h"
        !             9: #include "dmac.h"
        !            10: #include "fdc.h"
        !            11: #include "gvram.h"
        !            12: #include "iocon.h"
        !            13: #include "mfp.h"
        !            14: #include "pluto.h"
        !            15: #include "ppi.h"
        !            16: #include "printer.h"
        !            17: #include "ram.h"
        !            18: #include "rp5c15.h"
        !            19: #include "scc.h"
        !            20: #include "spc.h"
        !            21: #include "sprite.h"
        !            22: #include "sram.h"
        !            23: #include "sysport.h"
        !            24: #include "tvram.h"
        !            25: #include "vicon.h"
        !            26: #include "vm.h"
        !            27: #include "x68krom.h"
        !            28: #include "xiospace.h"
        !            29: 
        !            30: //
        !            31: // X68030 のメイン空間 ($000000-$FFFFFF) 担当。
        !            32: //
        !            33: 
        !            34: // デバイス
        !            35: AreaSetDevice *areaset;
        !            36: CGROMDevice *cgrom;
        !            37: CRTCDevice *crtc;
        !            38: DMACDevice *dmac;
        !            39: FDCDevice *fdc;
        !            40: IPLROM1Device *iplrom1;
        !            41: IPLROM2Device *iplrom2;
        !            42: PlutoDevice *pluto;
        !            43: PPIDevice *ppi;
        !            44: PrinterDevice *printer;
        !            45: SCCDevice *scc;
        !            46: SpriteDevice *sprite;
        !            47: SysportDevice *sysport;
        !            48: 
        !            49: // 1つの 8KB ブロックを複数のデバイスで共有する場合
        !            50: class MuxDevice
        !            51:        : public IODevice
        !            52: {
        !            53:        typedef IODevice inherited;
        !            54:  public:
        !            55:        MuxDevice();
        !            56:        virtual ~MuxDevice();
        !            57: 
        !            58:        virtual uint64 Read8(uint32 addr);
        !            59:        virtual uint64 Read16(uint32 addr);
        !            60:        virtual uint64 Write8(uint32 addr, uint32 data);
        !            61:        virtual uint64 Write16(uint32 addr, uint32 data);
        !            62:        virtual uint64 Peek8(uint32 addr);
        !            63: 
        !            64:        IODevice *SearchDevice(uint32 addr);
        !            65: 
        !            66:        void AddDevice(IODevice *dev);
        !            67: 
        !            68:        std::vector<IODevice*> devlist;
        !            69: };
        !            70: 
        !            71: MuxDevice::MuxDevice()
        !            72: {
        !            73:        logname = "none";
        !            74: }
        !            75: 
        !            76: MuxDevice::~MuxDevice()
        !            77: {
        !            78: }
        !            79: 
        !            80: // デバイスを追加します。
        !            81: // ここに追加するデバイスは dev->devlen の指定が必須です。
        !            82: void
        !            83: MuxDevice::AddDevice(IODevice *dev)
        !            84: {
        !            85:        if (dev->devlen == 0) {
        !            86:                printf("MuxDevice::AddDevice: '%s' devlen not set!\n", dev->devname);
        !            87:                exit(1);
        !            88:        }
        !            89:        devlist.push_back(dev);
        !            90: }
        !            91: 
        !            92: IODevice *
        !            93: MuxDevice::SearchDevice(uint32 addr)
        !            94: {
        !            95:        for (const auto& d : devlist) {
        !            96:                if (d->devaddr <= addr && addr < d->devaddr + d->devlen) {
        !            97:                        return d;
        !            98:                }
        !            99:        }
        !           100:        return nullptr;
        !           101: }
        !           102: 
        !           103: uint64
        !           104: MuxDevice::Read8(uint32 addr)
        !           105: {
        !           106:        IODevice *d = SearchDevice(addr);
        !           107:        if (d == nullptr) {
        !           108:                return (uint64)-1;
        !           109:        }
        !           110:        return d->Read8(addr);
        !           111: }
        !           112: 
        !           113: uint64
        !           114: MuxDevice::Read16(uint32 addr)
        !           115: {
        !           116:        IODevice *d = SearchDevice(addr);
        !           117:        if (d == nullptr) {
        !           118:                return (uint64)-1;
        !           119:        }
        !           120:        return d->Read16(addr);
        !           121: }
        !           122: 
        !           123: uint64
        !           124: MuxDevice::Write8(uint32 addr, uint32 data)
        !           125: {
        !           126:        IODevice *d = SearchDevice(addr);
        !           127:        if (d == nullptr) {
        !           128:                return (uint64)-1;
        !           129:        }
        !           130:        return d->Write8(addr, data);
        !           131: }
        !           132: 
        !           133: uint64
        !           134: MuxDevice::Write16(uint32 addr, uint32 data)
        !           135: {
        !           136:        IODevice *d = SearchDevice(addr);
        !           137:        if (d == nullptr) {
        !           138:                return (uint64)-1;
        !           139:        }
        !           140:        return d->Write16(addr, data);
        !           141: }
        !           142: 
        !           143: uint64
        !           144: MuxDevice::Peek8(uint32 addr)
        !           145: {
        !           146:        IODevice *d = SearchDevice(addr);
        !           147:        if (d == nullptr) {
        !           148:                return (uint64)-1;
        !           149:        }
        !           150:        return d->Peek8(addr);
        !           151: }
        !           152: 
        !           153: 
        !           154: // コンストラクタ
        !           155: XIOSpaceDevice::XIOSpaceDevice()
        !           156: {
        !           157:        logname = "xiospace";
        !           158:        devname = "IOSpace";
        !           159: 
        !           160:        // メモリ
        !           161:        // 通常メイン RAM は bus から直接アクセスするが、ウェイトを入れたい
        !           162:        // 場合や上位8ビットに値が入っていて 24bit にミラーされたアドレスへの
        !           163:        // アクセスになる場合はここを通る。
        !           164:        for (int i = 0; i < ram_size / 8192; i++) {
        !           165:                table[i] = gRAM;
        !           166:        }
        !           167: 
        !           168: #define ADD_DEVICE(varname, clsname)   do {    \
        !           169:        varname = new clsname;  \
        !           170:        AddDevice(static_cast<IODevice *>(varname));    \
        !           171: } while (0)
        !           172: 
        !           173:        // デバイスクラス作成 (順序に注意)
        !           174:        ADD_DEVICE(areaset, AreaSetDevice());
        !           175:        ADD_DEVICE(cgrom, CGROMDevice());
        !           176:        ADD_DEVICE(crtc, CRTCDevice());
        !           177:        ADD_DEVICE(dmac, DMACDevice());
        !           178:        ADD_DEVICE(fdc, FDCDevice());
        !           179:        ADD_DEVICE(gGVRAM, GVRAMDevice());
        !           180:        ADD_DEVICE(gIOCon, IOConDevice());
        !           181:        ADD_DEVICE(iplrom1, IPLROM1Device());
        !           182:        ADD_DEVICE(iplrom2, IPLROM2Device());
        !           183:        ADD_DEVICE(gMFP, MFPDevice());
        !           184:        ADD_DEVICE(pluto, PlutoDevice());
        !           185:        ADD_DEVICE(ppi, PPIDevice());
        !           186:        ADD_DEVICE(printer, PrinterDevice());
        !           187:        ADD_DEVICE(gRTC, RP5C15Device());
        !           188:        ADD_DEVICE(scc, SCCDevice());
        !           189:        ADD_DEVICE(gSPC, SPCDevice(0xe96000));
        !           190:        ADD_DEVICE(sprite, SpriteDevice());
        !           191:        ADD_DEVICE(gSRAM, SRAMDevice());
        !           192:        ADD_DEVICE(sysport, SysportDevice());
        !           193:        ADD_DEVICE(gTVRAM, TVRAMDevice());
        !           194:        ADD_DEVICE(gVicon, ViconDevice());
        !           195: 
        !           196:        // デバッグ表示
        !           197:        if (0) {
        !           198:                for (int i = 0; i < 512; i++) {
        !           199:                        printf("[%3d] $%06x ", i, 0xc00000 + i * 8192);
        !           200:                        if (table[i] == nullptr) {
        !           201:                                printf("null\n");
        !           202:                        } else if (dynamic_cast<MuxDevice*>(table[i])) {
        !           203:                                printf("MuxDevice\n");
        !           204:                        } else if (dynamic_cast<IODevice*>(table[i])) {
        !           205:                                printf("%s\n", table[i]->devname);
        !           206:                        }
        !           207:                }
        !           208:        }
        !           209: }
        !           210: 
        !           211: // デストラクタ
        !           212: XIOSpaceDevice::~XIOSpaceDevice()
        !           213: {
        !           214: }
        !           215: 
        !           216: // デバイステーブルに dev を追加する。
        !           217: // ここに追加するデバイスは dev->devlen の指定が必須です。
        !           218: void
        !           219: XIOSpaceDevice::AddDevice(IODevice *dev)
        !           220: {
        !           221:        if (dev->devaddr == 0) {
        !           222:                printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n", dev->devname);
        !           223:                exit(1);
        !           224:        }
        !           225:        if (dev->devlen == 0) {
        !           226:                printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n", dev->devname);
        !           227:                exit(1);
        !           228:        }
        !           229: 
        !           230:        int idx = dev->devaddr / 8192;
        !           231:        for (int i = idx; i < idx + (dev->devlen + 8191) /  8192; i++) {
        !           232:                if (table[i] == nullptr) {
        !           233:                        table[i] = dev;
        !           234:                } else if (typeid(*table[i]) == typeid(MuxDevice)) {
        !           235:                        (static_cast<MuxDevice*>(table[i]))->AddDevice(dev);
        !           236:                } else {
        !           237:                        MuxDevice *muxdev = new MuxDevice();
        !           238:                        muxdev->AddDevice(table[i]);
        !           239:                        muxdev->AddDevice(dev);
        !           240:                        table[i] = muxdev;
        !           241:                }
        !           242:        }
        !           243: }
        !           244: 
        !           245: uint64
        !           246: XIOSpaceDevice::Read8(uint32 addr)
        !           247: {
        !           248:        addr &= 0x00ffffff;
        !           249:        IODevice *d = SearchDevice(addr);
        !           250:        // BusErrDevice 導入すればこの if は不要
        !           251:        if (d == nullptr) {
        !           252:                return (uint64)-1;
        !           253:        }
        !           254:        return d->Read8(addr);
        !           255: }
        !           256: 
        !           257: uint64
        !           258: XIOSpaceDevice::Read16(uint32 addr)
        !           259: {
        !           260:        addr &= 0x00ffffff;
        !           261:        IODevice *d = SearchDevice(addr);
        !           262:        // BusErrDevice 導入すればこの if は不要
        !           263:        if (d == nullptr) {
        !           264:                return (uint64)-1;
        !           265:        }
        !           266:        return d->Read16(addr);
        !           267: }
        !           268: 
        !           269: uint64
        !           270: XIOSpaceDevice::Read32(uint32 addr)
        !           271: {
        !           272:        addr &= 0x00ffffff;
        !           273:        IODevice *d = SearchDevice(addr);
        !           274:        // BusErrDevice 導入すればこの if は不要
        !           275:        if (d == nullptr) {
        !           276:                return (uint64)-1;
        !           277:        }
        !           278:        return d->Read32(addr);
        !           279: }
        !           280: 
        !           281: uint64
        !           282: XIOSpaceDevice::Write8(uint32 addr, uint32 data)
        !           283: {
        !           284:        addr &= 0x00ffffff;
        !           285:        IODevice *d = SearchDevice(addr);
        !           286:        // BusErrDevice 導入すればこの if は不要
        !           287:        if (d == nullptr) {
        !           288:                return (uint64)-1;
        !           289:        }
        !           290:        return d->Write8(addr, data);
        !           291: }
        !           292: 
        !           293: uint64
        !           294: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
        !           295: {
        !           296:        addr &= 0x00ffffff;
        !           297:        IODevice *d = SearchDevice(addr);
        !           298:        // BusErrDevice 導入すればこの if は不要
        !           299:        if (d == nullptr) {
        !           300:                return (uint64)-1;
        !           301:        }
        !           302:        return d->Write16(addr, data);
        !           303: }
        !           304: 
        !           305: uint64
        !           306: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
        !           307: {
        !           308:        addr &= 0x00ffffff;
        !           309:        IODevice *d = SearchDevice(addr);
        !           310:        // BusErrDevice 導入すればこの if は不要
        !           311:        if (d == nullptr) {
        !           312:                return (uint64)-1;
        !           313:        }
        !           314:        return d->Write32(addr, data);
        !           315: }
        !           316: 
        !           317: uint64
        !           318: XIOSpaceDevice::Peek8(uint32 addr)
        !           319: {
        !           320:        addr &= 0x00ffffff;
        !           321:        IODevice *d = SearchDevice(addr);
        !           322:        // BusErrDevice 導入すればこの if は不要
        !           323:        if (d == nullptr) {
        !           324:                return (uint64)-1;
        !           325:        }
        !           326:        return d->Peek8(addr);
        !           327: }

unix.superglobalmegacorp.com

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