28 constexpr uint32_t kLoRomHeaderLocation = 0x7FC0;
29 constexpr uint32_t kMinRomSizeForHeader = 0x7FD9;
31 uint32_t header_rom_size = 0;
32 if (rom_data.size() < kMinRomSizeForHeader) {
35 "ROM too small for header access: %zu bytes (need at least %u bytes)",
36 rom_data.size(), kMinRomSizeForHeader);
40 auto location = kLoRomHeaderLocation;
41 uint8_t rom_size_shift = rom_data[location + 0x17];
42 uint8_t sram_size_shift = rom_data[location + 0x18];
45 if (rom_size_shift > 15) {
46 LOG_DEBUG(
"Memory",
"Invalid ROM size shift: %u, using file size",
49 header_rom_size = 0x400u << rom_size_shift;
52 if (sram_size_shift > 7) {
53 LOG_DEBUG(
"Memory",
"Invalid SRAM size shift: %u, using default",
66 const uint32_t file_rom_size =
static_cast<uint32_t
>(
67 std::min<size_t>(rom_data.size(), kMaxMappedRomSize));
69 std::min(std::bit_ceil(std::max({header_rom_size, file_rom_size, 1u})),
73 rom_.assign(rom_data.begin(), rom_data.end());
76 std::fill(
ram_.begin(),
ram_.end(), 0);
79 "LoROM initialized: ROM map size=$%06X (%uKB) file=$%06zX "
80 "header=$%06X SRAM size=$%04X",
85 if (rom_data.size() >= 0x7FFE) {
86 LOG_DEBUG(
"Memory",
"Reset vector at ROM offset $7FFC-$7FFD = $%02X%02X",
87 rom_data[0x7FFD], rom_data[0x7FFC]);
89 LOG_DEBUG(
"Memory",
"ROM too small to read reset vector (size: %zu bytes)",
165 if ((bank & 0x7f) < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
167 return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (
sram_size_ - 1)];
169 bool secondHalf = bank < 0x80;
171 if (adr >= 0x8000 || bank >= 0x40) {
173 return ReadRom(((bank & 0x3f) << 16) | (secondHalf ? 0x400000 : 0) | adr);