|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.