--- nono/vm/bankram.cpp 2026/04/29 17:05:25 1.1.1.2 +++ nono/vm/bankram.cpp 2026/04/29 17:05:38 1.1.1.4 @@ -13,10 +13,9 @@ #include "bankram.h" #include "config.h" -#include "mainbus.h" // コンストラクタ -BankRAMDevice::BankRAMDevice(int objid_, int ram_size_MB) +BankRAMDevice::BankRAMDevice(uint objid_, int ram_size_MB) : inherited(objid_) { // ram_size_MB は正数のみ。負数は親側で処理する。 @@ -35,10 +34,6 @@ BankRAMDevice::~BankRAMDevice() bool BankRAMDevice::Init() { - if (inherited::Init() == false) { - return false; - } - ram.reset(new uint8[ram_size]); return true; @@ -56,8 +51,8 @@ BankRAMDevice::ResetHard(bool poweron) // リセットでクリアされる。 SetPage(0); - std::fill(accstat_read.begin(), accstat_read.end(), 0); - std::fill(accstat_write.begin(), accstat_write.end(), 0); + memset(&accstat_read[0], 0, AccStat::BANKLEN); + memset(&accstat_write[0], 0, AccStat::BANKLEN); } inline uint32 @@ -67,74 +62,60 @@ BankRAMDevice::Decoder(uint32 addr) cons } busdata -BankRAMDevice::Read8(uint32 addr) +BankRAMDevice::Read(busaddr addr) { - uint32 offset = Decoder(addr); - accstat_read[offset >> 20] = MainbusDevice::ACC_READ; - uint32 data = ram[HLB(offset)]; - putlog(4, "$%08x.B -> $%02x", addr, data); - return data; -} + uint32 offset = Decoder(addr.Addr()); + busdata data; -busdata -BankRAMDevice::Read16(uint32 addr) -{ - uint32 offset = Decoder(addr); - accstat_read[offset >> 20] = MainbusDevice::ACC_READ; - uint32 data = *(uint16 *)&ram[HLW(offset)]; - putlog(4, "$%08x.W -> $%04x", addr, data); - return data; -} + accstat_read[offset >> AccStat::SHIFT] = AccStat::READ; -busdata -BankRAMDevice::Read32(uint32 addr) -{ - uint32 offset = Decoder(addr); - accstat_read[offset >> 20] = MainbusDevice::ACC_READ; - uint32 data = *(uint32 *)&ram[offset]; - putlog(4, "$%08x.L -> $%08x", addr, data); + data = *(uint32 *)&ram[offset & ~3U]; + putlog(4, "$%06x ($%06x) -> $%08x", addr.Addr(), offset, data.Data()); + data |= busdata::Wait(1); + data |= BusData::Size4; return data; } busdata -BankRAMDevice::Write8(uint32 addr, uint32 data) +BankRAMDevice::Write(busaddr addr, uint32 data) { - uint32 offset = Decoder(addr); - accstat_write[offset >> 20] = MainbusDevice::ACC_WRITE; - ram[HLB(offset)] = data; - putlog(3, "$%08x.B <- $%02x", addr, data); - return 0; -} - -busdata -BankRAMDevice::Write16(uint32 addr, uint32 data) -{ - uint32 offset = Decoder(addr); - accstat_write[offset >> 20] = MainbusDevice::ACC_WRITE; - *(uint16 *)&ram[HLW(offset)] = data; - putlog(3, "$%08x.W <- $%04x", addr, data); - return 0; -} + uint32 offset = Decoder(addr.Addr()); + uint32 reqsize = addr.GetSize(); + uint32 datasize = std::min(4 - (offset & 3U), reqsize); + + accstat_write[offset >> AccStat::SHIFT] = AccStat::WRITE; + + if (datasize == 4) { + putlog(3, "$%06x ($%06x) <- $%08x", addr.Addr(), offset, data); + *(uint32 *)&ram[offset] = data; + } else if (datasize == 1) { + data >>= (reqsize - datasize) * 8; + putlog(3, "$%06x ($%06x) <- $%02x", addr.Addr(), offset, data); + ram[HLB(offset)] = data; + } else { + data >>= (reqsize - datasize) * 8; + putlog(3, "$%06x ($%06x) <- $%0*x", addr.Addr(), offset, + datasize * 2, data); + for (int i = datasize - 1; i >= 0; i--) { + ram[HLB(offset + i)] = data; + data >>= 8; + } + } -busdata -BankRAMDevice::Write32(uint32 addr, uint32 data) -{ - uint32 offset = Decoder(addr); - accstat_write[offset >> 20] = MainbusDevice::ACC_WRITE; - *(uint32 *)&ram[offset] = data; - putlog(3, "$%08x.L <- $%08x", addr, data); - return 0; + busdata r = busdata::Wait(1); + r |= BusData::Size4; + return r; } busdata -BankRAMDevice::Peek8(uint32 addr) +BankRAMDevice::Peek1(uint32 addr) { uint32 offset = Decoder(addr); return ram[HLB(offset)]; } bool -BankRAMDevice::Poke8(uint32 addr, uint32 data) +BankRAMDevice::Poke1(uint32 addr, uint32 data) { if ((int32)data >= 0) { uint32 offset = Decoder(addr); @@ -156,15 +137,16 @@ BankRAMDevice::SetPage(uint32 page_) void BankRAMDevice::FetchAccStat(uint8 *acc) { + // 要素が8バイトと分かっていればこれだけで済む。 + static_assert(AccStat::BANKLEN == 8, ""); + // R|W をマージしながらコピー。 - for (int i = 0; i < accstat_read.size(); i += 4) { - uint32 tmp = 0; - tmp |= *(uint32 *)&accstat_read[i]; - tmp |= *(uint32 *)&accstat_write[i]; - *(uint32 *)&acc[i] = tmp; - } + uint64 tmp; + tmp = *(uint64 *)&accstat_read[0]; + tmp |= *(uint64 *)&accstat_write[0]; + *(uint64 *)acc = tmp; // 読んだのでリセット。 - std::fill(accstat_read.begin(), accstat_read.end(), 0); - std::fill(accstat_write.begin(), accstat_write.end(), 0); + memset(&accstat_read[0], 0, AccStat::BANKLEN); + memset(&accstat_write[0], 0, AccStat::BANKLEN); }