1 #pragma once 2 #include "stdafx.h" 3 #include "MMC3.h" 4 5 class MMC3_208 : public MMC3 6 { 7 private: 8 const uint8_t _protectionLut[256] = { 9 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09, 10 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01, 11 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x49, 0x19, 0x09, 0x59, 0x49, 0x19, 0x09, 12 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x51, 0x41, 0x11, 0x01, 0x51, 0x41, 0x11, 0x01, 13 0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 0x00, 0x10, 0x40, 0x50, 0x00, 0x10, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 0x08, 0x18, 0x48, 0x58, 0x08, 0x18, 0x48, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08, 18 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00, 19 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x48, 0x18, 0x08, 0x58, 0x48, 0x18, 0x08, 20 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x50, 0x40, 0x10, 0x00, 0x50, 0x40, 0x10, 0x00, 21 0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 0x01, 0x11, 0x41, 0x51, 0x01, 0x11, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 0x09, 0x19, 0x49, 0x59, 0x09, 0x19, 0x49, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 }; 26 27 uint8_t _exRegs[6]; 28 29 protected: RegisterStartAddress()30 uint16_t RegisterStartAddress() override { return 0x8000; } RegisterEndAddress()31 uint16_t RegisterEndAddress() override { return 0xFFFF; } AllowRegisterRead()32 bool AllowRegisterRead() override { return true; } 33 InitMapper()34 void InitMapper() override 35 { 36 _exRegs[5] = 3; 37 MMC3::InitMapper(); 38 AddRegisterRange(0x4800, 0x4FFF, MemoryOperation::Write); 39 AddRegisterRange(0x6800, 0x6FFF, MemoryOperation::Write); 40 AddRegisterRange(0x5000, 0x5FFF, MemoryOperation::Write); 41 AddRegisterRange(0x5800, 0x5FFF, MemoryOperation::Read); 42 RemoveRegisterRange(0x8000, 0xFFFF, MemoryOperation::Read); 43 } 44 StreamState(bool saving)45 void StreamState(bool saving) override 46 { 47 MMC3::StreamState(saving); 48 ArrayInfo<uint8_t> exRegs { _exRegs, 6 }; 49 Stream(exRegs); 50 } 51 UpdatePrgMapping()52 void UpdatePrgMapping() override 53 { 54 SelectPrgPage4x(0, _exRegs[5] << 2); 55 } 56 ReadRegister(uint16_t addr)57 uint8_t ReadRegister(uint16_t addr) override 58 { 59 return _exRegs[addr & 0x03]; 60 } 61 WriteRegister(uint16_t addr,uint8_t value)62 void WriteRegister(uint16_t addr, uint8_t value) override 63 { 64 if(addr >= 0x5000 && addr <= 0x5FFF) { 65 if(addr <= 0x57FF) { 66 _exRegs[4] = value; 67 } else { 68 _exRegs[addr & 0x03] = value ^ _protectionLut[_exRegs[4]]; 69 } 70 } else if(addr < 0x8000) { 71 _exRegs[5] = (value & 0x01) | ((value >> 3) & 0x02); 72 UpdatePrgMapping(); 73 } else { 74 MMC3::WriteRegister(addr, value); 75 } 76 } 77 };