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

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

//
// メインバス (NEWS)
//

// IODevice
//   +-- MainbusBaseDevice (InitMainbus() と FC アクセスを持つ)
//   |    +-- MainbusDevice (これがメインバス、システムに1つ)
//   |    |    +-- Mainbus24Device (上位8ビットがテーブルで表せるメインバス)
//   |    |    |    +-- LunaMainbus
//   |    |    |    |    +-- Luna1Mainbus
//   |    |    |    |    +-- Luna88kMainbus
//   |    |    |    |
//   |    |    |    |  +-------------+
//   |    |    |    +--| NewsMainbus |
//   |    |    |    |  +-------------+
//   |    |    |    |
//   |    |    |    +-- Virt68kMainbus
//   |    |    +-- X68kMainbus
//   |    +-- X68kIODevice
//   +-- XPbusDevice

#include "mainbus_news.h"
#include "buserr.h"
#include "interrupt.h"
#include "mainapp.h"
#include "mainram.h"
#include "monitor.h"
#include "newsctlr.h"
#include "newsio.h"
#include "nop.h"
#include "prom.h"
#include "romemu_news.h"

// コンストラクタ
NewsMainbus::NewsMainbus()
{
	NEWDV(BusErr, new BusErrDevice());
	NEWDV(Interrupt, new NewsInterrupt());
	NEWDV(PROM, new NewsROMEmuDevice());
	NEWDV(MainRAM, new MainRAMDevice());
	NEWDV(NopIO, new NopIODevice());				// required by NewsIO
	NEWDV(NewsCtlr, new NewsCtlrDevice());
	NEWDV(NewsIO, new NewsIODevice());

	// 公式には $c0'000000〜$ff'ffffff となっているが、
	// たぶん上位2ビットがデコードされてないように見えるので、
	// ここでは $00'000000〜$3f'ffffff ×4 として扱う。

	// $eX'XXXXXX はバスエラーが起きないらしい。
	// $fX'XXXXXX はバスエラーが起きるらしい。
	// それ以上は詳細不明。
	// とりあえず $eX'XXXXXX だけ NopIO、他はバスエラーにしておく。
	for (int i = 0; i < 0x40; i++) {
		devtable[i] = pBusErr.get();
	}
	for (int i = 0x20; i < 0x30; i++) {
		devtable[i] = pNopIO.get();
	}

	// 少ないので手動で置いていく。
	auto newsio = pNewsIO.get();
	auto newsctlr = pNewsCtlr.get();
	auto prom = pPROM.get();
#define A(addr)	(((addr) >> 24) & 0x3f)
	devtable[A(0xe0'000000)] = newsio;
	devtable[A(0xe1'000000)] = newsctlr;
	devtable[A(0xf8'000000)] = prom;

	// アドレス空間は 0xc000'0000 からの 30bit。
	accstat_baseaddr = 0xc0;
	accstat_bitlen = 30;
	accstat_monitor->SetSize(80, 2 + 32 / 4);
}

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

// メインバスの初期化
bool
NewsMainbus::InitMainbus()
{
	// RAM は容量が確定した後のここで配置。
	auto mainram = dynamic_cast<MainRAMDevice *>(pMainRAM.get());
	uint ram_size_MB = mainram->GetSizeMB();
	int i = 0;
	while (ram_size_MB >= 16) {
		// 16MB 単位にとりあえずしとく
		devtable[i++] = mainram;
		ram_size_MB -= 16;
	}

	// $40'000000〜、$80'000000〜、$c0'000000〜はミラーっぽい。
	memcpy(&devtable[0x40], &devtable[0], 0x40 * sizeof(devtable[0]));
	memcpy(&devtable[0x80], &devtable[0], 0x40 * sizeof(devtable[0]));
	memcpy(&devtable[0xc0], &devtable[0], 0x40 * sizeof(devtable[0]));

	// アクセス状況用のマップを作成。
	InitAccStat();

	return true;
}

// ブートページを切り替える。
void
NewsMainbus::SwitchBootPage(bool isram)
{
	// まだサポートしていない。
}

unix.superglobalmegacorp.com

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