--- nono/vm/sram.cpp 2026/04/29 17:04:28 1.1 +++ nono/vm/sram.cpp 2026/04/29 17:04:32 1.1.1.3 @@ -3,10 +3,11 @@ // Copyright (C) 2017 isaki@NetBSD.org // -#include "configfile.h" +#include "mainapp.h" #include "sram.h" #include #include +#include // // SRAM @@ -15,7 +16,7 @@ // 必要ならアクセス時に都度変換すること。 // -SRAMDevice *gSRAM; +std::unique_ptr gSRAM; SRAMDevice::SRAMDevice() { @@ -43,19 +44,40 @@ SRAMDevice::~SRAMDevice() bool SRAMDevice::Init() { - filename = gConfig->GetConfigDir() + "SRAM030.DAT"; + struct stat st; + + filename = gMainApp.GetVMDir() + "SRAM030.DAT"; + memlen = 16 * 1024; fd = open(filename.c_str(), O_RDWR); if (fd == -1) { - warn("%s: cannot open %s", devname, filename.c_str()); + warn("SRAM \"%s\" open failed", filename.c_str()); return false; } - memlen = 16 * 1024; + // ファイルサイズをチェック。 + // ファイルが短くても mmap はしれっと成功してしまうようだ。 + if (fstat(fd, &st) == -1) { + warn("SRAM \"%s\" fstat failed", filename.c_str()); + close(fd); + return false; + } + if (st.st_size < memlen) { + warnx("SRAM \"%s\" is too short (filesize is expected %d but %d)", + filename.c_str(), memlen, (int)st.st_size); + close(fd); + return false; + } + if (st.st_size > memlen) { + // 大きすぎるほうはワーニングだけでいいか + warnx("SRAM \"%s\" is too large (ignore %d bytes)", + filename.c_str(), (int)st.st_size - memlen); + } + mem = (uint8 *)mmap(NULL, memlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { - warn("%s: cannot mmap %s", devname, filename.c_str()); + warn("SRAM \"%s\" mmap failed", filename.c_str()); close(fd); return false; } @@ -63,26 +85,37 @@ SRAMDevice::Init() return true; } +// アドレスデコーダ +inline uint64 +SRAMDevice::Decoder(uint32 addr) const +{ + return addr - baseaddr; +} + uint64 SRAMDevice::Read8(uint32 addr) { - return mem[addr - baseaddr]; + uint32 offset = Decoder(addr); + return mem[offset]; } uint64 SRAMDevice::Read16(uint32 addr) { - return be16toh(*(uint16 *)&mem[addr - baseaddr]); + uint32 offset = Decoder(addr); + return be16toh(*(uint16 *)&mem[offset]); } uint64 SRAMDevice::Write8(uint32 addr, uint32 data) { + uint32 offset = Decoder(addr); + if (writeable) { - if (addr - baseaddr < 0x100) { + if (offset < 0x100) { putlog(1, "更新 $%06x <- $%02x", addr, data); } - mem[addr - baseaddr] = data; + mem[offset] = data; } else { putlog(1, "書き込み禁止 $%06x <- $%02x", addr, data); } @@ -92,11 +125,13 @@ SRAMDevice::Write8(uint32 addr, uint32 d uint64 SRAMDevice::Write16(uint32 addr, uint32 data) { + uint32 offset = Decoder(addr); + if (writeable) { - if (addr - baseaddr < 0x100) { + if (offset < 0x100) { putlog(1, "更新 $%06x <- $%04x", addr, data); } - *(uint16 *)&mem[addr - baseaddr] = htobe16(data); + *(uint16 *)&mem[offset] = htobe16(data); } else { putlog(1, "書き込み禁止 $%06x <- $%04x", addr, data); } @@ -106,7 +141,8 @@ SRAMDevice::Write16(uint32 addr, uint32 uint64 SRAMDevice::Peek8(uint32 addr) { - return mem[addr - baseaddr]; + uint32 offset = Decoder(addr); + return mem[offset]; } void