--- nono/vm/fuserom.cpp 2026/04/29 17:04:32 1.1 +++ nono/vm/fuserom.cpp 2026/04/29 17:04:35 1.1.1.2 @@ -1,35 +1,81 @@ // // nono -// Copyright (C) 2020 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "fuserom.h" +#include "ethernet.h" +#include "mainapp.h" + +// FuseROM は 128 バイト分のデータを保持できる 4bit ROM みたいなものっぽい。 +// 読み出しは1バイトが上位下位ニブルに分割して読める。そして LUNA88K バス +// なのでそれが 1ワード(1ロングワード) 境界ごとに配置される。 +// +// 例えば "01" という2バイトはゲストからは次のような 16バイトとして読める。 +// +// +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f +// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +// | 3f| ff| ff| ff| 0f| ff| ff| ff| 3f| ff| ff| ff| 1f| ff| ff| ff| +// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +// $3 $0 $3 $1 +// +// ここでは src[128] に元データを8ビット(バイト)単位で、つまり上の例の +// "01" のように人間が読める形式で用意しておき、アクセス時に都度ニブルに +// 変換して (さらに BusIO_BFFF<> 経由して) 返すことにする。 +// どうせ大したアクセス量でもないので、細かいことは気にしない。 FuseROMDevice::FuseROMDevice() : inherited() { logname = "fuserom"; - - mem = new uint8[sizeof(src) * 8]; - mask = (sizeof(src) * 8) - 1; } FuseROMDevice::~FuseROMDevice() { - delete[] mem; } bool FuseROMDevice::Init() { - // バイトデータ - memcpy(src, "MNAME=LUNA88K", 13 + 1); + memset(src, 0, sizeof(src)); // XXX 未調査 - // 1ロングワードに1ニブルずつ置いてある - uint32 *d = (uint32 *)mem; - for (int i = 0; i < sizeof(src); i++) { - *d++ = htobe32((src[i] << 24) | 0x0fffffff); - *d++ = htobe32((src[i] << 28) | 0x0fffffff); + // src に元データを用意する。 + if (gMainApp.GetVMType() == VMTYPE_LUNA88K) { + // LUNA88K なら先頭が MAC アドレス + macaddr_t macaddr = gEthernet->GetMacAddr(); + strcpy((char *)src, "ENADDR="); + strcpy((char *)src + 7, macaddr.to_string().c_str()); + } else { + // LUNA88K2 なら先頭が機種名 (MAC アドレスは NVRAM にある) のようだ。 } + return true; } + +uint64 +FuseROMDevice::Read(uint32 addr) +{ + return Peek(addr); +} + +uint64 +FuseROMDevice::Write(uint32 addr, uint32 data) +{ + return 0; +} + +// Read() からも呼ばれる +uint64 +FuseROMDevice::Peek(uint32 addr) +{ + uint8 data; + if ((addr & 1) == 0) { + // 上位ニブル + data = src[addr / 2]; + } else { + // 下位ニブル + data = (src[addr / 2] & 0x0f) << 4; + } + return data | 0x0f; +}