--- nono/vm/romemu_luna1.cpp 2026/04/29 17:05:24 1.1.1.9 +++ nono/vm/romemu_luna1.cpp 2026/04/29 17:05:28 1.1.1.10 @@ -9,23 +9,28 @@ // // IODevice -// | -// +-- ROMDevice (LoadROM()、ウェイト、マスク等を持つ) -// | | -// | +-- PROMDevice (LUNA* の PROM) -// | +-- IPLROM1Device (X680x0 の IPLROM 後半) -// | +-- IPLROM2Device (X680x0 の IPLROM 前半) -// | +-- CGROMDevice (X680x0 の CGROM) -// | +-- LunaPROMEmuDevice (LUNA PROM エミュレーションの共通部分) -// | | -// | | +--------------------+ -// | +--| Luna1PROMEmuDevice | (LUNA-I の PROM エミュレーション) -// | | +--------------------+ -// | | -// | +-- Luna88kPROMEmuDevice (LUNA-88K の 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 のブートページ切り替え用プロキシ) // ROM マップ // @@ -52,13 +57,12 @@ #include "romemu_luna1.h" #include "bt45x.h" #include "ethernet.h" +#include "iodevstream.h" #include "mainapp.h" -#include "mainbus.h" #include "mainram.h" #include "memorystream.h" #include "mk48t02.h" #include "mpu680x0.h" -#include "pio.h" #include "sysclk.h" // コンストラクタ @@ -91,83 +95,84 @@ Luna1PROMEmuDevice::Init() SysClkDevice *sysclk = GetSysClkDevice(); - MemoryStreamBE ms(imagebuf.get()); - ms.Write32(0x00002000); // +00: リセットベクタ SP - ms.Write32(0x41000400); // +04: リセットベクタ PC - ms.Write32(0); // +08 - ms.Write32(0x41000010); // +0c: メモリサイズ格納先 + MemoryStreamBE roms(imagebuf.get()); + roms.Write4(0x00002000); // +00: リセットベクタ SP + roms.Write4(0x41000400); // +04: リセットベクタ PC + roms.Write4(0); // +08 + roms.Write4(0x41000010); // +0c: メモリサイズ格納先 // +10: 値は ROM_Init() でセット - ms.SetOffset(0xb8); - ms.Write32(0x410000bc); // +b8: プレーンマスク格納先 + roms.SetOffset(0xb8); + roms.Write4(0x410000bc); // +b8: プレーンマスク格納先 // +bc: 値は ROM_Init() でセット // リセット時に実行する命令 - ms.SetOffset(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(0x2039); // move.l (ROMIO_LOAD),d0 - ms.Write32(ROMIO_LOAD); - ms.Write16(0x72ff); // moveq.l #0xffffffff,d1 - ms.Write16(0x6004); // bra _entry + roms.SetOffset(0x400); + roms.Write2(0x13c0); // move.b d0,#0x41000000 ; RAMに切り替え + roms.Write4(0x41000000); + roms.Write2(0x2039); // move.l (ROMIO_INIT),d0 + roms.Write4(ROMIO_INIT); + roms.Write2(0x2039); // move.l (ROMIO_LOAD),d0 + roms.Write4(ROMIO_LOAD); + roms.Write2(0x72ff); // moveq.l #0xffffffff,d1 + roms.Write2(0x6004); // bra _entry //_prompt: - uint32 _prompt = ms.GetOffset(); - ms.Write32(0x4e722500); // stop #0x2500 ; キー入力を待つ + uint32 _prompt = roms.GetOffset(); + roms.Write4(0x4e722500); // stop #0x2500 ; キー入力を待つ //_entry: - ms.Write16(0x2039); // move.l (ROMIO_ENTRY),d0 - ms.Write32(ROMIO_ENTRY); // ; エントリポイント取得 - ms.Write16(0xb081); // cmp.l d1,d0 - ms.Write16(0x67f2); // beq _prompt ; 起動先なければループ + roms.Write2(0x2039); // move.l (ROMIO_ENTRY),d0 + roms.Write4(ROMIO_ENTRY); // ; エントリポイント取得 + roms.Write2(0xb081); // cmp.l d1,d0 + roms.Write2(0x67f2); // beq _prompt ; 起動先なければループ //_go: - ms.Write16(0x2040); // move.l d0,a0 ; ジャンプ先を a0 にセット - ms.Write16(0x2039); // move.l (ROMIO_CLOSE),d0 - ms.Write32(ROMIO_CLOSE); // ; 後始末 - ms.Write16(0x4ed0); // jmp (a0) ; ジャンプ + roms.Write2(0x2040); // move.l d0,a0 ; ジャンプ先を a0 にセット + roms.Write2(0x2039); // move.l (ROMIO_CLOSE),d0 + roms.Write4(ROMIO_CLOSE); // ; 後始末 + roms.Write2(0x4ed0); // jmp (a0) ; ジャンプ // Lv5 (Sysclk) 割り込みハンドラ。 - ms.SetOffset(0x500); - ms.Write16(0x13c0); // move.b d0,#0x63000000 ; ACK - ms.Write32(0x63000000); - ms.Write16(0x52b9); // addq.l #1,(ROMIO_CLKCNT) - ms.Write32(ROMIO_CLKCNT); - ms.Write16(0x4e73); // rte + roms.SetOffset(0x500); + roms.Write2(0x13c0); // move.b d0,#0x63000000 ; ACK + roms.Write4(0x63000000); + roms.Write2(0x52b9); // addq.l #1,(ROMIO_CLKCNT) + roms.Write4(ROMIO_CLKCNT); + roms.Write2(0x4e73); // rte // Lv6 (SIO) 割り込みハンドラ // キーボード割り込みが上がったら KEYIN をコールする - ms.SetOffset(0x600); - ms.Write16(0x4ab9); // tst.l (ROMIO_KEYIN) - ms.Write32(ROMIO_KEYIN); // ; キー入力処理 - ms.Write16(0x4e73); // rte + roms.SetOffset(0x600); + roms.Write2(0x4ab9); // tst.l (ROMIO_KEYIN) + roms.Write4(ROMIO_KEYIN); // ; キー入力処理 + roms.Write2(0x4e73); // rte // NMI のハンドラ - ms.SetOffset(0x700); - ms.Write32(0x46fc2700); // move.w #0x2700,sr - ms.Write16(0x91c8); // suba.l a0,a0 - ms.Write32(0x4e7b8801); // movec a0,vbr - ms.Write16(0x2e50); // movea.l (a0),sp - ms.Write16(0x4ef9); // jmp _prompt - ms.Write32(0x41000000 + _prompt); + roms.SetOffset(0x700); + roms.Write4(0x46fc2700); // move.w #0x2700,sr + roms.Write2(0x91c8); // suba.l a0,a0 + roms.Write4(0x4e7b8801); // movec a0,vbr + roms.Write2(0x2e50); // movea.l (a0),sp + roms.Write2(0x4ef9); // jmp _prompt + roms.Write4(0x41000000 + _prompt); // デフォルトのハンドラ - ms.SetOffset(0x800); - ms.Write16(0x4e73); // rte + roms.SetOffset(0x800); + roms.Write2(0x4e73); // rte // サブルーチン - ms.SetOffset(0x900); //_ap1: - ms.Write16(0x2039); // move.l (ROMIO_AP1),d0 - ms.Write32(ROMIO_AP1); // - int freq = sysclk->GetFreq(); - ms.Write16(0x7200 + freq*3);// moveq.l #(CLK_FREQ*3),d1 + roms.SetOffset(0x900); //_ap1: + roms.Write2(0x2039); // move.l (ROMIO_AP1),d0 + roms.Write4(ROMIO_AP1); // + uint freq = sysclk->GetFreq(); + roms.Write2(0x7200 + freq * 3); + // moveq.l #(CLK_FREQ*3),d1 //@@: - ms.Write32(0x4e722400); // stop #0x2400 ; クロック入力を待つ - ms.Write16(0x2039); // move.l (ROMIO_CLKCNT),d0 - ms.Write32(ROMIO_CLKCNT); - ms.Write16(0xb001); // cmp.b d1,d0 - ms.Write16(0x66f2); // bne @b - ms.Write16(0x2039); // move.l (ROMIO_AP2),d0 - ms.Write32(ROMIO_AP2); // - ms.Write16(0x4e75); // rts + roms.Write4(0x4e722400); // stop #0x2400 ; クロック入力を待つ + roms.Write2(0x2039); // move.l (ROMIO_CLKCNT),d0 + roms.Write4(ROMIO_CLKCNT); + roms.Write2(0xb001); // cmp.b d1,d0 + roms.Write2(0x66f2); // bne @b + roms.Write2(0x2039); // move.l (ROMIO_AP2),d0 + roms.Write4(ROMIO_AP2); // + roms.Write2(0x4e75); // rts // MAC アドレス macaddr_t macaddr; @@ -186,42 +191,41 @@ Luna1PROMEmuDevice::Init() void Luna1PROMEmuDevice::ROM_InitMD() { - MemoryStreamBE ms(imagebuf.get()); + IODeviceStream rams(mainram); + MemoryStreamBE roms(imagebuf.get()); // +0010: メモリサイズ - ms.SetOffset(0x10); - ms.Write32(mainram->GetSize()); + roms.SetOffset(0x10); + roms.Write4(mainram->GetSize()); // プレーン数(1,4,8)をプレーンマスク(0x01, 0x0f, 0xff)に int nplane = bt45x->GetPlaneCount(); int planemask = (1 << nplane) - 1; // プレーンマスク。実際は RAM に書き込まれるがとりあえず - ms.SetOffset(0xbc); - ms.Write32(planemask); + roms.SetOffset(0xbc); + roms.Write4(planemask); // RAM にベクタを書き込む - ms.SetOffset(0); - mainram->Write32(0, ms.Read32()); // ROM のリセットベクタをコピー - mainram->Write32(4, ms.Read32()); - - for (int i = 2; i < 256; i++) { // デフォルトベクタで埋める - mainram->Write32(i * 4, 0x41000800); - } - mainram->Write32(0x74, 0x41000500); // +74: Lv5 割り込み - mainram->Write32(0x78, 0x41000600); // +78: Lv6 割り込み - mainram->Write32(0x7c, 0x41000700); // +7c: Lv7 割り込み = RESET + roms.SetOffset(0); + rams.SetOffset(0); + rams.Write4(roms.Read4()); // ROM のリセットベクタをコピー + rams.Write4(roms.Read4()); + for (uint i = 2; i < 256; i++) { // デフォルトベクタで埋める + rams.Write4(0x41000800); + } + rams.Write4(0x74, 0x41000500); // +74: Lv5 割り込み + rams.Write4(0x78, 0x41000600); // +78: Lv6 割り込み + rams.Write4(0x7c, 0x41000700); // +7c: Lv7 割り込み = RESET prompt_idx = 0; prompt = default_prompt; - uint32 ap = (nvram->Peek(0x7fd) << 8) | nvram->Peek(0x7fe); + uint32 ap = (nvram->PeekPort(0x7fd) << 8) | nvram->PeekPort(0x7fe); if (__predict_false(0||(ap & 0x3f1f) == 0x0104)) { - auto mainbus = GetMainbusDevice(); auto mpu680x0 = GetMPU680x0Device(mpu); m68kreg& reg = mpu680x0->reg; reg.A[7] -= 4; - // スタックはワードアラインなので HV 系でアクセス。 - mainbus->HVWrite32(reg.A[7], reg.pc); + rams.Write4(reg.A[7], reg.pc); reg.pc = 0x41000900; } } @@ -305,7 +309,7 @@ Luna1PROMEmuDevice::Command() std::vector arg; // 1ワードごとに分解 - strcpy(&buf[0], inputbuf.c_str()); + strlcpy(buf.data(), inputbuf.c_str(), buf.size()); char *p = &buf[0]; for (char *ap; (ap = strsep(&p, " ")) != NULL; ) { if (*ap != '\0') { @@ -314,7 +318,7 @@ Luna1PROMEmuDevice::Command() } if (loglevel >= 1) { for (int i = 0; i < arg.size(); i++) { - putmsgn("arg[%d]=|%s|", i, arg[i].c_str()); + putmsgn("arg[%u]=|%s|", i, arg[i].c_str()); } } @@ -618,10 +622,10 @@ Luna1PROMEmuDevice::GetNVRAM(bootinfo_t& // DKUNIT が装置番号(今はまだ SCSI ID=6 固定)。 // DKPART が 'a'..'h' でパーティション。 // DKFILE が読み込む次段プログラム (NetBSD では通常 /boot のこと)。 - bootinfo.dkunit = nvram->Peek(0x0090) - '0'; - bootinfo.dkpart = nvram->Peek(0x00b0) - 'a'; + bootinfo.dkunit = nvram->PeekPort(0x0090) - '0'; + bootinfo.dkpart = nvram->PeekPort(0x00b0) - 'a'; bootinfo.dkfile = nvram->PeekString(0x00d0); - putmsg(1, "%s DKUNIT=%d", __func__, bootinfo.dkunit); + putmsg(1, "%s DKUNIT=%u", __func__, bootinfo.dkunit); putmsg(1, "%s DKPART=%c", __func__, bootinfo.dkpart + 'a'); putmsg(1, "%s DKFILE=|%s|", __func__, bootinfo.dkfile.c_str()); }