1 #pragma once 2 #include "BaseMapper.h" 3 #include "CPU.h" 4 5 class FrontFareast : public BaseMapper 6 { 7 private: 8 uint16_t _irqCounter; 9 bool _irqEnabled; 10 bool _ffeAltMode; 11 12 protected: GetPRGPageSize()13 uint16_t GetPRGPageSize() override { return 0x2000; } GetCHRPageSize()14 uint16_t GetCHRPageSize() override { return 0x400; } GetChrRamSize()15 uint32_t GetChrRamSize() override { return 0x8000; } RegisterStartAddress()16 uint16_t RegisterStartAddress() override { return 0x42FE; } RegisterEndAddress()17 uint16_t RegisterEndAddress() override { return 0x4517; } 18 InitMapper()19 void InitMapper() override 20 { 21 _irqCounter = 0; 22 _irqEnabled = false; 23 _ffeAltMode = true; 24 25 switch(_romInfo.MapperID) { 26 case 6: 27 AddRegisterRange(0x8000, 0xFFFF, MemoryOperation::Write); 28 SelectPrgPage2x(0, 0); 29 SelectPrgPage2x(1, 14); 30 break; 31 32 case 8: 33 AddRegisterRange(0x8000, 0xFFFF, MemoryOperation::Write); 34 SelectPrgPage4x(0, 0); 35 break; 36 37 case 17: 38 SelectPrgPage4x(0, -4); 39 break; 40 } 41 } 42 StreamState(bool saving)43 void StreamState(bool saving) override 44 { 45 BaseMapper::StreamState(saving); 46 Stream(_irqCounter, _irqEnabled, _ffeAltMode); 47 } 48 ProcessCpuClock()49 void ProcessCpuClock() override 50 { 51 if(_irqEnabled) { 52 _irqCounter++; 53 if(_irqCounter == 0) { 54 _console->GetCpu()->SetIrqSource(IRQSource::External); 55 _irqEnabled = false; 56 } 57 } 58 } 59 WriteRegister(uint16_t addr,uint8_t value)60 void WriteRegister(uint16_t addr, uint8_t value) override 61 { 62 switch(addr) { 63 case 0x42FE: 64 _ffeAltMode = (value & 0x80) == 0x00; 65 switch((value >> 4) & 0x01) { 66 case 0: SetMirroringType(MirroringType::ScreenAOnly); break; 67 case 1: SetMirroringType(MirroringType::ScreenBOnly); break; 68 } 69 break; 70 71 case 0x42FF: 72 switch((value >> 4) & 0x01) { 73 case 0: SetMirroringType(MirroringType::Vertical); break; 74 case 1: SetMirroringType(MirroringType::Horizontal); break; 75 } 76 break; 77 78 case 0x4501: 79 _irqEnabled = false; 80 _console->GetCpu()->ClearIrqSource(IRQSource::External); 81 break; 82 83 case 0x4502: 84 _irqCounter = (_irqCounter & 0xFF00) | value; 85 _console->GetCpu()->ClearIrqSource(IRQSource::External); 86 break; 87 88 case 0x4503: 89 _irqCounter = (_irqCounter & 0x00FF) | (value << 8); 90 _irqEnabled = true; 91 _console->GetCpu()->ClearIrqSource(IRQSource::External); 92 break; 93 94 default: 95 if(_romInfo.MapperID == 6) { 96 if(addr >= 0x8000) { 97 if(HasChrRam() || _ffeAltMode) { 98 SelectPrgPage2x(0, (value & 0xFC) >> 1); 99 value &= 0x03; 100 } 101 SelectChrPage8x(0, value << 3); 102 } 103 } else if(_romInfo.MapperID == 8) { 104 if(addr >= 0x8000) { 105 SelectPrgPage2x(0, (value & 0xF8) >> 2); 106 SelectChrPage8x(0, (value & 0x07) << 3); 107 } 108 } else { 109 switch(addr) { 110 case 0x4504: case 0x4505: case 0x4506: case 0x4507: 111 SelectPRGPage(addr - 0x4504, value); 112 break; 113 114 case 0x4510: case 0x4511: case 0x4512: case 0x4513: case 0x4514: case 0x4515: case 0x4516: case 0x4517: 115 SelectCHRPage(addr - 0x4510, value); 116 break; 117 } 118 } 119 } 120 } 121 }; 122