|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2018 [email protected]
4: //
5:
6: #include <typeinfo>
7: #include "areaset.h"
1.1.1.2 ! root 8: #include "busio.h"
1.1 root 9: #include "crtc.h"
10: #include "dmac.h"
11: #include "fdc.h"
12: #include "gvram.h"
13: #include "iocon.h"
14: #include "mfp.h"
15: #include "pluto.h"
1.1.1.2 ! root 16: #include "pio.h"
1.1 root 17: #include "printer.h"
18: #include "ram.h"
1.1.1.2 ! root 19: #include "romimg_x68k.h"
1.1 root 20: #include "rp5c15.h"
21: #include "scc.h"
22: #include "spc.h"
23: #include "sprite.h"
24: #include "sram.h"
25: #include "sysport.h"
26: #include "tvram.h"
27: #include "vicon.h"
28: #include "vm.h"
29: #include "xiospace.h"
30:
31: //
32: // X68030 のメイン空間 ($000000-$FFFFFF) 担当。
33: //
34:
35: // デバイス
1.1.1.2 ! root 36: std::unique_ptr<AreaSetDevice> areaset;
! 37: std::unique_ptr<CGROMDevice> cgrom;
! 38: std::unique_ptr<CRTCDevice> crtc;
! 39: std::unique_ptr<FDCDevice> fdc;
! 40: std::unique_ptr<IPLROM1Device> iplrom1;
! 41: std::unique_ptr<IPLROM2Device> iplrom2;
! 42: std::unique_ptr<PlutoDevice> pluto;
! 43: std::unique_ptr<PPIDevice> ppi;
! 44: std::unique_ptr<PrinterDevice> printer;
! 45: std::unique_ptr<SpriteDevice> sprite;
! 46: std::unique_ptr<SysportDevice> sysport;
1.1 root 47:
48: // 1つの 8KB ブロックを複数のデバイスで共有する場合
49: class MuxDevice
50: : public IODevice
51: {
52: typedef IODevice inherited;
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:
79: // デバイスを追加します。
80: // ここに追加するデバイスは dev->devlen の指定が必須です。
81: void
82: MuxDevice::AddDevice(IODevice *dev)
83: {
84: if (dev->devlen == 0) {
85: printf("MuxDevice::AddDevice: '%s' devlen not set!\n", dev->devname);
86: exit(1);
87: }
88: devlist.push_back(dev);
89: }
90:
91: IODevice *
1.1.1.2 ! root 92: MuxDevice::SearchDevice(uint32 addr) const
1.1 root 93: {
94: for (const auto& d : devlist) {
95: if (d->devaddr <= addr && addr < d->devaddr + d->devlen) {
96: return d;
97: }
98: }
99: return nullptr;
100: }
101:
102: uint64
103: MuxDevice::Read8(uint32 addr)
104: {
105: IODevice *d = SearchDevice(addr);
106: if (d == nullptr) {
107: return (uint64)-1;
108: }
109: return d->Read8(addr);
110: }
111:
112: uint64
113: MuxDevice::Read16(uint32 addr)
114: {
115: IODevice *d = SearchDevice(addr);
116: if (d == nullptr) {
117: return (uint64)-1;
118: }
119: return d->Read16(addr);
120: }
121:
122: uint64
123: MuxDevice::Write8(uint32 addr, uint32 data)
124: {
125: IODevice *d = SearchDevice(addr);
126: if (d == nullptr) {
127: return (uint64)-1;
128: }
129: return d->Write8(addr, data);
130: }
131:
132: uint64
133: MuxDevice::Write16(uint32 addr, uint32 data)
134: {
135: IODevice *d = SearchDevice(addr);
136: if (d == nullptr) {
137: return (uint64)-1;
138: }
139: return d->Write16(addr, data);
140: }
141:
142: uint64
143: MuxDevice::Peek8(uint32 addr)
144: {
145: IODevice *d = SearchDevice(addr);
146: if (d == nullptr) {
147: return (uint64)-1;
148: }
149: return d->Peek8(addr);
150: }
151:
152:
153: // コンストラクタ
154: XIOSpaceDevice::XIOSpaceDevice()
155: {
156: logname = "xiospace";
157: devname = "IOSpace";
158:
159: // メモリ
160: // 通常メイン RAM は bus から直接アクセスするが、ウェイトを入れたい
161: // 場合や上位8ビットに値が入っていて 24bit にミラーされたアドレスへの
162: // アクセスになる場合はここを通る。
163: for (int i = 0; i < ram_size / 8192; i++) {
1.1.1.2 ! root 164: table[i] = gRAM.get();
1.1 root 165: }
166:
167: #define ADD_DEVICE(varname, clsname) do { \
1.1.1.2 ! root 168: varname.reset(new clsname); \
! 169: AddDevice(varname.get()); \
1.1 root 170: } while (0)
171:
172: // デバイスクラス作成 (順序に注意)
173: ADD_DEVICE(areaset, AreaSetDevice());
174: ADD_DEVICE(cgrom, CGROMDevice());
175: ADD_DEVICE(crtc, CRTCDevice());
1.1.1.2 ! root 176: ADD_DEVICE(gDMAC, DMACDevice());
1.1 root 177: ADD_DEVICE(fdc, FDCDevice());
178: ADD_DEVICE(gGVRAM, GVRAMDevice());
179: ADD_DEVICE(gIOCon, IOConDevice());
180: ADD_DEVICE(iplrom1, IPLROM1Device());
181: ADD_DEVICE(iplrom2, IPLROM2Device());
182: ADD_DEVICE(gMFP, MFPDevice());
183: ADD_DEVICE(pluto, PlutoDevice());
1.1.1.2 ! root 184: ADD_DEVICE(ppi, BusIO_EB<PPIDevice>());
1.1 root 185: ADD_DEVICE(printer, PrinterDevice());
186: ADD_DEVICE(gRTC, RP5C15Device());
1.1.1.2 ! root 187: ADD_DEVICE(gSCC, SCCDevice());
! 188: ADD_DEVICE(gSPC, BusIO_X68kSPC<SPCDevice>());
1.1 root 189: ADD_DEVICE(sprite, SpriteDevice());
190: ADD_DEVICE(gSRAM, SRAMDevice());
191: ADD_DEVICE(sysport, SysportDevice());
192: ADD_DEVICE(gTVRAM, TVRAMDevice());
193: ADD_DEVICE(gVicon, ViconDevice());
194:
195: // デバッグ表示
196: if (0) {
197: for (int i = 0; i < 512; i++) {
198: printf("[%3d] $%06x ", i, 0xc00000 + i * 8192);
199: if (table[i] == nullptr) {
200: printf("null\n");
201: } else if (dynamic_cast<MuxDevice*>(table[i])) {
202: printf("MuxDevice\n");
203: } else if (dynamic_cast<IODevice*>(table[i])) {
204: printf("%s\n", table[i]->devname);
205: }
206: }
207: }
208: }
209:
210: // デストラクタ
211: XIOSpaceDevice::~XIOSpaceDevice()
212: {
213: }
214:
215: // デバイステーブルに dev を追加する。
216: // ここに追加するデバイスは dev->devlen の指定が必須です。
217: void
218: XIOSpaceDevice::AddDevice(IODevice *dev)
219: {
220: if (dev->devaddr == 0) {
221: printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n", dev->devname);
222: exit(1);
223: }
224: if (dev->devlen == 0) {
225: printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n", dev->devname);
226: exit(1);
227: }
228:
229: int idx = dev->devaddr / 8192;
230: for (int i = idx; i < idx + (dev->devlen + 8191) / 8192; i++) {
231: if (table[i] == nullptr) {
232: table[i] = dev;
233: } else if (typeid(*table[i]) == typeid(MuxDevice)) {
234: (static_cast<MuxDevice*>(table[i]))->AddDevice(dev);
235: } else {
236: MuxDevice *muxdev = new MuxDevice();
237: muxdev->AddDevice(table[i]);
238: muxdev->AddDevice(dev);
239: table[i] = muxdev;
240: }
241: }
242: }
243:
244: uint64
245: XIOSpaceDevice::Read8(uint32 addr)
246: {
247: addr &= 0x00ffffff;
248: IODevice *d = SearchDevice(addr);
249: // BusErrDevice 導入すればこの if は不要
250: if (d == nullptr) {
251: return (uint64)-1;
252: }
253: return d->Read8(addr);
254: }
255:
256: uint64
257: XIOSpaceDevice::Read16(uint32 addr)
258: {
259: addr &= 0x00ffffff;
260: IODevice *d = SearchDevice(addr);
261: // BusErrDevice 導入すればこの if は不要
262: if (d == nullptr) {
263: return (uint64)-1;
264: }
265: return d->Read16(addr);
266: }
267:
268: uint64
269: XIOSpaceDevice::Read32(uint32 addr)
270: {
271: addr &= 0x00ffffff;
272: IODevice *d = SearchDevice(addr);
273: // BusErrDevice 導入すればこの if は不要
274: if (d == nullptr) {
275: return (uint64)-1;
276: }
277: return d->Read32(addr);
278: }
279:
280: uint64
281: XIOSpaceDevice::Write8(uint32 addr, uint32 data)
282: {
283: addr &= 0x00ffffff;
284: IODevice *d = SearchDevice(addr);
285: // BusErrDevice 導入すればこの if は不要
286: if (d == nullptr) {
287: return (uint64)-1;
288: }
289: return d->Write8(addr, data);
290: }
291:
292: uint64
293: XIOSpaceDevice::Write16(uint32 addr, uint32 data)
294: {
295: addr &= 0x00ffffff;
296: IODevice *d = SearchDevice(addr);
297: // BusErrDevice 導入すればこの if は不要
298: if (d == nullptr) {
299: return (uint64)-1;
300: }
301: return d->Write16(addr, data);
302: }
303:
304: uint64
305: XIOSpaceDevice::Write32(uint32 addr, uint32 data)
306: {
307: addr &= 0x00ffffff;
308: IODevice *d = SearchDevice(addr);
309: // BusErrDevice 導入すればこの if は不要
310: if (d == nullptr) {
311: return (uint64)-1;
312: }
313: return d->Write32(addr, data);
314: }
315:
316: uint64
317: XIOSpaceDevice::Peek8(uint32 addr)
318: {
319: addr &= 0x00ffffff;
320: IODevice *d = SearchDevice(addr);
321: // BusErrDevice 導入すればこの if は不要
322: if (d == nullptr) {
323: return (uint64)-1;
324: }
325: return d->Peek8(addr);
326: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.