|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2017 [email protected]
4: //
5:
6: #include "vm.h"
7: #include "bitmap.h"
8: #include "bt454.h"
9: #include "bus.h"
10: #include "crtc2.h"
11: #include "ethernet.h"
12: #include "human68k.h"
13: #include "lance.h"
14: #include "lcd.h"
15: #include "lunakbd.h"
16: #include "lunarom.h"
17: #include "mk48t02.h"
18: #include "mpu.h"
19: #include "ppi.h"
20: #include "ram.h"
21: #include "renderer.h"
22: #include "rp5c15.h"
23: #include "scsitarget.h"
24: #include "sio.h"
25: #include "spc.h"
26: #include "sysclk.h"
27: #include "scheduler.h"
28: #include "x68kkbd.h"
29: #include "xiospace.h"
30: #include "zram.h"
31:
32: VM *gVM;
33:
34: // コンストラクタ
35: VM::VM(vmtype_t type)
36: {
37: vmtype = type;
38:
39: // どこでやるのがいいかわからんけど、このコンストラクタはメインスレッドで
40: // 作られるので、ここでメインスレッドの名前を設定。
41: pthread_setname_np("Main");
42:
43: // Scheduler は必ず先頭。(Scheduler::Init のコメント参照)
44: gScheduler = new Scheduler();
45: buserr = new BusErrDevice();
46:
47: // まず全域をバスエラーで初期化。
48: // この後継承先で必要に応じて上書きする。
49: for (int i = 0; i < countof(::devtable); i++) {
50: ::devtable[i] = buserr;
51: }
52: }
53:
54: // デストラクタ
55: VM::~VM()
56: {
57: }
58:
59: // コンストラクタ後の初期化
60: bool
61: VM::Create()
62: {
63: for (const auto& d : gDevices) {
64: if (!d->Create()) {
65: return false;
66: }
67: }
68:
69: return true;
70: }
71:
72: // 初期化
73: bool
74: VM::Init()
75: {
76: for (const auto& d : gDevices) {
77: if (!d->Init()) {
78: return false;
79: }
80: }
81:
82: return true;
83: }
84:
85: // 設定の適用
86: bool
87: VM::Apply()
88: {
89: for (const auto& d : gDevices) {
90: if (!d->Apply()) {
91: return false;
92: }
93: }
94:
95: return true;
96: }
97:
98: // VM の全デバイスの電源をオン
99: bool
100: VM::DevicePowerOn()
101: {
102: for (const auto& d : gDevices) {
103: if (!d->PowerOn()) {
104: return false;
105: }
106: }
107:
108: // ハードウェアリセット
109: ResetHard();
110:
111: // スケジューラを開始
112: // (ResetMPU より後で起動時に1回だけ呼び出す)
113: gScheduler->Run();
114:
115: return true;
116: }
117:
118: // VM の全デバイスの電源をオフ
119: // (Scheduler から呼ばれる)
120: bool
121: VM::DevicePowerOff()
122: {
123: for (const auto& d : gDevices) {
124: if (!d->PowerOff()) {
125: return false;
126: }
127: }
128: // GUI に通知
129: if (poweroff_callback) {
130: poweroff_callback();
131: }
132: return true;
133: }
134:
135: // VM 電源オフ時のコールバックを設定する
136: void
137: VM::SetPowerOffCallback(void (*callback)())
138: {
139: poweroff_callback = callback;
140: }
141:
142: // ハードウェアリセット
143: void
144: VM::ResetHard()
145: {
146: for (const auto& d : gDevices) {
147: d->ResetHard();
148: }
149: }
150:
151: // MPU の RESET 命令によるリセット
152: void
153: VM::ResetSoft()
154: {
155: for (const auto& d : gDevices) {
156: d->ResetSoft();
157: }
158: }
159:
160:
161: //
162: // X68030 VM
163: //
164:
165: // コンストラクタ
166: VM_X68030::VM_X68030()
167: : VM(TYPE_X68030)
168: {
169: // デバイス (順序に注意)
170: // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。
171: gMPU = new MPUDevice(0xff0000);
172: gRAM = new RAMDevice(); // required by XIOSpace
173: xiospace = new XIOSpaceDevice();
174:
175: gKeyboard = new X68030Keyboard();
176: gRenderer = new X68030Renderer();
177:
178: // 割り当て
179: // 今は拡張メモリがないので、今は上位8ビット全領域がミラーになっている。
180: for (int i = 0; i < countof(::devtable); i++) {
181: ::devtable[i] = xiospace;
182: }
183: }
184:
185: // デストラクタ
186: VM_X68030::~VM_X68030()
187: {
188: }
189:
190: // X68030 の電源ボタンを押します。
191: void
192: VM_X68030::PowerButton()
193: {
194: // 電源 ボタン
195: // ON OFF->ON 電源オフ割り込みをネゲート?
196: // ON ON ->OFF 電源オフ割り込みをアサート?
197: // OFF OFF->ON 電源オン
198: // OFF ON ->OFF (通常はあり得ないはず)
199:
200: // ボタンの状態を更新して..
201: power_button = !power_button;
202:
203: // デバイスに指示
204: DevicePowerOn();
205: }
206:
207:
208: //
209: // LUNA
210: //
211:
212: // コンストラクタ
213: VM_LUNA::VM_LUNA()
214: : VM(TYPE_LUNA)
215: {
216: // デバイス (順序に注意)
217: // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。
218: gMPU = new MPUDevice(0x41000000);
219: gRAM = new RAMDevice();
220: gPROM = new PROMDevice();
221: mk48 = new MK48T02Device();
222: gRTC = (RTCDevice *)mk48; // MK48T02 は NVRAM でも RTC でもある…
223: pio0 = new PIO0Device();
224: pio1 = new PIO1Device();
225: gSIO = new SIODevice();
226: sysclk = new SysClkDevice();
227: gZRAM = new ZRAMDevice();
228: maskrom = new MaskROMDevice();
229: gBitmap = new BitmapDevice(); // required by BT454
230: gBT454 = new BT454Device();
231: crtc2 = new CRTC2Device();
232: gSPC = new SPCDevice(0xe1000000);
233: gLance = new LanceDevice();
234: nulldev = new NullDevice();
235:
236: gEthernet = gLance;
237: gLCD = new LCDDevice();
238: gKeyboard = new LunaKeyboard();
239: gRenderer = new LunaRenderer();
240:
241: // デバイスマップから devtable を作成
242: for (uint i = 0; i < countof(::devtable); i++) {
243: IODevice *d;
244: switch (maptable[i]) {
245: case NONE: d = nulldev; break;
246: case BUSERR: d = buserr; break;
247: case RAM: d = gRAM; break;
248: case PROM: d = gPROM; break;
249: case MK48: d = mk48; break;
250: case PIO0: d = pio0; break;
251: case PIO1: d = pio1; break;
252: case SIO: d = gSIO; break;
253: case TAS: d = gZRAM; break;
254: case SYSCLK: d = sysclk; break;
255: case ZRAM: d = gZRAM; break;
256: case MROM: d = maskrom; break;
257: case BITMAP: d = gBitmap; break;
258: case BT454: d = gBT454; break;
259: case CRTC2: d = crtc2; break;
260: case SCSI: d = gSPC; break;
261: case LANCE: d = gLance; break;
262: default:
263: __unreachable();
264: }
265: ::devtable[i] = d;
266: }
267: }
268:
269: // デストラクタ
270: VM_LUNA::~VM_LUNA()
271: {
272: }
273:
274: void
275: VM_LUNA::PowerButton()
276: {
277: // LUNA の電源ボタンは電源オンにしか使わない。
278: //
279: // 電源 ボタン
280: // ON PUSH (何も起きない)
281: // OFF PUSH 電源オン
282:
283: // デバイスに指示
284: DevicePowerOn();
285: }
286:
287: // LUNA のデバイス割り当て表 (上位8ビット)
288: //
289: // 仕様 実際
290: // 00 00 メインメモリ
291: // -- 01..03 二重バスフォールトするようだ
292: // -- 04..0f 何かよく分からないものが読める
293: // -- 10..3f BUSERR
294: // 41 40..43 PROM
295: // 45 44..47 mk48t02
296: // 49 48..4b pio0
297: // 4d 4c..4f pio1
298: // 51 50..53 sio
299: // -- 54..5f 0x7f が読めるようだ
300: // 61 60..61 TAS
301: // 63 62..63 システムクロック
302: // -- 64..6f 61 (TAS) と同じパターンのように見えるけど不詳
303: // 71 70..7f 3ポートRAM
304: // 81 80.. BUSERR (オンボード拡張スロットA)
305: // 83 ..8f BUSERR (オンボード拡張スロットB)
306: // 91 90..9f 0xff が読めるようだ (PC-9000 拡張スロット)
307: //
308: // a1 マスクROM
309: // a0,a2,a4,... BUSERR
310: // a1,a3,a5,... マスクROM
311: // b1 ビットマップ
312: // b0/b1 で同様
313: // c1 パレット
314: // c0/c1 で同様
315: // d1 CRTC-II
316: // d0/d1 で同様
317: //
318: // e1 e0..e3 SCSI
319: // -- e4..ef 不詳だけど、同じパターンが読めるようだ
320: // f1 f0..f3 LANCE
321: // -- f4..ff 0xff が読めるようだ
322:
323: /*static*/ const uint8
324: VM_LUNA::maptable[256] = {
325: RAM, NONE, NONE, NONE, // 00 (二重バスフォールト領域は未対応)
326: NONE, NONE, NONE, NONE, // 04
327: NONE, NONE, NONE, NONE, // 08
328: NONE, NONE, NONE, NONE, // 0c
329: #if 1
330: BUSERR, BUSERR, BUSERR, BUSERR, // 10
331: BUSERR, BUSERR, BUSERR, BUSERR, // 14
332: BUSERR, BUSERR, BUSERR, BUSERR, // 18
333: BUSERR, BUSERR, BUSERR, BUSERR, // 1c
334: BUSERR, BUSERR, BUSERR, BUSERR, // 20
335: BUSERR, BUSERR, BUSERR, BUSERR, // 24
336: BUSERR, BUSERR, BUSERR, BUSERR, // 28
337: BUSERR, BUSERR, BUSERR, BUSERR, // 2c
338: BUSERR, BUSERR, BUSERR, BUSERR, // 30
339: BUSERR, BUSERR, BUSERR, BUSERR, // 34
340: BUSERR, BUSERR, BUSERR, BUSERR, // 38
341: BUSERR, BUSERR, BUSERR, BUSERR, // 3c
342:
343: PROM, PROM, PROM, PROM, // 40
344: #else
345: // ROM が搭載メモリ量を調べる際の終了条件はここでいう NONE デバイス
346: // なので、256MB(-32KB) 以上実装する場合は少なくとも実装メモリの直後を
347: // NONE にしておく必要がある。
348: NONE, NONE, NONE, NONE, // 10
349: NONE, NONE, NONE, NONE, // 14
350: NONE, NONE, NONE, NONE, // 18
351: NONE, NONE, NONE, NONE, // 1c
352: NONE, NONE, NONE, NONE, // 20
353: NONE, NONE, NONE, NONE, // 24
354: NONE, NONE, NONE, NONE, // 28
355: NONE, NONE, NONE, NONE, // 2c
356: NONE, NONE, NONE, NONE, // 30
357: NONE, NONE, NONE, NONE, // 34
358: NONE, NONE, NONE, NONE, // 38
359: NONE, NONE, NONE, NONE, // 3c
360:
361: NONE, PROM, PROM, PROM, // 40
362: #endif
363: MK48, MK48, MK48, MK48, // 44
364: PIO0, PIO0, PIO0, PIO0, // 48
365: PIO1, PIO1, PIO1, PIO1, // 4c
366: SIO, SIO, SIO, SIO, // 50
367: NONE, NONE, NONE, NONE, // 54
368: NONE, NONE, NONE, NONE, // 58
369: NONE, NONE, NONE, NONE, // 5c
370: TAS, TAS, SYSCLK, SYSCLK, // 60
371: NONE, NONE, NONE, NONE, // 64
372: NONE, NONE, NONE, NONE, // 68
373: NONE, NONE, NONE, NONE, // 6c
374: ZRAM, ZRAM, ZRAM, ZRAM, // 70
375: ZRAM, ZRAM, ZRAM, ZRAM, // 74
376: ZRAM, ZRAM, ZRAM, ZRAM, // 78
377: ZRAM, ZRAM, ZRAM, ZRAM, // 7c
378:
379: BUSERR, BUSERR, BUSERR, BUSERR, // 80
380: BUSERR, BUSERR, BUSERR, BUSERR, // 84
381: BUSERR, BUSERR, BUSERR, BUSERR, // 88
382: BUSERR, BUSERR, BUSERR, BUSERR, // 8c
383: NONE, NONE, NONE, NONE, // 90
384: NONE, NONE, NONE, NONE, // 94
385: NONE, NONE, NONE, NONE, // 98
386: NONE, NONE, NONE, NONE, // 9c
387: BUSERR, MROM, BUSERR, MROM, // a0
388: BUSERR, MROM, BUSERR, MROM, // a4
389: BUSERR, MROM, BUSERR, MROM, // a8
390: BUSERR, MROM, BUSERR, MROM, // ac
391: BUSERR, BITMAP, BUSERR, BITMAP, // b0
392: BUSERR, BITMAP, BUSERR, BITMAP, // b4
393: BUSERR, BITMAP, BUSERR, BITMAP, // b8
394: BUSERR, BITMAP, BUSERR, BITMAP, // bc
395:
396: BUSERR, BT454, BUSERR, BT454, // c0
397: BUSERR, BT454, BUSERR, BT454, // c4
398: BUSERR, BT454, BUSERR, BT454, // c8
399: BUSERR, BT454, BUSERR, BT454, // cc
400: BUSERR, CRTC2, BUSERR, CRTC2, // d0
401: BUSERR, CRTC2, BUSERR, CRTC2, // d4
402: BUSERR, CRTC2, BUSERR, CRTC2, // d8
403: BUSERR, CRTC2, BUSERR, CRTC2, // dc
404: SCSI, SCSI, SCSI, SCSI, // e0
405: NONE, NONE, NONE, NONE, // e4
406: NONE, NONE, NONE, NONE, // e8
407: NONE, NONE, NONE, NONE, // ec
408: LANCE, LANCE, LANCE, LANCE, // f0
409: NONE, NONE, NONE, NONE, // f4
410: NONE, NONE, NONE, NONE, // f8
411: NONE, NONE, NONE, NONE, // fc
412: };
413:
414:
415: //
416: // RXZ .r .x .z human68k console emulator
417: //
418:
419: // コンストラクタ
420: VM_RXZ::VM_RXZ(const char *file, const char *arg)
421: : VM(TYPE_RXZ)
422: {
423: // デバイス (順序に注意)
424: // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。
425: gMPU = new MPUDevice(0);
426: gRAM = new RAMDevice(); // required by Human68k
427: gRTC = new RP5C15Device();
428: human68k = new Human68k(file, arg);
429: }
430:
431: // デストラクタ
432: VM_RXZ::~VM_RXZ()
433: {
434: }
435:
436: void
437: VM_RXZ::PowerButton()
438: {
439: // RXZ の電源ボタンは電源オンにしか使わない。
440: //
441: // 電源 ボタン
442: // ON PUSH (何も起きない)
443: // OFF PUSH 電源オン
444:
445: // デバイスに指示
446: DevicePowerOn();
447: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.