--- nono/vm/bankram.cpp 2026/04/29 17:05:21 1.1.1.1 +++ nono/vm/bankram.cpp 2026/04/29 17:05:43 1.1.1.5 @@ -15,7 +15,7 @@ #include "config.h" // コンストラクタ -BankRAMDevice::BankRAMDevice(int objid_, int ram_size_MB) +BankRAMDevice::BankRAMDevice(uint objid_, int ram_size_MB) : inherited(objid_) { // ram_size_MB は正数のみ。負数は親側で処理する。 @@ -34,12 +34,13 @@ BankRAMDevice::~BankRAMDevice() bool BankRAMDevice::Init() { - if (inherited::Init() == false) { + ram.reset(new(std::nothrow) uint8[ram_size]); + if ((bool)ram == false) { + errno = ENOMEM; + warn("BankRAM(%u bytes)", ram_size); return false; } - ram.reset(new uint8[ram_size]); - return true; } @@ -54,6 +55,9 @@ BankRAMDevice::ResetHard(bool poweron) // リセットでクリアされる。 SetPage(0); + + memset(&accstat_read[0], 0, AccStat::BANKLEN); + memset(&accstat_write[0], 0, AccStat::BANKLEN); } inline uint32 @@ -62,75 +66,67 @@ BankRAMDevice::Decoder(uint32 addr) cons return pageaddr + (addr & 0xffff); } -uint64 -BankRAMDevice::Read8(uint32 addr) +busdata +BankRAMDevice::Read(busaddr addr) { - uint32 offset = Decoder(addr); - uint32 data = ram[HLB(offset)]; - putlog(4, "$%08x.B -> $%02x", addr, data); - return data; -} + uint32 offset = Decoder(addr.Addr()); + busdata data; -uint64 -BankRAMDevice::Read16(uint32 addr) -{ - uint32 offset = Decoder(addr); - uint32 data = *(uint16 *)&ram[HLW(offset)]; - putlog(4, "$%08x.W -> $%04x", addr, data); - return data; -} + accstat_read[offset >> AccStat::SHIFT] = AccStat::READ; -uint64 -BankRAMDevice::Read32(uint32 addr) -{ - uint32 offset = Decoder(addr); - 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; } -uint64 -BankRAMDevice::Write8(uint32 addr, uint32 data) -{ - uint32 offset = Decoder(addr); - ram[HLB(offset)] = data; - putlog(3, "$%08x.B <- $%02x", addr, data); - return 0; -} - -uint64 -BankRAMDevice::Write16(uint32 addr, uint32 data) +busdata +BankRAMDevice::Write(busaddr addr, uint32 data) { - uint32 offset = Decoder(addr); - *(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; + } + } -uint64 -BankRAMDevice::Write32(uint32 addr, uint32 data) -{ - uint32 offset = Decoder(addr); - *(uint32 *)&ram[offset] = data; - putlog(3, "$%08x.L <- $%08x", addr, data); - return 0; + busdata r = busdata::Wait(1); + r |= BusData::Size4; + return r; } -uint64 -BankRAMDevice::Peek8(uint32 addr) +busdata +BankRAMDevice::Peek1(uint32 addr) { uint32 offset = Decoder(addr); return ram[HLB(offset)]; } -uint64 -BankRAMDevice::Poke8(uint32 addr, uint32 data) +bool +BankRAMDevice::Poke1(uint32 addr, uint32 data) { if ((int32)data >= 0) { uint32 offset = Decoder(addr); ram[HLB(offset)] = data; } - return 0; + return true; } void @@ -142,3 +138,20 @@ BankRAMDevice::SetPage(uint32 page_) putlog(2, "Page <- $%02x", page); } + +void +BankRAMDevice::FetchAccStat(uint8 *acc) +{ + // 要素が8バイトと分かっていればこれだけで済む。 + static_assert(AccStat::BANKLEN == 8, ""); + + // R|W をマージしながらコピー。 + uint64 tmp; + tmp = *(uint64 *)&accstat_read[0]; + tmp |= *(uint64 *)&accstat_write[0]; + *(uint64 *)acc = tmp; + + // 読んだのでリセット。 + memset(&accstat_read[0], 0, AccStat::BANKLEN); + memset(&accstat_write[0], 0, AccStat::BANKLEN); +}