--- nono/vm/romemu_luna.cpp 2026/04/29 17:04:55 1.1.1.9 +++ nono/vm/romemu_luna.cpp 2026/04/29 17:05:03 1.1.1.11 @@ -5,17 +5,25 @@ // // LUNA シリーズの ROM エミュレーション共通部分 - -// IODevice -// | -// +----------+---------------------+ -// v v -// ROMDevice LunaPROMEmuDeivce (ROM エミュレーションの共通部分) -// | | -// | +------------+----------------+ -// v v v -// PROMDevice Luna1PROMEmuDevice Luna88kPROMEmuDevice -// (実ROM) (LUNA-I エミュレーション) (LUNA88K エミュレーション) +// +// IODevice +// | +// +-- ROMDevice (LoadROM()、ウェイト、マスク等を持つ) +// | | +// | +-- PROMDevice (LUNA* の PROM) +// | +-- IPLROM1Device (X680x0 の IPLROM 後半) +// | +-- IPLROM2Device (X680x0 の IPLROM 前半) +// | +-- CGROMDevice (X680x0 の CGROM) +// | | +// | | +-------------------+ +// | +--| LunaPROMEmuDevice | (LUNA PROM エミュレーションの共通部分) +// | +-------------------+ +// | | +// | +-- Luna1PROMEmuDevice (LUNA1 の PROM エミュレーション) +// | +-- Luna88kPROMEmuDevice (LUNA88K の PROM エミュレーション) +// | +// +-- PROM0Device (LUNA* のブートページ切り替え用プロキシ) +// +-- IPLROM0Device (X680x0 のブートページ切り替え用プロキシ) #include "romemu_luna.h" #include "bt454.h" @@ -31,6 +39,8 @@ LunaPROMEmuDevice::LunaPROMEmuDevice() : inherited("PROM") { + // LUNA では ROM への書き込みは何も起きない + write_op = 0; } // デストラクタ @@ -47,46 +57,11 @@ LunaPROMEmuDevice::Init() return true; } -void -LunaPROMEmuDevice::ResetHard() -{ - // ブートページを ROM に切り替える。 - isrom = true; - gVM->SwitchBootPage(this, true); -} - -// アドレスデコーダ -inline uint64 -LunaPROMEmuDevice::Decoder(uint32 addr) const -{ - // 折り返しなし - return addr - baseaddr; -} - -uint64 -LunaPROMEmuDevice::Read8(uint32 addr) -{ - uint64 offset = Decoder(addr); - - // 謎の IO 空間はロングワードアクセスのみ - return romdata[offset & (devlen - 1)]; -} - -uint64 -LunaPROMEmuDevice::Read16(uint32 addr) -{ - uint64 offset = Decoder(addr); - - // 謎の IO 空間はロングワードアクセスのみ - return be16toh(*(uint16 *)&romdata[offset & (devlen - 1)]); -} - uint64 LunaPROMEmuDevice::Read32(uint32 addr) { - uint64 offset = Decoder(addr); - - // ROM からのロングワードアクセスでだけ謎の I/O 空間が見える + // ROM からのロングワードアクセスでだけ謎の I/O 空間が見える。 + // addr をマスクする前に評価すること。 if ((gMPU->GetPaddr() & 0xff000000) == baseaddr) { switch (addr) { case ROMIO_INIT: @@ -107,45 +82,14 @@ LunaPROMEmuDevice::Read32(uint32 addr) break; } } - return be32toh(*(uint32 *)&romdata[offset & (devlen - 1)]); -} - -uint64 -LunaPROMEmuDevice::Write8(uint32 addr, uint32 data) -{ - return 0; -} -uint64 -LunaPROMEmuDevice::Write16(uint32 addr, uint32 data) -{ - return 0; -} - -uint64 -LunaPROMEmuDevice::Write32(uint32 addr, uint32 data) -{ - return 0; -} - -uint64 -LunaPROMEmuDevice::Peek8(uint32 addr) -{ - uint64 offset = Decoder(addr); - - return romdata[offset & (devlen - 1)]; + return inherited::Read32(addr); } // デバイスの初期化の共通部分。(継承クラスの ROM_Init() から呼ぶ) void LunaPROMEmuDevice::InitDevice() { - // ブートページを RAM に切り替える。 - if (isrom) { - isrom = false; - gVM->SwitchBootPage(this, false); - } - // 初期パレット // 偶数番は白(R/G/B=15/15/15)、奇数番は黒(0/0/0)。 uint8 val = 0xf0; @@ -192,11 +136,10 @@ LunaPROMEmuDevice::InitScreen(const char void LunaPROMEmuDevice::ROM_Close() { - // SIO からキーの Break 入力を取り除いておく。 - // コマンド入力によってここへ来る時は、キーの Make で呼ばれるため - // Break はまだ取り出されておらず SIO のバッファに残っている。 - // コマンド入力によらずここに来た場合でも空読みして問題ないだろう。 - (void)gSIO->Read(2); + // SIO をリセットしておく。 + // SIO のバッファにデータが残っていると、NetBSD のブートローダが + // 起動してこないようだ。リセットして RXEN を落としておけば大丈夫ぽい。 + gSIO->ResetHard(); // コンソールクローズ gLunafb->EmuConsoleClose(); @@ -397,15 +340,15 @@ LunaPROMEmuDevice::VerifyNVRAM() const return true; } -// -A オプションで指定されたホストファイルをロードする。 +// -X オプションで指定されたホストファイルをロードする。 // ロードできればエントリポイントを返す。 -// host_file が指定されている時に呼ぶこと。 +// exec_file が指定されている時に呼ぶこと。 uint32 LunaPROMEmuDevice::LoadHostFile() { - assert(gMainApp.host_file); + assert(gMainApp.exec_file); - uint32 entry = gRAM->LoadFile(gMainApp.host_file); + uint32 entry = gRAM->LoadFile(gMainApp.exec_file); if (entry) { text.Print("Host program loaded. Entry point = $%08x\n", entry); @@ -439,12 +382,12 @@ LunaPROMEmuDevice::LoadGuestFile(const b return 0; } - SCSIHD *hd = dynamic_cast(target); + SCSIDisk *hd = dynamic_cast(target); putmsg(2, "%s SCSIHD[%d] found", __func__, id); // +0 セクタ目(512byte)に Sun disklabel scd_dk_label dk; - if (hd->PeekImage(&dk, 0, sizeof(dk)) == false) { + if (hd->Peek(&dk, 0, sizeof(dk)) == false) { putmsg(0, "SCSIHD[%d] ReadSector failed", id); errmsg = string_format("dk%d Read disklabel failed.", dkunit); return 0;