1#include "ppu.hpp"
2#include "mapper.hpp"
3
4
5Mapper::Mapper(u8* rom) : rom(rom)
6{
7 // Read infos from header:
8 prgSize = rom[4] * 0x4000;
9 chrSize = rom[5] * 0x2000;
10 prgRamSize = rom[8] ? rom[8] * 0x2000 : 0x2000;
11 set_mirroring((rom[6] & 1) ? PPU::VERTICAL : PPU::HORIZONTAL);
12
13 this->prg = rom + 16;
14 this->prgRam = new u8[prgRamSize];
15
16 // CHR ROM:
17 if (chrSize)
18 this->chr = rom + 16 + prgSize;
19 // CHR RAM:
20 else
21 {
22 chrRam = true;
23 chrSize = 0x2000;
24 this->chr = new u8[chrSize];
25 }
26}
27
28Mapper::~Mapper()
29{
30 delete rom;
31 delete prgRam;
32 if (chrRam)
33 delete chr;
34}
35
36/* Access to memory */
37u8 Mapper::read(u16 addr)
38{
39 if (addr >= 0x8000)
40 return prg[prgMap[(addr - 0x8000) / 0x2000] + ((addr - 0x8000) % 0x2000)];
41 else
42 return prgRam[addr - 0x6000];
43}
44
45u8 Mapper::chr_read(u16 addr)
46{
47 return chr[chrMap[addr / 0x400] + (addr % 0x400)];
48}
49
50/* PRG mapping functions */
51template <int pageKBs> void Mapper::map_prg(int slot, int bank)
52{
53 if (bank < 0)
54 bank = (prgSize / (0x400*pageKBs)) + bank;
55
56 for (int i = 0; i < (pageKBs/8); i++)
57 prgMap[(pageKBs/8) * slot + i] = (pageKBs*0x400*bank + 0x2000*i) % prgSize;
58}
59template void Mapper::map_prg<32>(int, int);
60template void Mapper::map_prg<16>(int, int);
61template void Mapper::map_prg<8> (int, int);
62
63/* CHR mapping functions */
64template <int pageKBs> void Mapper::map_chr(int slot, int bank)
65{
66 for (int i = 0; i < pageKBs; i++)
67 chrMap[pageKBs*slot + i] = (pageKBs*0x400*bank + 0x400*i) % chrSize;
68}
69template void Mapper::map_chr<8>(int, int);
70template void Mapper::map_chr<4>(int, int);
71template void Mapper::map_chr<2>(int, int);
72template void Mapper::map_chr<1>(int, int);
73