1 #pragma once
2 #include "stdafx.h"
3 #include "BaseMapper.h"
4 
5 class Mapper103 : public BaseMapper
6 {
7 private:
8 	bool _prgRamDisabled;
9 	uint8_t _prgReg;
10 
11 protected:
GetPRGPageSize()12 	virtual uint16_t GetPRGPageSize() override { return 0x2000; }
GetCHRPageSize()13 	virtual uint16_t GetCHRPageSize() override { return 0x2000; }
GetWorkRamSize()14 	virtual uint32_t GetWorkRamSize() override { return 0x4000; }
GetWorkRamPageSize()15 	virtual uint32_t GetWorkRamPageSize() override { return 0x2000; }
RegisterStartAddress()16 	virtual uint16_t RegisterStartAddress() override { return 0x6000; }
EndStartAddress()17 	virtual uint16_t EndStartAddress() { return 0xFFFF; }
18 
InitMapper()19 	void InitMapper() override
20 	{
21 		_prgRamDisabled = false;
22 		_prgReg = 0;
23 		SelectCHRPage(0, 0);
24 		UpdateState();
25 	}
26 
StreamState(bool saving)27 	void StreamState(bool saving) override
28 	{
29 		BaseMapper::StreamState(saving);
30 		Stream(_prgRamDisabled, _prgReg);
31 		if(!saving) {
32 			UpdateState();
33 		}
34 	}
35 
UpdateState()36 	void UpdateState()
37 	{
38 		SelectPrgPage4x(0, -4);
39 		if(_prgRamDisabled) {
40 			SetCpuMemoryMapping(0x6000, 0x7FFF, _prgReg, PrgMemoryType::PrgRom);
41 		} else {
42 			SetCpuMemoryMapping(0x6000, 0x7FFF, 0, PrgMemoryType::WorkRam);
43 			SetCpuMemoryMapping(0xB800, 0xD7FF, 1, PrgMemoryType::WorkRam);
44 		}
45 	}
46 
WriteRegister(uint16_t addr,uint8_t value)47 	void WriteRegister(uint16_t addr, uint8_t value) override
48 	{
49 		switch(addr & 0xF000) {
50 			case 0x6000: case 0x7000:
51 				//Workram is always writeable, even when PRG ROM is mapped to $6000
52 				_workRam[addr - 0x6000] = value;
53 				break;
54 
55 			case 0x8000:
56 				_prgReg = value & 0x0F;
57 				UpdateState();
58 				break;
59 
60 			case 0xB000: case 0xC000: case 0xD000:
61 				//Workram is always writeable, even when PRG ROM is mapped to $B800-$D7FF
62 				if(addr >= 0xB800 && addr < 0xD800) {
63 					_workRam[0x2000 + addr - 0xB800] = value;
64 				}
65 				break;
66 
67 			case 0xE000:
68 				SetMirroringType(value & 0x08 ? MirroringType::Horizontal : MirroringType::Vertical);
69 				break;
70 
71 			case 0xF000:
72 				_prgRamDisabled = (value & 0x10) == 0x10;
73 				UpdateState();
74 				break;
75 		}
76 	}
77 };