File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / romimg_x68k.cpp
Revision 1.1.1.14 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:43 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, v024, v023, HEAD
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;
}

unix.superglobalmegacorp.com

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