1 #pragma once
2 
3 #include "stdafx.h"
4 #include "MMC3.h"
5 
6 class MMC3_199 : public MMC3
7 {
8 private:
9 	uint8_t _exRegs[4];
10 
11 protected:
GetChrRamSize()12 	uint32_t GetChrRamSize() override { return 0x2000; }
GetChrRamPageSize()13 	uint16_t GetChrRamPageSize() override { return 0x400; }
14 
InitMapper()15 	void InitMapper() override
16 	{
17 		_exRegs[0] = 0xFE;
18 		_exRegs[1] = 0xFF;
19 		_exRegs[2] = 1;
20 		_exRegs[3] = 3;
21 
22 		MMC3::InitMapper();
23 	}
24 
StreamState(bool saving)25 	void StreamState(bool saving) override
26 	{
27 		MMC3::StreamState(saving);
28 		Stream(_exRegs[0], _exRegs[1], _exRegs[2], _exRegs[3]);
29 	}
30 
WriteRegister(uint16_t addr,uint8_t value)31 	void WriteRegister(uint16_t addr, uint8_t value) override
32 	{
33 		if(addr == 0x8001 && (GetState().Reg8000 & 0x08)) {
34 			_exRegs[GetState().Reg8000 & 0x03] = value;
35 			UpdatePrgMapping();
36 			UpdateChrMapping();
37 		} else {
38 			MMC3::WriteRegister(addr, value);
39 		}
40 	}
41 
UpdateMirroring()42 	void UpdateMirroring() override
43 	{
44 		switch(GetState().RegA000 & 0x03) {
45 			case 0: SetMirroringType(MirroringType::Vertical); break;
46 			case 1: SetMirroringType(MirroringType::Horizontal); break;
47 			case 2: SetMirroringType(MirroringType::ScreenAOnly); break;
48 			case 3: SetMirroringType(MirroringType::ScreenBOnly); break;
49 		}
50 	}
51 
UpdatePrgMapping()52 	void UpdatePrgMapping() override
53 	{
54 		MMC3::UpdatePrgMapping();
55 		SelectPRGPage(2, _exRegs[0]);
56 		SelectPRGPage(3, _exRegs[1]);
57 	}
58 
SelectCHRPage(uint16_t slot,uint16_t page,ChrMemoryType memoryType)59 	void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType) override
60 	{
61 		MMC3::SelectCHRPage(slot, page, page < 8 ? ChrMemoryType::ChrRam : ChrMemoryType::ChrRom);
62 
63 		MMC3::SelectCHRPage(0, _registers[0], _registers[0] < 8 ? ChrMemoryType::ChrRam : ChrMemoryType::ChrRom);
64 		MMC3::SelectCHRPage(1, _exRegs[2], _exRegs[2] < 8 ? ChrMemoryType::ChrRam : ChrMemoryType::ChrRom);
65 		MMC3::SelectCHRPage(2, _registers[1], _registers[1] < 8 ? ChrMemoryType::ChrRam : ChrMemoryType::ChrRom);
66 		MMC3::SelectCHRPage(3, _exRegs[3], _exRegs[3] < 8 ? ChrMemoryType::ChrRam : ChrMemoryType::ChrRom);
67 	}
68 };