|
|
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;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.