Add iNes Mapper 003 (CNROM) Support

Add support for iNES Mapper 003, which is a very simple mapper
only swiching out CHR chunks.

There is 16kB of fixed space mapped from $C000-FFFF and,
optionally 16kB more of fixed space from $8000-$BFFF (if not,
this area is mirrored)

The CHR ROM from $0000-$1FFF is banked in 8k chunks, up to four.
Some games look for bus contention, it is not implemented.
This commit is contained in:
Jeff Katz 2016-11-28 23:15:58 +01:00
parent 85f8496f17
commit 7555d58e09
3 changed files with 76 additions and 0 deletions

View file

@ -3,6 +3,7 @@
#include "cpu.hpp"
#include "mappers/mapper0.hpp"
#include "mappers/mapper1.hpp"
#include "mappers/mapper3.hpp"
#include "mappers/mapper4.hpp"
#include "ppu.hpp"
#include "cartridge.hpp"
@ -52,6 +53,7 @@ void load(const char* fileName)
{
case 0: mapper = new Mapper0(rom); break;
case 1: mapper = new Mapper1(rom); break;
case 3: mapper = new Mapper3(rom); break;
case 4: mapper = new Mapper4(rom); break;
}

50
src/mappers/mapper3.cpp Normal file
View file

@ -0,0 +1,50 @@
#include "ppu.hpp"
#include "mappers/mapper3.hpp"
/* Based off of https://wiki.nesdev.com/w/index.php/INES_Mapper_003 */
/* Apply the registers state */
void Mapper3::apply()
{
if (PRG_size_16k)
{
/*
* mirror the bottom on the top
* 0x8000 - 0xBFFF ==
* 0xC000 - 0xFFFF
*/
map_prg<16>(0,0);
map_prg<16>(1,0);
}
else
{
/* no mirroring */
map_prg<16>(0,0);
map_prg<16>(1,1);
}
/* 8k bankswitched CHR */
map_chr<8>(0, regs[0] & 0b11);
/* mirroring is based on the header (soldered) */
set_mirroring(vertical_mirroring?PPU::VERTICAL:PPU::HORIZONTAL);
}
u8 Mapper3::write(u16 addr, u8 v)
{
/* check for bus contingency? */
/* chr bank switching */
if (addr & 0x8000)
{
regs[0] = v;
apply();
}
return v;
}
u8 Mapper3::chr_write(u16 addr, u8 v)
{
return chr[addr] = v;
}

24
src/mappers/mapper3.hpp Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include "mapper.hpp"
class Mapper3 : public Mapper
{
u8 regs[1];
bool vertical_mirroring;
bool PRG_size_16k;
void apply();
public:
Mapper3(u8* rom) : Mapper(rom)
{
PRG_size_16k = rom[4] == 1;
vertical_mirroring = rom[7] & 0x01;
regs[0] = 0;
apply();
}
u8 write(u16 addr, u8 v);
u8 chr_write(u16 addr, u8 v);
};