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