yaze 0.2.0
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1#ifndef MEM_H
2#define MEM_H
3
4#include <cstdint>
5#include <functional>
6#include <iostream>
7#include <string>
8#include <vector>
9
10#include "app/emu/debug/log.h"
12
13// LoROM (Mode 20):
14
15// Banks Offset Purpose
16// 00-3F 0000-1FFF LowRAM (shadowed from 7E)
17// 2000-2FFF PPU1, APU
18// 3000-3FFF SFX, DSP, etc.
19// 4000-41FF Controller
20// 4200-5FFF PPU2, DMA, etc.
21// 6000-7FFF Expansion RAM (reserved)
22// 8000-FFFF 32k ROM Chunk
23// 40-7C 0000-7FFF 32k ROM Chunk
24// 8000-FFFF 32k ROM Chunk
25// 7D 0000-FFFF SRAM
26// 7E 0000-1FFF LowRAM
27// 2000-FFFF System RAM
28// 7F 0000-FFFF System RAM
29
30namespace yaze {
31namespace app {
32namespace emu {
33namespace memory {
34
35enum RomSpeed { SLOW_ROM = 0x00, FAST_ROM = 0x07 };
36
37enum BankSize { LOW_ROM = 0x00, HI_ROM = 0x01 };
38
39enum RomType {
41 ROM_RAM = 0x01,
42 ROM_SRAM = 0x02,
43 ROM_DSP1 = 0x03,
46 FX = 0x06
47};
48
49enum RomSize {
54 SIZE_32_MBIT = 0x0C
55};
56
58 NO_SRAM = 0x00,
61 SRAM_64_KBIT = 0x03
62};
63
65 JAPAN = 0x00,
66 USA = 0x01,
68 // ... and other countries
69};
70
71enum License {
74 ZAMUSE = 5,
75 CAPCOM = 8,
76 // ... and other licenses
77};
78
95
96typedef struct CpuCallbacks {
97 std::function<uint8_t(uint32_t)> read_byte;
98 std::function<void(uint32_t, uint8_t)> write_byte;
99 std::function<void(bool waiting)> idle;
101
102constexpr uint32_t kROMStart = 0x008000;
103constexpr uint32_t kROMSize = 0x200000;
104constexpr uint32_t kRAMStart = 0x7E0000;
105constexpr uint32_t kRAMSize = 0x20000;
106
110class Memory {
111 public:
112 virtual ~Memory() = default;
113 virtual uint8_t ReadByte(uint32_t address) const = 0;
114 virtual uint16_t ReadWord(uint32_t address) const = 0;
115 virtual uint32_t ReadWordLong(uint32_t address) const = 0;
116 virtual std::vector<uint8_t> ReadByteVector(uint32_t address,
117 uint16_t length) const = 0;
118
119 virtual void WriteByte(uint32_t address, uint8_t value) = 0;
120 virtual void WriteWord(uint32_t address, uint16_t value) = 0;
121 virtual void WriteLong(uint32_t address, uint32_t value) = 0;
122
123 virtual void PushByte(uint8_t value) = 0;
124 virtual uint8_t PopByte() = 0;
125 virtual void PushWord(uint16_t value) = 0;
126 virtual uint16_t PopWord() = 0;
127 virtual void PushLong(uint32_t value) = 0;
128 virtual uint32_t PopLong() = 0;
129
130 virtual uint16_t SP() const = 0;
131 virtual void SetSP(uint16_t value) = 0;
132
133 virtual void ClearMemory() = 0;
134
135 virtual uint8_t operator[](int i) const = 0;
136 virtual uint8_t at(int i) const = 0;
137
138 virtual uint8_t open_bus() const = 0;
139 virtual void set_open_bus(uint8_t value) = 0;
140
141 virtual bool hdma_init_requested() const = 0;
142 virtual bool hdma_run_requested() const = 0;
143 virtual void init_hdma_request() = 0;
144 virtual void run_hdma_request() = 0;
145 virtual void set_hdma_run_requested(bool value) = 0;
146 virtual void set_hdma_init_requested(bool value) = 0;
147 virtual void set_pal_timing(bool value) = 0;
148 virtual void set_h_pos(uint16_t value) = 0;
149 virtual void set_v_pos(uint16_t value) = 0;
150
151 // get h_pos and v_pos
152 virtual auto h_pos() const -> uint16_t = 0;
153 virtual auto v_pos() const -> uint16_t = 0;
154 // get pal timing
155 virtual auto pal_timing() const -> bool = 0;
156};
157
164class MemoryImpl : public Memory, public Loggable {
165 public:
166 uint32_t romSize;
167 uint32_t sramSize;
168 void Initialize(const std::vector<uint8_t>& romData, bool verbose = false);
169
170 uint16_t GetHeaderOffset() {
171 uint8_t mapMode = memory_[(0x00 << 16) + 0xFFD5];
172 uint16_t offset;
173
174 switch (mapMode & 0x07) {
175 case 0: // LoROM
176 offset = 0x7FC0;
177 break;
178 case 1: // HiROM
179 offset = 0xFFC0;
180 break;
181 case 5: // ExHiROM
182 offset = 0x40;
183 break;
184 default:
185 throw std::invalid_argument(
186 "Unable to locate supported ROM mapping mode in the provided ROM "
187 "file. Please try another ROM file.");
188 }
189
190 return offset;
191 }
192
193 memory::RomInfo ReadRomHeader();
194
195 uint8_t cart_read(uint8_t bank, uint16_t adr);
196 void cart_write(uint8_t bank, uint16_t adr, uint8_t val);
197
198 uint8_t cart_readLorom(uint8_t bank, uint16_t adr);
199 void cart_writeLorom(uint8_t bank, uint16_t adr, uint8_t val);
200
201 uint8_t cart_readHirom(uint8_t bank, uint16_t adr);
202 uint8_t cart_readExHirom(uint8_t bank, uint16_t adr);
203
204 void cart_writeHirom(uint8_t bank, uint16_t adr, uint8_t val);
205
206 uint8_t ReadByte(uint32_t address) const override {
207 uint32_t mapped_address = GetMappedAddress(address);
208 return memory_.at(mapped_address);
209 }
210 uint16_t ReadWord(uint32_t address) const override {
211 uint32_t mapped_address = GetMappedAddress(address);
212 return static_cast<uint16_t>(memory_.at(mapped_address)) |
213 (static_cast<uint16_t>(memory_.at(mapped_address + 1)) << 8);
214 }
215 uint32_t ReadWordLong(uint32_t address) const override {
216 uint32_t mapped_address = GetMappedAddress(address);
217 return static_cast<uint32_t>(memory_.at(mapped_address)) |
218 (static_cast<uint32_t>(memory_.at(mapped_address + 1)) << 8) |
219 (static_cast<uint32_t>(memory_.at(mapped_address + 2)) << 16);
220 }
221 std::vector<uint8_t> ReadByteVector(uint32_t address,
222 uint16_t length) const override {
223 uint32_t mapped_address = GetMappedAddress(address);
224 return std::vector<uint8_t>(memory_.begin() + mapped_address,
225 memory_.begin() + mapped_address + length);
226 }
227
228 void WriteByte(uint32_t address, uint8_t value) override {
229 uint32_t mapped_address = GetMappedAddress(address);
230 memory_[mapped_address] = value;
231 }
232 void WriteWord(uint32_t address, uint16_t value) override {
233 uint32_t mapped_address = GetMappedAddress(address);
234 memory_.at(mapped_address) = value & 0xFF;
235 memory_.at(mapped_address + 1) = (value >> 8) & 0xFF;
236 }
237 void WriteLong(uint32_t address, uint32_t value) override {
238 uint32_t mapped_address = GetMappedAddress(address);
239 memory_.at(mapped_address) = value & 0xFF;
240 memory_.at(mapped_address + 1) = (value >> 8) & 0xFF;
241 memory_.at(mapped_address + 2) = (value >> 16) & 0xFF;
242 }
243
244 // Stack operations
245 void PushByte(uint8_t value) override {
246 if (SP_ > 0x0100) {
247 memory_.at(SP_--) = value;
248 } else {
249 // Handle stack underflow
250 std::cout << "Stack underflow!" << std::endl;
251 throw std::runtime_error("Stack underflow!");
252 }
253 }
254
255 uint8_t PopByte() override {
256 if (SP_ < 0x1FF) {
257 return memory_.at(++SP_);
258 } else {
259 // Handle stack overflow
260 std::cout << "Stack overflow!" << std::endl;
261 throw std::runtime_error("Stack overflow!");
262 }
263 }
264
265 void PushWord(uint16_t value) override {
266 PushByte(value >> 8);
267 PushByte(value & 0xFF);
268 }
269
270 uint16_t PopWord() override {
271 uint8_t low = PopByte();
272 uint8_t high = PopByte();
273 return (static_cast<uint16_t>(high) << 8) | low;
274 }
275
276 void PushLong(uint32_t value) override {
277 PushByte(value >> 16);
278 PushByte(value >> 8);
279 PushByte(value & 0xFF);
280 }
281
282 uint32_t PopLong() override {
283 uint8_t low = PopByte();
284 uint8_t mid = PopByte();
285 uint8_t high = PopByte();
286 return (static_cast<uint32_t>(high) << 16) |
287 (static_cast<uint32_t>(mid) << 8) | low;
288 }
289
290 // Stack Pointer access.
291 uint16_t SP() const override { return SP_; }
292 auto mutable_sp() -> uint16_t& { return SP_; }
293 void SetSP(uint16_t value) override { SP_ = value; }
294 void ClearMemory() override { std::fill(memory_.begin(), memory_.end(), 0); }
295
296 uint8_t at(int i) const override { return memory_[i]; }
297 uint8_t operator[](int i) const override {
298 if (i > memory_.size()) {
299 std::cout << i << " out of bounds \n";
300 return memory_[0];
301 }
302 return memory_[i];
303 }
304
305 auto size() const { return memory_.size(); }
306 auto begin() const { return memory_.begin(); }
307 auto end() const { return memory_.end(); }
308 auto data() const { return memory_.data(); }
309 void set_open_bus(uint8_t value) override { open_bus_ = value; }
310 auto open_bus() const -> uint8_t override { return open_bus_; }
311 auto hdma_init_requested() const -> bool override {
312 return hdma_init_requested_;
313 }
314 auto hdma_run_requested() const -> bool override {
315 return hdma_run_requested_;
316 }
317 void init_hdma_request() override { hdma_init_requested_ = true; }
318 void run_hdma_request() override { hdma_run_requested_ = true; }
319 void set_hdma_run_requested(bool value) override {
320 hdma_run_requested_ = value;
321 }
322 void set_hdma_init_requested(bool value) override {
323 hdma_init_requested_ = value;
324 }
325 void set_pal_timing(bool value) override { pal_timing_ = value; }
326 void set_h_pos(uint16_t value) override { h_pos_ = value; }
327 void set_v_pos(uint16_t value) override { v_pos_ = value; }
328 auto h_pos() const -> uint16_t override { return h_pos_; }
329 auto v_pos() const -> uint16_t override { return v_pos_; }
330 auto pal_timing() const -> bool override { return pal_timing_; }
331
332 auto dma_state() -> uint8_t& { return dma_state_; }
333 void set_dma_state(uint8_t value) { dma_state_ = value; }
334 auto dma_channels() -> DmaChannel* { return channel; }
335
336 // Define memory regions
337 std::vector<uint8_t> rom_;
338 std::vector<uint8_t> ram_;
339
340 private:
341 uint32_t GetMappedAddress(uint32_t address) const;
342
343 bool verbose_ = false;
344
345 // DMA requests
346 bool hdma_run_requested_ = false;
347 bool hdma_init_requested_ = false;
348
349 bool pal_timing_ = false;
350
351 // Frame timing
352 uint16_t h_pos_ = 0;
353 uint16_t v_pos_ = 0;
354
355 // Dma State
356 uint8_t dma_state_ = 0;
357
358 // Dma Channels
359 DmaChannel channel[8];
360
361 // Open bus
362 uint8_t open_bus_ = 0;
363
364 // Stack Pointer
365 uint16_t SP_ = 0;
366
367 // Cart Type
368 uint8_t type_ = 1;
369
370 // Memory (64KB)
371 std::vector<uint8_t> memory_;
372};
373
374void DrawSnesMemoryMapping(const MemoryImpl& memory);
375
376} // namespace memory
377} // namespace emu
378} // namespace app
379} // namespace yaze
380
381#endif // MEM_H
Implementation of the Memory interface for emulating memory in a SNES system.
Definition memory.h:164
uint32_t ReadWordLong(uint32_t address) const override
Definition memory.h:215
std::vector< uint8_t > memory_
Definition memory.h:371
auto mutable_sp() -> uint16_t &
Definition memory.h:292
void WriteWord(uint32_t address, uint16_t value) override
Definition memory.h:232
void WriteLong(uint32_t address, uint32_t value) override
Definition memory.h:237
uint16_t PopWord() override
Definition memory.h:270
auto v_pos() const -> uint16_t override
Definition memory.h:329
void set_dma_state(uint8_t value)
Definition memory.h:333
auto dma_channels() -> DmaChannel *
Definition memory.h:334
void set_h_pos(uint16_t value) override
Definition memory.h:326
void PushWord(uint16_t value) override
Definition memory.h:265
std::vector< uint8_t > ReadByteVector(uint32_t address, uint16_t length) const override
Definition memory.h:221
void set_open_bus(uint8_t value) override
Definition memory.h:309
auto h_pos() const -> uint16_t override
Definition memory.h:328
void init_hdma_request() override
Definition memory.h:317
uint8_t at(int i) const override
Definition memory.h:296
void run_hdma_request() override
Definition memory.h:318
uint8_t ReadByte(uint32_t address) const override
Definition memory.h:206
std::vector< uint8_t > rom_
Definition memory.h:337
auto hdma_run_requested() const -> bool override
Definition memory.h:314
uint16_t SP() const override
Definition memory.h:291
void set_hdma_run_requested(bool value) override
Definition memory.h:319
void PushLong(uint32_t value) override
Definition memory.h:276
void SetSP(uint16_t value) override
Definition memory.h:293
void set_pal_timing(bool value) override
Definition memory.h:325
auto dma_state() -> uint8_t &
Definition memory.h:332
void WriteByte(uint32_t address, uint8_t value) override
Definition memory.h:228
auto open_bus() const -> uint8_t override
Definition memory.h:310
void set_v_pos(uint16_t value) override
Definition memory.h:327
std::vector< uint8_t > ram_
Definition memory.h:338
uint8_t PopByte() override
Definition memory.h:255
uint32_t PopLong() override
Definition memory.h:282
void set_hdma_init_requested(bool value) override
Definition memory.h:322
uint16_t ReadWord(uint32_t address) const override
Definition memory.h:210
auto pal_timing() const -> bool override
Definition memory.h:330
void PushByte(uint8_t value) override
Definition memory.h:245
auto hdma_init_requested() const -> bool override
Definition memory.h:311
uint8_t operator[](int i) const override
Definition memory.h:297
Memory interface.
Definition memory.h:110
virtual std::vector< uint8_t > ReadByteVector(uint32_t address, uint16_t length) const =0
virtual void PushLong(uint32_t value)=0
virtual void WriteLong(uint32_t address, uint32_t value)=0
virtual void set_pal_timing(bool value)=0
virtual void PushByte(uint8_t value)=0
virtual uint16_t SP() const =0
virtual void set_v_pos(uint16_t value)=0
virtual void SetSP(uint16_t value)=0
virtual void PushWord(uint16_t value)=0
virtual auto v_pos() const -> uint16_t=0
virtual void WriteByte(uint32_t address, uint8_t value)=0
virtual uint8_t operator[](int i) const =0
virtual void set_hdma_run_requested(bool value)=0
virtual uint8_t at(int i) const =0
virtual uint8_t open_bus() const =0
virtual void WriteWord(uint32_t address, uint16_t value)=0
virtual void set_h_pos(uint16_t value)=0
virtual void run_hdma_request()=0
virtual bool hdma_run_requested() const =0
virtual uint8_t ReadByte(uint32_t address) const =0
virtual auto h_pos() const -> uint16_t=0
virtual void set_hdma_init_requested(bool value)=0
virtual uint32_t PopLong()=0
virtual uint16_t ReadWord(uint32_t address) const =0
virtual uint32_t ReadWordLong(uint32_t address) const =0
virtual void init_hdma_request()=0
virtual uint8_t PopByte()=0
virtual uint16_t PopWord()=0
virtual auto pal_timing() const -> bool=0
virtual void set_open_bus(uint8_t value)=0
virtual bool hdma_init_requested() const =0
constexpr uint32_t kROMSize
Definition memory.h:103
constexpr uint32_t kRAMSize
Definition memory.h:105
struct yaze::app::emu::memory::CpuCallbacks CpuCallbacks
constexpr uint32_t kROMStart
Definition memory.h:102
void DrawSnesMemoryMapping(const MemoryImpl &memory)
Definition memory.cc:221
constexpr uint32_t kRAMStart
Definition memory.h:104
Definition common.cc:21
std::function< uint8_t(uint32_t)> read_byte
Definition memory.h:97
std::function< void(bool waiting)> idle
Definition memory.h:99
std::function< void(uint32_t, uint8_t)> write_byte
Definition memory.h:98