--- nono/vm/sram.cpp 2026/04/29 17:05:24 1.1.1.12 +++ nono/vm/sram.cpp 2026/04/29 17:05:42 1.1.1.15 @@ -15,7 +15,7 @@ #include "config.h" #include "mainapp.h" #include "mainram.h" -#include +#include // コンストラクタ SRAMDevice::SRAMDevice() @@ -26,22 +26,46 @@ SRAMDevice::SRAMDevice() // デストラクタ SRAMDevice::~SRAMDevice() { + if ((bool)file) { + // この場合は mem は file が管理している。 + file.reset(); + } else { + if (mem) { + munmap(mem, sramsize); + } + } } // 初期化 bool SRAMDevice::Init() { - if (inherited::Init() == false) { - return false; - } - - filename = gMainApp.GetVMDir() + "SRAM.DAT"; - file.SetFilename(filename); - file.SetDispname(string_format("SRAM \"%s\"", filename.c_str())); - mem = file.OpenCreate(16 * 1024); - if (mem == NULL) { - return false; + // SRAM ファイルをオープン。 + if (gMainApp.GetVMDir().empty()) { + // Human68k モードで VM ディレクトリ指定がなければ、ダミーを用意。 + void *m = mmap(NULL, sramsize, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0); + if (m == MAP_FAILED) { + warn("mmap"); + return false; + } + mem = (uint8 *)m; + memcpy(mem, &InitialData[0], InitialData.size()); + } else { + filename = gMainApp.GetVMDir() + "SRAM.DAT"; + try { + file.reset(new MappedFile()); + } catch (...) { } + if ((bool)file == false) { + warnx("Failed to initialize MappedFile at %s", __method__); + return false; + } + file->SetFilename(filename); + file->SetDispname(string_format("SRAM \"%s\"", filename.c_str())); + mem = file->OpenCreate(sramsize); + if (mem == NULL) { + return false; + } } // SRAM の RAM 容量欄を設定値に同期させる。 @@ -77,7 +101,7 @@ SRAMDevice::SyncRAMSize() } } - uint32 ramsize = GetMainRAMDevice()->GetSize(); + uint32 ramsize = (uint32)GetMainRAMDevice()->GetSize(); // 値が違う時だけ表示したいので一旦読み出して比較 uint32 cursize; @@ -86,8 +110,11 @@ SRAMDevice::SyncRAMSize() cursize |= mem[0x0a] << 8; cursize |= mem[0x0b]; if (cursize != ramsize) { - // ここは Init() なので putmsg() は使えない - warnx("SRAM: Update ramsize %dMB", ramsize / 1024 / 1024); + if (gMainApp.GetVMDir().empty()) { + // Human68k モードで -c のない時は表示不要。ダミー SRAM なので。 + } else { + warnx("SRAM: Update ramsize %uMB", ramsize / 1024 / 1024); + } mem[0x08] = ramsize >> 24; mem[0x09] = ramsize >> 16; @@ -101,77 +128,65 @@ inline uint32 SRAMDevice::Decoder(uint32 addr) const { uint32 offset = addr - baseaddr; - assertmsg(offset < file.GetMemSize(), - "offset=%x memlen=%x", offset, (int)file.GetMemSize()); + assertmsg(offset < file->GetMemSize(), + "offset=%x memlen=%x", offset, (uint)file->GetMemSize()); return offset; } busdata -SRAMDevice::Read8(uint32 addr) -{ - uint32 offset = Decoder(addr); - uint32 data; - - data = Get8(offset); - putlog(2, "$%06x.B -> $%02x", addr, data); - - return data; -} - -busdata -SRAMDevice::Read16(uint32 addr) +SRAMDevice::Read(busaddr addr) { - uint32 offset = Decoder(addr); - uint32 data; - - data = Get16(offset); - putlog(2, "$%06x.W -> $%04x", addr, data); + uint32 offset = Decoder(addr.Addr()); + busdata data; + data = Get16(offset & ~1U); + data |= BusData::Size2; + putlog(2, "$%06x -> $%04x", addr.Addr() & ~1U, data.Data()); return data; } busdata -SRAMDevice::Write8(uint32 addr, uint32 data) +SRAMDevice::Write(busaddr addr, uint32 data) { - uint32 offset = Decoder(addr); + uint32 offset = Decoder(addr.Addr()); + uint32 reqsize = addr.GetSize(); + uint32 datasize = std::min(2 - (offset & 1), reqsize); + data >>= (reqsize - datasize) * 8; if (writeable) { if (offset < 0x100) { - putlog(1, "$%06x.B <- $%02x", addr, data); + putlog(1, "$%06x.%c <- $%0*x", addr.Addr(), + (datasize == 1 ? 'B' : 'W'), datasize * 2, data); + } + if (datasize == 1) { + mem[offset] = data; + } else { + *(uint16 *)&mem[offset] = htobe16(data); } - mem[offset] = data; } else { - putlog(1, "Write protected $%06x.B <- $%02x", addr, data); + putlog(1, "Write protected $%06x.%c <- $%0*x", addr.Addr(), + (datasize == 1 ? 'B' : 'W'), datasize * 2, data); } - return 0; + + busdata r = busdata::Size(datasize); + return r; } busdata -SRAMDevice::Write16(uint32 addr, uint32 data) +SRAMDevice::Peek1(uint32 addr) { uint32 offset = Decoder(addr); + uint32 data = Get16(offset & ~1U); - if (writeable) { - if (offset < 0x100) { - putlog(1, "$%06x.W <- $%04x", addr, data); - } - *(uint16 *)&mem[offset] = htobe16(data); + if ((offset & 1) == 0) { + return data >> 8; } else { - putlog(1, "Write protected $%06x.W <- $%04x", addr, data); + return data & 0xff; } - return 0; -} - -busdata -SRAMDevice::Peek8(uint32 addr) -{ - uint32 offset = Decoder(addr); - - return Get8(offset); } bool -SRAMDevice::Poke8(uint32 addr, uint32 data) +SRAMDevice::Poke1(uint32 addr, uint32 data) { // WriteEnable() に関わらず変更する。 // また Get8()、Get16() はこの変更の影響を受けないことに注意。 @@ -198,23 +213,17 @@ SRAMDevice::WriteEnable(bool value) // SRAM から副作用なく読み出す。 // ただしホストファイル起動モードなら改変した値を返す。 uint32 -SRAMDevice::Get8(uint32 offset) const +SRAMDevice::Get16(uint32 offset) const { if (gMainApp.exec_file) { switch (offset) { case 0x0c: // ROM 起動アドレス(.L) - return plutoaddr >> 24; - case 0x0d: - return (plutoaddr >> 16) & 0xff; + return (plutoaddr >> 16) & 0xffff; case 0x0e: - return (plutoaddr >> 8) & 0xff; - case 0x0f: - return plutoaddr & 0xff; + return plutoaddr & 0xffff; case 0x18: // 起動デバイス(.W) を ROM($a000) にする - return 0xa0; - case 0x19: - return 0x00; + return 0xa000; default: break; @@ -222,20 +231,8 @@ SRAMDevice::Get8(uint32 offset) const } // 他は SRAM から - return mem[offset]; -} - -// SRAM から副作用なくワードで読み出す。 -// ただしホストファイル起動モードなら改変した値を返す。 -uint32 -SRAMDevice::Get16(uint32 offset) const -{ - uint32 data; - - data = Get8(offset) << 8; - data |= Get8(offset + 1); - - return data; + uint32 data = *(uint16 *)&mem[offset]; + return be16toh(data); } // SRAM から副作用なくロングワードで読み出す。