--- nono/vm/romemu_news.cpp 2026/04/29 17:05:24 1.1.1.2 +++ nono/vm/romemu_news.cpp 2026/04/29 17:05:28 1.1.1.3 @@ -8,6 +8,29 @@ // NEWS の ROM エミュレーション (-X のみ対応) // +// 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_news.h" #include "mainbus.h" #include "mainram.h" @@ -43,46 +66,46 @@ NewsROMEmuDevice::Init() mainram = GetMainRAMDevice(); - MemoryStreamBE ms(imagebuf.get()); - ms.Write32(0x00000400); // +00: リセットベクタ SP - ms.Write32(0xf8000400); // +04: リセットベクタ PC + MemoryStreamBE roms(imagebuf.get()); + roms.Write4(0x00000400); // +00: リセットベクタ SP + roms.Write4(0xf8000400); // +04: リセットベクタ PC // ベクタ for (int i = 2; i < 256; i++) { - ms.Write32(0); + roms.Write4(0); } - ms.SetOffset(32 * 4); - ms.Write32(0xf8000500); // Trap#0 で ROM のサービスコール + roms.SetOffset(32 * 4); + roms.Write4(0xf8000500); // Trap#0 で ROM のサービスコール // Trap#15 は ROM モニタらしい。今の所停止するだけ。 // とりあえず Trap#1..#14 も全部ここへ向けておく。 for (int i = 1; i < 16; i++) { - ms.Write32(0xf8000600); + roms.Write4(0xf8000600); } // リセット時に実行する命令 - ms.SetOffset(0x400); - ms.Write16(0x2039); // move.l (ROMIO_INIT),d0 - ms.Write32(ROMIO_INIT); - 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(0x2040); // move.l d0,a0 ; ジャンプ先を a0 にセット + roms.Write2(0x4ed0); // jmp (a0) ; ジャンプ // ROM サービスコール - ms.SetOffset(0x500); - ms.Write16(0x0c80); // cmpi.l #3,d0 - ms.Write32(0x00000003); // - ms.Write16(0x6708); // beq @f - ms.Write16(0x2039); // move.l (ROMIO_SYS),d0 - ms.Write32(ROMIO_SYS); // - ms.Write16(0x4e73); // rte + roms.SetOffset(0x500); + roms.Write2(0x0c80); // cmpi.l #3,d0 + roms.Write4(0x00000003); // + roms.Write2(0x6708); // beq @f + roms.Write2(0x2039); // move.l (ROMIO_SYS),d0 + roms.Write4(ROMIO_SYS); // + roms.Write2(0x4e73); // rte //@@: ; Read は対応してないので - ms.Write32(0x4e722500); // stop #0x2500 ; STOP しつつ - ms.Write16(0x60fa); // bra @b ; 無限ループ。 - ms.Write16(0x4e73); // rte + roms.Write4(0x4e722500); // stop #0x2500 ; STOP しつつ + roms.Write2(0x60fa); // bra @b ; 無限ループ。 + roms.Write2(0x4e73); // rte // ROM モニタの TRAP#n。はないのでここに来たらとりあえず停止する? - ms.SetOffset(0x600); + roms.SetOffset(0x600); //@@: - ms.Write32(0x4e722700); // stop #0x2700 ; STOP しつつ - ms.Write16(0x60fa); // bra @b ; 無限ループ。 + roms.Write4(0x4e722700); // stop #0x2700 ; STOP しつつ + roms.Write2(0x60fa); // bra @b ; 無限ループ。 return true; } @@ -91,26 +114,28 @@ void NewsROMEmuDevice::ResetHard(bool poweron) { // 起動時に RAM にリセットベクタを書き込んでおく。(手抜き) - for (int i = 0; i < 8; i++) { - mainram->Write8(i, imagebuf[i]); - } + mainram->WriteMem(0, &imagebuf[0], 8); } -busdata -NewsROMEmuDevice::Read32(uint32 addr) +// ROMIO から読み出す。 +// ROMIO が応答すべきでなければ (uint64)-1 を返す。 +uint64 +NewsROMEmuDevice::ReadROMIO(busaddr addr) { - switch (addr) { - case ROMIO_INIT: - return ROM_Init(); + if (addr.GetSize() == 4) { + switch (addr.Addr()) { + case ROMIO_INIT: + return ROM_Init(); - case ROMIO_SYS: - return ROM_Sys(); + case ROMIO_SYS: + return ROM_Sys(); - default: - break; + default: + break; + } } - return inherited::Read32(addr); + return (uint64)-1; } uint32 @@ -162,12 +187,12 @@ NewsROMEmuDevice::ROM_Sys() if (reg.D[0] == SYS_write) { uint32 a6 = reg.A[6]; - uint32 fd = mainbus->HVRead32(a6 + 8); - uint32 buf = mainbus->HVRead32(a6 + 12); - uint32 len = mainbus->HVRead32(a6 + 16); + uint32 fd = mainbus->HVRead4(a6 + 8); + uint32 buf = mainbus->HVRead4(a6 + 12); + uint32 len = mainbus->HVRead4(a6 + 16); for (int i = 0; i < len; i++) { - busdata bd = mainbus->HVRead8(buf++); + busdata bd = mainbus->HVRead1(buf++); if (bd.IsBusErr()) { // XXX ? return 0;