From 3390eb07bdee8b39eebc7822b36d5901dd3fb077 Mon Sep 17 00:00:00 2001 From: Ignacio Sanchez Gines <863613+drhelius@users.noreply.github.com> Date: Sat, 6 Apr 2024 20:24:38 +0200 Subject: [PATCH] Add differences for TI SN76489 in SG-1000. Fix #100 --- src/Audio.cpp | 4 ++-- src/GearsystemCore.cpp | 2 +- src/Processor.cpp | 15 ++++++++++++++- src/Processor.h | 4 +++- src/SmsIOPorts.cpp | 3 ++- src/SmsIOPorts.h | 7 ++++++- src/audio/Sms_Apu.cpp | 24 ++++++++++++++---------- src/audio/Sms_Apu.h | 2 +- src/audio/Sms_Oscs.h | 3 ++- 9 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/Audio.cpp b/src/Audio.cpp index 0f3ecdaa..53e59143 100644 --- a/src/Audio.cpp +++ b/src/Audio.cpp @@ -72,7 +72,7 @@ void Audio::Reset(bool bPAL) m_bYM2413Enabled = false; m_pYM2413->Enable(false); m_bPSGEnabled = true; - m_pApu->reset(); + m_pApu->reset(m_pCartridge->IsSG1000()); m_pApu->volume(1.0); m_pBuffer->clear(); m_pBuffer->clock_rate(m_bPAL ? GS_MASTER_CLOCK_PAL : GS_MASTER_CLOCK_NTSC); @@ -144,7 +144,7 @@ void Audio::LoadState(std::istream& stream) stream.read(reinterpret_cast (m_pYM2413Buffer), sizeof(s16) * GS_AUDIO_BUFFER_SIZE); m_pYM2413->LoadState(stream); - m_pApu->reset(); + m_pApu->reset(m_pCartridge->IsSG1000()); m_pApu->volume(1.0); m_pBuffer->clear(); } diff --git a/src/GearsystemCore.cpp b/src/GearsystemCore.cpp index 441ed7e5..5d2fb464 100644 --- a/src/GearsystemCore.cpp +++ b/src/GearsystemCore.cpp @@ -91,7 +91,7 @@ void GearsystemCore::Init(GS_Color_Format pixelFormat) m_pVideo = new Video(m_pMemory, m_pProcessor, m_pCartridge); m_pInput = new Input(m_pProcessor); m_pAudio = new Audio(m_pCartridge); - m_pSmsIOPorts = new SmsIOPorts(m_pAudio, m_pVideo, m_pInput, m_pCartridge, m_pMemory); + m_pSmsIOPorts = new SmsIOPorts(m_pAudio, m_pVideo, m_pInput, m_pCartridge, m_pMemory, m_pProcessor); m_pGameGearIOPorts = new GameGearIOPorts(m_pAudio, m_pVideo, m_pInput, m_pCartridge, m_pMemory); m_pMemory->Init(); diff --git a/src/Processor.cpp b/src/Processor.cpp index 94ab6df5..6fe5390f 100644 --- a/src/Processor.cpp +++ b/src/Processor.cpp @@ -35,6 +35,7 @@ Processor::Processor(Memory* pMemory) m_bHalt = false; m_bBranchTaken = false; m_iTStates = 0; + m_iInjectedTStates = 0; m_bAfterEI = false; m_iInterruptMode = 0; m_bINTRequested = false; @@ -84,6 +85,7 @@ void Processor::Reset() m_bHalt = false; m_bBranchTaken = false; m_iTStates = 0; + m_iInjectedTStates = 0; m_bAfterEI = false; m_iInterruptMode = 1; PC.SetValue(0x0000); @@ -121,7 +123,7 @@ IOPorts* Processor::GetIOPOrts() return m_pIOPorts; } -unsigned int Processor::RunFor(u8 tstates) +unsigned int Processor::RunFor(unsigned int tstates) { u8 executed = 0; @@ -168,11 +170,22 @@ unsigned int Processor::RunFor(u8 tstates) DisassembleNextOpcode(); executed += m_iTStates; + + if (m_iInjectedTStates > 0) + { + executed += m_iInjectedTStates; + m_iInjectedTStates = 0; + } } return executed; } +void Processor::InjectTStates(unsigned int tstates) +{ + m_iInjectedTStates += tstates; +} + void Processor::RequestINT(bool assert) { m_bINTRequested = assert; diff --git a/src/Processor.h b/src/Processor.h index a79dc524..ec448416 100644 --- a/src/Processor.h +++ b/src/Processor.h @@ -59,7 +59,8 @@ class Processor ~Processor(); void Init(); void Reset(); - unsigned int RunFor(u8 tstates); + unsigned int RunFor(unsigned int tstates); + void InjectTStates(unsigned int tstates); void RequestINT(bool assert); void RequestNMI(); void SetIOPOrts(IOPorts* pIOPorts); @@ -101,6 +102,7 @@ class Processor bool m_bHalt; bool m_bBranchTaken; unsigned int m_iTStates; + unsigned int m_iInjectedTStates; bool m_bAfterEI; int m_iInterruptMode; IOPorts* m_pIOPorts; diff --git a/src/SmsIOPorts.cpp b/src/SmsIOPorts.cpp index d63a6c0c..78d06cfe 100644 --- a/src/SmsIOPorts.cpp +++ b/src/SmsIOPorts.cpp @@ -19,13 +19,14 @@ #include "SmsIOPorts.h" -SmsIOPorts::SmsIOPorts(Audio* pAudio, Video* pVideo, Input* pInput, Cartridge* pCartridge, Memory* pMemory) +SmsIOPorts::SmsIOPorts(Audio* pAudio, Video* pVideo, Input* pInput, Cartridge* pCartridge, Memory* pMemory, Processor* pProcessor) { m_pAudio = pAudio; m_pVideo = pVideo; m_pInput = pInput; m_pCartridge = pCartridge; m_pMemory = pMemory; + m_pProcessor = pProcessor; m_Port3F = 0; m_Port3F_HC = 0; } diff --git a/src/SmsIOPorts.h b/src/SmsIOPorts.h index 1c51d2a8..d6b497f1 100644 --- a/src/SmsIOPorts.h +++ b/src/SmsIOPorts.h @@ -27,11 +27,12 @@ class Video; class Input; class Cartridge; class Memory; +class Processor; class SmsIOPorts : public IOPorts { public: - SmsIOPorts(Audio* pAudio, Video* pVideo, Input* pInput, Cartridge* pCartridge, Memory* pMemory); + SmsIOPorts(Audio* pAudio, Video* pVideo, Input* pInput, Cartridge* pCartridge, Memory* pMemory, Processor* pProcessor); ~SmsIOPorts(); void Reset(); u8 DoInput(u8 port); @@ -44,6 +45,7 @@ class SmsIOPorts : public IOPorts Input* m_pInput; Cartridge* m_pCartridge; Memory* m_pMemory; + Processor* m_pProcessor; u8 m_Port3F; u8 m_Port3F_HC; @@ -54,6 +56,7 @@ class SmsIOPorts : public IOPorts #include "Input.h" #include "Cartridge.h" #include "Memory.h" +#include "Processor.h" #include "YM2413.h" inline u8 SmsIOPorts::DoInput(u8 port) @@ -126,6 +129,8 @@ inline void SmsIOPorts::DoOutput(u8 port, u8 value) { // Writes to any address go to the SN76489 PSG m_pAudio->WriteAudioRegister(value); + if (m_pCartridge->IsSG1000()) + m_pProcessor->InjectTStates(32); } else if ((port >= 0x80) && (port < 0xC0)) { diff --git a/src/audio/Sms_Apu.cpp b/src/audio/Sms_Apu.cpp index 4110e12e..90b368ec 100644 --- a/src/audio/Sms_Apu.cpp +++ b/src/audio/Sms_Apu.cpp @@ -96,8 +96,9 @@ void Sms_Square::run( blip_time_t time, blip_time_t end_time ) static int const noise_periods [3] = { 0x100, 0x200, 0x400 }; -inline void Sms_Noise::reset() +inline void Sms_Noise::reset(bool ti_chip) { + ti = ti_chip; period = &noise_periods [0]; shifter = 0x8000; feedback = 0x9000; @@ -106,7 +107,12 @@ inline void Sms_Noise::reset() void Sms_Noise::run( blip_time_t time, blip_time_t end_time ) { - int amp = (shifter & 1) ? 0 : volume * 2; + int amp = (shifter & 1) ? 0 : volume; + + if (!ti) + { + amp *= 2; + } { int delta = amp - last_amp; @@ -163,7 +169,7 @@ Sms_Apu::Sms_Apu() oscs [3] = &noise; volume( 1.0 ); - reset(); + reset(false); } Sms_Apu::~Sms_Apu() @@ -200,17 +206,15 @@ void Sms_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right osc_output( i, center, left, right ); } -void Sms_Apu::reset( unsigned feedback, int noise_width ) +void Sms_Apu::reset(bool ti_chip ) { last_time = 0; latch = 0; ggstereo_save = 0xFF; - if ( !feedback || !noise_width ) - { - feedback = 0x0009; - noise_width = 16; - } + unsigned feedback = ti_chip ? 0x0003 : 0x0009; + int noise_width = ti_chip ? 15 : 16; + // convert to "Galios configuration" looped_feedback = 1 << (noise_width - 1); noise_feedback = 0; @@ -223,7 +227,7 @@ void Sms_Apu::reset( unsigned feedback, int noise_width ) squares [0].reset(); squares [1].reset(); squares [2].reset(); - noise.reset(); + noise.reset(ti_chip); } void Sms_Apu::run_until( blip_time_t end_time ) diff --git a/src/audio/Sms_Apu.h b/src/audio/Sms_Apu.h index a170590d..cd54547a 100644 --- a/src/audio/Sms_Apu.h +++ b/src/audio/Sms_Apu.h @@ -30,7 +30,7 @@ class Sms_Apu { void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right ); // Reset oscillators and internal state - void reset( unsigned noise_feedback = 0, int noise_width = 0 ); + void reset( bool ti_chip ); // Write GameGear left/right assignment byte void write_ggstereo( blip_time_t, int ); diff --git a/src/audio/Sms_Oscs.h b/src/audio/Sms_Oscs.h index bbc465ff..d5d4b7f1 100644 --- a/src/audio/Sms_Oscs.h +++ b/src/audio/Sms_Oscs.h @@ -37,11 +37,12 @@ struct Sms_Noise : Sms_Osc const int* period; unsigned shifter; unsigned feedback; + bool ti; typedef Blip_Synth Synth; Synth synth; - void reset(); + void reset(bool ti_chip); void run( blip_time_t, blip_time_t ); };