--- nono/vm/romemu_virt68k.cpp 2026/04/29 17:05:24 1.1.1.1 +++ nono/vm/romemu_virt68k.cpp 2026/04/29 17:05:28 1.1.1.2 @@ -5,12 +5,35 @@ // // -// virt68k の IPLROM 相当の何か +// virt-m68k の IPLROM 相当の何か // +// IODevice +// | +// +- ROMDevice (LoadROM()、ウェイト、マスク等を持つ) +// | +- PROMDevice (LUNA* の PROM) +// | +- IPLROM1Device (X680x0 の IPLROM 後半) +// | +- IPLROM2Device (X680x0 の IPLROM 前半) +// | +- CGROMDevice (X680x0 の CGROM) +// | | +// | +- ROMEmuDevice +// | +- LunaPROMEmuDevice (LUNA PROM エミュレーションの共通部分) +// | | +- Luna1PROMEmuDevice (LUNA-I の PROM エミュレーション) +// | | +- Luna88kPROMEmuDevice (LUNA-88K の PROM エミュレーション) +// | +- NewsROMEmuDevice (NEWS の ROM エミュレーション) +// | +- ROM30EmuDevice (X68030 の ROM30 エミュレーション) +// | | +// | | +---------------------+ +// | +-| Virt68kROMEmuDevice | (virt-m68k の IPLROM 相当の何か) +// | +---------------------+ +// | +// +- PROM0Device (LUNA* のブートページ切り替え用プロキシ) +// +- IPLROM0Device (X680x0 のブートページ切り替え用プロキシ) + #include "romemu_virt68k.h" #include "autofd.h" #include "config.h" +#include "iodevstream.h" #include "mainapp.h" #include "mainram.h" #include "memorystream.h" @@ -47,26 +70,26 @@ Virt68kROMEmuDevice::Init() mainram = GetMainRAMDevice(); - MemoryStreamBE ms(imagebuf.get()); - ms.Write32(0x00001000); // +00: リセットベクタ SP - ms.Write32(0xff000400); // +04: リセットベクタ PC + MemoryStreamBE roms(imagebuf.get()); + roms.Write4(0x00001000); // +00: リセットベクタ SP + roms.Write4(0xff000400); // +04: リセットベクタ PC // ベクタ for (int i = 2; i < 256; i++) { - ms.Write32(0); + roms.Write4(0); } // リセット時に実行する命令 - ms.SetOffset(0x400); - ms.Write16(0x2039); // move.l (ROMIO_INIT),d0 - ms.Write32(ROMIO_INIT); - ms.Write16(0x0c80); // cmpi.l #0xffffffff,d0 - ms.Write32(0xffffffff); - ms.Write16(0x6704); // beq @f - ms.Write16(0x2040); // move.l d0,a0 ; ジャンプ先を a0 にセット - ms.Write16(0x4ed0); // jmp (a0) ; ジャンプ + roms.SetOffset(0x400); + roms.Write2(0x2039); // move.l (ROMIO_INIT),d0 + roms.Write4(ROMIO_INIT); + roms.Write2(0x0c80); // cmpi.l #0xffffffff,d0 + roms.Write4(0xffffffff); + roms.Write2(0x6704); // beq @f + roms.Write2(0x2040); // move.l d0,a0 ; ジャンプ先を a0 にセット + roms.Write2(0x4ed0); // jmp (a0) ; ジャンプ //@@: - ms.Write32(0x4e722700); // stop #0x2700 - ms.Write16(0x67fc); // bra @b + roms.Write4(0x4e722700); // stop #0x2700 + roms.Write2(0x67fc); // bra @b return true; } @@ -75,23 +98,25 @@ void Virt68kROMEmuDevice::ResetHard(bool poweron) { // 起動時に RAM にリセットベクタを書き込んでおく。(手抜き) - for (int i = 0; i < 8; i++) { - mainram->Write8(i, imagebuf[i]); - } + mainram->WriteMem(0, &imagebuf[0], 8); } -busdata -Virt68kROMEmuDevice::Read32(uint32 addr) +// ROMIO から読み出す。 +// ROMIO が応答すべきでなければ (uint64)-1 を返す。 +uint64 +Virt68kROMEmuDevice::ReadROMIO(busaddr addr) { - switch (addr) { - case ROMIO_INIT: - return ROM_Init(); + if (addr.GetSize() == 4) { + switch (addr.Addr()) { + case ROMIO_INIT: + return ROM_Init(); - default: - break; + default: + break; + } } - return inherited::Read32(addr); + return (uint64)-1; } uint32 @@ -211,8 +236,8 @@ BootInfo::GetLong(uint32 offset) const // 伝統的な(?) NetBSD アーキテクチャは、ブートローダからカーネルへの // パラメータはレジスタ渡しかスタック渡しでアーキテクチャごとに固定の // フォーマットになっている。少なくともいくつかの m68k では。 -// NetBSD/virt68k では Linux/m68k の方式を採用しているようだ。QEMU が -// そうしてくるからそう受け取らざるを得なかったということかも知れないが。 +// NetBSD/virt68k では Linux/m68k の方式を採用しているようだが、 +// これは virt-m68k がそういう仕様だから。 // // NetBSD/virt68k のブートパラメータ BootInfo は、カーネルがロードされた // セクションの末尾 (リンカによってアドレスが求まる) 以降の次のロングワード @@ -488,13 +513,13 @@ Virt68kROMEmuDevice::WriteBootInfo(IODev break; } putmsg(1, "BootInfo $%08x: %-14s: %s", - stream.GetAddr(), tagname.c_str(), buf.c_str()); + stream.GetOffset(), tagname.c_str(), buf.c_str()); } // 出力。 - stream.Write16(bi.bi_tag); - stream.Write16(size); + stream.Write2(bi.bi_tag); + stream.Write2(size); for (const auto c : bi.bi_data) { - stream.Write8(c); + stream.Write1(c); } }