|
| 1 | +#pragma once |
| 2 | +#include "stdafx.h" |
| 3 | +#include "MMC3.h" |
| 4 | + |
| 5 | +class MMC3_420 : public MMC3 |
| 6 | +{ |
| 7 | +private: |
| 8 | + uint8_t _exRegs[4]; |
| 9 | + |
| 10 | +protected: |
| 11 | + virtual void InitMapper() override |
| 12 | + { |
| 13 | + AddRegisterRange(0x6000, 0x7FFF, MemoryOperation::Write); |
| 14 | + MMC3::InitMapper(); |
| 15 | + } |
| 16 | + |
| 17 | + virtual void Reset(bool softReset) override |
| 18 | + { |
| 19 | + memset(_exRegs, 0, sizeof(_exRegs)); |
| 20 | + |
| 21 | + if(!softReset) { |
| 22 | + MMC3::ResetMmc3(); |
| 23 | + } |
| 24 | + |
| 25 | + MMC3::UpdateState(); |
| 26 | + } |
| 27 | + |
| 28 | + virtual void StreamState(bool saving) override |
| 29 | + { |
| 30 | + MMC3::StreamState(saving); |
| 31 | + Stream(_exRegs[0], _exRegs[1], _exRegs[2], _exRegs[3]); |
| 32 | + |
| 33 | + if (!saving) { |
| 34 | + MMC3::UpdateState(); |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | + virtual void SelectCHRPage(uint16_t slot, uint16_t page, ChrMemoryType memoryType = ChrMemoryType::Default) override |
| 39 | + { |
| 40 | + uint16_t mask = 0xFF >> ((_exRegs[1] & 0x80) >> 7); |
| 41 | + uint16_t base = ((_exRegs[1] << 1) & 0x100) | ((_exRegs[1] << 5) & 0x80); |
| 42 | + |
| 43 | + MMC3::SelectCHRPage(slot, base | (page & mask), memoryType); |
| 44 | + } |
| 45 | + |
| 46 | + virtual void SelectPRGPage(uint16_t slot, uint16_t page, PrgMemoryType memoryType = PrgMemoryType::PrgRom) override |
| 47 | + { |
| 48 | + uint16_t mask; |
| 49 | + uint16_t base; |
| 50 | + if(_exRegs[0] & 0x80) { |
| 51 | + base = ((_exRegs[0] >> 1) & 0x07 | ((_exRegs[3] >> 2) & 0x08)) << 2; |
| 52 | + page = slot; |
| 53 | + mask = 0x03; |
| 54 | + } else { |
| 55 | + mask = 0x3F >> (((_exRegs[3] & 0x20) >> 5) | ((_exRegs[0] & 0x20) >> 4)); |
| 56 | + base = ((_exRegs[3] << 3) & 0x20); |
| 57 | + } |
| 58 | + |
| 59 | + MMC3::SelectPRGPage(slot, base | (page & mask), memoryType); |
| 60 | + } |
| 61 | + |
| 62 | + void WriteRegister(uint16_t addr, uint8_t value) override |
| 63 | + { |
| 64 | + if(addr < 0x8000) { |
| 65 | + WritePrgRam(addr, value); |
| 66 | + _exRegs[addr & 3] = value; |
| 67 | + MMC3::UpdatePrgMapping(); |
| 68 | + MMC3::UpdateChrMapping(); |
| 69 | + } else { |
| 70 | + MMC3::WriteRegister(addr, value); |
| 71 | + } |
| 72 | + } |
| 73 | +}; |
0 commit comments