|
|
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.3 ! root 7: #include "xiospace.h"
1.1 root 8: #include "areaset.h"
1.1.1.2 root 9: #include "busio.h"
1.1 root 10: #include "crtc.h"
11: #include "dmac.h"
12: #include "fdc.h"
13: #include "gvram.h"
1.1.1.3 ! root 14: #include "ioctlr.h"
1.1 root 15: #include "mfp.h"
1.1.1.2 root 16: #include "pio.h"
1.1.1.3 ! root 17: #include "pluto.h"
1.1 root 18: #include "printer.h"
19: #include "ram.h"
1.1.1.2 root 20: #include "romimg_x68k.h"
1.1 root 21: #include "rp5c15.h"
22: #include "scc.h"
23: #include "spc.h"
24: #include "sprite.h"
25: #include "sram.h"
26: #include "sysport.h"
27: #include "tvram.h"
1.1.1.3 ! root 28: #include "videoctlr.h"
1.1 root 29: #include "vm.h"
1.1.1.3 ! root 30: #include <typeinfo>
1.1 root 31:
32: //
33: // X68030 のメイン空間 ($000000-$FFFFFF) 担当。
34: //
35:
36: // デバイス
1.1.1.3 ! root 37: static std::unique_ptr<AreaSetDevice> areaset;
! 38: static std::unique_ptr<CGROMDevice> cgrom;
! 39: static std::unique_ptr<FDCDevice> fdc;
! 40: static std::unique_ptr<IPLROM1Device> iplrom1;
! 41: static std::unique_ptr<IPLROM2Device> iplrom2;
! 42: static std::unique_ptr<PlutoDevice> pluto;
! 43: static std::unique_ptr<PPIDevice> ppi;
! 44: static std::unique_ptr<PrinterDevice> printer;
! 45: static std::unique_ptr<SpriteDevice> sprite;
! 46: static std::unique_ptr<SysportDevice> sysport;
1.1 root 47:
48: // 1つの 8KB ブロックを複数のデバイスで共有する場合
49: class MuxDevice
50: : public IODevice
51: {
1.1.1.3 ! root 52: using inherited = IODevice;
1.1 root 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:
1.1.1.3 ! root 79: // デバイスを追加する。
! 80: // ここに追加するデバイスは dev->devlen を指定すること。
1.1 root 81: void
82: MuxDevice::AddDevice(IODevice *dev)
83: {
84: if (dev->devlen == 0) {
1.1.1.3 ! root 85: printf("MuxDevice::AddDevice: '%s' devlen not set!\n",
! 86: dev->devname.c_str());
1.1 root 87: exit(1);
88: }
89: devlist.push_back(dev);
90: }
91:
92: IODevice *
1.1.1.2 root 93: MuxDevice::SearchDevice(uint32 addr) const
1.1 root 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++) {
1.1.1.2 root 165: table[i] = gRAM.get();
1.1 root 166: }
167:
168: #define ADD_DEVICE(varname, clsname) do { \
1.1.1.2 root 169: varname.reset(new clsname); \
170: AddDevice(varname.get()); \
1.1 root 171: } while (0)
172:
173: // デバイスクラス作成 (順序に注意)
174: ADD_DEVICE(areaset, AreaSetDevice());
175: ADD_DEVICE(cgrom, CGROMDevice());
1.1.1.3 ! root 176: ADD_DEVICE(gCRTC, BusIO_W<CRTCDevice>());
! 177: ADD_DEVICE(gDMAC, BusIO_B<DMACDevice>());
! 178: ADD_DEVICE(fdc, BusIO_EB<FDCDevice>());
1.1 root 179: ADD_DEVICE(gGVRAM, GVRAMDevice());
1.1.1.3 ! root 180: ADD_DEVICE(gIOCtlr, BusIO_EB<IOCtlrDevice>());
1.1 root 181: ADD_DEVICE(iplrom1, IPLROM1Device());
182: ADD_DEVICE(iplrom2, IPLROM2Device());
1.1.1.3 ! root 183: ADD_DEVICE(gMFP, BusIO_EB<MFPDevice>());
1.1 root 184: ADD_DEVICE(pluto, PlutoDevice());
1.1.1.2 root 185: ADD_DEVICE(ppi, BusIO_EB<PPIDevice>());
1.1 root 186: ADD_DEVICE(printer, PrinterDevice());
1.1.1.3 ! root 187: ADD_DEVICE(gRTC, BusIO_EB<RP5C15Device>());
! 188: ADD_DEVICE(gSCC, BusIO_EB<SCCDevice>());
1.1.1.2 root 189: ADD_DEVICE(gSPC, BusIO_X68kSPC<SPCDevice>());
1.1 root 190: ADD_DEVICE(sprite, SpriteDevice());
191: ADD_DEVICE(gSRAM, SRAMDevice());
1.1.1.3 ! root 192: ADD_DEVICE(sysport, BusIO_FB<SysportDevice>());
1.1 root 193: ADD_DEVICE(gTVRAM, TVRAMDevice());
1.1.1.3 ! root 194: ADD_DEVICE(gVideoCtlr, BusIO_W<VideoCtlrDevice>());
1.1 root 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])) {
1.1.1.3 ! root 205: printf("%s\n", table[i]->devname.c_str());
1.1 root 206: }
207: }
208: }
209: }
210:
211: // デストラクタ
212: XIOSpaceDevice::~XIOSpaceDevice()
213: {
214: }
215:
216: // デバイステーブルに dev を追加する。
1.1.1.3 ! root 217: // ここに追加するデバイスは dev->devlen を指定すること。
1.1 root 218: void
219: XIOSpaceDevice::AddDevice(IODevice *dev)
220: {
221: if (dev->devaddr == 0) {
1.1.1.3 ! root 222: printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n",
! 223: dev->devname.c_str());
1.1 root 224: exit(1);
225: }
226: if (dev->devlen == 0) {
1.1.1.3 ! root 227: printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n",
! 228: dev->devname.c_str());
1.1 root 229: exit(1);
230: }
231:
232: int idx = dev->devaddr / 8192;
233: for (int i = idx; i < idx + (dev->devlen + 8191) / 8192; i++) {
234: if (table[i] == nullptr) {
235: table[i] = dev;
236: } else if (typeid(*table[i]) == typeid(MuxDevice)) {
237: (static_cast<MuxDevice*>(table[i]))->AddDevice(dev);
238: } else {
239: MuxDevice *muxdev = new MuxDevice();
240: muxdev->AddDevice(table[i]);
241: muxdev->AddDevice(dev);
242: table[i] = muxdev;
243: }
244: }
245: }
246:
247: uint64
248: XIOSpaceDevice::Read8(uint32 addr)
249: {
250: addr &= 0x00ffffff;
251: IODevice *d = SearchDevice(addr);
252: // BusErrDevice 導入すればこの if は不要
253: if (d == nullptr) {
254: return (uint64)-1;
255: }
256: return d->Read8(addr);
257: }
258:
259: uint64
260: XIOSpaceDevice::Read16(uint32 addr)
261: {
262: addr &= 0x00ffffff;
263: IODevice *d = SearchDevice(addr);
264: // BusErrDevice 導入すればこの if は不要
265: if (d == nullptr) {
266: return (uint64)-1;
267: }
268: return d->Read16(addr);
269: }
270:
271: uint64
272: XIOSpaceDevice::Read32(uint32 addr)
273: {
274: addr &= 0x00ffffff;
275: IODevice *d = SearchDevice(addr);
276: // BusErrDevice 導入すればこの if は不要
277: if (d == nullptr) {
278: return (uint64)-1;
279: }
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: // BusErrDevice 導入すればこの if は不要
289: if (d == nullptr) {
290: return (uint64)-1;
291: }
292: return d->Write8(addr, data);
293: }
294:
295: uint64
296: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
297: {
298: addr &= 0x00ffffff;
299: IODevice *d = SearchDevice(addr);
300: // BusErrDevice 導入すればこの if は不要
301: if (d == nullptr) {
302: return (uint64)-1;
303: }
304: return d->Write16(addr, data);
305: }
306:
307: uint64
308: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
309: {
310: addr &= 0x00ffffff;
311: IODevice *d = SearchDevice(addr);
312: // BusErrDevice 導入すればこの if は不要
313: if (d == nullptr) {
314: return (uint64)-1;
315: }
316: return d->Write32(addr, data);
317: }
318:
319: uint64
320: XIOSpaceDevice::Peek8(uint32 addr)
321: {
322: addr &= 0x00ffffff;
323: IODevice *d = SearchDevice(addr);
324: // BusErrDevice 導入すればこの if は不要
325: if (d == nullptr) {
326: return (uint64)-1;
327: }
328: return d->Peek8(addr);
329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.