--- nono/vm/vm_luna.cpp 2026/04/29 17:05:14 1.1.1.11 +++ nono/vm/vm_luna.cpp 2026/04/29 17:05:18 1.1.1.12 @@ -9,12 +9,12 @@ // #include "vm_luna.h" -#include "bus.h" -#include "bt454.h" +#include "bt45x.h" #include "busio.h" #include "cmmu.h" #include "config.h" #include "crtc2.h" +#include "dipsw.h" #include "ethernet.h" #include "fdc.h" #include "fuserom.h" @@ -24,25 +24,29 @@ #include "lunafb.h" #include "lunakbd.h" #include "mainapp.h" +#include "mainbus.h" +#include "mainram.h" #include "mk48t02.h" +#include "mpu64180.h" #include "mpu680x0.h" #include "mpu88xx0.h" +#include "msxdos.h" #include "nmi.h" +#include "partialram.h" #include "pio.h" #include "power.h" #include "prom.h" -#include "ram.h" -#include "ram_partial.h" #include "renderer.h" #include "romemu_luna1.h" #include "romemu_luna88k.h" #include "scheduler.h" #include "sio.h" #include "spc.h" +#include "subram.h" #include "sysclk.h" #include "sysctlr.h" #include "tas.h" -#include "zram.h" +#include "xpbus.h" // // LUNA 共通部 @@ -59,10 +63,10 @@ enum { SIO, TAS, SYSCLK, - ZRAM, + SUBRAM, MROM, LUNAFB, - BT454, + BT45x, CRTC2, SCSI, LANCE, @@ -78,7 +82,11 @@ VM_LUNA::VM_LUNA() gConfig->SetDefault("rtc-epoch-year", 1970); // LUNA 共通だしここで作成しておく + NEWDV(Dipsw, new LunaDipswDevice()); + NEWDV(MPU64180, new MPU64180Device()); NEWDV(NopIO, new NopIODevice()); + + NEWDV(XPbus, new XPbusDevice()); } // デストラクタ @@ -90,32 +98,35 @@ VM_LUNA::~VM_LUNA() void VM_LUNA::MakeDevtable(const uint8 *maptable) { - for (uint i = 0; i < countof(::devtable); i++) { + auto mainbus = dynamic_cast(pMainbus.get()); + + for (int i = 0; i < mainbus->devtable.size(); i++) { IODevice *d; switch (maptable[i]) { - case NONE: d = gNopIO; break; - case BUSERR: d = gBusErr; break; - case PROM: d = gPROM; break; - case MK48: d = gRTC; break; - case PIO0: d = gPIO0; break; - case PIO1: d = gPIO1; break; - case SIO: d = gSIO; break; - case TAS: d = gTAS; break; - case SYSCLK: d = gSysClk; break; - case ZRAM: d = gZRAM; break; - case MROM: d = gNopIO; break; - case LUNAFB: d = gPlaneVRAM; break; - case BT454: d = gBT454; break; - case CRTC2: d = gCRTC2; break; - case SCSI: d = gSPC; break; - case LANCE: d = gEthernet; break; - case FUSE: d = gFuseROM; break; - case SYSCTL: d = gInterrupt; break; - case CMMU: d = gCMMU; break; + case NONE: d = pNopIO.get(); break; + case BUSERR: d = pBusErr.get(); break; + case PROM: d = pPROM.get(); break; + case MK48: d = pRTC.get(); break; + case PIO0: d = pPIO0.get(); break; + case PIO1: d = pPIO1.get(); break; + case SIO: d = pSIO.get(); break; + case TAS: d = pTAS.get(); break; + case SYSCLK: d = pSysClk.get(); break; + case SUBRAM: d = pSubRAM.get(); break; + case MROM: d = pNopIO.get(); break; + case LUNAFB: d = pPlaneVRAM.get(); break; + case BT45x: d = pBT45x.get(); break; + case CRTC2: d = pCRTC2.get(); break; + case SCSI: d = pSPC.get(); break; + case LANCE: d = pEthernet.get(); break; + case SYSCTL: d = pInterrupt.get(); break; + // これらはサブクラスが所有しているので Get で取得する必要がある。 + case FUSE: d = GetFuseROMDevice(); break; + case CMMU: d = GetCMMUDevice(); break; default: - __unreachable(); + PANIC("corrupted maptable[%d]=%d", i, maptable[i]); } - ::devtable[i] = d; + mainbus->SetDevice(i, d); } } @@ -123,26 +134,29 @@ VM_LUNA::MakeDevtable(const uint8 *mapta bool VM_LUNA::Init() { - // 親クラス if (inherited::Init() == false) { return false; } + auto mainbus = dynamic_cast(pMainbus.get()); + auto mainram = dynamic_cast(pMainRAM.get()); + auto partial = dynamic_cast(pPartialRAM.get()); + // RAM 容量が確定したので、ここで devtable に RAM を配置。 - int ram_size_MB = gRAM->GetSizeMB(); + int ram_size_MB = mainram->GetSizeMB(); int i = 0; while (ram_size_MB >= 16) { // 16MB あれば RAM が直接担当 - ::devtable[i++] = gRAM; + mainbus->SetDevice(i++, mainram); ram_size_MB -= 16; } // 16MB 未満なら PartialRAM が担当 if (ram_size_MB > 0) { - ::devtable[i] = gPartialRAM; + mainbus->SetDevice(i, partial); } // ブートページ切り替え用に覚えておく - ram0 = ::devtable[0]; + ram0 = mainbus->devtable[0]; return true; } @@ -154,15 +168,19 @@ VM_LUNA::SwitchBootPage(Device *parent, // 共通処理 inherited::SwitchBootPage(parent, isrom); + auto mainbus = dynamic_cast(pMainbus.get()); + // ROM は 128KB しかないので 16MB まるごと切り替わったりはしないとは // 思うけど、具体的にどの範囲が切り替わるのかを知る方法がないのと // 大して副作用もないので、先頭の 1ブロックをまるごと切り替えておく。 if (isrom) { - ::devtable[0x00] = gPROM0; - ::devtable[0x41] = gPROM0; + auto prom0 = GetPROM0Device(); + mainbus->SetDevice(0x00, prom0); + mainbus->SetDevice(0x41, prom0); } else { - ::devtable[0x00] = ram0; - ::devtable[0x41] = gPROM; + auto prom = GetPROMDevice(); + mainbus->SetDevice(0x00, ram0); + mainbus->SetDevice(0x41, prom); } } @@ -231,8 +249,8 @@ VM_LUNA1::maptable[256] = { NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 58 TAS, TAS, SYSCLK, SYSCLK, TAS, TAS, SYSCLK, SYSCLK, // 60 TAS, TAS, SYSCLK, SYSCLK, TAS, TAS, SYSCLK, SYSCLK, // 68 - ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 70 - ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 78 + SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, // 70 + SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, // 78 BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 80 BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 88 @@ -243,8 +261,8 @@ VM_LUNA1::maptable[256] = { BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b0 BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b8 - BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c0 - BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c8 + BUSERR, BT45x, BUSERR, BT45x, BUSERR, BT45x, BUSERR, BT45x, // c0 + BUSERR, BT45x, BUSERR, BT45x, BUSERR, BT45x, BUSERR, BT45x, // c8 BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d0 BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d8 SCSI, SCSI, SCSI, SCSI, NONE, NONE, NONE, NONE, // e0 @@ -271,26 +289,29 @@ VM_LUNA1::VM_LUNA1() NEWDV(MPU, new MPU680x0Device()); NEWDV(Interrupt, new LunaInterrupt()); - NEWDV(RAM, new RAMDevice()); // required by PartialRAM - NEWDV(PartialRAM, new PartialRAMDevice()); - NEWDV(Ethernet, new BusIO_W()); // required by PROM - if (gMainApp.exec_file || gConfig->Find("prom-image").AsString().empty()) { + if (gMainApp.msxdos_mode) { + NEWDV(PROM, new MSXDOSDevice()); + } else if (gMainApp.exec_file || + gConfig->Find("prom-image").AsString().empty()) { NEWDV(PROM, new Luna1PROMEmuDevice()); } else { - NEWDV(PROM, new PROMDevice()); + NEWDV(PROM, new PROMDevice()); // required by RAM,BT45x } NEWDV(PROM0, new PROM0Device()); + NEWDV(MainRAM, new MainRAMDevice()); // required by PartialRAM + NEWDV(PartialRAM, new PartialRAMDevice()); NEWDV(RTC, new BusIO_B()); // required by Sysclk NEWDV(PIO0, new BusIO_B()); NEWDV(PIO1, new BusIO_B()); NEWDV(SIO, new BusIO_BB()); NEWDV(SysClk, new BusIO_B()); NEWDV(TAS, new BusIO_B()); - NEWDV(ZRAM, new ZRAMDevice()); - NEWDV(PlaneVRAM, new LunafbDevice()); // required by BT454 - NEWDV(BT454, new BusIO_B()); + NEWDV(SubRAM, new SubRAMDevice(128)); + NEWDV(BT45x, new BT45xDevice()); // required by Lunafb + NEWDV(PlaneVRAM, new LunafbDevice()); NEWDV(CRTC2, new BusIO_B()); NEWDV(SPC, new BusIO_BBBB()); + NEWDV(Ethernet, new BusIO_W()); NEWDV(NMI, new NMIDevice()); NEWDV(LCD, new LCDDevice()); @@ -308,14 +329,63 @@ VM_LUNA1::~VM_LUNA1() // -// LUNA88K +// LUNA-88K // +// 00..03 RAM (64MB 実機の場合) +// 04..3f アドレスの残像? (64MB 実機の場合) +// 40,41 PROM (B、N=256KB でミラー) +// 42,43 FUSEROM (BFFF、N=256 でミラー) +// 44,45 NVRAM (BFFF、N=2048 でミラー) +// 46,47 アドレスの残像? +// 48,49 PIO0 (BFFF、N=4 でミラー) +// 4a,4b アドレスの残像? +// 4c,4d PIO1 (BFFF、N=4 でミラー) +// 4e,4f アドレスの残像? +// 50,51 SIO (BFFF、N=4 でミラー) +// 52..5f アドレスの残像? +// 60,61 TAS? (BFFF、N=1 ?) +// 62,63 SysClk (BFFF、N=1 ?) +// 64,65,66,67 SysCtlr? (BFFF、N=4 ?) +// 68,69,6a,6b SysCtlr? (L、N=4 ?) +// 6c,6d CPU リセット +// 6e,6f 68-6b と同じパターンの気がする +// 70-7f SubRAM +// 80-9f アドレスの残像? +// a0-af 偶数(a0,a2,..)は残像、奇数(a1,a3,..)は ff +// b0-bf 偶数(b0,b2,..)は残像、奇数(b1,b3,..)は LUNAFB +// c0-cf 偶数(c0,c2,..)は残像、奇数(c1,c3,..)は BT454(BFFF、N=4) +// d0-df 偶数(d0,d2,..)は残像、奇数(d1,d3,..)はたぶん CRTC2 +// (CRTC2 は今の所 $ff しか観測できていないので詳細不明) +// e0,e1 SPC (BFFF、N=16 でミラー) +// e2-e7 繋がってない? 概ね $f4'00'c0'01 が読める。 +// FUSEROM などの繋がってないところと同じパターンが読める。 +// f0,f1 たぶん Lance (BFFF、N=2) +// f2-fd $ff +// fe $fe00'0000-$fef7'ffff まではアドレスの残像 +// $fef8'0000-$feff'ffff までは $ff +// ff たぶん CMMU 以外はアドレスの残像 +// +// アドレスの残像(?) は +// - バイトアクセスならアドレスの下位 8bit、 +// - ワードアクセスならアドレスの下位 16bit、 +// - ロングワードアクセスならアドレス 32bit +// が見え、時々 $ffffffff が混ざるようだ ($00..$ff までのうち2個程度)。 +// 一方、デバイスに接続されていない下位24ビットあるいは28ビットに +// $f400c001 が見えるエリアも多いが、$f400c001 は jmp r1 命令なので、おそらく +// PROM モニターがこのダンプを表示する際のプログラムコードがデータバスバッファ +// を通過したのが見えている可能性がある。 +// いずれも再現は難しいので見なかったことにする。 + /*static*/ const uint8 VM_LUNA88K::maptable[256] = { - // RAM は Init() で動的に配置する。 - NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 00 - NONE, NONE, NONE, NONE, NONE, NONE, NONE, BUSERR, // 08 + // RAM は Init() で動的に配置する (64MB なら 00..03 の4枠)。 + // RAM 未実装領域については要調査。少なくとも末尾に BUSERR がないと + // OpenBSD カーネルが起動しない。 + // 先頭 64MB の空間 (00..03) だけは、PROM 1.20 ではメモリが無いときでも + // バスエラーにならないことを期待しているので NONE にしておく。 + NONE, NONE, NONE, NONE, BUSERR, BUSERR, BUSERR, BUSERR, // 00 + BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 08 BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 10 BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 18 BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 20 @@ -323,34 +393,34 @@ VM_LUNA88K::maptable[256] = { BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 30 BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 38 - // LUNA88K2 は 47 に(も?) NVRAM がいるようだ + // LUNA-88K2 は 47 に(も?) NVRAM がいるようだ // 69,6b,6d にも何かのコントローラ? - PROM, PROM, PROM, FUSE, MK48, MK48, MK48, MK48, // 40 - PIO0, PIO0, PIO0, PIO0, PIO1, PIO1, PIO1, PIO1, // 48 - SIO, SIO, SIO, SIO, NONE, NONE, NONE, NONE, // 50 + PROM, PROM, FUSE, FUSE, MK48, MK48, NONE, NONE, // 40 + PIO0, PIO0, NONE, NONE, PIO1, PIO1, NONE, NONE, // 48 + SIO, SIO, NONE, NONE, NONE, NONE, NONE, NONE, // 50 NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 58 - TAS, TAS, SYSCLK, SYSCLK, NONE, SYSCTL, NONE, NONE, // 60 - NONE, SYSCTL, NONE, NONE, NONE, SYSCTL, NONE, NONE, // 68 - ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 70 - ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, ZRAM, // 78 + TAS, TAS, SYSCLK, SYSCLK, SYSCTL, SYSCTL, SYSCTL, SYSCTL, // 60 + SYSCTL, SYSCTL, SYSCTL, SYSCTL, SYSCTL, SYSCTL, SYSCTL, SYSCTL, // 68 + SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, // 70 + SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, SUBRAM, // 78 - BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 80 - BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, BUSERR, // 88 + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 80 + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 88 NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 90 NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // 98 - BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, // a0 - BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, BUSERR, MROM, // a8 - BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b0 - BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, BUSERR, LUNAFB, // b8 + NONE, MROM, NONE, MROM, NONE, MROM, NONE, MROM, // a0 + NONE, MROM, NONE, MROM, NONE, MROM, NONE, MROM, // a8 + NONE, LUNAFB, NONE, LUNAFB, NONE, LUNAFB, NONE, LUNAFB, // b0 + NONE, LUNAFB, NONE, LUNAFB, NONE, LUNAFB, NONE, LUNAFB, // b8 // d0 にボードチェックレジスタ? - BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c0 - BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, BUSERR, BT454, // c8 - BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d0 - BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, BUSERR, CRTC2, // d8 - SCSI, SCSI, SCSI, SCSI, NONE, NONE, NONE, NONE, // e0 + NONE, BT45x, NONE, BT45x, NONE, BT45x, NONE, BT45x, // c0 + NONE, BT45x, NONE, BT45x, NONE, BT45x, NONE, BT45x, // c8 + NONE, CRTC2, NONE, CRTC2, NONE, CRTC2, NONE, CRTC2, // d0 + NONE, CRTC2, NONE, CRTC2, NONE, CRTC2, NONE, CRTC2, // d8 + SCSI, SCSI, NONE, NONE, NONE, NONE, NONE, NONE, // e0 NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, // e8 - LANCE, LANCE, LANCE, LANCE, NONE, NONE, NONE, NONE, // f0 + LANCE, LANCE, NONE, NONE, NONE, NONE, NONE, NONE, // f0 NONE, NONE, NONE, NONE, NONE, NONE, NONE, CMMU, // f8 }; @@ -364,7 +434,7 @@ VM_LUNA88K::VM_LUNA88K() gConfig->SetDefault("ram-size", 64); // SPC の入力クロック (XXX LUNA-I と同じ?) gConfig->Add("!spc-tCLF", 163); - // LUNA-II, LUNA88K, LUNA88K2 のクロック割り込みは 100Hz らしい + // LUNA-II, LUNA-88K, LUNA-88K2 のクロック割り込みは 100Hz らしい gConfig->Add("!sysclk-period", 10_msec); // デバイス (順序に注意) @@ -372,27 +442,27 @@ VM_LUNA88K::VM_LUNA88K() NEWDV(MPU, new MPU88xx0Device()); NEWDV(Interrupt, new SysCtlrDevice()); - NEWDV(RAM, new RAMDevice()); // required by PartialRAM - NEWDV(PartialRAM, new PartialRAMDevice()); - NEWDV(Ethernet, new BusIO_WF()); // required by FuseROM - NEWDV(FuseROM, new BusIO_BFFF()); if (gMainApp.exec_file || gConfig->Find("prom-image").AsString().empty()) { NEWDV(PROM, new Luna88kPROMEmuDevice()); } else { - NEWDV(PROM, new PROMDevice()); + NEWDV(PROM, new PROMDevice()); // required by RAM } NEWDV(PROM0, new PROM0Device()); + NEWDV(MainRAM, new MainRAMDevice()); // required by PartialRAM + NEWDV(PartialRAM, new PartialRAMDevice()); + NEWDV(FuseROM, new BusIO_BFFF()); NEWDV(RTC, new BusIO_BFFF()); NEWDV(PIO0, new BusIO_BFFF()); NEWDV(PIO1, new BusIO_BFFF()); NEWDV(SIO, new BusIO_BFFF()); NEWDV(SysClk, new BusIO_BFFF()); NEWDV(TAS, new BusIO_BFFF()); - NEWDV(ZRAM, new ZRAMDevice()); - NEWDV(PlaneVRAM, new LunafbDevice()); // required by BT454 - NEWDV(BT454, new BusIO_B()); + NEWDV(SubRAM, new SubRAMDevice(128)); + NEWDV(BT45x, new BT45xDevice()); // required by Lunafb + NEWDV(PlaneVRAM, new LunafbDevice()); NEWDV(CRTC2, new BusIO_BFFF()); NEWDV(SPC, new BusIO_BFFF()); + NEWDV(Ethernet, new BusIO_WF()); NEWDV(CMMU, new CMMUDevice()); NEWDV(NMI, new NMIDevice());