|
|
nono 1.3.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// X680x0 の各種 ROM
//
// IODevice
// |
// +- ROMDevice (LoadROM()、ウェイト、マスク等を持つ)
// | +- PROMDevice (LUNA* の PROM)
// | |
// | | +---------------+
// | +-| IPLROM1Device | (X680x0 の IPLROM 後半)
// | | +---------------+
// | |
// | | +---------------+
// | +-| IPLROM2Device | (X680x0 の IPLROM 前半)
// | | +---------------+
// | |
// | | +-------------+
// | +-| CGROMDevice | (X680x0 の CGROM)
// | | +-------------+
// | |
// | +- ROMEmuDevice
// | +- LunaPROMEmuDevice (LUNA PROM エミュレーションの共通部分)
// | | +- Luna1PROMEmuDevice (LUNA-I の PROM エミュレーション)
// | | +- Luna88kPROMEmuDevice (LUNA-88K の PROM エミュレーション)
// | +- NewsROMEmuDevice (NEWS の ROM エミュレーション)
// | +- ROM30EmuDevice (X68030 の ROM30 エミュレーション)
// | +- Virt68kROMEmuDevice (virt-m68k の IPLROM 相当の何か)
// |
// +- PROM0Device (LUNA* のブートページ切り替え用プロキシ)
// |
// | +---------------+
// +-| IPLROM0Device | (X680x0 のブートページ切り替え用プロキシ)
// +---------------+
#include "romimg_x68k.h"
#include "builtinrom.h"
#include "config.h"
#include "mainbus.h"
//
// IPLROM0
//
// IPLROM0 は IPLROM(1) のブートページ担当。
// これ自身はメモリ領域を持たず IPLROM1 へのプロキシとして動作する。
//
// X680x0 のブートページは $000000..$00ffff の 64KB で、
// ここへのアクセスは $ff0000..$ffffff (IPLROM1 の後半 64KB) が見える。
// ROM へアクセスがあればブートページを RAM に切り替える。
// そのため、RAM 側も ROM 側もこいつが応対する必要がある。
// コンストラクタ
IPLROM0Device::IPLROM0Device()
: inherited(OBJ_IPLROM_BOOT)
{
// 通常ここからログを出すことはない
ClearAlias();
}
// デストラクタ
IPLROM0Device::~IPLROM0Device()
{
}
// 初期化
bool
IPLROM0Device::Init()
{
iplrom1 = GetIPLROM1Device();
return true;
}
// リセット
void
IPLROM0Device::ResetHard(bool poweron)
{
auto mainbus = GetMainbusDevice();
mainbus->SwitchBootPageToROM();
}
// Read の共通処理。
// アドレスのデコードと RAM への切り替え判定を行う。
uint32
IPLROM0Device::ReadDecoder(uint32 addr)
{
// ROM アドレスがアクセスされたら切り替える
if (addr >= 0xff0000) {
auto mainbus = GetMainbusDevice();
mainbus->SwitchBootPageToRAM();
}
// どちらにしてもアクセスは ROM のアドレス
return addr | 0xff0000;
}
busdata
IPLROM0Device::Read(busaddr addr)
{
addr.ChangeAddr(ReadDecoder(addr.Addr()));
return iplrom1->Read(addr);
}
// Write は RAM 領域へも ROM 領域へも発生しないはずなので基底のを使う。
busdata
IPLROM0Device::Peek1(uint32 addr)
{
addr |= 0xff0000;
return iplrom1->Peek1(addr);
}
//
// IPLROM(1) 0xfe0000..0xffffff 担当
//
// コンストラクタ
IPLROM1Device::IPLROM1Device()
: inherited(OBJ_IPLROM1)
{
// X680x0 では ROM への書き込みはバスエラー
write_op = BusData::BusErr;
}
// デストラクタ
IPLROM1Device::~IPLROM1Device()
{
}
// 初期化
bool
IPLROM1Device::Init()
{
std::string name;
uint devlen = 0x020000;
mask = devlen - 1;
const ConfigItem& item = gConfig->Find("iplrom1-image");
name = item.AsString();
if (name.empty()) {
// 指定がなければ、内蔵 IPLROM を使う。
mem = Builtin::IPLROM30;
return true;
}
// 外部ファイルが指定されれば、それを使う。
return LoadROM(name.c_str(), devlen);
}
//
// IPLROM(2) 0xfc0000..0xfdffff 担当
//
// コンストラクタ
IPLROM2Device::IPLROM2Device()
: inherited(OBJ_IPLROM2)
{
// X680x0 では ROM への書き込みはバスエラー
write_op = BusData::BusErr;
}
// デストラクタ
IPLROM2Device::~IPLROM2Device()
{
}
// 初期化
bool
IPLROM2Device::Init()
{
uint devlen = 0x020000;
mask = devlen - 1;
const ConfigItem& item = gConfig->Find("iplrom2-image");
std::string name = item.AsString();
if (name.empty()) {
printf("iplrom2: not yet\n");
return false;
}
// 外部ファイルが指定されれば、それを使う。
return LoadROM(name.c_str(), devlen);
}
//
// CGROM
//
// コンストラクタ
CGROMDevice::CGROMDevice()
: inherited(OBJ_CGROM)
{
// X680x0 では ROM への書き込みはバスエラー
write_op = BusData::BusErr;
}
// デストラクタ
CGROMDevice::~CGROMDevice()
{
}
// 初期化
bool
CGROMDevice::Init()
{
uint devlen = 768 * 1024;
mask = 1024 * 1024 - 1;
const ConfigItem& item = gConfig->Find("cgrom-image");
std::string name = item.AsString();
if (name.empty()) {
// 指定がなければ、内蔵 CGROM を使う。
mem = Builtin::CGROM;
return true;
}
// 外部ファイルが指定されれば、それを使う。
if (LoadROM(name.c_str(), devlen) == false) {
// 指定したファイルが読めなければエラー。
return false;
}
// X68030 の CGROM には、X68000 のものには収録されていない 6x12 フォント
// が収録されている。6x12 フォント以外は(たぶん)同じなのでほとんどの場面
// で困ることはないが、それ故に忘れた頃に一部の文字だけ表示されなくて
// 「???」ということになりがちなので、6x12 フォントが収録されてなさそう
// なら警告を出しておく (処理は続行する)。
uint8 val = 0;
for (int i = 0; i < 12; i++) {
val |= imagebuf[0xbf400 + ('0' * 12) + i];
}
if (val == 0) {
warnx("warning: 6x12 font not found in CGROM30.DAT");
}
return true;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.