--- nono/vm/prom.cpp 2026/04/29 17:04:36 1.1.1.1 +++ nono/vm/prom.cpp 2026/04/29 17:04:45 1.1.1.3 @@ -21,7 +21,6 @@ #include "prom.h" #include "config.h" #include "mainapp.h" -#include "scheduler.h" // コンストラクタ PROMDevice::PROMDevice() @@ -66,20 +65,38 @@ PROMDevice::InitLuna() return false; } - // MAC アドレスは ROM に書き込まれているので、ここで上書き - if (strcmp((const char *)&mem[0x1ffd8], "ENADDR") != 0) { - warnx("ENADDR not found; unknown ROM variants?"); - return false; + // ROM バージョンを確認。確認されてるのは + // V4.02 (Wed Oct 12 17:07:11 1988) + // V4.22 (Thu Jul 27 11:45:42 1989) + // V4.25 + // + // とりあえず V4.22 は +$00d390 からにタイムスタンプ文字列があるので + // それで判別してみる。 + //00d390 54 68 75 20 4a 75 6c 20 32 37 20 31 31 3a 34 35 |Thu Jul 27 11:45| + //00d3a0 3a 34 32 20 31 39 38 39 00 00 00 00 4e 56 fd f8 |:42 1989....NV..| + + if (strcmp((const char *)&mem[0xd390], "Thu Jul 27 11:45:42 1989") == 0) { + // V4.22 + putlog(1, "V4.22 detected"); + + // MAC アドレスは ROM に書き込まれているので、ここで上書き + if (strcmp((const char *)&mem[0x1ffd8], "ENADDR") != 0) { + warnx("ENADDR not found; unknown ROM V4.22 variants?"); + return false; + } + + // MAC アドレスは12桁の16進数文字列として書き込まれている。例えば + // 前半の 00:00:0A 部分は 30 30 30 30 30 41 "00000A" という感じ。 + const macaddr_t macaddr = gEthernet->GetMacAddr(); + memcpy(&mem[0x1ffe0], macaddr.to_string().c_str(), 12); + + // SCSI デバッグビット + bool scsi_debug_bit = gConfig->Find(".prom-scsi-debug").AsInt(); + mem[0x4100981d - 0x41000000] = (scsi_debug_bit) ? 0x01 : 0; + } else { + // 他の ROM は何も分からないので何もしない。 + putlog(0, "Unknown PROM Version"); } - // MAC アドレスは12桁の16進数文字列として書き込まれている。例えば - // 前半の 00:00:0A 部分は 30 30 30 30 30 41 "00000A" という感じ。 - const macaddr_t macaddr = gEthernet->GetMacAddr(); - memcpy(&mem[0x1ffe0], macaddr.to_string().c_str(), 12); - - // SCSI デバッグビット - // XXX ROM を確認してから適用したほうがいい - bool scsi_debug_bit = gConfig->Find(".prom-scsi-debug").AsInt(); - mem[0x4100981d - 0x41000000] = (scsi_debug_bit) ? 0x01 : 0; return true; } @@ -134,7 +151,7 @@ PROMDevice::Read8(uint32 addr) // 電源オン時からここまでの時間を表示するだけでリセット等はしない。 end = ::GetRealTime(); - vt = gScheduler->GetVirtTime(); + vt = gMPU->GetVirtTime(); result = end - start_time; putlog(0, "電源オンから %d.%03d 秒経過 %3.3f%%", (int)(result / (1000 * 1000 * 1000)),