1 #pragma once 2 #include "stdafx.h" 3 #include "BaseMapper.h" 4 5 class Kaiser202 : public BaseMapper 6 { 7 uint16_t _irqReloadValue; 8 uint16_t _irqCounter; 9 bool _irqEnabled; 10 uint8_t _selectedReg; 11 uint8_t _prgRegs[4]; 12 13 protected: GetPRGPageSize()14 virtual uint16_t GetPRGPageSize() override { return 0x2000; } GetCHRPageSize()15 virtual uint16_t GetCHRPageSize() override { return 0x0400; } 16 InitMapper()17 void InitMapper() override 18 { 19 _irqReloadValue = 0; 20 _irqCounter = 0; 21 _irqEnabled = 0; 22 _selectedReg = 0; 23 memset(_prgRegs, 0, sizeof(_prgRegs)); 24 25 SelectPRGPage(3, -1); 26 } 27 StreamState(bool saving)28 void StreamState(bool saving) override 29 { 30 BaseMapper::StreamState(saving); 31 Stream(_irqReloadValue, _irqCounter, _irqEnabled, _selectedReg, _prgRegs[0], _prgRegs[1], _prgRegs[2], _prgRegs[3]); 32 33 if(!saving) { 34 SetCpuMemoryMapping(0x6000, 0x7FFF, _prgRegs[3], PrgMemoryType::PrgRom, MemoryAccessType::ReadWrite); 35 } 36 } 37 ProcessCpuClock()38 void ProcessCpuClock() override 39 { 40 if(_irqEnabled) { 41 _irqCounter++; 42 if(_irqCounter == 0xFFFF) { 43 _irqCounter = _irqReloadValue; 44 _console->GetCpu()->SetIrqSource(IRQSource::External); 45 } 46 } 47 } 48 WriteRegister(uint16_t addr,uint8_t value)49 void WriteRegister(uint16_t addr, uint8_t value) override 50 { 51 switch(addr & 0xF000) { 52 case 0x8000: _irqReloadValue = (_irqReloadValue & 0xFFF0) | (value & 0x0F); break; 53 case 0x9000: _irqReloadValue = (_irqReloadValue & 0xFF0F) | ((value & 0x0F) << 4); break; 54 case 0xA000: _irqReloadValue = (_irqReloadValue & 0xF0FF) | ((value & 0x0F) << 8); break; 55 case 0xB000: _irqReloadValue = (_irqReloadValue & 0x0FFF) | ((value & 0x0F) << 12); break; 56 57 case 0xC000: 58 _irqEnabled = (value != 0); 59 if(_irqEnabled) { 60 _irqCounter = _irqReloadValue; 61 } 62 _console->GetCpu()->ClearIrqSource(IRQSource::External); 63 break; 64 65 case 0xD000: _console->GetCpu()->ClearIrqSource(IRQSource::External); break; 66 case 0xE000: _selectedReg = (value & 0x0F) - 1; break; 67 68 case 0xF000: 69 if(_selectedReg < 3) { 70 _prgRegs[_selectedReg] = ((_prgRegs[_selectedReg]) & 0x10) | (value & 0x0F); 71 } else if(_selectedReg < 4) { 72 //For Kaiser7032 (Mapper 142) 73 _prgRegs[_selectedReg] = value; 74 SetCpuMemoryMapping(0x6000, 0x7FFF, value, PrgMemoryType::PrgRom, MemoryAccessType::ReadWrite); 75 } 76 77 switch(addr & 0xFC00) { 78 case 0xF000: { 79 uint8_t bank = addr & 0x03; 80 if(bank < 3) { 81 _prgRegs[bank] = (value & 0x10) | (_prgRegs[bank] & 0x0F); 82 } 83 break; 84 } 85 86 case 0xF800: 87 SetMirroringType(value & 0x01 ? MirroringType::Vertical : MirroringType::Horizontal); 88 break; 89 90 case 0xFC00: 91 SelectCHRPage(addr & 0x07, value); 92 break; 93 } 94 95 SelectPRGPage(0, _prgRegs[0]); 96 SelectPRGPage(1, _prgRegs[1]); 97 SelectPRGPage(2, _prgRegs[2]); 98 break; 99 } 100 } 101 };