Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mapper 474 #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/nes/cartridge/mapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ Mapper::Mapper(
#include "mappers/mapper_004.h"
#include "mappers/mapper_007.h"
#include "mappers/mapper_009.h"
#include "mappers/mapper_474.h"

Mapper* Mapper::Factory(const ROM_File* rom_file) {
if (rom_file == nullptr)
Expand All @@ -111,6 +112,7 @@ Mapper* Mapper::Factory(const ROM_File* rom_file) {
case 4: return new Mapper_004(*rom_file);
case 7: return new Mapper_007(*rom_file);
case 9: return new Mapper_009(*rom_file);
case 474: return new Mapper_474(*rom_file);
}

return nullptr;
Expand Down
52 changes: 52 additions & 0 deletions src/nes/cartridge/mappers/mapper_474.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "mapper_474.h"

#include <cassert>
#include <cstdio>

Mapper_474::Mapper_474(const ROM_File& rom_file)
: Mapper(474, "NROM-383", rom_file, 0x4000, 0x2000)
, prg_ram(0x2000)
{
this->mirror_mode = rom_file.meta.mirror_mode;
this->has_battery = rom_file.meta.has_battery;
}

// reading has no side-effects
u8 Mapper_474::read(u16 addr) { return this->peek(addr); }
u8 Mapper_474::peek(u16 addr) const {
// Wired to the PPU MMU
if (in_range(addr, 0x0000, 0x1FFF)) return this->chr_mem->peek(addr);

// Wired to the CPU MMU

// submapper 3 has_battery must be true
if (in_range(addr, 0x4020, 0x5FFF)) return this->has_battery ?
this->prg_ram.peek(addr - 0x4000) :
this->prg_extra->peek(addr - 0x4000);
if (in_range(addr, 0x6000, 0x7FFF)) return this->prg_extra->peek(addr - 0x4000);
if (in_range(addr, 0x8000, 0xBFFF)) return this->prg_lo->peek(addr - 0x8000);
if (in_range(addr, 0xC000, 0xFFFF)) return this->prg_hi->peek(addr - 0xC000);

assert(false);
return 0;
}

void Mapper_474::write(u16 addr, u8 val) {
// Since there is potentially CHR RAM, try to write to it (if in range)
if (in_range(addr, 0x0000, 0x1FFF)) {
this->chr_mem->write(addr, val);
}
else if (in_range(addr, 0x4020, 0x5FFF)) {
if (this->has_battery) {
this->prg_ram.write(addr - 0x4000, val);
}
}
}

void Mapper_474::update_banks() {
this->prg_extra = &this->get_prg_bank(0);
this->prg_lo = &this->get_prg_bank(1);
this->prg_hi = &this->get_prg_bank(2);

this->chr_mem = &this->get_chr_bank(0);
}
45 changes: 45 additions & 0 deletions src/nes/cartridge/mappers/mapper_474.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "nes/generic/ram/ram.h"
#include "nes/generic/rom/rom.h"
#include "common/util.h"
#include "../mapper.h"

#include "common/serializable.h"

// https://www.nesdev.org/wiki/NES_2.0_Mapper_474
class Mapper_474 final : public Mapper {
private:
// CPU Memory Space
RAM prg_ram; // 0x4020 ... 0x5FFF - Fixed RAM (only submapper 3)
ROM* prg_extra; // 0x4020 ... 0x7FFF - Fixed
ROM* prg_lo; // 0x8000 ... 0xBFFF - Fixed
ROM* prg_hi; // 0xC000 ... 0xFFFF - Fixed

// PPU Memory Space
Memory* chr_mem; // 0x0000 ... 0x1FFF - Fixed

Mirroring::Type mirror_mode;
bool has_battery;

SERIALIZE_PARENT(Mapper)
SERIALIZE_START(1, "Mapper_474")
SERIALIZE_POD(mirror_mode)
SERIALIZE_END(1)

void update_banks() override;

// Nothing to reset...
void reset() override {}

public:
Mapper_474(const ROM_File& rom_file);

// <Memory>
u8 read(u16 addr) override;
u8 peek(u16 addr) const override;
void write(u16 addr, u8 val) override;
// <Memory/>

Mirroring::Type mirroring() const override { return this->mirror_mode; };
};
9 changes: 8 additions & 1 deletion src/nes/cartridge/parse_rom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ static ROM_File* parseROM_iNES(const u8* data, uint data_len) {
if (rf->meta.is_VS)
fprintf(stderr, "[File Parsing][iNES] This is a VS ROM\n");

rf->meta.mapper = data[6] >> 4 | (data[7] & 0xFF00);
if (is_NES2)
{
rf->meta.mapper = data[6] >> 4 | (data[7] & 0xF0) | ((data[8] & 0xF) << 8);
}
else
{
rf->meta.mapper = data[6] >> 4 | (data[7] & 0xF0);
}

fprintf(stderr, "[File Parsing][iNES] Mapper: %d\n", rf->meta.mapper);

Expand Down
2 changes: 1 addition & 1 deletion src/nes/cartridge/rom_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct ROM_File {
struct { // ROM metadata
Mirroring::Type mirror_mode;

u8 mapper;
u16 mapper;

bool has_battery; // Has battery backed SRAM at 0x6000 - 0x7FFF
bool has_trainer; // Has 512 byte trainer at 0x7000 - 0x71FF
Expand Down
Loading