yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
memory.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstdint>
5#include <vector>
6
7#include "util/log.h"
8
9namespace yaze {
10namespace emu {
11
12void MemoryImpl::Initialize(const std::vector<uint8_t>& rom_data,
13 bool verbose) {
14 verbose_ = verbose;
15 type_ = 1; // LoROM
16
17 // Validate ROM data size before accessing header
18 // LoROM header is at 0x7FC0, and we need to access bytes at 0x7FD7 and 0x7FD8
19 constexpr uint32_t kLoRomHeaderLocation = 0x7FC0;
20 constexpr uint32_t kMinRomSizeForHeader = 0x7FD9; // 0x7FC0 + 0x18 + 1
21
22 if (rom_data.size() < kMinRomSizeForHeader) {
23 LOG_DEBUG("Memory", "ROM too small for header access: %zu bytes (need at least %u bytes)",
24 rom_data.size(), kMinRomSizeForHeader);
25 // Fallback: use ROM data size directly if header is not accessible
26 rom_size_ = static_cast<uint32_t>(rom_data.size());
27 sram_size_ = 0x2000; // Default 8KB SRAM
28 LOG_DEBUG("Memory", "Using fallback: ROM size=%u bytes, SRAM size=%u bytes",
30 } else {
31 auto location = kLoRomHeaderLocation; // LoROM header location
32 uint8_t rom_size_shift = rom_data[location + 0x17];
33 uint8_t sram_size_shift = rom_data[location + 0x18];
34
35 // Validate shift values to prevent excessive memory allocation
36 if (rom_size_shift > 15) { // Max reasonable shift (0x400 << 15 = 128MB)
37 LOG_DEBUG("Memory", "Invalid ROM size shift: %u, using fallback", rom_size_shift);
38 rom_size_ = static_cast<uint32_t>(rom_data.size());
39 } else {
40 rom_size_ = 0x400 << rom_size_shift;
41 }
42
43 if (sram_size_shift > 7) { // Max reasonable shift (0x400 << 7 = 512KB)
44 LOG_DEBUG("Memory", "Invalid SRAM size shift: %u, using default", sram_size_shift);
45 sram_size_ = 0x2000; // Default 8KB SRAM
46 } else {
47 sram_size_ = 0x400 << sram_size_shift;
48 }
49 }
50
51 // Allocate ROM and SRAM storage
52 rom_.resize(rom_size_);
53 const size_t copy_size = std::min<size_t>(rom_size_, rom_data.size());
54 std::copy(rom_data.begin(), rom_data.begin() + copy_size, rom_.begin());
55
56 ram_.resize(sram_size_);
57 std::fill(ram_.begin(), ram_.end(), 0);
58
59 LOG_DEBUG("Memory",
60 "LoROM initialized: ROM size=$%06X (%zuKB) SRAM size=$%04X",
62
63 // Log reset vector if ROM is large enough
64 if (rom_data.size() >= 0x7FFE) {
65 LOG_DEBUG("Memory", "Reset vector at ROM offset $7FFC-$7FFD = $%02X%02X",
66 rom_data[0x7FFD], rom_data[0x7FFC]);
67 } else {
68 LOG_DEBUG("Memory", "ROM too small to read reset vector (size: %zu bytes)",
69 rom_data.size());
70 }
71}
72
73uint8_t MemoryImpl::cart_read(uint8_t bank, uint16_t adr) {
74 // Emulator uses this path for all ROM/cart reads
75 switch (type_) {
76 case 0:
77 return open_bus_;
78 case 1:
79 return cart_readLorom(bank, adr);
80 case 2:
81 return cart_readHirom(bank, adr);
82 case 3:
83 return cart_readExHirom(bank, adr);
84 }
85 return open_bus_;
86}
87
88void MemoryImpl::cart_write(uint8_t bank, uint16_t adr, uint8_t val) {
89 switch (type_) {
90 case 0:
91 break;
92 case 1:
93 cart_writeLorom(bank, adr, val);
94 break;
95 case 2:
96 cart_writeHirom(bank, adr, val);
97 break;
98 case 3:
99 cart_writeHirom(bank, adr, val);
100 break;
101 }
102}
103
104uint8_t MemoryImpl::cart_readLorom(uint8_t bank, uint16_t adr) {
105 // SRAM access: banks 70-7e and f0-ff, addresses 0000-7fff
106 if (((bank >= 0x70 && bank < 0x7e) || bank >= 0xf0) && adr < 0x8000 &&
107 sram_size_ > 0) {
108 return ram_[(((bank & 0xf) << 15) | adr) & (sram_size_ - 1)];
109 }
110
111 // ROM access: banks 00-7f (mirrored to 80-ff), addresses 8000-ffff
112 // OR banks 40-7f, all addresses
113 bank &= 0x7f;
114 if (adr >= 0x8000 || bank >= 0x40) {
115 uint32_t rom_offset = ((bank << 15) | (adr & 0x7fff)) & (rom_size_ - 1);
116 if (rom_offset >= rom_.size()) {
117 return open_bus_;
118 }
119 return rom_[rom_offset];
120 }
121
122 return open_bus_;
123}
124
125void MemoryImpl::cart_writeLorom(uint8_t bank, uint16_t adr, uint8_t val) {
126 if (((bank >= 0x70 && bank < 0x7e) || bank > 0xf0) && adr < 0x8000 &&
127 sram_size_ > 0) {
128 // banks 70-7e and f0-ff, adr 0000-7fff
129 ram_[(((bank & 0xf) << 15) | adr) & (sram_size_ - 1)] = val;
130 }
131}
132
133uint8_t MemoryImpl::cart_readHirom(uint8_t bank, uint16_t adr) {
134 bank &= 0x7f;
135 if (bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
136 // banks 00-3f and 80-bf, adr 6000-7fff
137 return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sram_size_ - 1)];
138 }
139 if (adr >= 0x8000 || bank >= 0x40) {
140 // adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff
141 return rom_[(((bank & 0x3f) << 16) | adr) & (rom_size_ - 1)];
142 }
143 return open_bus_;
144}
145
146uint8_t MemoryImpl::cart_readExHirom(uint8_t bank, uint16_t adr) {
147 if ((bank & 0x7f) < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
148 // banks 00-3f and 80-bf, adr 6000-7fff
149 return ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sram_size_ - 1)];
150 }
151 bool secondHalf = bank < 0x80;
152 bank &= 0x7f;
153 if (adr >= 0x8000 || bank >= 0x40) {
154 // adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff
155 return rom_[(((bank & 0x3f) << 16) | (secondHalf ? 0x400000 : 0) | adr) &
156 (rom_size_ - 1)];
157 }
158 return open_bus_;
159}
160
161void MemoryImpl::cart_writeHirom(uint8_t bank, uint16_t adr, uint8_t val) {
162 bank &= 0x7f;
163 if (bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && sram_size_ > 0) {
164 // banks 00-3f and 80-bf, adr 6000-7fff
165 ram_[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (sram_size_ - 1)] = val;
166 }
167}
168
169uint32_t MemoryImpl::GetMappedAddress(uint32_t address) const {
170 // NOTE: This function is only used by ROM editor via Memory interface.
171 // The emulator core uses cart_read/cart_write instead.
172 // Returns identity mapping for now - full implementation not needed for
173 // emulator.
174 return address;
175}
176
177} // namespace emu
178} // namespace yaze
std::vector< uint8_t > rom_
Definition memory.h:285
std::vector< uint8_t > ram_
Definition memory.h:286
uint8_t cart_readHirom(uint8_t bank, uint16_t adr)
Definition memory.cc:133
uint32_t GetMappedAddress(uint32_t address) const
Definition memory.cc:169
uint8_t cart_read(uint8_t bank, uint16_t adr)
Definition memory.cc:73
void cart_writeLorom(uint8_t bank, uint16_t adr, uint8_t val)
Definition memory.cc:125
uint8_t cart_readLorom(uint8_t bank, uint16_t adr)
Definition memory.cc:104
uint8_t cart_readExHirom(uint8_t bank, uint16_t adr)
Definition memory.cc:146
void cart_write(uint8_t bank, uint16_t adr, uint8_t val)
Definition memory.cc:88
void cart_writeHirom(uint8_t bank, uint16_t adr, uint8_t val)
Definition memory.cc:161
void Initialize(const std::vector< uint8_t > &romData, bool verbose=false)
Definition memory.cc:12
uint32_t sram_size_
Definition memory.h:301
#define LOG_DEBUG(category, format,...)
Definition log.h:103