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