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

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

unix.superglobalmegacorp.com

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