1 #pragma once
2 
3 #include "nes/generic/ram/ram.h"
4 #include "nes/generic/rom/rom.h"
5 #include "common/bitfield.h"
6 #include "common/util.h"
7 #include "../mapper.h"
8 
9 // https://wiki.nesdev.com/w/index.php/INES_Mapper_003
10 class Mapper_003 final : public Mapper {
11 private:
12   // CPU Memory Space
13   ROM* prg_lo;     // 0x8000 ... 0xBFFF - Fixed
14   ROM* prg_hi;     // 0xC000 ... 0xFFFF - Fixed
15 
16   // PPU Memory Space
17   Memory* chr_mem; // 0x0000 ... 0x1FFF - Switchable
18 
19   struct { // Registers
20     // Bank select - 0x8000 ... 0xFFFF
21     // 7  bit  0
22     // ---- ----
23     // cccc ccCC
24     // |||| ||||
25     // ++++-++++- Select 8 KB CHR ROM bank for PPU $0000-$1FFF
26     // CNROM only implements the lowest 2 bits, capping it at 32 KiB CHR.
27     // Other boards may implement 4 or more bits for larger CHR.
28     //
29     // ANESE will just give it the entire 8 bits...
30     u8 bank_select;
31   } reg;
32 
33   Mirroring::Type mirror_mode;
34 
35   void update_banks() override;
36 
37   void reset() override;
38 
39   SERIALIZE_PARENT(Mapper)
40   SERIALIZE_START(2, "Mapper_003")
41     SERIALIZE_POD(mirror_mode)
42     SERIALIZE_POD(reg)
43   SERIALIZE_END(2)
44 
45 public:
46   Mapper_003(const ROM_File& rom_file);
47 
48   // <Memory>
49   u8 peek(u16 addr) const override;
50   void write(u16 addr, u8 val) override;
51   // <Memory/>
52 
mirroring()53   Mirroring::Type mirroring() const override { return this->mirror_mode; };
54 };
55