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

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"
1.1.1.3 ! root       14: #include "ioctlr.h"
1.1       root       15: #include "mfp.h"
1.1.1.2   root       16: #include "pio.h"
1.1.1.3 ! root       17: #include "pluto.h"
1.1       root       18: #include "printer.h"
                     19: #include "ram.h"
1.1.1.2   root       20: #include "romimg_x68k.h"
1.1       root       21: #include "rp5c15.h"
                     22: #include "scc.h"
                     23: #include "spc.h"
                     24: #include "sprite.h"
                     25: #include "sram.h"
                     26: #include "sysport.h"
                     27: #include "tvram.h"
1.1.1.3 ! root       28: #include "videoctlr.h"
1.1       root       29: #include "vm.h"
1.1.1.3 ! root       30: #include <typeinfo>
1.1       root       31: 
                     32: //
                     33: // X68030 のメイン空間 ($000000-$FFFFFF) 担当。
                     34: //
                     35: 
                     36: // デバイス
1.1.1.3 ! root       37: static std::unique_ptr<AreaSetDevice> areaset;
        !            38: static std::unique_ptr<CGROMDevice> cgrom;
        !            39: static std::unique_ptr<FDCDevice> fdc;
        !            40: static std::unique_ptr<IPLROM1Device> iplrom1;
        !            41: static std::unique_ptr<IPLROM2Device> iplrom2;
        !            42: static std::unique_ptr<PlutoDevice> pluto;
        !            43: static std::unique_ptr<PPIDevice> ppi;
        !            44: static std::unique_ptr<PrinterDevice> printer;
        !            45: static std::unique_ptr<SpriteDevice> sprite;
        !            46: static std::unique_ptr<SysportDevice> sysport;
1.1       root       47: 
                     48: // 1つの 8KB ブロックを複数のデバイスで共有する場合
                     49: class MuxDevice
                     50:        : public IODevice
                     51: {
1.1.1.3 ! root       52:        using inherited = IODevice;
1.1       root       53:  public:
                     54:        MuxDevice();
                     55:        virtual ~MuxDevice();
                     56: 
                     57:        virtual uint64 Read8(uint32 addr);
                     58:        virtual uint64 Read16(uint32 addr);
                     59:        virtual uint64 Write8(uint32 addr, uint32 data);
                     60:        virtual uint64 Write16(uint32 addr, uint32 data);
                     61:        virtual uint64 Peek8(uint32 addr);
                     62: 
1.1.1.2   root       63:        IODevice *SearchDevice(uint32 addr) const;
1.1       root       64: 
                     65:        void AddDevice(IODevice *dev);
                     66: 
                     67:        std::vector<IODevice*> devlist;
                     68: };
                     69: 
                     70: MuxDevice::MuxDevice()
                     71: {
                     72:        logname = "none";
                     73: }
                     74: 
                     75: MuxDevice::~MuxDevice()
                     76: {
                     77: }
                     78: 
1.1.1.3 ! root       79: // デバイスを追加する。
        !            80: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root       81: void
                     82: MuxDevice::AddDevice(IODevice *dev)
                     83: {
                     84:        if (dev->devlen == 0) {
1.1.1.3 ! root       85:                printf("MuxDevice::AddDevice: '%s' devlen not set!\n",
        !            86:                        dev->devname.c_str());
1.1       root       87:                exit(1);
                     88:        }
                     89:        devlist.push_back(dev);
                     90: }
                     91: 
                     92: IODevice *
1.1.1.2   root       93: MuxDevice::SearchDevice(uint32 addr) const
1.1       root       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++) {
1.1.1.2   root      165:                table[i] = gRAM.get();
1.1       root      166:        }
                    167: 
                    168: #define ADD_DEVICE(varname, clsname)   do {    \
1.1.1.2   root      169:        varname.reset(new clsname);     \
                    170:        AddDevice(varname.get());       \
1.1       root      171: } while (0)
                    172: 
                    173:        // デバイスクラス作成 (順序に注意)
                    174:        ADD_DEVICE(areaset, AreaSetDevice());
                    175:        ADD_DEVICE(cgrom, CGROMDevice());
1.1.1.3 ! root      176:        ADD_DEVICE(gCRTC, BusIO_W<CRTCDevice>());
        !           177:        ADD_DEVICE(gDMAC, BusIO_B<DMACDevice>());
        !           178:        ADD_DEVICE(fdc, BusIO_EB<FDCDevice>());
1.1       root      179:        ADD_DEVICE(gGVRAM, GVRAMDevice());
1.1.1.3 ! root      180:        ADD_DEVICE(gIOCtlr, BusIO_EB<IOCtlrDevice>());
1.1       root      181:        ADD_DEVICE(iplrom1, IPLROM1Device());
                    182:        ADD_DEVICE(iplrom2, IPLROM2Device());
1.1.1.3 ! root      183:        ADD_DEVICE(gMFP, BusIO_EB<MFPDevice>());
1.1       root      184:        ADD_DEVICE(pluto, PlutoDevice());
1.1.1.2   root      185:        ADD_DEVICE(ppi, BusIO_EB<PPIDevice>());
1.1       root      186:        ADD_DEVICE(printer, PrinterDevice());
1.1.1.3 ! root      187:        ADD_DEVICE(gRTC, BusIO_EB<RP5C15Device>());
        !           188:        ADD_DEVICE(gSCC, BusIO_EB<SCCDevice>());
