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