diff --git a/Components/SN76489/SN76489.cpp b/Components/SN76489/SN76489.cpp index 495a43607..a321b3898 100644 --- a/Components/SN76489/SN76489.cpp +++ b/Components/SN76489/SN76489.cpp @@ -8,11 +8,12 @@ #include "SN76489.hpp" +#include #include using namespace TI; -SN76489::SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_(task_queue) { +SN76489::SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue, int additional_divider) : task_queue_(task_queue) { // Build a volume table. double multiplier = pow(10.0, -0.1); double volume = 8191.0f; @@ -37,6 +38,10 @@ SN76489::SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue & shifter_is_16bit_ = true; break; } + + assert((master_divider_period_ % additional_divider) == 0); + assert(additional_divider < master_divider_period_); + master_divider_period_ /= additional_divider; } void SN76489::set_register(uint8_t value) { diff --git a/Components/SN76489/SN76489.hpp b/Components/SN76489/SN76489.hpp index eb58af331..12f2b2d3f 100644 --- a/Components/SN76489/SN76489.hpp +++ b/Components/SN76489/SN76489.hpp @@ -23,7 +23,7 @@ class SN76489: public Outputs::Speaker::SampleSource { }; /// Creates a new SN76489. - SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue); + SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue, int additional_divider = 1); /// Writes a new value to the SN76489. void set_register(uint8_t value); diff --git a/Machines/ColecoVision/ColecoVision.cpp b/Machines/ColecoVision/ColecoVision.cpp index 77ecded30..d742baa74 100644 --- a/Machines/ColecoVision/ColecoVision.cpp +++ b/Machines/ColecoVision/ColecoVision.cpp @@ -21,6 +21,10 @@ #include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" +namespace { +const int sn76489_divider = 4; +} + namespace Coleco { namespace Vision { @@ -107,10 +111,9 @@ class ConcreteMachine: public: ConcreteMachine() : z80_(*this), - sn76489_(TI::SN76489::Personality::SN76489, audio_queue_), + sn76489_(TI::SN76489::Personality::SN76489, audio_queue_, sn76489_divider), speaker_(sn76489_) { -// speaker_.set_input_rate(3579545.0f); - speaker_.set_input_rate(3579545.0f / 2.0f); + speaker_.set_input_rate(3579545.0f / static_cast(sn76489_divider)); set_clock_rate(3579545); joysticks_.emplace_back(new Joystick); joysticks_.emplace_back(new Joystick); @@ -176,7 +179,7 @@ class ConcreteMachine: case CPU::Z80::PartialMachineCycle::ReadOpcode: case CPU::Z80::PartialMachineCycle::Read: if(address < 0x2000) { - *cycle.value = bios_[address]; + *cycle.value = bios_[address & 0x1fff]; } else if(address >= 0x6000 && address < 0x8000) { *cycle.value = ram_[address & 1023]; } else if(address >= 0x8000) { @@ -264,8 +267,7 @@ class ConcreteMachine: private: void update_audio() { - speaker_.run_for(audio_queue_, time_since_sn76489_update_.divide_cycles(Cycles(2))); -// speaker_.run_for(audio_queue_, time_since_sn76489_update_.cycles()); + speaker_.run_for(audio_queue_, time_since_sn76489_update_.divide_cycles(Cycles(sn76489_divider))); } void update_video() { vdp_->run_for(time_since_vdp_update_.flush());