|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #include "vm_luna.h"
8: #include "aout.h"
9: #include "bt454.h"
10: #include "busio.h"
1.1.1.2 root 11: #include "cmmu.h"
12: #include "config.h"
1.1 root 13: #include "crtc2.h"
14: #include "ethernet.h"
15: #include "fuserom.h"
1.1.1.4 root 16: #include "interrupt.h"
1.1 root 17: #include "lance.h"
18: #include "lcd.h"
1.1.1.7 root 19: #include "lunafb.h"
1.1 root 20: #include "lunakbd.h"
21: #include "mainapp.h"
22: #include "mk48t02.h"
1.1.1.2 root 23: #include "mpu680x0.h"
24: #include "mpu88xx0.h"
1.1 root 25: #include "pio.h"
1.1.1.2 root 26: #include "prom.h"
1.1 root 27: #include "ram.h"
1.1.1.5 root 28: #include "ram_partial.h"
1.1 root 29: #include "renderer.h"
1.1.1.5 root 30: #include "romemu_luna1.h"
1.1 root 31: #include "romemu_luna88k.h"
32: #include "scheduler.h"
33: #include "sio.h"
34: #include "spc.h"
35: #include "sysclk.h"
1.1.1.2 root 36: #include "sysctlr.h"
37: #include "tas.h"
1.1 root 38: #include "zram.h"
39:
1.1.1.5 root 40: //
41: // LUNA 共通部
42: //
43:
44: // デバイスマップ用の識別子
45: enum {
46: NONE,
47: BUSERR,
48: PROM,
49: MK48,
50: PIO0,
51: PIO1,
52: SIO,
53: TAS,
54: SYSCLK,
55: ZRAM,
56: MROM,
1.1.1.7 root 57: LUNAFB,
1.1.1.5 root 58: BT454,
59: CRTC2,
60: SCSI,
61: LANCE,
62: FUSE,
63: SYSCTL,
64: CMMU,
65: };
66:
67: // コンストラクタ
68: VM_LUNA::VM_LUNA()
69: {
70: // この機種に不要なパラメータはここで削除する
71: // (機種が決まるより前に全機種の設定の和集合を用意してあるため)。
72: // o LUNA-I は 68881 固定なので不要。
73: // o これは m68k パラメータなので LUNA88K には不要。
74: gConfig->Delete("mpu-has-fpu");
75:
76: // LUNA 共通だしここで作成しておく
1.1.1.7 root 77: gNopIO.reset(new NopIODevice());
1.1.1.5 root 78: }
79:
80: // デストラクタ
81: VM_LUNA::~VM_LUNA()
82: {
83: }
84:
85: // デバイスマップから devtable を作成 (ここは共通にできる)
86: void
87: VM_LUNA::MakeDevtable(const uint8 *maptable)
88: {
89: for (uint i = 0; i < countof(::devtable); i++) {
90: IODevice *d;
91: switch (maptable[i]) {
1.1.1.7 root 92: case NONE: d = gNopIO.get(); break;
1.1.1.6 root 93: case BUSERR: d = gBusErr.get(); break;
1.1.1.8 root 94: case PROM: d = gPROM.get(); break;
1.1.1.5 root 95: case MK48: d = gRTC.get(); break;
96: case PIO0: d = gPIO0.get(); break;
97: case PIO1: d = gPIO1.get(); break;
98: case SIO: d = gSIO.get(); break;
99: case TAS: d = gTAS.get(); break;
100: case SYSCLK: d = gSysClk.get(); break;
101: case ZRAM: d = gZRAM.get(); break;
1.1.1.7 root 102: case MROM: d = gNopIO.get(); break;
103: case LUNAFB: d = gLunafb.get(); break;
1.1.1.5 root 104: case BT454: d = gBT454.get(); break;
105: case CRTC2: d = gCRTC2.get(); break;
106: case SCSI: d = gSPC.get(); break;
107: case LANCE: d = gEthernet.get(); break;
108: case FUSE: d = gFuseROM.get(); break;
109: case SYSCTL: d = gInterrupt.get(); break;
110: case CMMU: d = gCMMU.get(); break;
111: default:
112: __unreachable();
113: }
114: ::devtable[i] = d;
115: }
116: }
117:
118: // 初期化
119: bool
120: VM_LUNA::Init()
121: {
122: // 親クラス
123: if (inherited::Init() == false) {
124: return false;
125: }
126:
127: // RAM 容量が確定したので、ここで devtable に RAM を配置。
128: int ram_size_MB = gRAM->GetSizeMB();
129: int i = 0;
130: while (ram_size_MB >= 16) {
131: // 16MB あれば RAM が直接担当
132: ::devtable[i++] = gRAM.get();
133: ram_size_MB -= 16;
134: }
135: // 16MB 未満なら PartialRAM が担当
136: if (ram_size_MB > 0) {
137: ::devtable[i] = gPartialRAM.get();
138: }
139:
1.1.1.8 root 140: // ブートページ切り替え用に覚えておく
141: ram0 = ::devtable[0];
142:
1.1.1.5 root 143: return true;
144: }
145:
146: void
147: VM_LUNA::PowerButton()
148: {
149: // LUNA の電源ボタンは電源オンにしか使わない。
150: //
151: // 電源 ボタン
152: // ON PUSH (何も起きない)
153: // OFF PUSH 電源オン
154:
1.1.1.6 root 155: // スケジューラに指示
156: gScheduler->RequestPowerOn();
157: }
158:
159: // ブートページを切り替える。
160: void
161: VM_LUNA::SwitchBootPage(Device *parent, bool isrom)
162: {
163: // 共通処理
164: inherited::SwitchBootPage(parent, isrom);
165:
166: // ROM は 128KB しかないので 16MB まるごと切り替わったりはしないとは
167: // 思うけど、具体的にどの範囲が切り替わるのかを知る方法がないのと
168: // 大して副作用もないので、先頭の 1ブロックをまるごと切り替えておく。
169: if (isrom) {
1.1.1.8 root 170: ::devtable[0x00] = gPROM0.get();
171: ::devtable[0x41] = gPROM0.get();
1.1.1.6 root 172: } else {
1.1.1.8 root 173: ::devtable[0x00] = ram0;
174: ::devtable[0x41] = gPROM.get();
1.1.1.6 root 175: }
1.1.1.5 root 176: }
177:
178:
179: //
180: // LUNA-I
181: //
182:
183: // LUNA-I のデバイス割り当て表 (上位8ビット)
1.1 root 184: //
185: // 仕様 実際
186: // 00 00 メインメモリ
187: // -- 01..03 二重バスフォールトするようだ
188: // -- 04..0f 何かよく分からないものが読める
189: // -- 10..3f BUSERR
190: // 41 40..43 PROM (B、N=128KBでミラー)
191: // 45 44..47 mk48t02 (B、N=2048でミラー)
192: // 49 48..4b pio0 (B、N=4でミラー)
193: // 4d 4c..4f pio1 (B、N=4でミラー)
194: // 51 50..53 sio (BB、N=4でミラー)
195: // -- 54..5f 0xff が読めるようだ
196: // 61 60..61 TAS (B、N=1でミラー)
197: // 63 62..63 システムクロック (B、N=1でミラー)
198: // -- 以降TASとSysClkで2枠ずつ。また無効ビットの読み出しは
199: // -- 必ずしも Hi とは限らず不安定のようだ。
200: // 71 70..7f 3ポートRAM (B、N=128KBでミラー)
201: // 81 80.. BUSERR (オンボード拡張スロットA)
202: // 83 ..8f BUSERR (オンボード拡張スロットB)
203: // 91 90..9f 0xff が読めるようだ (PC-9000 拡張スロット)
204: //
205: // a1 マスクROM
206: // a0,a2,a4,... BUSERR
207: // a1,a3,a5,... マスクROM(なければ0xffが読める)
208: // b1 ビットマップ
209: // b0,b2,b4,... BUSERR
1.1.1.7 root 210: // b1,b3,b5,... ビットマップ (内訳は lunafb.cpp 参照)
1.1 root 211: // c1 パレット
212: // c0,c2,c4,... BUSERR
213: // c1,c3,c5,... パレット (B、N=4でミラー)
214: // d1 CRTC-II
215: // d0,d2,d4,... BUSERR
216: // d1,d3,d5,... CRTC-II (B、N=2でミラー)
217: //
218: // e1 e0..e3 SCSI (BBBB、N=16 でミラー)
219: // -- e4..ef 0xff が読めるようだが不安定。
220: // f1 f0..f3 LANCE (WW、N=2 でミラー)
221: // -- f4..ff 0xff が読めるようだ
222:
223: /*static*/ const uint8
1.1.1.5 root 224: VM_LUNA1::maptable[256] = {
225: // (00,)01,02,03 は実際にはたぶんパリティチェックが入っていて(?)
226: // 非実装領域にアクセスすると二重バスフォールトになるがそれは未対応。
227: // RAM は Init() で動的に配置する。
228: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 00
1.1 root 229: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 08
230: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 10
231: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 18
232: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 20
233: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 28
234: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 30
235: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 38
236:
237: PROM, PROM, PROM, PROM, MK48, MK48, MK48, MK48, // 40
238: PIO0, PIO0, PIO0, PIO0, PIO1, PIO1, PIO1, PIO1, // 48
239: SIO, SIO, SIO, SIO, NONE, NONE, NONE, NONE, // 50
240: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 58
241: TAS, TAS, SYSCLK, SYSCLK, TAS, TAS, SYSCLK, SYSCLK, // 60
242: TAS, TAS, SYSCLK, SYSCLK, TAS, TAS, SYSCLK, SYSCLK, // 68
243: ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 70
244: ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 78
245:
246: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 80
247: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 88
248: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 90
249: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 98
250: BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, // a0
251: BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, // a8
1.1.1.7 root 252: BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b0
253: BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b8
1.1 root 254:
255: BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c0
256: BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c8
257: BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d0
258: BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d8
259: SCSI, SCSI, SCSI, SCSI, NONE, NONE, NONE, NONE, // e0
260: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // e8
261: LANCE, LANCE, LANCE, LANCE, NONE, NONE, NONE, NONE, // f0
262: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // f8
263: };
264:
265: // コンストラクタ
1.1.1.5 root 266: VM_LUNA1::VM_LUNA1()
1.1 root 267: {
1.1.1.2 root 268: // 機種固有パラメータ
269: // MPU クロックの初期値は機種ごとに異なる。単位は MHz
270: gConfig->SetDefault("mpu-clock", 20);
271: // RAM 初期値は MAX にしておく
272: gConfig->SetDefault("ram-size", 16);
273: // SPC の入力クロック (おそらく 6.144MHz = 163ns が入ってる)
274: gConfig->Add("!spc-tCLF", 163);
275: // LUNA-I のクロック割り込みは 60Hz
276: gConfig->Add("!sysclk-period", 16.666667_msec);
277:
1.1 root 278: // デバイス (順序に注意)
1.1.1.7 root 279: // BusErrDevice, NopIODevice は親コンストラクタで作成済み。
1.1.1.2 root 280:
1.1.1.6 root 281: gMPU.reset(new MPU680x0Device()); // required by Scheduler
1.1.1.2 root 282: gScheduler.reset(new Scheduler()); // required by *
1.1.1.4 root 283: gInterrupt.reset(new LunaInterrupt());
1.1.1.5 root 284: gRAM.reset(new RAMDevice()); // required by PartialRAM
285: gPartialRAM.reset(new PartialRAMDevice());
1.1.1.2 root 286: gEthernet.reset(new BusIO_W<LanceDevice>()); // required by PROM
1.1.1.8 root 287: if (gMainApp.exec_file || gConfig->Find("prom-image").AsString().empty()) {
288: gPROM.reset(new Luna1PROMEmuDevice());
1.1 root 289: } else {
1.1.1.8 root 290: gPROM.reset(new PROMDevice());
1.1 root 291: }
1.1.1.8 root 292: gPROM0.reset(new PROM0Device());
1.1 root 293: gRTC.reset(new BusIO_B<MK48T02Device>());
294: gPIO0.reset(new BusIO_B<PIO0Device>());
295: gPIO1.reset(new BusIO_B<PIO1Device>());
296: gSIO.reset(new BusIO_BB<SIODevice>());
1.1.1.4 root 297: gSysClk.reset(new BusIO_B<SysClkDevice>());
1.1.1.2 root 298: gTAS.reset(new BusIO_B<TASDevice>());
1.1 root 299: gZRAM.reset(new ZRAMDevice());
1.1.1.7 root 300: gLunafb.reset(new LunafbDevice()); // required by BT454
1.1 root 301: gBT454.reset(new BusIO_B<BT454Device>());
1.1.1.5 root 302: gCRTC2.reset(new BusIO_B<CRTC2Device>());
1.1 root 303: gSPC.reset(new BusIO_BBBB<SPCDevice>());
304:
305: gLCD.reset(new LCDDevice());
306: gKeyboard.reset(new LunaKeyboard());
307: gRenderer.reset(new LunaRenderer());
308:
309: // デバイスマップから devtable を作成
1.1.1.5 root 310: MakeDevtable(maptable);
1.1 root 311: }
312:
313: // デストラクタ
1.1.1.5 root 314: VM_LUNA1::~VM_LUNA1()
1.1 root 315: {
316: }
317:
318: //
319: // LUNA88K
320: //
321:
322: /*static*/ const uint8
323: VM_LUNA88K::maptable[256] = {
1.1.1.5 root 324: // RAM は Init() で動的に配置する。
325: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 00
1.1.1.6 root 326: NONE, NONE, NONE, NONE, NONE, NONE, NONE, BUSERR, // 08
1.1 root 327: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 10
328: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 18
329: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 20
330: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 28
331: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 30
332: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 38
333:
334: // LUNA88K2 は 47 に(も?) NVRAM がいるようだ
335: // 69,6b,6d にも何かのコントローラ?
336: PROM, PROM, PROM, FUSE, MK48, MK48, MK48, MK48, // 40
337: PIO0, PIO0, PIO0, PIO0, PIO1, PIO1, PIO1, PIO1, // 48
338: SIO, SIO, SIO, SIO, NONE, NONE, NONE, NONE, // 50
339: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 58
1.1.1.2 root 340: TAS, TAS, SYSCLK, SYSCLK, NONE, SYSCTL, NONE, NONE, // 60
341: NONE, SYSCTL, NONE, NONE, NONE, SYSCTL, NONE, NONE, // 68
1.1 root 342: ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 70
343: ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 78
344:
345: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 80
346: BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 88
347: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 90
348: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 98
349: BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, // a0
350: BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, // a8
1.1.1.7 root 351: BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b0
352: BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b8
1.1 root 353:
354: // d0 にボードチェックレジスタ?
355: BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c0
356: BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c8
357: BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d0
358: BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d8
359: SCSI, SCSI, SCSI, SCSI, NONE, NONE, NONE, NONE, // e0
360: NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // e8
361: LANCE, LANCE, LANCE, LANCE, NONE, NONE, NONE, NONE, // f0
1.1.1.2 root 362: NONE, NONE, NONE, NONE, NONE, NONE, NONE, CMMU, // f8
1.1 root 363: };
364:
365: // コンストラクタ
366: VM_LUNA88K::VM_LUNA88K()
367: {
1.1.1.2 root 368: // 機種固有パラメータ
369: // MPU クロックの初期値は機種ごとに異なる。単位は MHz
370: gConfig->SetDefault("mpu-clock", 25);
371: // RAM 初期値は MAX にしておく
1.1.1.3 root 372: gConfig->SetDefault("ram-size", 64);
1.1.1.2 root 373: // SPC の入力クロック (XXX LUNA-I と同じ?)
374: gConfig->Add("!spc-tCLF", 163);
375: // LUNA-II, LUNA88K, LUNA88K2 のクロック割り込みは 100Hz らしい
376: gConfig->Add("!sysclk-period", 10_msec);
377:
1.1.1.5 root 378: // この機種に不要なパラメータはここで削除する
379: // (機種が決まるより前に全機種の設定の和集合を用意してあるため)
380: gConfig->Delete("mpu-has-fpu");
381:
1.1 root 382: // デバイス (順序に注意)
1.1.1.7 root 383: // BusErrDevice, NopIODevice は親コンストラクタで作成済み。
1.1.1.2 root 384:
1.1.1.6 root 385: gMPU.reset(new MPU88xx0Device()); // required by Scheduler
1.1.1.2 root 386: gScheduler.reset(new Scheduler()); // required by *
1.1.1.4 root 387: gInterrupt.reset(new SysCtlrDevice());
1.1.1.5 root 388: gRAM.reset(new RAMDevice()); // required by PartialRAM
389: gPartialRAM.reset(new PartialRAMDevice());
1.1.1.9 ! root 390: gEthernet.reset(new BusIO_WF<LanceDevice>()); // required by FuseROM
! 391: gFuseROM.reset(new BusIO_BFFF<FuseROMDevice>());
1.1.1.8 root 392: if (gMainApp.exec_file || gConfig->Find("prom-image").AsString().empty()) {
393: gPROM.reset(new Luna88kPROMEmuDevice());
1.1 root 394: } else {
1.1.1.8 root 395: gPROM.reset(new PROMDevice());
1.1 root 396: }
1.1.1.8 root 397: gPROM0.reset(new PROM0Device());
1.1 root 398: gRTC.reset(new BusIO_BFFF<MK48T02Device>());
1.1.1.2 root 399: gPIO0.reset(new BusIO_BFFF<PIO0Device>());
400: gPIO1.reset(new BusIO_BFFF<PIO1Device>());
1.1 root 401: gSIO.reset(new BusIO_BFFF<SIODevice>());
1.1.1.4 root 402: gSysClk.reset(new BusIO_BFFF<SysClkDevice>());
1.1.1.2 root 403: gTAS.reset(new BusIO_BFFF<TASDevice>());
1.1 root 404: gZRAM.reset(new ZRAMDevice());
1.1.1.7 root 405: gLunafb.reset(new LunafbDevice()); // required by BT454
1.1 root 406: gBT454.reset(new BusIO_B<BT454Device>());
1.1.1.5 root 407: gCRTC2.reset(new BusIO_BFFF<CRTC2Device>());
1.1 root 408: gSPC.reset(new BusIO_BFFF<SPCDevice>());
1.1.1.2 root 409: gCMMU.reset(new CMMUDevice());
1.1 root 410:
411: gLCD.reset(new LCDDevice());
412: gKeyboard.reset(new LunaKeyboard());
413: gRenderer.reset(new LunaRenderer());
414:
415: // デバイスマップから devtable を作成
1.1.1.5 root 416: MakeDevtable(maptable);
1.1 root 417: }
418:
419: // デストラクタ
420: VM_LUNA88K::~VM_LUNA88K()
421: {
422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.