--- nono/vm/romemu_luna1.cpp 2026/04/29 17:04:55 1.1.1.3 +++ nono/vm/romemu_luna1.cpp 2026/04/29 17:04:59 1.1.1.4 @@ -5,17 +5,25 @@ // // LUNA-I の ROM エミュレーション - -// IODevice -// | -// +----------+---------------------+ -// v v -// ROMDevice LunaPROMEmuDeivce (ROM エミュレーションの共通部分) -// | | -// | +------------+----------------+ -// v v v -// PROMDevice Luna1PROMEmuDevice Luna88kPROMEmuDevice -// (実ROM) (LUNA-I エミュレーション) (LUNA88K エミュレーション) +// +// 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 "romemu_luna1.h" #include "ethernet.h" @@ -33,7 +41,11 @@ Luna1PROMEmuDevice::Luna1PROMEmuDevice() // LUNA-I の ROM の特定アドレスを読み出す人がいるので、 // サイズは実 ROM と同じにしておく必要がある。 devlen = 128 * 1024; - romdata.reset(new uint8 [devlen]); + imagebuf.reset(new uint8 [devlen]); + memset(&imagebuf[0], 0, devlen); + mem = &imagebuf[0]; + + mask = devlen - 1; } // デストラクタ @@ -49,14 +61,16 @@ Luna1PROMEmuDevice::Init() return false; } - MemoryStreamBE ms(romdata.get()); + MemoryStreamBE ms(imagebuf.get()); ms.Write32(0x00002000); // +00: リセットベクタ SP ms.Write32(0x41000400); // +04: リセットベクタ PC ms.Write32(0); // +08 ms.Write32(0x41000500); // +0c: メモリサイズ格納先 // リセット時に実行する命令 - ms.SetPtr(&romdata[0x400]); + ms.SetPtr(&imagebuf[0x400]); + ms.Write16(0x13c0); // move.b d0,#0x41000000 ; RAMに切り替え + ms.Write32(0x41000000); ms.Write16(0x2039); // move.l (ROMIO_INIT),d0 ms.Write32(ROMIO_INIT); ms.Write16(0x660c); // bne _go ; 起動先あればGO @@ -73,15 +87,15 @@ Luna1PROMEmuDevice::Init() // Lv6 (SIO) 割り込みハンドラ // キーボード割り込みが上がったら KEYIN をコールする - ms.SetPtr(&romdata[0x600]); + ms.SetPtr(&imagebuf[0x600]); ms.Write16(0x4ab9); // tst.l (ROMIO_KEYIN) ms.Write32(ROMIO_KEYIN); // ; キー入力処理 ms.Write16(0x4e73); // rte // MAC アドレス const macaddr_t macaddr = gEthernet->GetMacAddr(); - strcpy((char *)&romdata[0x1ffd8], "ENADDR"); - memcpy(&romdata[0x1ffe0], macaddr.to_string().c_str(), 12); + strcpy((char *)&imagebuf[0x1ffd8], "ENADDR"); + memcpy(&imagebuf[0x1ffe0], macaddr.to_string().c_str(), 12); // RAM にベクタを書き込む // XXX VBR を 41000000 に向けるのとどっちが楽かはある @@ -93,8 +107,6 @@ Luna1PROMEmuDevice::Init() void Luna1PROMEmuDevice::ResetHard() { - inherited::ResetHard(); - x_executed = false; x_entrypoint = 0; } @@ -117,14 +129,14 @@ Luna1PROMEmuDevice::ROM_Init() // ROM 0x410000b8.L プレーンマスク格納先アドレス // メモリサイズはとりあえず 0x41000500 に格納 - ms.SetPtr(&romdata[0x500]); + ms.SetPtr(&imagebuf[0x500]); ms.Write32(gRAM->GetSize()); // プレーン数(1..4)をプレーンマスク(0x01..0x0f)に int nplane = gLunafb->GetPlaneCount(); int planemask = (1 << nplane) - 1; // 実際は RAM 上を指しているのだが、とりあえずすぐ隣に置いておく。 - ms.SetPtr(&romdata[0xb8]); + ms.SetPtr(&imagebuf[0xb8]); ms.Write32(0x410000bc); ms.Write32(planemask); @@ -148,7 +160,7 @@ Luna1PROMEmuDevice::ROM_Init() // DIPSW#1-1 が UP なら自動起動、DOWN なら ROM モニタ起動なので、 // これを真似する。 if ((gPIO0->GetDIPSW1() & 1)) { - if (gMainApp.host_file) { + if (gMainApp.exec_file) { // ホストのファイルを読み込んでエントリポイントアドレスを // この Read アクセスの読み出し値として返す。 // エラーがあればエラーメッセージは呼び出し先側で表示してある。 @@ -338,12 +350,12 @@ Luna1PROMEmuDevice::CommandG(const std:: } // "gh" コマンド (勝手に拡張) -// -A オプションで指定されたホストプログラムをロードする。 +// -X オプションで指定されたホストプログラムをロードする。 void Luna1PROMEmuDevice::CommandGH() { // 指定されてたら読み込む - if (gMainApp.host_file == NULL) { + if (gMainApp.exec_file == NULL) { text.Print("** Cannot loaded; host program is not specified.\n"); return; }