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