1 module nes.mapper225;
2 
3 import std.conv;
4 import std.format;
5 import std.stdio;
6 
7 import nes.cartridge;
8 import nes.mapper;
9 import nes.memory;
10 
11 class Mapper225 : Mapper {
12     this(Cartridge cartridge) {
13         this.cart = cartridge;
14         this.chrBank = 0;
15         this.prgBank1 = 0;
16 
17         auto prgBanks = cast(int)(cartridge.prg.length / 0x4000);
18 
19         this.prgBank2 = prgBanks - 1;
20     }
21 
22     void step() {
23     }
24 
25     ubyte read(ushort address) {
26         if (address < 0x2000) {
27             auto index = this.chrBank * 0x2000 + cast(int)address;
28             return this.cart.chr[index];
29         }
30         else if (address >= 0xC000) {
31             auto index = this.prgBank2 * 0x4000 + cast(int)(address - 0xC000);
32             return this.cart.prg[index];
33         }
34         else if (address >= 0x8000) {
35             auto index = this.prgBank1 * 0x4000 + cast(int)(address - 0x8000);
36             return this.cart.prg[index];
37         }
38         else if (address >= 0x6000) {
39             auto index = cast(int)address - 0x6000;
40             return this.cart.sram[index];
41         }
42         else {
43             throw new MapperException(format("unhandled mapper225 read at address: 0x%04X", address));
44         }
45     }
46 
47     void write(ushort address, ubyte value) {
48         if (address < 0x8000) {
49             return;
50         }
51 
52         auto a = cast(int)address;
53         auto bank = (a >> 14) & 1;
54         this.chrBank = (a & 0x3f) | (bank << 6);
55         auto prg = ((a >> 6) & 0x3f) | (bank << 6);
56         auto mode = (a >> 12) & 1;
57         if (mode == 1) {
58             this.prgBank1 = prg;
59             this.prgBank2 = prg;
60         } else {
61             this.prgBank1 = prg;
62             this.prgBank2 = prg + 1;
63         }
64 
65         auto mirr = (a >> 13) & 1;
66         if (mirr == 1) {
67             this.cart.mirror = MirrorHorizontal;
68         } else {
69             this.cart.mirror = MirrorVertical;
70         }
71     }
72 
73     void save(string[string] state) {
74         state["mapper225.chrBank"] = to!string(this.chrBank);
75         state["mapper225.prgBank1"] = to!string(this.prgBank1);
76         state["mapper225.prgBank2"] = to!string(this.prgBank2);
77     }
78 
79     void load(string[string] state) {
80         this.chrBank = to!int(state["mapper225.chrBank"]);
81         this.prgBank1 = to!int(state["mapper225.prgBank1"]);
82         this.prgBank2 = to!int(state["mapper225.prgBank2"]);
83     }
84 
85     private:
86         Cartridge cart;
87         int chrBank;
88         int prgBank1;
89         int prgBank2;
90 }