|
|
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.10 root 7: //
8: // X68030 のメイン空間 ($000000-$FFFFFF) 担当
9: //
10:
1.1.1.3 root 11: #include "xiospace.h"
1.1.1.11! root 12: #include "adpcm.h"
1.1 root 13: #include "areaset.h"
1.1.1.2 root 14: #include "busio.h"
1.1.1.11! root 15: #include "config.h"
1.1 root 16: #include "crtc.h"
17: #include "dmac.h"
18: #include "fdc.h"
19: #include "gvram.h"
20: #include "mfp.h"
1.1.1.5 root 21: #include "opm.h"
22: #include "pedec.h"
1.1.1.2 root 23: #include "pio.h"
1.1.1.3 root 24: #include "pluto.h"
1.1 root 25: #include "printer.h"
26: #include "ram.h"
1.1.1.11! root 27: #include "romemu_x68k.h"
1.1.1.2 root 28: #include "romimg_x68k.h"
1.1 root 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"
1.1.1.3 root 36: #include "videoctlr.h"
1.1.1.11! root 37: #include "vm.h"
1.1 root 38:
39: //
40: // 1つの 8KB ブロックを複数のデバイスで共有する場合
1.1.1.10 root 41: //
1.1.1.8 root 42: class MuxDevice : public IODevice
1.1 root 43: {
1.1.1.3 root 44: using inherited = IODevice;
1.1 root 45: public:
46: MuxDevice();
1.1.1.5 root 47: virtual ~MuxDevice() override;
1.1 root 48:
1.1.1.5 root 49: uint64 Read8(uint32 addr) override;
50: uint64 Read16(uint32 addr) override;
51: uint64 Write8(uint32 addr, uint32 data) override;
52: uint64 Write16(uint32 addr, uint32 data) override;
53: uint64 Peek8(uint32 addr) override;
1.1 root 54:
1.1.1.2 root 55: IODevice *SearchDevice(uint32 addr) const;
1.1 root 56:
57: void AddDevice(IODevice *dev);
58:
59: std::vector<IODevice*> devlist;
60: };
61:
1.1.1.10 root 62: // コンストラクタ
1.1 root 63: MuxDevice::MuxDevice()
1.1.1.8 root 64: : inherited("MuxDevice")
1.1 root 65: {
66: }
67:
1.1.1.10 root 68: // デストラクタ
1.1 root 69: MuxDevice::~MuxDevice()
70: {
71: }
72:
1.1.1.3 root 73: // デバイスを追加する。
74: // ここに追加するデバイスは dev->devlen を指定すること。
1.1 root 75: void
76: MuxDevice::AddDevice(IODevice *dev)
77: {
1.1.1.10 root 78: assertmsg(dev->devlen != 0, "MuxDevice::AddDevice '%s'",
79: dev->GetName().c_str());
80:
1.1 root 81: devlist.push_back(dev);
82: }
83:
84: IODevice *
1.1.1.2 root 85: MuxDevice::SearchDevice(uint32 addr) const
1.1 root 86: {
87: for (const auto& d : devlist) {
88: if (d->devaddr <= addr && addr < d->devaddr + d->devlen) {
89: return d;
90: }
91: }
92: return nullptr;
93: }
94:
95: uint64
96: MuxDevice::Read8(uint32 addr)
97: {
98: IODevice *d = SearchDevice(addr);
99: if (d == nullptr) {
100: return (uint64)-1;
101: }
102: return d->Read8(addr);
103: }
104:
105: uint64
106: MuxDevice::Read16(uint32 addr)
107: {
108: IODevice *d = SearchDevice(addr);
109: if (d == nullptr) {
110: return (uint64)-1;
111: }
112: return d->Read16(addr);
113: }
114:
115: uint64
116: MuxDevice::Write8(uint32 addr, uint32 data)
117: {
118: IODevice *d = SearchDevice(addr);
119: if (d == nullptr) {
120: return (uint64)-1;
121: }
122: return d->Write8(addr, data);
123: }
124:
125: uint64
126: MuxDevice::Write16(uint32 addr, uint32 data)
127: {
128: IODevice *d = SearchDevice(addr);
129: if (d == nullptr) {
130: return (uint64)-1;
131: }
132: return d->Write16(addr, data);
133: }
134:
135: uint64
136: MuxDevice::Peek8(uint32 addr)
137: {
138: IODevice *d = SearchDevice(addr);
139: if (d == nullptr) {
140: return (uint64)-1;
141: }
142: return d->Peek8(addr);
143: }
144:
145:
1.1.1.10 root 146: //
147: // X68030 のメイン空間担当
148: //
149:
150: // グローバル参照用
151: XIOSpaceDevice *gXIOSpace;
1.1.1.6 root 152:
1.1 root 153: // コンストラクタ
154: XIOSpaceDevice::XIOSpaceDevice()
1.1.1.8 root 155: : inherited("IOSpace")
1.1 root 156: {
1.1.1.10 root 157: #define ADD_DEVICE(NAME, NEW_CTOR) do { \
158: NEWDV(NAME, NEW_CTOR); \
159: AddDevice(dynamic_cast<IODevice *>(__CONCAT(p,NAME).get())); \
1.1 root 160: } while (0)
161:
162: // デバイスクラス作成 (順序に注意)
1.1.1.11! root 163: ADD_DEVICE(ADPCM, new BusIO_EB<ADPCMDevice>());
1.1.1.10 root 164: ADD_DEVICE(AreaSet, new AreaSetDevice());
165: ADD_DEVICE(CGROM, new CGROMDevice());
166: ADD_DEVICE(CRTC, new BusIO_W<CRTCDevice>());
1.1.1.11! root 167: ADD_DEVICE(DMAC, new DMACDevice());
1.1.1.10 root 168: ADD_DEVICE(FDC, new BusIO_EB<FDCDevice>());
169: ADD_DEVICE(GVRAM, new GVRAMDevice());
170: ADD_DEVICE(PEDEC, new BusIO_EB<PEDECDevice>());
171: ADD_DEVICE(IPLROM1, new IPLROM1Device());
1.1.1.11! root 172: if (gConfig->Find("iplrom2-image").AsString().empty()) {
! 173: ADD_DEVICE(IPLROM2, new ROM30EmuDevice());
! 174: } else {
! 175: ADD_DEVICE(IPLROM2, new IPLROM2Device());
! 176: }
1.1.1.10 root 177: ADD_DEVICE(MFP, new BusIO_EB<MFPDevice>());
178: ADD_DEVICE(PlaneVRAM, new TVRAMDevice());
179: ADD_DEVICE(Pluto, new PlutoDevice());
180: ADD_DEVICE(PPI, new BusIO_EB<PPIDevice>());
181: ADD_DEVICE(Printer, new PrinterDevice());
182: ADD_DEVICE(RTC, new BusIO_EB<RP5C15Device>());
183: ADD_DEVICE(SCC, new BusIO_EB<SCCDevice>());
184: ADD_DEVICE(SRAM, new SRAMDevice()); // Required by SPC
185: ADD_DEVICE(SPC, new BusIO_X68kSPC<SPCDevice>());
186: ADD_DEVICE(Sprite, new SpriteDevice());
187: ADD_DEVICE(Sysport, new BusIO_FB<SysportDevice>());
188: ADD_DEVICE(VideoCtlr, new BusIO_W<VideoCtlrDevice>());
189: ADD_DEVICE(OPM, new BusIO_EB<OPMDevice>());
1.1.1.4 root 190: }
191:
192: // デストラクタ
193: XIOSpaceDevice::~XIOSpaceDevice()
194: {
1.1.1.10 root 195: gXIOSpace = NULL;
1.1.1.4 root 196: }
197:
198: bool
199: XIOSpaceDevice::Init()
200: {
201: // RAM のみ RamDevice::Init() で ram_size が決定してから行う。
1.1.1.6 root 202: int ram_size = gRAM->GetSize();
1.1.1.4 root 203: for (int i = 0; i < ram_size / 8192; i++) {
1.1.1.10 root 204: table[i] = gRAM;
1.1.1.4 root 205: }
206:
207: // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを
1.1.1.7 root 208: // BusErr に差し替える。
1.1.1.4 root 209: for (auto&& d : table) {
210: if (d == nullptr) {
1.1.1.10 root 211: d = gBusErr;
1.1.1.4 root 212: }
213: }
1.1 root 214:
215: // デバッグ表示
216: if (0) {
1.1.1.9 root 217: for (int i = 1536; i < table.size(); i++) {
218: printf("[%3d] $%06x ", i, i * 8192);
1.1.1.4 root 219: assert(table[i]);
220: if (dynamic_cast<MuxDevice*>(table[i])) {
1.1 root 221: printf("MuxDevice\n");
1.1.1.4 root 222: } else {
1.1.1.8 root 223: printf("%s\n", table[i]->GetName().c_str());
1.1 root 224: }
225: }
226: }
227:
1.1.1.4 root 228: return true;
1.1 root 229: }
230:
231: // デバイステーブルに dev を追加する。
1.1.1.3 root 232: // ここに追加するデバイスは dev->devlen を指定すること。
1.1 root 233: void
234: XIOSpaceDevice::AddDevice(IODevice *dev)
235: {
1.1.1.10 root 236: assertmsg(dev->devaddr != 0, "XIOSpaceDevice:AddDevice '%s'",
237: dev->GetName().c_str());
238: assertmsg(dev->devlen != 0, "XIOSpaceDevice:AddDevice '%s'",
239: dev->GetName().c_str());
1.1 root 240:
241: int idx = dev->devaddr / 8192;
242: for (int i = idx; i < idx + (dev->devlen + 8191) / 8192; i++) {
243: if (table[i] == nullptr) {
244: table[i] = dev;
245: } else {
1.1.1.4 root 246: MuxDevice *mux = dynamic_cast<MuxDevice*>(table[i]);
247: if (mux) {
248: mux->AddDevice(dev);
249: } else {
250: MuxDevice *muxdev = new MuxDevice();
251: muxdev->AddDevice(table[i]);
252: muxdev->AddDevice(dev);
253: table[i] = muxdev;
254: }
1.1 root 255: }
256: }
257: }
258:
259: uint64
260: XIOSpaceDevice::Read8(uint32 addr)
261: {
262: addr &= 0x00ffffff;
263: IODevice *d = SearchDevice(addr);
264: return d->Read8(addr);
265: }
266:
267: uint64
268: XIOSpaceDevice::Read16(uint32 addr)
269: {
270: addr &= 0x00ffffff;
271: IODevice *d = SearchDevice(addr);
272: return d->Read16(addr);
273: }
274:
275: uint64
276: XIOSpaceDevice::Read32(uint32 addr)
277: {
278: addr &= 0x00ffffff;
279: IODevice *d = SearchDevice(addr);
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: return d->Write8(addr, data);
289: }
290:
291: uint64
292: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
293: {
294: addr &= 0x00ffffff;
295: IODevice *d = SearchDevice(addr);
296: return d->Write16(addr, data);
297: }
298:
299: uint64
300: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
301: {
302: addr &= 0x00ffffff;
303: IODevice *d = SearchDevice(addr);
304: return d->Write32(addr, data);
305: }
306:
307: uint64
308: XIOSpaceDevice::Peek8(uint32 addr)
309: {
310: addr &= 0x00ffffff;
311: IODevice *d = SearchDevice(addr);
312: return d->Peek8(addr);
313: }
1.1.1.7 root 314:
315: // ブートページを切り替える。
316: // (VM_X68030::SwitchBootPage() の下請け)
317: void
318: XIOSpaceDevice::SwitchBootPage(bool isrom)
319: {
320: IODevice *ram;
321: IODevice *rom;
322:
323: if (isrom) {
324: // 0x000000 からの 64KB ( 8エントリ)、
325: // 0xfe0000 からの 128KB (16エントリ) のどちらも IPLROM0 が担当する。
1.1.1.10 root 326: ram = gIPLROM0;
327: rom = gIPLROM0;
1.1.1.7 root 328: } else {
329: // 0x000000 からの 64KB ( 8エントリ) に RAM を見せる。
330: // 0xfe0000 からの 128KB (16エントリ) に IPLROM1 を見せる。
1.1.1.10 root 331: ram = gRAM;
332: rom = gIPLROM1;
1.1.1.7 root 333: }
334:
335: for (int i = 0; i < 8; i++) {
336: table[i] = ram;
337: }
338: for (int i = 0; i < 16; i++) {
339: table[table.size() - 16 + i] = rom;
340: }
341: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.