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

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

//
// X68030 勝手に拡張メモリ
//
// 拡張メモリは TS-6BE16 互換か 060turbo 互換のいずれか。
// TS-6BE16 互換だと $0100'0000 〜 $01ff'ffff の 16MB。
// 060turbo 互換だと $1000'0000 〜 $17ff'ffff の 128MB、
//                   $1000'0000 〜 $1fff'ffff の 256MB。
//                   $1000'0000 〜 $2fff'ffff の 512MB。(独自拡張)
//

// 拡張 RAM はロングワード単位でホストバイトオーダ配置なので、
// バイトアクセス、ワードアクセス時は HLB(), HLW() マクロを使用のこと。

#include "extram.h"
#include "config.h"

// コンストラクタ
ExtRAMDevice::ExtRAMDevice()
	: inherited(OBJ_EXTRAM)
{
}

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

// 初期化
bool
ExtRAMDevice::Init()
{
	const ConfigItem& item = gConfig->Find("extram-size");
	uint32 extram_size_MB = item.AsInt();
	if (extram_size_MB == 0) {
		return true;
	}
	switch (extram_size_MB) {
	 case 16:
		ram_addr = 0x01'000000;
		break;
	 case 128:
	 case 256:
	 case 384:
	 case 512:
		ram_addr = 0x10'000000;
		break;
	 default:
		item.Err("Valid size are 16, 128, 256, 384 or 512 for now");
		return false;
	}

	ram_size = extram_size_MB * 1024 * 1024;
	ram.reset(new(std::nothrow) uint8[ram_size]);
	if ((bool)ram == false) {
		warnx("Could not allocate ExtRAM(%u bytes)", ram_size);
		return false;
	}

	return true;
}

// 電源オン/リセット
void
ExtRAMDevice::ResetHard(bool poweron)
{
	if (poweron) {
		// ノイズで埋めたいがとりあえず。
		memset(&ram[0], 0, ram_size);
	}
}

inline uint32
ExtRAMDevice::Decoder(uint32 addr) const
{
	return (addr - ram_addr);
}

busdata
ExtRAMDevice::Read(busaddr addr)
{
	uint32 offset = Decoder(addr.Addr());
	busdata data;

	data  = *(uint32 *)&ram[offset & ~3U];
	putlog(4, "$%08x -> $%08x", addr.Addr(), data.Data());
	data |= BusData::Size4;
	return data;
}

busdata
ExtRAMDevice::Write(busaddr addr, uint32 data)
{
	uint32 paddr = Decoder(addr.Addr());
	uint32 reqsize = addr.GetSize();
	uint32 datasize = std::min(4 - (paddr & 3U), reqsize);

	if (datasize == 4) {
		*(uint32 *)&ram[paddr] = data;
		putlog(3, "$%08x <- $%08x", addr.Addr(), data);
	} else {
		data >>= (reqsize - datasize) * 8;
		putlog(3, "$%08x <- $%0*x", addr.Addr(), datasize * 2, data);
		for (int i = datasize - 1; i >= 0; i--) {
			ram[HLB(paddr + i)] = data;
			data >>= 8;
		}
	}

	busdata r = BusData::Size4;
	return r;
}

busdata
ExtRAMDevice::Peek1(uint32 addr)
{
	uint32 offset = Decoder(addr);
	return ram[HLB(offset)];
}

bool
ExtRAMDevice::Poke1(uint32 addr, uint32 data)
{
	if ((int32)data >= 0) {
		uint32 offset = Decoder(addr);
		ram[HLB(offset)] = data;
	}
	return true;
}

unix.superglobalmegacorp.com

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