Added basic EPSM IRQ behaviour
Added IRQ's for EPSM still WIP but should work Some cleanup of build warnings
This commit is contained in:
parent
c5ac9ecb74
commit
649a62e7e1
5 changed files with 113 additions and 10 deletions
|
@ -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];
|
||||
|
|
115
Core/EPSMAudio.h
115
Core/EPSMAudio.h
|
@ -5,6 +5,7 @@
|
|||
#include "BaseExpansionAudio.h"
|
||||
#include "SSGAudio.h"
|
||||
#include "Console.h"
|
||||
#include "Cpu.h"
|
||||
|
||||
#include <array>
|
||||
#include "ym3438.h"
|
||||
|
@ -19,9 +20,22 @@ private:
|
|||
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 @@ private:
|
|||
|
||||
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 @@ private:
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
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 @@ protected:
|
|||
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 @@ protected:
|
|||
if(input.wrote)
|
||||
{
|
||||
input.wrote = false;
|
||||
|
||||
OPN2_Write(&_chip, input.addr, input.data);
|
||||
}
|
||||
}
|
||||
|
@ -131,9 +231,9 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ public:
|
|||
_inputBuffer = {};
|
||||
|
||||
_clock = 0;
|
||||
_clockIRQ = 0;
|
||||
|
||||
irqATimerEnable = 0;
|
||||
irqBTimerEnable = 0;
|
||||
OPN2_Reset(&_chip);
|
||||
OPN2_SetChipType(0);
|
||||
}
|
||||
|
@ -182,13 +285,13 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ enum class IRQSource
|
|||
FrameCounter = 2,
|
||||
DMC = 4,
|
||||
FdsDisk = 8,
|
||||
EPSM = 16,
|
||||
};
|
||||
|
||||
enum class MemoryOperation
|
||||
|
|
|
@ -41,7 +41,6 @@ private:
|
|||
|
||||
void UpdateOutputLevel()
|
||||
{
|
||||
int16_t summedOutput = 0;
|
||||
_console->GetApu()->AddExpansionAudioDelta(AudioChannel::VRC7, _currentOutput - _lastOutput);
|
||||
_lastOutput = _currentOutput;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue