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 }