1.1.1.2   root      189:        ADD_DEVICE(gSPC, BusIO_X68kSPC<SPCDevice>());
1.1       root      190:        ADD_DEVICE(sprite, SpriteDevice());
                    191:        ADD_DEVICE(gSRAM, SRAMDevice());
1.1.1.3 ! root      192:        ADD_DEVICE(sysport, BusIO_FB<SysportDevice>());
1.1       root      193:        ADD_DEVICE(gTVRAM, TVRAMDevice());
1.1.1.3 ! root      194:        ADD_DEVICE(gVideoCtlr, BusIO_W<VideoCtlrDevice>());
1.1       root      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])) {
1.1.1.3 ! root      205:                                printf("%s\n", table[i]->devname.c_str());
1.1       root      206:                        }
                    207:                }
                    208:        }
                    209: }
                    210: 
                    211: // デストラクタ
                    212: XIOSpaceDevice::~XIOSpaceDevice()
                    213: {
                    214: }
                    215: 
                    216: // デバイステーブルに dev を追加する。
1.1.1.3 ! root      217: // ここに追加するデバイスは dev->devlen を指定すること。
1.1       root      218: void
                    219: XIOSpaceDevice::AddDevice(IODevice *dev)
                    220: {
                    221:        if (dev->devaddr == 0) {
1.1.1.3 ! root      222:                printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n",
        !           223:                        dev->devname.c_str());
1.1       root      224:                exit(1);
                    225:        }
                    226:        if (dev->devlen == 0) {
1.1.1.3 ! root      227:                printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n",
        !           228:                        dev->devname.c_str());
1.1       root      229:                exit(1);
                    230:        }
                    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 if (typeid(*table[i]) == typeid(MuxDevice)) {
                    237:                        (static_cast<MuxDevice*>(table[i]))->AddDevice(dev);
                    238:                } else {
                    239:                        MuxDevice *muxdev = new MuxDevice();
                    240:                        muxdev->AddDevice(table[i]);
                    241:                        muxdev->AddDevice(dev);
                    242:                        table[i] = muxdev;
                    243:                }
                    244:        }
                    245: }
                    246: 
                    247: uint64
                    248: XIOSpaceDevice::Read8(uint32 addr)
                    249: {
                    250:        addr &= 0x00ffffff;
                    251:        IODevice *d = SearchDevice(addr);
                    252:        // BusErrDevice 導入すればこの if は不要
                    253:        if (d == nullptr) {
                    254:                return (uint64)-1;
                    255:        }
                    256:        return d->Read8(addr);
                    257: }
                    258: 
                    259: uint64
                    260: XIOSpaceDevice::Read16(uint32 addr)
                    261: {
                    262:        addr &= 0x00ffffff;
                    263:        IODevice *d = SearchDevice(addr);
                    264:        // BusErrDevice 導入すればこの if は不要
                    265:        if (d == nullptr) {
                    266:                return (uint64)-1;
                    267:        }
                    268:        return d->Read16(addr);
                    269: }
                    270: 
                    271: uint64
                    272: XIOSpaceDevice::Read32(uint32 addr)
                    273: {
                    274:        addr &= 0x00ffffff;
                    275:        IODevice *d = SearchDevice(addr);
                    276:        // BusErrDevice 導入すればこの if は不要
                    277:        if (d == nullptr) {
                    278:                return (uint64)-1;
                    279:        }
                    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:        // BusErrDevice 導入すればこの if は不要
                    289:        if (d == nullptr) {
                    290:                return (uint64)-1;
                    291:        }
                    292:        return d->Write8(addr, data);
                    293: }
                    294: 
                    295: uint64
                    296: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
                    297: {
                    298:        addr &= 0x00ffffff;
                    299:        IODevice *d = SearchDevice(addr);
                    300:        // BusErrDevice 導入すればこの if は不要
                    301:        if (d == nullptr) {
                    302:                return (uint64)-1;
                    303:        }
                    304:        return d->Write16(addr, data);
                    305: }
                    306: 
                    307: uint64
                    308: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
                    309: {
                    310:        addr &= 0x00ffffff;
                    311:        IODevice *d = SearchDevice(addr);
                    312:        // BusErrDevice 導入すればこの if は不要
                    313:        if (d == nullptr) {
                    314:                return (uint64)-1;
                    315:        }
                    316:        return d->Write32(addr, data);
                    317: }
                    318: 
                    319: uint64
                    320: XIOSpaceDevice::Peek8(uint32 addr)
                    321: {
                    322:        addr &= 0x00ffffff;
                    323:        IODevice *d = SearchDevice(addr);
                    324:        // BusErrDevice 導入すればこの if は不要
                    325:        if (d == nullptr) {
                    326:                return (uint64)-1;
                    327:        }
                    328:        return d->Peek8(addr);
                    329: }

unix.superglobalmegacorp.com

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