Annotation of nono/vm/xiospace.cpp, revision 1.1.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.