From 80a6981ad2335fac09b2eb177d3846714e891126 Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 17 Jun 2018 12:47:57 -0400 Subject: [PATCH] UNIF: Added support for UNL-CITYFIGHT board --- Core/APU.cpp | 5 ++ Core/APU.h | 1 + Core/CityFighter.h | 115 ++++++++++++++++++++++++++++++++++++++ Core/Core.vcxproj | 1 + Core/Core.vcxproj.filters | 3 + Core/MapperFactory.cpp | 2 + Core/UnifBoards.h | 1 + Core/UnifLoader.cpp | 2 +- 8 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 Core/CityFighter.h diff --git a/Core/APU.cpp b/Core/APU.cpp index 743617e8..51834479 100644 --- a/Core/APU.cpp +++ b/Core/APU.cpp @@ -256,6 +256,11 @@ bool APU::IsApuEnabled() return _apuEnabled; } +void APU::WriteDmc4011(uint8_t value) +{ + Instance->_deltaModulationChannel->WriteRAM(0x4011, value); +} + ApuState APU::GetState() { ApuState state; diff --git a/Core/APU.h b/Core/APU.h index 91e26d52..9ff2430a 100644 --- a/Core/APU.h +++ b/Core/APU.h @@ -86,4 +86,5 @@ class APU : public Snapshotable, public IMemoryHandler static void AddExpansionAudioDelta(AudioChannel channel, int16_t delta); static void SetApuStatus(bool enabled); static bool IsApuEnabled(); + static void WriteDmc4011(uint8_t value); }; \ No newline at end of file diff --git a/Core/CityFighter.h b/Core/CityFighter.h new file mode 100644 index 00000000..ad8530e7 --- /dev/null +++ b/Core/CityFighter.h @@ -0,0 +1,115 @@ +#pragma once +#pragma once +#include "stdafx.h" +#include "APU.h" +#include "BaseMapper.h" + +class CityFighter : public BaseMapper +{ +private: + uint8_t _prgReg; + uint8_t _prgMode; + uint8_t _mirroring; + uint8_t _chrRegs[8]; + bool _irqEnabled; + uint16_t _irqCounter; + +protected: + uint16_t GetPRGPageSize() override { return 0x2000; } + uint16_t GetCHRPageSize() override { return 0x400; } + + void InitMapper() override + { + _prgReg = 0; + _prgMode = 0; + _mirroring = 0; + _irqCounter = 0; + _irqEnabled = false; + memset(_chrRegs, 0, sizeof(_chrRegs)); + + UpdateState(); + } + + void StreamState(bool saving) override + { + BaseMapper::StreamState(saving); + ArrayInfo chrRegs { _chrRegs, 8 }; + Stream(_prgReg, _prgMode, _mirroring, _irqEnabled, _irqCounter, chrRegs); + } + + void UpdateState() + { + SelectPrgPage4x(0x8000, _prgReg); + if(!_prgMode) { + SelectPRGPage(2, _prgReg); + } + + for(int i = 0; i < 8; i++) { + SelectCHRPage(i, _chrRegs[i]); + } + + switch(_mirroring) { + case 0: SetMirroringType(MirroringType::Vertical); break; + case 1: SetMirroringType(MirroringType::Horizontal); break; + case 2: SetMirroringType(MirroringType::ScreenAOnly); break; + case 3: SetMirroringType(MirroringType::ScreenBOnly); break; + } + } + + void ProcessCpuClock() override + { + if(_irqEnabled) { + _irqCounter--; + if(_irqCounter == 0) { + CPU::SetIRQSource(IRQSource::External); + } + } + } + + void WriteRegister(uint16_t addr, uint8_t value) override + { + switch(addr & 0xF00C) { + case 0x9000: + _prgReg = value & 0x0C; + _mirroring = value & 0x03; + break; + + case 0x9004: case 0x9008: case 0x900C: + if(addr & 0x800) { + APU::WriteDmc4011((value & 0x0F) << 3); + } else { + _prgReg = value & 0x0C; + } + break; + + case 0xC000: case 0xC004: case 0xC008: case 0xC00C: + _prgMode = value & 0x01; + break; + + case 0xD000: _chrRegs[0] = (_chrRegs[0] & 0xF0) | (value & 0x0F); break; + case 0xD004: _chrRegs[0] = (_chrRegs[0] & 0x0F) | (value << 4); break; + case 0xD008: _chrRegs[1] = (_chrRegs[1] & 0xF0) | (value & 0x0F); break; + case 0xD00C: _chrRegs[1] = (_chrRegs[1] & 0x0F) | (value << 4); break; + case 0xA000: _chrRegs[2] = (_chrRegs[2] & 0xF0) | (value & 0x0F); break; + case 0xA004: _chrRegs[2] = (_chrRegs[2] & 0x0F) | (value << 4); break; + case 0xA008: _chrRegs[3] = (_chrRegs[3] & 0xF0) | (value & 0x0F); break; + case 0xA00C: _chrRegs[3] = (_chrRegs[3] & 0x0F) | (value << 4); break; + case 0xB000: _chrRegs[4] = (_chrRegs[4] & 0xF0) | (value & 0x0F); break; + case 0xB004: _chrRegs[4] = (_chrRegs[4] & 0x0F) | (value << 4); break; + case 0xB008: _chrRegs[5] = (_chrRegs[5] & 0xF0) | (value & 0x0F); break; + case 0xB00C: _chrRegs[5] = (_chrRegs[5] & 0x0F) | (value << 4); break; + case 0xE000: _chrRegs[6] = (_chrRegs[6] & 0xF0) | (value & 0x0F); break; + case 0xE004: _chrRegs[6] = (_chrRegs[6] & 0x0F) | (value << 4); break; + case 0xE008: _chrRegs[7] = (_chrRegs[7] & 0xF0) | (value & 0x0F); break; + case 0xE00C: _chrRegs[7] = (_chrRegs[7] & 0x0F) | (value << 4); break; + case 0xF000: _irqCounter = ((_irqCounter & 0x1E0) | ((value & 0x0F) << 1)); break; + case 0xF004: _irqCounter = ((_irqCounter & 0x1E) | ((value & 0x0F) << 5)); break; + case 0xF008: + _irqEnabled = (value & 0x02) != 0; + CPU::ClearIRQSource(IRQSource::External); + break; + } + + UpdateState(); + } +}; \ No newline at end of file diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index 3ec0b8e9..d1811eae 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -522,6 +522,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 2030e29f..d3d06573 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -1399,6 +1399,9 @@ Nes\Mappers\Unif + + Nes\Mappers\Unif + diff --git a/Core/MapperFactory.cpp b/Core/MapperFactory.cpp index 31f57dd9..c4007b68 100644 --- a/Core/MapperFactory.cpp +++ b/Core/MapperFactory.cpp @@ -37,6 +37,7 @@ #include "Caltron41.h" #include "Cc21.h" #include "Cheapocabra.h" +#include "CityFighter.h" #include "CNROM.h" #include "CpRom.h" #include "ColorDreams.h" @@ -538,6 +539,7 @@ BaseMapper* MapperFactory::GetMapperFromID(RomData &romData) case UnifBoards::BmdNtd03: return new BmcNtd03(); case UnifBoards::Bs5: return new Bs5(); case UnifBoards::Cc21: return new Cc21(); + case UnifBoards::CityFighter: return new CityFighter(); case UnifBoards::Coolboy: return new MMC3_Coolboy(); case UnifBoards::Dance2000: return new Dance2000(); case UnifBoards::DreamTech01: return new DreamTech01(); diff --git a/Core/UnifBoards.h b/Core/UnifBoards.h index f6acb0ce..d8dd10f9 100644 --- a/Core/UnifBoards.h +++ b/Core/UnifBoards.h @@ -61,5 +61,6 @@ namespace UnifBoards { Unl158B, Bmc80013B, Dance2000, + CityFighter, }; } \ No newline at end of file diff --git a/Core/UnifLoader.cpp b/Core/UnifLoader.cpp index b5ae3e71..19a42dc6 100644 --- a/Core/UnifLoader.cpp +++ b/Core/UnifLoader.cpp @@ -28,7 +28,7 @@ std::unordered_map UnifLoader::_boardMappings = std::unordered_map< { "BB", UnifBoards::Bb }, { "BS-5", UnifBoards::Bs5 }, { "CC-21", UnifBoards::Cc21 }, - { "CITYFIGHT", UnifBoards::UnknownBoard }, + { "CITYFIGHT", UnifBoards::CityFighter }, { "COOLBOY", UnifBoards::Coolboy }, { "10-24-C-A1", UnifBoards::UnknownBoard }, { "CNROM", 3 },