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