--- nono/vm/romemu_virt68k.cpp 2026/04/29 17:05:28 1.1.1.2 +++ nono/vm/romemu_virt68k.cpp 2026/04/29 17:05:59 1.1.1.6 @@ -37,6 +37,8 @@ #include "mainapp.h" #include "mainram.h" #include "memorystream.h" +#include "mpu680x0.h" +#include "power.h" #include #include #include @@ -46,13 +48,6 @@ Virt68kROMEmuDevice::Virt68kROMEmuDevice() : inherited(OBJ_PROM) { - // 適当 - uint devlen = 4096; - imagebuf.reset(new uint8 [devlen]); - memset(&imagebuf[0], 0, devlen); - - mem = &imagebuf[0]; - mask = devlen - 1; } // デストラクタ @@ -64,7 +59,9 @@ Virt68kROMEmuDevice::~Virt68kROMEmuDevic bool Virt68kROMEmuDevice::Init() { - if (inherited::Init() == false) { + // ROM 領域を用意。サイズは適当。 + if (AllocROM(2048, 0) == false) { + // エラーメッセージは表示済み。 return false; } @@ -130,8 +127,10 @@ Virt68kROMEmuDevice::ROM_Init() // カーネル側もそのように想定しているようだ。 info.loadsym = false; - if (mainram->LoadExec(&info) == false) { - warnx("** Couldn't load specified host program."); + if (BootLoader::LoadExec(mainram, &info) == false) { + // エラーメッセージは表示済み。 + auto power = GetPowerDevice(); + power->PushPowerButton(); return -1; } @@ -158,9 +157,11 @@ class BootInfo void Init(uint16 tag_, uint32 val_); void AddWord(uint32 val_); void AddLong(uint32 val_); + void AddString(const char *val_); uint32 GetWord(uint32 offset) const; uint32 GetLong(uint32 offset) const; + const char *GetString() const { return (const char *)bi_data.data(); } }; // コンストラクタ @@ -204,6 +205,16 @@ BootInfo::AddLong(uint32 val_) bi_data.push_back(val_); } +// データに文字列を追加する。 +void +BootInfo::AddString(const char *val_) +{ + for (const char *s = val_; *s; s++) { + bi_data.push_back(*s); + } + bi_data.push_back('\0'); +} + // offset の位置からの 16 ビット整数を取得。 uint32 BootInfo::GetWord(uint32 offset) const @@ -266,20 +277,45 @@ Virt68kROMEmuDevice::MakeBootInfo(LoadIn { IODeviceStream ds(mainram, info->end); BootInfo bi; + uint32 cpu_type; + uint32 mmu_type; + uint32 fpu_type; + + auto mpu680x0 = GetMPU680x0Device(mpu); + switch (mpu680x0->GetMPUType()) { + case m680x0MPUType::M68030: + cpu_type = BI_CPU_68030; + mmu_type = BI_MMU_68030; + if (mpu680x0->HasFPU()) { + fpu_type = BI_FPU_68881; + } else { + fpu_type = 0; + } + break; + case m680x0MPUType::M68040: + cpu_type = BI_CPU_68040; + mmu_type = BI_MMU_68040; + fpu_type = BI_FPU_68040; + break; + default: + assert(false); + } bi.Init(BI_MACHTYPE, BI_MACH_VIRT); WriteBootInfo(ds, bi); - bi.Init(BI_CPUTYPE, BI_CPU_68030); + bi.Init(BI_CPUTYPE, cpu_type); WriteBootInfo(ds, bi); - bi.Init(BI_FPUTYPE, BI_FPU_68881); + bi.Init(BI_MMUTYPE, mmu_type); WriteBootInfo(ds, bi); - bi.Init(BI_MMUTYPE, BI_MMU_68030); - WriteBootInfo(ds, bi); + if (fpu_type != 0) { + bi.Init(BI_FPUTYPE, fpu_type); + WriteBootInfo(ds, bi); + } - uint32 ramsize = mainram->GetSize(); + uint32 ramsize = (uint32)mainram->GetSize(); // RAMDISK は (あれば) initrd イメージ置き場で、 // メモリセグメントとは別セグメントにする必要がある。 @@ -296,31 +332,31 @@ Virt68kROMEmuDevice::MakeBootInfo(LoadIn fd = open(cpath, O_RDONLY); if (fd == -1) { - warn("%s \"%s\" open failed", __func__, cpath); + warn("%s \"%s\" open failed", __method__, cpath); return false; } if (fstat(fd, &st) == -1) { - warn("%s \"%s\" fstat failed", __func__, cpath); + warn("%s \"%s\" fstat failed", __method__, cpath); return false; } if (S_ISDIR(st.st_mode)) { - warnx("%s \"%s\" is a directory", __func__, cpath); + warnx("%s \"%s\" is a directory", __method__, cpath); return false; } rdsize = st.st_size; mdata = (uint8 *)mmap(NULL, rdsize, PROT_READ, MAP_PRIVATE, fd, 0); if (mdata == MAP_FAILED) { - warnx("%s \"%s\" mmap failed", __func__, cpath); + warnx("%s \"%s\" mmap failed", __method__, cpath); return false; } // ロード。 LoadInfo rdinfo(cpath, mdata, rdsize); rdinfo.start = (ramsize - rdsize) & ~0xfff; - bool rv = mainram->LoadData(&rdinfo); + bool rv = BootLoader::LoadData(mainram, &rdinfo); munmap(mdata, rdsize); if (rv == false) { warnx("** Couldn't load specified initrd."); @@ -397,6 +433,15 @@ Virt68kROMEmuDevice::MakeBootInfo(LoadIn bi.AddLong(8 + (2 - 1) * 32 + 0); // base irq WriteBootInfo(ds, bi); + // ブートパラメータ + const ConfigItem& bootparam_item = gConfig->Find("exec-bootparam"); + const std::string& bootparam = bootparam_item.AsString(); + if (bootparam.empty() == false) { + bi.Init(BI_COMMANDLINE); + bi.AddString(bootparam.c_str()); + WriteBootInfo(ds, bi); + } + bi.Init(BI_LAST); WriteBootInfo(ds, bi); @@ -511,9 +556,12 @@ Virt68kROMEmuDevice::WriteBootInfo(IODev case BI_RNG_SEED: buf = string_format("len=%u", bi.GetWord(0)); break; + case BI_COMMANDLINE: + buf = string_format("\"%s\"", bi.GetString()); + break; } putmsg(1, "BootInfo $%08x: %-14s: %s", - stream.GetOffset(), tagname.c_str(), buf.c_str()); + stream.GetAddr(), tagname.c_str(), buf.c_str()); } // 出力。