1#include <cstdio>
2#include "apu.hpp"
3#include "cpu.hpp"
4#include "mappers/mapper0.hpp"
5#include "mappers/mapper1.hpp"
6#include "mappers/mapper2.hpp"
7#include "mappers/mapper3.hpp"
8#include "mappers/mapper4.hpp"
9#include "ppu.hpp"
10#include "cartridge.hpp"
11
12namespace Cartridge {
13
14
15Mapper* mapper = nullptr; // Mapper chip.
16
17/* PRG-ROM access */
18template <bool wr> u8 access(u16 addr, u8 v)
19{
20 if (!wr) return mapper->read(addr);
21 else return mapper->write(addr, v);
22}
23template u8 access<0>(u16, u8); template u8 access<1>(u16, u8);
24
25/* CHR-ROM/RAM access */
26template <bool wr> u8 chr_access(u16 addr, u8 v)
27{
28 if (!wr) return mapper->chr_read(addr);
29 else return mapper->chr_write(addr, v);
30}
31template u8 chr_access<0>(u16, u8); template u8 chr_access<1>(u16, u8);
32
33void signal_scanline()
34{
35 mapper->signal_scanline();
36}
37
38/* Load the ROM from a file. */
39void load(const char* fileName)
40{
41 FILE* f = fopen(fileName, "rb");
42
43 fseek(f, 0, SEEK_END);
44 int size = ftell(f);
45 fseek(f, 0, SEEK_SET);
46
47 u8* rom = new u8[size];
48 fread(rom, size, 1, f);
49 fclose(f);
50
51 int mapperNum = (rom[7] & 0xF0) | (rom[6] >> 4);
52 if (loaded())
53 {
54 delete mapper;
55 mapper = nullptr;
56 }
57 switch (mapperNum)
58 {
59 case 0: mapper = new Mapper0(rom); break;
60 case 1: mapper = new Mapper1(rom); break;
61 case 2: mapper = new Mapper2(rom); break;
62 case 3: mapper = new Mapper3(rom); break;
63 case 4: mapper = new Mapper4(rom); break;
64 default:
65 fprintf(stderr, "%s: mapper %d not supported\n", fileName, mapperNum);
66 return;
67 }
68
69 CPU::power();
70 PPU::reset();
71 APU::reset();
72}
73
74bool loaded()
75{
76 return mapper != nullptr;
77}
78
79
80}
81