|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // X68030 のメイン空間 ($000000-$FFFFFF) 担当 ! 9: // ! 10: ! 11: #include "x68kio.h" ! 12: #include "adpcm.h" ! 13: #include "areaset.h" ! 14: #include "busio.h" ! 15: #include "config.h" ! 16: #include "crtc.h" ! 17: #include "dmac.h" ! 18: #include "fdc.h" ! 19: #include "gvram.h" ! 20: #include "mainram.h" ! 21: #include "mfp.h" ! 22: #include "opm.h" ! 23: #include "pedec.h" ! 24: #include "pio.h" ! 25: #include "pluto.h" ! 26: #include "printer.h" ! 27: #include "romemu_x68k.h" ! 28: #include "romimg_x68k.h" ! 29: #include "rp5c15.h" ! 30: #include "scc.h" ! 31: #include "spc.h" ! 32: #include "sprite.h" ! 33: #include "sram.h" ! 34: #include "sysport.h" ! 35: #include "tvram.h" ! 36: #include "videoctlr.h" ! 37: #include "vm.h" ! 38: ! 39: // コンストラクタ ! 40: X68kIODevice::X68kIODevice() ! 41: : inherited(OBJ_X68KIO) ! 42: { ! 43: #define ADD_DEVICE(NAME, ADDR, LEN) \ ! 44: AddDevice(__CONCAT(p,NAME).get(), ADDR, LEN) ! 45: ! 46: #define N(NAME, NEW_CTOR, ADDR, LEN) do { \ ! 47: NEWDV(NAME, NEW_CTOR); \ ! 48: ADD_DEVICE(NAME, ADDR, LEN); \ ! 49: } while (0) ! 50: ! 51: // デバイスクラス作成。 ! 52: // 初期化順の制約がない限りアドレス順。 ! 53: // 開始アドレス 長さ ! 54: N(GVRAM, new GVRAMDevice(), 0xc00000,0x200000); ! 55: N(PlaneVRAM, new TVRAMDevice(), 0xe00000, 0x80000); ! 56: N(CRTC, new BusIO_W<CRTCDevice>(), 0xe80000, 0x2000); ! 57: N(VideoCtlr, new VideoCtlrDevice(), 0xe82000, 0x2000); ! 58: N(DMAC, new DMACDevice(), 0xe84000, 0x2000); ! 59: N(AreaSet, new AreaSetDevice(), 0xe86000, 0x2000); ! 60: N(MFP, new BusIO_EB<MFPDevice>(), 0xe88000, 0x2000); ! 61: N(RTC, new BusIO_EB<RP5C15Device>(), 0xe8a000, 0x2000); ! 62: N(Printer, new PrinterDevice(), 0xe8c000, 0x2000); ! 63: N(Sysport,new BusIO_FB<SysportDevice>(), 0xe8e000, 0x2000); ! 64: N(OPM, new BusIO_EB<OPMDevice>(), 0xe90000, 0x2000); ! 65: N(ADPCM, new BusIO_EB<ADPCMDevice>(), 0xe92000, 0x2000); ! 66: N(FDC, new BusIO_EB<FDCDevice>(), 0xe94000, 0x2000); ! 67: N(SPC, new BusIO_X68kSPC<SPCDevice>(), 0xe96000, 0x2000); ! 68: N(SCC, new BusIO_EB<SCCDevice>(), 0xe98000, 0x2000); ! 69: N(PPI, new BusIO_EB<PPIDevice>(), 0xe9a000, 0x2000); ! 70: N(PEDEC, new BusIO_EB<PEDECDevice>(), 0xe9c000, 0x2000); ! 71: N(Pluto, new PlutoDevice(), 0xeac000, 0x2000); ! 72: N(Sprite, new SpriteDevice(), 0xeb0000, 0x10000); ! 73: N(SRAM, new SRAMDevice(), 0xed0000, 0x4000); ! 74: N(CGROM, new CGROMDevice(), 0xf00000, 0xc0000); ! 75: if (gConfig->Find("iplrom2-image").AsString().empty()) { ! 76: NEWDV(IPLROM2, new ROM30EmuDevice()); ! 77: } else { ! 78: NEWDV(IPLROM2, new IPLROM2Device()); ! 79: } ! 80: ADD_DEVICE(IPLROM2, 0xfc0000, 0x20000); ! 81: N(IPLROM1, new IPLROM1Device(), 0xfe0000, 0x20000); ! 82: } ! 83: ! 84: // デストラクタ ! 85: X68kIODevice::~X68kIODevice() ! 86: { ! 87: } ! 88: ! 89: // 初期化 ! 90: bool ! 91: X68kIODevice::Init() ! 92: { ! 93: if (inherited::Init() == false) { ! 94: return false; ! 95: } ! 96: ! 97: auto buserr = GetBusErrDevice(); ! 98: auto mainram = GetMainRAMDevice(); ! 99: ! 100: // RAM のみ RamDevice::Init() で ram_size が決定してから行う。 ! 101: for (int i = 0; i < mainram->GetSize() / 8192; i++) { ! 102: table[i] = mainram; ! 103: } ! 104: ! 105: // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを ! 106: // BusErr に差し替える。 ! 107: for (auto&& d : table) { ! 108: if (d == nullptr) { ! 109: d = buserr; ! 110: } ! 111: } ! 112: ! 113: // デバッグ表示 ! 114: if (0) { ! 115: for (int i = 1536; i < table.size(); i++) { ! 116: printf("[%3d] $%06x ", i, i * 8192); ! 117: assert(table[i]); ! 118: printf("%s\n", table[i]->GetName().c_str()); ! 119: } ! 120: } ! 121: ! 122: return true; ! 123: } ! 124: ! 125: // デバイステーブルに dev を追加する。 ! 126: void ! 127: X68kIODevice::AddDevice(IODevice *dev, uint devaddr, uint devlen) ! 128: { ! 129: int idx = devaddr / 8192; ! 130: for (int i = idx; i < idx + (devlen + 8191) / 8192; i++) { ! 131: // 重複するケースは未対応 ! 132: assertmsg(table[i] == nullptr, "X68kIODevice.AddDevice '%s'", ! 133: table[i]->GetName().c_str()); ! 134: ! 135: table[i] = dev; ! 136: } ! 137: } ! 138: ! 139: // アドレス addr に対応する IODevice* を返す。 ! 140: // addr は事前に 24bit マスクしてあるもの。 ! 141: inline IODevice * ! 142: X68kIODevice::SearchDevice(uint32 addr) const ! 143: { ! 144: uint idx = addr / 8192; ! 145: __assume(idx < 2048); ! 146: return table[idx]; ! 147: } ! 148: ! 149: uint64 ! 150: X68kIODevice::Read8(uint32 addr) ! 151: { ! 152: addr &= 0x00ffffff; ! 153: IODevice *d = SearchDevice(addr); ! 154: return d->Read8(addr); ! 155: } ! 156: ! 157: uint64 ! 158: X68kIODevice::Read16(uint32 addr) ! 159: { ! 160: addr &= 0x00ffffff; ! 161: IODevice *d = SearchDevice(addr); ! 162: return d->Read16(addr); ! 163: } ! 164: ! 165: uint64 ! 166: X68kIODevice::Read32(uint32 addr) ! 167: { ! 168: addr &= 0x00ffffff; ! 169: IODevice *d = SearchDevice(addr); ! 170: return d->Read32(addr); ! 171: } ! 172: ! 173: uint64 ! 174: X68kIODevice::Write8(uint32 addr, uint32 data) ! 175: { ! 176: addr &= 0x00ffffff; ! 177: IODevice *d = SearchDevice(addr); ! 178: return d->Write8(addr, data); ! 179: } ! 180: ! 181: uint64 ! 182: X68kIODevice::Write16(uint32 addr, uint32 data) ! 183: { ! 184: addr &= 0x00ffffff; ! 185: IODevice *d = SearchDevice(addr); ! 186: return d->Write16(addr, data); ! 187: } ! 188: ! 189: uint64 ! 190: X68kIODevice::Write32(uint32 addr, uint32 data) ! 191: { ! 192: addr &= 0x00ffffff; ! 193: IODevice *d = SearchDevice(addr); ! 194: return d->Write32(addr, data); ! 195: } ! 196: ! 197: uint64 ! 198: X68kIODevice::Peek8(uint32 addr) ! 199: { ! 200: addr &= 0x00ffffff; ! 201: IODevice *d = SearchDevice(addr); ! 202: return d->Peek8(addr); ! 203: } ! 204: ! 205: // このアドレスを担当する次段の IODevice を返す (IOContainerDevice 用) ! 206: IODevice * ! 207: X68kIODevice::GetDevice(uint32 addr) const ! 208: { ! 209: return SearchDevice(addr & 0x00ffffff); ! 210: } ! 211: ! 212: // ブートページを切り替える。 ! 213: // (VM_X68030::SwitchBootPage() の下請け) ! 214: void ! 215: X68kIODevice::SwitchBootPage(bool isrom) ! 216: { ! 217: IODevice *ram; ! 218: IODevice *rom; ! 219: ! 220: if (isrom) { ! 221: // 0x000000 からの 64KB ( 8エントリ)、 ! 222: // 0xfe0000 からの 128KB (16エントリ) のどちらも IPLROM0 が担当する。 ! 223: ram = GetIPLROM0Device(); ! 224: rom = GetIPLROM0Device(); ! 225: } else { ! 226: // 0x000000 からの 64KB ( 8エントリ) に RAM を見せる。 ! 227: // 0xfe0000 からの 128KB (16エントリ) に IPLROM1 を見せる。 ! 228: ram = GetMainRAMDevice(); ! 229: rom = GetIPLROM1Device(); ! 230: } ! 231: ! 232: for (int i = 0; i < 8; i++) { ! 233: table[i] = ram; ! 234: } ! 235: for (int i = 0; i < 16; i++) { ! 236: table[table.size() - 16 + i] = rom; ! 237: } ! 238: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.