yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EMU_MEMORY_H
2#define YAZE_APP_EMU_MEMORY_H
3
4#include <cstdint>
5#include <functional>
6#include <iostream>
7#include <vector>
8
9// LoROM (Mode 20):
10
11// Banks Offset Purpose
12// 00-3F 0000-1FFF LowRAM (shadowed from 7E)
13// 2000-2FFF PPU1, APU
14// 3000-3FFF SFX, DSP, etc.
15// 4000-41FF Controller
16// 4200-5FFF PPU2, DMA, etc.
17// 6000-7FFF Expansion RAM (reserved)
18// 8000-FFFF 32k ROM Chunk
19// 40-7C 0000-7FFF 32k ROM Chunk
20// 8000-FFFF 32k ROM Chunk
21// 7D 0000-FFFF SRAM
22// 7E 0000-1FFF LowRAM
23// 2000-FFFF System RAM
24// 7F 0000-FFFF System RAM
25
26namespace yaze {
27namespace emu {
28
29typedef struct DmaChannel {
30 uint8_t b_addr;
31 uint16_t a_addr;
32 uint8_t a_bank;
33 uint16_t size; // also indirect hdma adr
34 uint8_t ind_bank; // hdma
35 uint16_t table_addr; // hdma
36 uint8_t rep_count; // hdma
37 uint8_t unusedByte;
40 uint8_t mode;
41 bool fixed;
43 bool indirect; // hdma
44 bool from_b;
46 bool do_transfer; // hdma
47 bool terminated; // hdma
49
50typedef struct CpuCallbacks {
51 std::function<uint8_t(uint32_t)> read_byte;
52 std::function<void(uint32_t, uint8_t)> write_byte;
53 std::function<void(bool waiting)> idle;
55
56constexpr uint32_t kROMStart = 0x008000;
57constexpr uint32_t kROMSize = 0x200000;
58constexpr uint32_t kRAMStart = 0x7E0000;
59constexpr uint32_t kRAMSize = 0x20000;
60
64class Memory {
65public:
66 virtual ~Memory() = default;
67 virtual uint8_t ReadByte(uint32_t address) const = 0;
68 virtual uint16_t ReadWord(uint32_t address) const = 0;
69 virtual uint32_t ReadWordLong(uint32_t address) const = 0;
70 virtual std::vector<uint8_t> ReadByteVector(uint32_t address,
71 uint16_t length) const = 0;
72
73 virtual void WriteByte(uint32_t address, uint8_t value) = 0;
74 virtual void WriteWord(uint32_t address, uint16_t value) = 0;
75 virtual void WriteLong(uint32_t address, uint32_t value) = 0;
76
77 virtual void PushByte(uint8_t value) = 0;
78 virtual uint8_t PopByte() = 0;
79 virtual void PushWord(uint16_t value) = 0;
80 virtual uint16_t PopWord() = 0;
81 virtual void PushLong(uint32_t value) = 0;
82 virtual uint32_t PopLong() = 0;
83
84 virtual uint16_t SP() const = 0;
85 virtual void SetSP(uint16_t value) = 0;
86
87 virtual void ClearMemory() = 0;
88
89 virtual uint8_t operator[](int i) const = 0;
90 virtual uint8_t at(int i) const = 0;
91
92 virtual uint8_t open_bus() const = 0;
93 virtual void set_open_bus(uint8_t value) = 0;
94
95 virtual bool hdma_init_requested() const = 0;
96 virtual bool hdma_run_requested() const = 0;
97 virtual void init_hdma_request() = 0;
98 virtual void run_hdma_request() = 0;
99 virtual void set_hdma_run_requested(bool value) = 0;
100 virtual void set_hdma_init_requested(bool value) = 0;
101 virtual void set_pal_timing(bool value) = 0;
102 virtual void set_h_pos(uint16_t value) = 0;
103 virtual void set_v_pos(uint16_t value) = 0;
104
105 // get h_pos and v_pos
106 virtual auto h_pos() const -> uint16_t = 0;
107 virtual auto v_pos() const -> uint16_t = 0;
108 // get pal timing
109 virtual auto pal_timing() const -> bool = 0;
110};
111
118class MemoryImpl : public Memory {
119public:
120 void Initialize(const std::vector<uint8_t> &romData, bool verbose = false);
121
122 uint16_t GetHeaderOffset() {
123 uint16_t offset;
124 switch (memory_[(0x00 << 16) + 0xFFD5] & 0x07) {
125 case 0: // LoROM
126 offset = 0x7FC0;
127 break;
128 case 1: // HiROM
129 offset = 0xFFC0;
130 break;
131 case 5: // ExHiROM
132 offset = 0x40;
133 break;
134 default:
135 throw std::invalid_argument(
136 "Unable to locate supported ROM mapping mode in the provided ROM "
137 "file. Please try another ROM file.");
138 }
139
140 return offset;
141 }
142
143 uint8_t cart_read(uint8_t bank, uint16_t adr);
144 void cart_write(uint8_t bank, uint16_t adr, uint8_t val);
145
146 uint8_t cart_readLorom(uint8_t bank, uint16_t adr);
147 void cart_writeLorom(uint8_t bank, uint16_t adr, uint8_t val);
148
149 uint8_t cart_readHirom(uint8_t bank, uint16_t adr);
150 uint8_t cart_readExHirom(uint8_t bank, uint16_t adr);
151
152 void cart_writeHirom(uint8_t bank, uint16_t adr, uint8_t val);
153
154 uint8_t ReadByte(uint32_t address) const override {
155 uint32_t mapped_address = GetMappedAddress(address);
156 return memory_.at(mapped_address);
157 }
158 uint16_t ReadWord(uint32_t address) const override {
159 uint32_t mapped_address = GetMappedAddress(address);
160 return static_cast<uint16_t>(memory_.at(mapped_address)) |
161 (static_cast<uint16_t>(memory_.at(mapped_address + 1)) << 8);
162 }
163 uint32_t ReadWordLong(uint32_t address) const override {
164 uint32_t mapped_address = GetMappedAddress(address);
165 return static_cast<uint32_t>(memory_.at(mapped_address)) |
166 (static_cast<uint32_t>(memory_.at(mapped_address + 1)) << 8) |
167 (static_cast<uint32_t>(memory_.at(mapped_address + 2)) << 16);
168 }
169 std::vector<uint8_t> ReadByteVector(uint32_t address,
170 uint16_t length) const override {
171 uint32_t mapped_address = GetMappedAddress(address);
172 return std::vector<uint8_t>(memory_.begin() + mapped_address,
173 memory_.begin() + mapped_address + length);
174 }
175
176 void WriteByte(uint32_t address, uint8_t value) override {
177 uint32_t mapped_address = GetMappedAddress(address);
178 memory_[mapped_address] = value;
179 }
180 void WriteWord(uint32_t address, uint16_t value) override {
181 uint32_t mapped_address = GetMappedAddress(address);
182 memory_.at(mapped_address) = value & 0xFF;
183 memory_.at(mapped_address + 1) = (value >> 8) & 0xFF;
184 }
185 void WriteLong(uint32_t address, uint32_t value) override {
186 uint32_t mapped_address = GetMappedAddress(address);
187 memory_.at(mapped_address) = value & 0xFF;
188 memory_.at(mapped_address + 1) = (value >> 8) & 0xFF;
189 memory_.at(mapped_address + 2) = (value >> 16) & 0xFF;
190 }
191
192 // Stack operations
193 void PushByte(uint8_t value) override {
194 if (SP_ > 0x0100) {
195 memory_.at(SP_--) = value;
196 } else {
197 // Handle stack underflow
198 std::cout << "Stack underflow!" << std::endl;
199 throw std::runtime_error("Stack underflow!");
200 }
201 }
202
203 uint8_t PopByte() override {
204 if (SP_ < 0x1FF) {
205 return memory_.at(++SP_);
206 } else {
207 // Handle stack overflow
208 std::cout << "Stack overflow!" << std::endl;
209 throw std::runtime_error("Stack overflow!");
210 }
211 }
212
213 void PushWord(uint16_t value) override {
214 PushByte(value >> 8);
215 PushByte(value & 0xFF);
216 }
217
218 uint16_t PopWord() override {
219 uint8_t low = PopByte();
220 uint8_t high = PopByte();
221 return (static_cast<uint16_t>(high) << 8) | low;
222 }
223
224 void PushLong(uint32_t value) override {
225 PushByte(value >> 16);
226 PushByte(value >> 8);
227 PushByte(value & 0xFF);
228 }
229
230 uint32_t PopLong() override {
231 uint8_t low = PopByte();
232 uint8_t mid = PopByte();
233 uint8_t high = PopByte();
234 return (static_cast<uint32_t>(high) << 16) |
235 (static_cast<uint32_t>(mid) << 8) | low;
236 }
237
238 // Stack Pointer access.
239 uint16_t SP() const override { return SP_; }
240 auto mutable_sp() -> uint16_t & { return SP_; }
241 void SetSP(uint16_t value) override { SP_ = value; }
242 void ClearMemory() override { std::fill(memory_.begin(), memory_.end(), 0); }
243
244 uint8_t at(int i) const override { return memory_[i]; }
245 uint8_t operator[](int i) const override {
246 if (i > memory_.size()) {
247 std::cout << i << " out of bounds \n";
248 return memory_[0];
249 }
250 return memory_[i];
251 }
252
253 auto size() const { return memory_.size(); }
254 auto begin() const { return memory_.begin(); }
255 auto end() const { return memory_.end(); }
256 auto data() const { return memory_.data(); }
257 void set_open_bus(uint8_t value) override { open_bus_ = value; }
258 auto open_bus() const -> uint8_t override { return open_bus_; }
259 auto hdma_init_requested() const -> bool override {
261 }
262 auto hdma_run_requested() const -> bool override {
263 return hdma_run_requested_;
264 }
265 void init_hdma_request() override { hdma_init_requested_ = true; }
266 void run_hdma_request() override { hdma_run_requested_ = true; }
267 void set_hdma_run_requested(bool value) override {
268 hdma_run_requested_ = value;
269 }
270 void set_hdma_init_requested(bool value) override {
271 hdma_init_requested_ = value;
272 }
273 void set_pal_timing(bool value) override { pal_timing_ = value; }
274 void set_h_pos(uint16_t value) override { h_pos_ = value; }
275 void set_v_pos(uint16_t value) override { v_pos_ = value; }
276 auto h_pos() const -> uint16_t override { return h_pos_; }
277 auto v_pos() const -> uint16_t override { return v_pos_; }
278 auto pal_timing() const -> bool override { return pal_timing_; }
279
280 auto dma_state() -> uint8_t & { return dma_state_; }
281 void set_dma_state(uint8_t value) { dma_state_ = value; }
282 auto dma_channels() -> DmaChannel * { return channel; }
283
284 // Define memory regions
285 std::vector<uint8_t> rom_;
286 std::vector<uint8_t> ram_;
287
288private:
289 uint32_t GetMappedAddress(uint32_t address) const;
290
291 bool verbose_ = false;
292
293 // DMA requests
296
297 bool pal_timing_ = false;
298
299 // Memory regions
300 uint32_t rom_size_;
301 uint32_t sram_size_;
302
303 // Frame timing
304 uint16_t h_pos_ = 0;
305 uint16_t v_pos_ = 0;
306
307 // Dma State
308 uint8_t dma_state_ = 0;
309
310 // Open bus
311 uint8_t open_bus_ = 0;
312
313 // Stack Pointer
314 uint16_t SP_ = 0;
315
316 // Cart Type
317 uint8_t type_ = 1;
318
319 // Dma Channels
321
322 // Memory (64KB)
323 std::vector<uint8_t> memory_;
324};
325
326} // namespace emu
327} // namespace yaze
328
329#endif // YAZE_APP_EMU_MEMORY_H
Implementation of the Memory interface for emulating memory in a SNES system.
Definition memory.h:118
auto begin() const
Definition memory.h:254
uint8_t at(int i) const override
Definition memory.h:244
auto open_bus() const -> uint8_t override
Definition memory.h:258
void set_dma_state(uint8_t value)
Definition memory.h:281
auto dma_state() -> uint8_t &
Definition memory.h:280
void WriteWord(uint32_t address, uint16_t value) override
Definition memory.h:180
void set_h_pos(uint16_t value) override
Definition memory.h:274
std::vector< uint8_t > rom_
Definition memory.h:285
auto size() const
Definition memory.h:253
uint16_t GetHeaderOffset()
Definition memory.h:122
void init_hdma_request() override
Definition memory.h:265
void WriteByte(uint32_t address, uint8_t value) override
Definition memory.h:176
uint16_t SP() const override
Definition memory.h:239
auto dma_channels() -> DmaChannel *
Definition memory.h:282
void set_v_pos(uint16_t value) override
Definition memory.h:275
auto v_pos() const -> uint16_t override
Definition memory.h:277
std::vector< uint8_t > ram_
Definition memory.h:286
void set_hdma_run_requested(bool value) override
Definition memory.h:267
auto data() const
Definition memory.h:256
uint16_t PopWord() override
Definition memory.h:218
uint8_t PopByte() override
Definition memory.h:203
auto hdma_init_requested() const -> bool override
Definition memory.h:259
auto mutable_sp() -> uint16_t &
Definition memory.h:240
uint32_t ReadWordLong(uint32_t address) const override
Definition memory.h:163
auto h_pos() const -> uint16_t override
Definition memory.h:276
DmaChannel channel[8]
Definition memory.h:320
void WriteLong(uint32_t address, uint32_t value) override
Definition memory.h:185
uint32_t GetMappedAddress(uint32_t address) const
Definition memory.cc:132
void SetSP(uint16_t value) override
Definition memory.h:241
void set_open_bus(uint8_t value) override
Definition memory.h:257
auto end() const
Definition memory.h:255
std::vector< uint8_t > memory_
Definition memory.h:323
void PushWord(uint16_t value) override
Definition memory.h:213
uint8_t operator[](int i) const override
Definition memory.h:245
uint32_t PopLong() override
Definition memory.h:230
void run_hdma_request() override
Definition memory.h:266
void ClearMemory() override
Definition memory.h:242
void set_pal_timing(bool value) override
Definition memory.h:273
void PushByte(uint8_t value) override
Definition memory.h:193
auto pal_timing() const -> bool override
Definition memory.h:278
void set_hdma_init_requested(bool value) override
Definition memory.h:270
void PushLong(uint32_t value) override
Definition memory.h:224
std::vector< uint8_t > ReadByteVector(uint32_t address, uint16_t length) const override
Definition memory.h:169
void Initialize(const std::vector< uint8_t > &romData, bool verbose=false)
Definition memory.cc:9
uint32_t sram_size_
Definition memory.h:301
auto hdma_run_requested() const -> bool override
Definition memory.h:262
uint16_t ReadWord(uint32_t address) const override
Definition memory.h:158
uint8_t ReadByte(uint32_t address) const override
Definition memory.h:154
Memory interface.
Definition memory.h:64
virtual void PushWord(uint16_t value)=0
virtual void PushLong(uint32_t value)=0
virtual void WriteLong(uint32_t address, uint32_t value)=0
virtual void init_hdma_request()=0
virtual ~Memory()=default
virtual bool hdma_run_requested() const =0
virtual void set_v_pos(uint16_t value)=0
virtual uint16_t PopWord()=0
virtual void WriteWord(uint32_t address, uint16_t value)=0
virtual void ClearMemory()=0
virtual auto pal_timing() const -> bool=0
virtual uint32_t PopLong()=0
virtual uint16_t SP() const =0
virtual auto h_pos() const -> uint16_t=0
virtual auto v_pos() const -> uint16_t=0
virtual void PushByte(uint8_t value)=0
virtual void set_hdma_run_requested(bool value)=0
virtual uint32_t ReadWordLong(uint32_t address) const =0
virtual uint8_t ReadByte(uint32_t address) const =0
virtual void WriteByte(uint32_t address, uint8_t value)=0
virtual void run_hdma_request()=0
virtual bool hdma_init_requested() const =0
virtual uint8_t open_bus() const =0
virtual uint8_t PopByte()=0
virtual uint8_t operator[](int i) const =0
virtual void set_hdma_init_requested(bool value)=0
virtual std::vector< uint8_t > ReadByteVector(uint32_t address, uint16_t length) const =0
virtual void set_h_pos(uint16_t value)=0
virtual void SetSP(uint16_t value)=0
virtual void set_pal_timing(bool value)=0
virtual uint16_t ReadWord(uint32_t address) const =0
virtual uint8_t at(int i) const =0
virtual void set_open_bus(uint8_t value)=0
SNES Emulation and debugging tools.
Definition apu.cc:13
constexpr uint32_t kROMSize
Definition memory.h:57
struct yaze::emu::DmaChannel DmaChannel
constexpr uint32_t kROMStart
Definition memory.h:56
constexpr uint32_t kRAMStart
Definition memory.h:58
constexpr uint32_t kRAMSize
Definition memory.h:59
struct yaze::emu::CpuCallbacks CpuCallbacks
Main namespace for the application.
Definition controller.cc:18
std::function< void(bool waiting)> idle
Definition memory.h:53
std::function< uint8_t(uint32_t)> read_byte
Definition memory.h:51
std::function< void(uint32_t, uint8_t)> write_byte
Definition memory.h:52
uint16_t table_addr
Definition memory.h:35