--- nono/vm/romimg_x68k.cpp 2026/04/29 17:04:59 1.1.1.7 +++ nono/vm/romimg_x68k.cpp 2026/04/29 17:05:29 1.1.1.12 @@ -4,49 +4,49 @@ // 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 のブートページ切り替え用プロキシ) -// +---------------+ +// | +// +- 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 "romimg_x68k.h" -#include "cgrom.h" -#include "mainapp.h" -#include "pluto.h" -#include "scheduler.h" - -std::unique_ptr gCGROM; -std::unique_ptr gIPLROM0; -std::unique_ptr gIPLROM1; -std::unique_ptr gIPLROM2; +#include "builtinrom.h" +#include "config.h" +#include "mainbus.h" // +// IPLROM0 +// // IPLROM0 は IPLROM(1) のブートページ担当。 // これ自身はメモリ領域を持たず IPLROM1 へのプロキシとして動作する。 // @@ -55,28 +55,38 @@ std::unique_ptr gIPLROM2; // ROM へアクセスがあればブートページを RAM に切り替える。 // そのため、RAM 側も ROM 側もこいつが応対する必要がある。 +// コンストラクタ IPLROM0Device::IPLROM0Device() - : inherited("IPLROM(0)") + : inherited(OBJ_IPLROM_BOOT) { + // 通常ここからログを出すことはない ClearAlias(); - AddAlias("IPLROM0"); } +// デストラクタ IPLROM0Device::~IPLROM0Device() { } +// 初期化 bool IPLROM0Device::Init() { - iplrom1 = gIPLROM1.get(); + if (inherited::Init() == false) { + return false; + } + + iplrom1 = GetIPLROM1Device(); + return true; } +// リセット void -IPLROM0Device::ResetHard() +IPLROM0Device::ResetHard(bool poweron) { - gVM->SwitchBootPageToROM(this); + auto mainbus = GetMainbusDevice(); + mainbus->SwitchBootPageToROM(); } // Read の共通処理。 @@ -86,117 +96,110 @@ IPLROM0Device::ReadDecoder(uint32 addr) { // ROM アドレスがアクセスされたら切り替える if (addr >= 0xff0000) { - gVM->SwitchBootPageToRAM(this); + auto mainbus = GetMainbusDevice(); + mainbus->SwitchBootPageToRAM(); } // どちらにしてもアクセスは ROM のアドレス return addr | 0xff0000; } -uint64 -IPLROM0Device::Read8(uint32 addr) -{ - addr = ReadDecoder(addr); - return iplrom1->Read8(addr); -} - -uint64 -IPLROM0Device::Read16(uint32 addr) -{ - addr = ReadDecoder(addr); - return iplrom1->Read16(addr); -} - -uint64 -IPLROM0Device::Read32(uint32 addr) +busdata +IPLROM0Device::Read(busaddr addr) { - addr = ReadDecoder(addr); - return iplrom1->Read32(addr); + addr.ChangeAddr(ReadDecoder(addr.Addr())); + return iplrom1->Read(addr); } // Write は RAM 領域へも ROM 領域へも発生しないはずなので基底のを使う。 -uint64 -IPLROM0Device::Peek8(uint32 addr) +busdata +IPLROM0Device::Peek1(uint32 addr) { addr |= 0xff0000; - return iplrom1->Peek8(addr); + return iplrom1->Peek1(addr); } // -// IPLROM(1) +// IPLROM(1) 0xfe0000..0xffffff 担当 // +// コンストラクタ IPLROM1Device::IPLROM1Device() - : inherited("IPLROM(1)") + : inherited(OBJ_IPLROM1) { - ClearAlias(); - AddAlias("IPLROM1"); - - devaddr = 0xfe0000; - devlen = 0x020000; - mask = devlen - 1; - // X680x0 では ROM への書き込みはバスエラー write_op = -1; } +// デストラクタ IPLROM1Device::~IPLROM1Device() { } +// 初期化 bool IPLROM1Device::Init() { + if (inherited::Init() == false) { + return false; + } + std::string name; + uint devlen = 0x020000; + mask = devlen - 1; - if (gMainApp.benchmark_mode != 0) { - name = string_format("BENCH%02d.ROM", gMainApp.benchmark_mode); - } else { - name = "IPLROM30.DAT"; + const ConfigItem& item = gConfig->Find("iplrom1-image"); + name = item.AsString(); + if (name.empty()) { + // 指定がなければ、内蔵 IPLROM を使う。 + mem = Builtin::IPLROM30; + return true; } - if (LoadROM(name.c_str(), 128 * 1024) == false) { - return false; - } - return true; + // 外部ファイルが指定されれば、それを使う。 + return LoadROM(name.c_str(), devlen); } // -// IPLROM(2) +// IPLROM(2) 0xfc0000..0xfdffff 担当 // +// コンストラクタ IPLROM2Device::IPLROM2Device() - : inherited("IPLROM(2)") + : inherited(OBJ_IPLROM2) { - ClearAlias(); - AddAlias("IPLROM2"); - - devaddr = 0xfc0000; - devlen = 0x020000; - mask = devlen - 1; - // X680x0 では ROM への書き込みはバスエラー write_op = -1; } +// デストラクタ IPLROM2Device::~IPLROM2Device() { } +// 初期化 bool IPLROM2Device::Init() { - if (gMainApp.benchmark_mode != 0) { - return true; + if (inherited::Init() == false) { + return false; } - if (LoadROM("ROM30.DAT", 128 * 1024) == false) { + uint devlen = 0x020000; + mask = devlen - 1; + + const ConfigItem& item = gConfig->Find("iplrom2-image"); + std::string name = item.AsString(); + if (name.empty()) { + printf("iplrom2: not yet\n"); return false; } - return true; + + // 外部ファイルが指定されれば、それを使う。 + return LoadROM(name.c_str(), devlen); } @@ -204,30 +207,56 @@ IPLROM2Device::Init() // CGROM // +// コンストラクタ CGROMDevice::CGROMDevice() - : inherited("CGROM") + : inherited(OBJ_CGROM) { - devaddr = 0xf00000; - devlen = 768 * 1024; - mask = 1024 * 1024 - 1; - // X680x0 では ROM への書き込みはバスエラー write_op = -1; } +// デストラクタ CGROMDevice::~CGROMDevice() { } +// 初期化 bool CGROMDevice::Init() { -#if 0 - mem = builtin_cgrom; -#else - if (LoadROM("CGROM30.DAT", 768 * 1024) == false) { + if (inherited::Init() == false) { return false; } -#endif + + uint devlen = 768 * 1024; + mask = 1024 * 1024 - 1; + + const ConfigItem& item = gConfig->Find("cgrom-image"); + std::string name = item.AsString(); + if (name.empty()) { + // 指定がなければ、内蔵 CGROM を使う。 + mem = Builtin::CGROM; + return true; + } + + // 外部ファイルが指定されれば、それを使う。 + if (LoadROM(name.c_str(), devlen) == false) { + // 指定したファイルが読めなければエラー。 + return false; + } + + // X68030 の CGROM には、X68000 のものには収録されていない 6x12 フォント + // が収録されている。6x12 フォント以外は(たぶん)同じなのでほとんどの場面 + // で困ることはないが、それ故に忘れた頃に一部の文字だけ表示されなくて + // 「???」ということになりがちなので、6x12 フォントが収録されてなさそう + // なら警告を出しておく (処理は続行する)。 + uint8 val = 0; + for (int i = 0; i < 12; i++) { + val |= imagebuf[0xbf400 + ('0' * 12) + i]; + } + if (val == 0) { + warnx("warning: 6x12 font not found in CGROM30.DAT"); + } + return true; }