From 649a62e7e13737fad45d9f46be732f352f7f3a66 Mon Sep 17 00:00:00 2001 From: Perkka2 <36314461+Perkka2@users.noreply.github.com> Date: Thu, 26 Aug 2021 15:03:02 +0200 Subject: [PATCH] Added basic EPSM IRQ behaviour Added IRQ's for EPSM still WIP but should work Some cleanup of build warnings --- Core/BaseMapper.cpp | 4 +- Core/EPSMAudio.h | 115 ++++++++++++++++++++++++++++++++++++++--- Core/MemoryManager.cpp | 2 +- Core/Types.h | 1 + Core/Vrc7Audio.h | 1 - 5 files changed, 113 insertions(+), 10 deletions(-) diff --git a/Core/BaseMapper.cpp b/Core/BaseMapper.cpp index d7785537f..ff19cf62c 100644 --- a/Core/BaseMapper.cpp +++ b/Core/BaseMapper.cpp @@ -14,7 +14,7 @@ #include "CPU.h" void BaseMapper::WriteRegister(uint16_t addr, uint8_t value) { } -void BaseMapper::WriteEPSM(uint16_t addr, uint8_t value) { _epsmaudio->WriteRegister(addr, value); } +void BaseMapper::WriteEPSM(uint16_t addr, uint8_t value) {_epsmaudio->WriteRegister(addr, value); } uint8_t BaseMapper::ReadRegister(uint16_t addr) { return 0; } void BaseMapper::InitMapper(RomData &romData) { } void BaseMapper::Reset(bool softReset) { } @@ -787,7 +787,7 @@ uint8_t BaseMapper::DebugReadRAM(uint16_t addr) void BaseMapper::WriteRAM(uint16_t addr, uint8_t value) { if((addr == 0x4016) & (_console->GetCpu()->GetCycleCount() % 2 == 1)){ WriteEPSM(addr, value); } - if ((addr >= 0x401c && addr <= 0x401f)) { WriteEPSM(addr, value); } + if ((addr >= 0x401c && addr <= 0x401f)) {WriteEPSM(addr, value); } if(_isWriteRegisterAddr[addr]) { if(_hasBusConflicts) { uint8_t prgValue = _prgPages[addr >> 8][(uint8_t)addr]; diff --git a/Core/EPSMAudio.h b/Core/EPSMAudio.h index 9aff336e3..9a6ed86a6 100644 --- a/Core/EPSMAudio.h +++ b/Core/EPSMAudio.h @@ -5,6 +5,7 @@ #include "BaseExpansionAudio.h" #include "SSGAudio.h" #include "Console.h" +#include "Cpu.h" #include #include "ym3438.h" @@ -19,9 +20,22 @@ class EPSMAudio : public EPSMSSGAudio int16_t _lastOutputs[2]; int16_t _currentOutputs[2]; uint8_t writeValue; - int16_t writeAddr; + uint16_t writeAddr; + uint16_t irqATimer; + uint16_t irqBTimer; + uint16_t irqACurrentTimer; + uint16_t irqBCurrentTimer; + uint8_t irqATimerEnable; + uint8_t irqBTimerEnable; + uint8_t irqAHighValue; + uint8_t irqALowValue; + uint8_t irqBValue; + uint16_t currentRegister; + double _clock; + double _clockIRQ; + double _cycleCountIRQ = 0; static constexpr uint8_t cycleCount = 24; @@ -39,7 +53,6 @@ class EPSMAudio : public EPSMSSGAudio void UpdateOutputLevel() { - int16_t summedOutput = 0; for (size_t x = 0; x < 2; x++) { _console->GetApu()->AddExpansionAudioDelta(x == 0 ? AudioChannel::EPSM_L : AudioChannel::EPSM_R, _currentOutputs[x] - _lastOutputs[x]); @@ -69,6 +82,71 @@ class EPSMAudio : public EPSMSSGAudio }; } + + void WriteToChipIRQ(uint16_t addr, uint8_t value) + { + switch (addr) { + case 0xC000: + case 0xC002: + currentRegister = value; + break; + + case 0xE000: + if (currentRegister == 0x24) { + //Timer A High 8 bits + //std::cout << "Timer A High 8 bits" << std::endl; + irqAHighValue = value; + } + if (currentRegister == 0x25) { + //Timer A Low 2 bits + //std::cout << "Timer A Low 2 bits" << std::endl; + irqALowValue = (value & 0x3); + } + if (currentRegister == 0x26) { + //Timer B 8 bits + //std::cout << "Timer B 8 bits" << std::endl; + irqBValue = value; + } + if ((currentRegister == 0x27) && ((value & 0x5)|(value & 0xA))) { + //Load+Enable IRQ (0xA = TimerB, 0x5 = TimerA) + //std::cout << "Load+Enable IRQ" << std::endl; + if ((currentRegister == 0x27) && (value & 0x5)) { + irqATimer = (uint16_t(irqAHighValue) << 2) | irqALowValue; + irqACurrentTimer = 72 * (1024 - irqATimer) * 2; + irqATimerEnable = 1; + //std::cout << "Load+Enable IRQ A" << std::endl; + } + if ((currentRegister == 0x27) && (value & 0xA)) { + irqBTimer = 1152 * (256 - irqBValue) * 2; + irqBCurrentTimer = irqBTimer; + irqBTimerEnable = 1; + //std::cout << "Load+Enable IRQ B " << irqBCurrentTimer << std::endl; + } + } + if ((currentRegister == 0x27) && (value & 0x30)) { + //Enable/Reset IRQ + //std::cout << std::hex << uint16_t(value) << "Reset IRQ" << std::endl; + _console->GetCpu()->ClearIrqSource(IRQSource::EPSM); + irqATimerEnable = 0; + irqBTimerEnable = 0; + } + if ((currentRegister == 0x29) && (value & 0x3)) { + //enable IRQ's + //std::cout << "enable IRQ's" << std::endl; + } + break; + case 0xE002: + /*if (currentRegister == 0x10) { + std::cout << "0x10" << std::endl; + }*/ + break; + } + + //irqBValue = value; + //std::cout << std::hex << irqBValue << std::endl; + + } + uint32_t getClockFrequency() { return _console->GetSettings()->GetEPSMClockFrequency() / 6; @@ -92,6 +170,29 @@ class EPSMAudio : public EPSMSSGAudio EPSMSSGAudio::ClockAudio(); _clock += getClockFrequency() / (double)_console->GetCpu()->GetClockRate(_console->GetModel()); + _clockIRQ += (getClockFrequency()*6) / (double)_console->GetCpu()->GetClockRate(_console->GetModel()); + while (_clockIRQ >= _cycleCountIRQ) { + _cycleCountIRQ++; + //std::cout << _cycleCountIRQ << std::endl; + if (irqATimerEnable) { + irqACurrentTimer--; + if (!irqACurrentTimer) { + //std::cout << "***IRQ***" << std::endl; + irqATimerEnable = 0; + _console->GetCpu()->SetIrqSource(IRQSource::EPSM); + } + + } + if (irqBTimerEnable) { + irqBCurrentTimer--; + if (!irqBCurrentTimer) { + //std::cout << "***IRQ***" << std::endl; + irqBTimerEnable = 0; + _console->GetCpu()->SetIrqSource(IRQSource::EPSM); + } + + } + } while (_clock >= cycleCount) { @@ -117,7 +218,6 @@ class EPSMAudio : public EPSMSSGAudio if(input.wrote) { input.wrote = false; - OPN2_Write(&_chip, input.addr, input.data); } } @@ -131,9 +231,9 @@ class EPSMAudio : public EPSMSSGAudio } } - virtual uint32_t GetSSGClockFrequency() + virtual uint32_t GetSSGClockFrequency() override { - return EPSMSSGAudio::GetSSGClockFrequency() * (_console->GetSettings()->GetEPSMClockFrequency() / 3579545.0 ); + return EPSMSSGAudio::GetSSGClockFrequency() * (_console->GetSettings()->GetEPSMClockFrequency() / 3579545 ); } public: @@ -144,7 +244,10 @@ class EPSMAudio : public EPSMSSGAudio _inputBuffer = {}; _clock = 0; + _clockIRQ = 0; + irqATimerEnable = 0; + irqBTimerEnable = 0; OPN2_Reset(&_chip); OPN2_SetChipType(0); } @@ -182,13 +285,13 @@ class EPSMAudio : public EPSMSSGAudio if (addr == 0x401d) { addr = 0xE000; } if (addr == 0x401e) { addr = 0xC002; } if (addr == 0x401f) { addr = 0xE002; } - switch(addr) { case 0xC000: case 0xE000: case 0xC002: case 0xE002: + WriteToChipIRQ(addr, value); const uint8_t a0 = (addr & 0xF000) == 0xE000; const uint8_t a1 = !!(addr & 0xF); EPSMSSGAudio::WriteRegister(addr, value); diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp index ce3308908..1d6423923 100644 --- a/Core/MemoryManager.cpp +++ b/Core/MemoryManager.cpp @@ -133,7 +133,7 @@ void MemoryManager::Write(uint16_t addr, uint8_t value, MemoryOperationType oper { if(_console->DebugProcessRamOperation(operationType, addr, value)) { _ramWriteHandlers[addr]->WriteRAM(addr, value); - if ((addr == 0x4016) | (addr >= 0x401c && addr <= 0x401f)) { + if ((addr == 0x4016) /*| (addr >= 0x401c && addr <= 0x401f)*/) { _ramWriteHandlers[0xE000]->WriteRAM(addr, value); } } diff --git a/Core/Types.h b/Core/Types.h index 0d3d0c9a4..6da8021a8 100644 --- a/Core/Types.h +++ b/Core/Types.h @@ -30,6 +30,7 @@ enum class IRQSource FrameCounter = 2, DMC = 4, FdsDisk = 8, + EPSM = 16, }; enum class MemoryOperation diff --git a/Core/Vrc7Audio.h b/Core/Vrc7Audio.h index 0c5c6b78e..975640869 100644 --- a/Core/Vrc7Audio.h +++ b/Core/Vrc7Audio.h @@ -41,7 +41,6 @@ class Vrc7Audio : public BaseExpansionAudio void UpdateOutputLevel() { - int16_t summedOutput = 0; _console->GetApu()->AddExpansionAudioDelta(AudioChannel::VRC7, _currentOutput - _lastOutput); _lastOutput = _currentOutput; }