File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / fuserom.cpp
Revision 1.1.1.11 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:37 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, v024, v023, v022, HEAD
nono 1.2.0

//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//

//
// FuseROM (82S129)
//

// FuseROM は 128 バイト分のデータを保持できる 4bit ROM みたいなものっぽい。
// 読み出しは1バイトが上位下位ニブルに分割して読める。そして LUNA-88K バス
// なのでそれが 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<> 経由して) 返すことにする。
// どうせ大したアクセス量でもないので、細かいことは気にしない。
//
// デバイスに繋がっている4ビット以外の 28ビットのところは実際には
// $f'ffffff ではなく $4'00c001 であることが多いが時々数ビット異なる。
// その時のアクセスのパターンから決まる直近の残像のようなものに見える。
// この辺をどこまで再現するかは疑問。

#include "fuserom.h"
#include "ethernet.h"
#include "mainapp.h"

// コンストラクタ
FuseROMDevice::FuseROMDevice()
	: inherited(OBJ_FUSEROM)
{
}

// デストラクタ
FuseROMDevice::~FuseROMDevice()
{
}

// 初期化
bool
FuseROMDevice::Init()
{
	uint8 checksum = 0;

	// XXX 初期値は未調査

	// src に元データを用意する。
	if (gMainApp.IsLUNA88K()) {
		// LUNA-88K なら先頭が MAC アドレス
		MacAddr macaddr;
		if (EthernetDevice::GetConfigMacAddr(0, &macaddr, false) == false) {
			// エラーメッセージは表示済み
			return false;
		}
		putmsg(1, "macaddr=%s", macaddr.ToString(':').c_str());
		strlcpy((char *)&src[0], "ENADDR=", src.size());
		strlcpy((char *)&src[7], macaddr.ToString().c_str(), src.size() - 7);
	} else {
		// LUNA-88K2 なら先頭が機種名 (MAC アドレスは NVRAM にある) のようだ。
	}

	// 最終バイトはチェックバイト (Mach の kernel/luna88k/autoconf.c より)
	for (int i = 0; i < src.size() - 1; i++) {
		checksum ^= src[i];
	}
	src[src.size() - 1] = checksum;

	return true;
}

busdata
FuseROMDevice::ReadPort(uint32 offset)
{
	busdata data = GetByte(offset);
	data |= BusData::Size1;
	return data;
}

busdata
FuseROMDevice::WritePort(uint32 offset, uint32 data)
{
	return BusData::Size1;
}

// ReadPort() からも呼ばれる
busdata
FuseROMDevice::PeekPort(uint32 offset)
{
	return GetByte(offset);
}

bool
FuseROMDevice::PokePort(uint32 offset, uint32 data)
{
	return false;
}

// offset の位置の値を返す
uint8
FuseROMDevice::GetByte(uint32 offset) const
{
	uint8 data;
	if ((offset & 1) == 0) {
		// 上位ニブル
		data = src[offset / 2];
	} else {
		// 下位ニブル
		data = (src[offset / 2] & 0x0f) << 4;
	}
	return data | 0x0f;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.