summaryrefslogtreecommitdiff
path: root/src/nes/mapper.cc
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2025-01-18 19:35:42 +0100
committerHannes Schulze <haschu0103@outlook.de>2025-01-18 19:35:42 +0100
commit67672d06776e38b06f31f6599678767c60eed58a (patch)
tree4846c762815b887036b10a7aadd849dd8fdd4420 /src/nes/mapper.cc
parentfe7243fdd14f6ef57033f9e70141aba970dba7ea (diff)
implement ppu io registers
Diffstat (limited to 'src/nes/mapper.cc')
-rw-r--r--src/nes/mapper.cc78
1 files changed, 72 insertions, 6 deletions
diff --git a/src/nes/mapper.cc b/src/nes/mapper.cc
index a451e3a..237ab47 100644
--- a/src/nes/mapper.cc
+++ b/src/nes/mapper.cc
@@ -4,10 +4,15 @@
namespace nes
{
- mapper::mapper(cartridge& cartridge, read_func const read, write_func const write)
+ mapper::mapper(
+ cartridge& cartridge,
+ read_cpu_func const read_cpu, write_cpu_func const write_cpu,
+ read_ppu_func const read_ppu, write_ppu_func const write_ppu)
: cartridge_{ cartridge }
- , read_{ read }
- , write_{ write }
+ , read_cpu_{ read_cpu }
+ , write_cpu_{ write_cpu }
+ , read_ppu_{ read_ppu }
+ , write_ppu_{ write_ppu }
{
}
@@ -16,16 +21,21 @@ namespace nes
switch (cartridge.get_mapper_number())
{
case 0x00:
- return mapper{ cartridge, &mapper::nrom_read, &mapper::nrom_write };
+ return mapper{
+ cartridge,
+ &mapper::nrom_read_cpu, &mapper::nrom_write_cpu,
+ &mapper::nrom_read_ppu, &mapper::nrom_write_ppu };
default:
std::cerr << "Mapper not implemented: " << std::hex << cartridge.get_mapper_number() << std::endl;
std::abort();
}
}
+ // -----------------------------------------------------------------------------------------------------------------
// NROM
+ // -----------------------------------------------------------------------------------------------------------------
- auto mapper::nrom_read(address const addr) -> std::uint8_t
+ auto mapper::nrom_read_cpu(address const addr) -> std::uint8_t
{
if (addr <= address{ 0x5FFF })
{
@@ -54,7 +64,7 @@ namespace nes
return 0x0;
}
- auto mapper::nrom_write(address const addr, std::uint8_t const value) -> void
+ auto mapper::nrom_write_cpu(address const addr, std::uint8_t const value) -> void
{
if (addr <= address{ 0x5FFF })
{
@@ -63,7 +73,63 @@ namespace nes
if (addr <= address{ 0x7FFF })
{
cartridge_.get_ram_mut()[addr.get_absolute() - 0x6000] = value;
+ return;
+ }
+ }
+
+ auto mapper::nrom_read_ppu(address const addr, std::uint8_t const* vram) -> std::uint8_t
+ {
+ if (addr <= address{ 0x1FFF })
+ {
+ auto const rel = addr.get_absolute();
+ if (rel >= cartridge_.get_chr_rom_length()) { return 0x0; }
+
+ return cartridge_.get_chr_rom()[rel];
+ }
+ if (addr <= address{ 0x3EFF })
+ {
+ return vram[nrom_mirrored_vram_address(addr)];
+ }
+
+ return 0x0;
+ }
+
+ auto mapper::nrom_write_ppu(address const addr, std::uint8_t* vram, std::uint8_t const value) -> void
+ {
+ if (addr <= address{ 0x1FFF })
+ {
+ return;
+ }
+ if (addr <= address{ 0x3EFF })
+ {
+ vram[nrom_mirrored_vram_address(addr)] = value;
+ return;
}
}
+ auto mapper::nrom_mirrored_vram_address(address const addr) const -> unsigned
+ {
+ auto rel = addr.get_absolute();
+ if (rel >= 0x3000) { rel -= 0x1000; }
+
+ switch (cartridge_.get_name_table_arrangement())
+ {
+ case name_table_arrangement::horizontal:
+ // $2000 = $2400, $2800 = $2c00
+ if (rel <= 0x23FF) { return 0x000 + (rel % 0x400); }
+ if (rel <= 0x27FF) { return 0x000 + (rel % 0x400); }
+ if (rel <= 0x2BFF) { return 0x400 + (rel % 0x400); }
+ if (rel <= 0x2FFF) { return 0x400 + (rel % 0x400); }
+ break;
+ case name_table_arrangement::vertical:
+ // $2000 = $2800, $2400 = $2c00
+ if (rel <= 0x23FF) { return 0x000 + (rel % 0x400); }
+ if (rel <= 0x27FF) { return 0x400 + (rel % 0x400); }
+ if (rel <= 0x2BFF) { return 0x000 + (rel % 0x400); }
+ if (rel <= 0x2FFF) { return 0x400 + (rel % 0x400); }
+ break;
+ }
+
+ return 0;
+ }
} // namespace nes \ No newline at end of file