--- nono/vm/romimg_x68k.cpp 2026/04/29 17:04:32 1.1 +++ nono/vm/romimg_x68k.cpp 2026/04/29 17:05:11 1.1.1.8 @@ -1,29 +1,159 @@ // // nono -// Copyright (C) 2019 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// 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" -#include "mystring.h" -#include "pluto.h" -#include "scheduler.h" + +// グローバル参照用 +CGROMDevice *gCGROM; +IPLROM0Device *gIPLROM0; +IPLROM1Device *gIPLROM1; +IPLROM2Device *gIPLROM2; + +// +// IPLROM0 +// +// IPLROM0 は IPLROM(1) のブートページ担当。 +// これ自身はメモリ領域を持たず IPLROM1 へのプロキシとして動作する。 +// +// X680x0 のブートページは $000000..$00ffff の 64KB で、 +// ここへのアクセスは $ff0000..$ffffff (IPLROM1 の後半 64KB) が見える。 +// ROM へアクセスがあればブートページを RAM に切り替える。 +// そのため、RAM 側も ROM 側もこいつが応対する必要がある。 + +// コンストラクタ +IPLROM0Device::IPLROM0Device() + : inherited("IPLROM(BOOT)") +{ + ClearAlias(); + AddAlias("IPLROMBOOT"); +} + +// デストラクタ +IPLROM0Device::~IPLROM0Device() +{ + gIPLROM0 = NULL; +} + +bool +IPLROM0Device::Init() +{ + iplrom1 = gIPLROM1; + return true; +} + +// リセット +void +IPLROM0Device::ResetHard(bool poweron) +{ + 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) +{ + addr = ReadDecoder(addr); + return iplrom1->Read8(addr); +} + +uint64 +IPLROM0Device::Read16(uint32 addr) +{ + addr = ReadDecoder(addr); + return iplrom1->Read16(addr); +} + +uint64 +IPLROM0Device::Read32(uint32 addr) +{ + addr = ReadDecoder(addr); + return iplrom1->Read32(addr); +} + +// Write は RAM 領域へも ROM 領域へも発生しないはずなので基底のを使う。 + +uint64 +IPLROM0Device::Peek8(uint32 addr) +{ + addr |= 0xff0000; + return iplrom1->Peek8(addr); +} + // // IPLROM(1) // +// コンストラクタ IPLROM1Device::IPLROM1Device() + : inherited("IPLROM(1)") { - devname = "IPLROM(1)"; + ClearAlias(); + AddAlias("IPLROM1"); + devaddr = 0xfe0000; devlen = 0x020000; mask = devlen - 1; + + // X680x0 では ROM への書き込みはバスエラー + write_op = -1; } +// デストラクタ IPLROM1Device::~IPLROM1Device() { + gIPLROM1 = NULL; } bool @@ -48,16 +178,25 @@ IPLROM1Device::Init() // IPLROM(2) // +// コンストラクタ IPLROM2Device::IPLROM2Device() + : inherited("IPLROM(2)") { - devname = "IPLROM(2)"; + ClearAlias(); + AddAlias("IPLROM2"); + devaddr = 0xfc0000; devlen = 0x020000; mask = devlen - 1; + + // X680x0 では ROM への書き込みはバスエラー + write_op = -1; } +// デストラクタ IPLROM2Device::~IPLROM2Device() { + gIPLROM2 = NULL; } bool @@ -78,16 +217,22 @@ IPLROM2Device::Init() // CGROM // +// コンストラクタ CGROMDevice::CGROMDevice() + : inherited("CGROM") { - devname = "CGROM"; devaddr = 0xf00000; devlen = 768 * 1024; mask = 1024 * 1024 - 1; + + // X680x0 では ROM への書き込みはバスエラー + write_op = -1; } +// デストラクタ CGROMDevice::~CGROMDevice() { + gCGROM = NULL; } bool