|
|
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.