--- nono/vm/fuserom.cpp 2026/04/29 17:04:55 1.1.1.4 +++ nono/vm/fuserom.cpp 2026/04/29 17:05:24 1.1.1.9 @@ -4,12 +4,12 @@ // Licensed under nono-license.txt // -#include "fuserom.h" -#include "ethernet.h" -#include "mainapp.h" +// +// FuseROM (82S129) +// // FuseROM は 128 バイト分のデータを保持できる 4bit ROM みたいなものっぽい。 -// 読み出しは1バイトが上位下位ニブルに分割して読める。そして LUNA88K バス +// 読み出しは1バイトが上位下位ニブルに分割して読める。そして LUNA-88K バス // なのでそれが 1ワード(1ロングワード) 境界ごとに配置される。 // // 例えば "01" という2バイトはゲストからは次のような 16バイトとして読める。 @@ -24,50 +24,77 @@ // "01" のように人間が読める形式で用意しておき、アクセス時に都度ニブルに // 変換して (さらに BusIO_BFFF<> 経由して) 返すことにする。 // どうせ大したアクセス量でもないので、細かいことは気にしない。 +// +// デバイスに繋がっている4ビット以外の 28ビットのところは実際には +// $f'ffffff ではなく $4'00c001 であることが多いが時々数ビット異なる。 +// その時のアクセスのパターンから決まる直近の残像のようなものに見える。 +// この辺をどこまで再現するかは疑問。 -std::unique_ptr gFuseROM; +#include "fuserom.h" +#include "ethernet.h" +#include "mainapp.h" +// コンストラクタ FuseROMDevice::FuseROMDevice() - : inherited("FuseROM") + : inherited(OBJ_FUSEROM) { } +// デストラクタ FuseROMDevice::~FuseROMDevice() { } +// 初期化 bool FuseROMDevice::Init() { + if (inherited::Init() == false) { + return false; + } + + uint8 checksum = 0; + memset(src, 0, sizeof(src)); // XXX 未調査 // src に元データを用意する。 - if (gMainApp.GetVMType() == VMTYPE_LUNA88K) { - // LUNA88K なら先頭が MAC アドレス - macaddr_t macaddr = gEthernet->GetMacAddr(); + if (gMainApp.IsLUNA88K()) { + // LUNA-88K なら先頭が MAC アドレス + macaddr_t macaddr; + if (EthernetDevice::GetConfigMacAddr(0, &macaddr, false) == false) { + // エラーメッセージは表示済み + return false; + } + putmsg(1, "macaddr=%s", macaddr.ToString(':').c_str()); strcpy((char *)src, "ENADDR="); - strcpy((char *)src + 7, macaddr.to_string().c_str()); + strcpy((char *)src + 7, macaddr.ToString().c_str()); } else { - // LUNA88K2 なら先頭が機種名 (MAC アドレスは NVRAM にある) のようだ。 + // LUNA-88K2 なら先頭が機種名 (MAC アドレスは NVRAM にある) のようだ。 + } + + // 最終バイトはチェックバイト (Mach の kernel/luna88k/autoconf.c より) + for (int i = 0; i < sizeof(src) - 1; i++) { + checksum ^= src[i]; } + src[sizeof(src) - 1] = checksum; return true; } -uint64 +busdata FuseROMDevice::Read(uint32 offset) { return Peek(offset); } -uint64 +busdata FuseROMDevice::Write(uint32 offset, uint32 data) { return 0; } // Read() からも呼ばれる -uint64 +busdata FuseROMDevice::Peek(uint32 offset) { uint8 data;