--- nono/vm/romimg_x68k.cpp 2026/04/29 17:04:55 1.1.1.6 +++ nono/vm/romimg_x68k.cpp 2026/04/29 17:04:59 1.1.1.7 @@ -4,6 +4,37 @@ // Licensed under nono-license.txt // +// X680x0 の各種 ROM +// +// 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 "romimg_x68k.h" #include "cgrom.h" #include "mainapp.h" @@ -29,8 +60,6 @@ IPLROM0Device::IPLROM0Device() { ClearAlias(); AddAlias("IPLROM0"); - - mask = 0x10000 - 1; } IPLROM0Device::~IPLROM0Device() @@ -47,40 +76,42 @@ IPLROM0Device::Init() void IPLROM0Device::ResetHard() { - gVM->SwitchBootPage(this, true); + gVM->SwitchBootPageToROM(this); +} + +// Read の共通処理。 +// アドレスのデコードと RAM への切り替え判定を行う。 +uint32 +IPLROM0Device::ReadDecoder(uint32 addr) +{ + // ROM アドレスがアクセスされたら切り替える + if (addr >= 0xff0000) { + gVM->SwitchBootPageToRAM(this); + } + + // どちらにしてもアクセスは ROM のアドレス + return addr | 0xff0000; } uint64 IPLROM0Device::Read8(uint32 addr) { - if (addr < 0x10000) { - return iplrom1->Read8(addr + 0x10000); - } else { - gVM->SwitchBootPage(this, false); - return iplrom1->Read8(addr); - } + addr = ReadDecoder(addr); + return iplrom1->Read8(addr); } uint64 IPLROM0Device::Read16(uint32 addr) { - if (addr < 0x10000) { - return iplrom1->Read16(addr + 0x10000); - } else { - gVM->SwitchBootPage(this, false); - return iplrom1->Read16(addr); - } + addr = ReadDecoder(addr); + return iplrom1->Read16(addr); } uint64 IPLROM0Device::Read32(uint32 addr) { - if (addr < 0x10000) { - return iplrom1->Read32(addr + 0x10000); - } else { - gVM->SwitchBootPage(this, false); - return iplrom1->Read32(addr); - } + addr = ReadDecoder(addr); + return iplrom1->Read32(addr); } // Write は RAM 領域へも ROM 領域へも発生しないはずなので基底のを使う。 @@ -88,11 +119,8 @@ IPLROM0Device::Read32(uint32 addr) uint64 IPLROM0Device::Peek8(uint32 addr) { - if (addr < 0x10000) { - return iplrom1->Peek8(addr + 0x10000); - } else { - return iplrom1->Peek8(addr); - } + addr |= 0xff0000; + return iplrom1->Peek8(addr); } @@ -109,6 +137,9 @@ IPLROM1Device::IPLROM1Device() devaddr = 0xfe0000; devlen = 0x020000; mask = devlen - 1; + + // X680x0 では ROM への書き込みはバスエラー + write_op = -1; } IPLROM1Device::~IPLROM1Device() @@ -146,6 +177,9 @@ IPLROM2Device::IPLROM2Device() devaddr = 0xfc0000; devlen = 0x020000; mask = devlen - 1; + + // X680x0 では ROM への書き込みはバスエラー + write_op = -1; } IPLROM2Device::~IPLROM2Device() @@ -176,6 +210,9 @@ CGROMDevice::CGROMDevice() devaddr = 0xf00000; devlen = 768 * 1024; mask = 1024 * 1024 - 1; + + // X680x0 では ROM への書き込みはバスエラー + write_op = -1; } CGROMDevice::~CGROMDevice()