--- nono/vm/sram.cpp 2026/04/29 17:04:36 1.1.1.4 +++ nono/vm/sram.cpp 2026/04/29 17:05:14 1.1.1.10 @@ -4,35 +4,40 @@ // Licensed under nono-license.txt // -#include "sram.h" -#include "mainapp.h" -#include "mystring.h" - // // SRAM // + // SRAM はビッグエンディアンのままメモリに置かれるので、 // 必要ならアクセス時に都度変換すること。 -// -std::unique_ptr gSRAM; +#include "sram.h" +#include "config.h" +#include "mainapp.h" +#include "ram.h" +#include + +// グローバル参照用 +SRAMDevice *gSRAM; +// コンストラクタ SRAMDevice::SRAMDevice() + : inherited("SRAM") { - logname = "sram"; - devname = "SRAM"; devaddr = baseaddr; devlen = 0x4000; } +// デストラクタ SRAMDevice::~SRAMDevice() { + gSRAM = NULL; } bool SRAMDevice::Init() { - filename = gMainApp.GetVMDir() + "SRAM030.DAT"; + filename = gMainApp.GetVMDir() + "SRAM.DAT"; file.SetFilename(filename); file.SetDispname(string_format("SRAM \"%s\"", filename.c_str())); mem = file.OpenCreate(16 * 1024); @@ -40,9 +45,58 @@ SRAMDevice::Init() return false; } + // SRAM の RAM 容量欄を設定値に同期させる。 + // この処理はアプリケーション起動時に一回行われるのみで、 + // その後の VM 内のリセット等では動作しない。 + bool sync = gConfig->Find("sram-sync-ramsize").AsInt(); + if (sync) { + SyncRAMSize(); + } + return true; } +// リセット +void +SRAMDevice::ResetHard(bool poweron) +{ + // XXX 未調査 + writeable = false; +} + +// SRAM の RAM 容量欄を設定値に同期させる。 +void +SRAMDevice::SyncRAMSize() +{ + // SRAM の内容が無効なら何もしない。 + static const std::array magic { + 0x82, 0x77, '6', '8', '0', '0', '0' + }; + for (int i = 0; i < magic.size(); i++) { + if (mem[i] != magic[i]) { + return; + } + } + + uint32 ramsize = gRAM->GetSize(); + + // 値が違う時だけ表示したいので一旦読み出して比較 + uint32 cursize; + cursize = mem[0x08] << 24; + cursize |= mem[0x09] << 16; + cursize |= mem[0x0a] << 8; + cursize |= mem[0x0b]; + if (cursize != ramsize) { + // ここは Init() なので putmsg() は使えない + warnx("SRAM: Update ramsize %dMB", ramsize / 1024 / 1024); + + mem[0x08] = ramsize >> 24; + mem[0x09] = ramsize >> 16; + mem[0x0a] = ramsize >> 8; + mem[0x0b] = ramsize; + } +} + // アドレスデコーダ inline uint64 SRAMDevice::Decoder(uint32 addr) const @@ -60,7 +114,7 @@ SRAMDevice::Read8(uint32 addr) uint32 data; // ホストファイル起動モードなら起動アドレスとして Pluto-X を見せる。 - if (gMainApp.host_file) { + if (gMainApp.exec_file) { data = PeekHostBoot(offset); if ((int32)data >= 0) { if ((offset & 1) == 0) { @@ -83,7 +137,7 @@ SRAMDevice::Read16(uint32 addr) uint32 data; // ホストファイル起動モードなら起動アドレスとして Pluto-X を見せる。 - if (gMainApp.host_file) { + if (gMainApp.exec_file) { data = PeekHostBoot(offset); if ((int32)data >= 0) { return data; @@ -101,11 +155,11 @@ SRAMDevice::Write8(uint32 addr, uint32 d if (writeable) { if (offset < 0x100) { - putlog(1, "更新 $%06x <- $%02x", addr, data); + putlog(1, "$%06x.B <- $%02x", addr, data); } mem[offset] = data; } else { - putlog(1, "書き込み禁止 $%06x <- $%02x", addr, data); + putlog(1, "Write protected $%06x.B <- $%02x", addr, data); } return 0; } @@ -117,11 +171,11 @@ SRAMDevice::Write16(uint32 addr, uint32 if (writeable) { if (offset < 0x100) { - putlog(1, "更新 $%06x <- $%04x", addr, data); + putlog(1, "$%06x.W <- $%04x", addr, data); } *(uint16 *)&mem[offset] = htobe16(data); } else { - putlog(1, "書き込み禁止 $%06x <- $%04x", addr, data); + putlog(1, "Write protected $%06x.W <- $%04x", addr, data); } return 0; } @@ -132,7 +186,7 @@ SRAMDevice::Peek8(uint32 addr) uint32 offset = Decoder(addr); // ホストファイル起動モードなら起動アドレスとして Pluto-X を見せる。 - if (gMainApp.host_file) { + if (gMainApp.exec_file) { uint32 data = PeekHostBoot(offset); if ((int32)data >= 0) { if ((offset & 1) == 0) { @@ -151,9 +205,9 @@ void SRAMDevice::write_enable(bool value) { if (writeable == false && value == true) { - putlog(1, "書き込み許可"); + putlog(1, "Write Enable"); } else if (writeable == true && value == false) { - putlog(1, "書き込み禁止"); + putlog(1, "Write Disable"); } writeable = value; @@ -180,3 +234,17 @@ SRAMDevice::PeekHostBoot(uint32 offset) } return (uint32)-1; } + +// SRAM $ed000c.L ROM 起動アドレスを返す +uint32 +SRAMDevice::GetROMAddr() const +{ + uint32 data; + + data = mem[0x0c] << 24; + data |= mem[0x0d] << 16; + data |= mem[0x0e] << 8; + data |= mem[0x0f]; + + return data; +}