From fffc03c4e4aae7abd319d7508c800672d220803f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 Nov 2021 15:30:52 -0500 Subject: [PATCH] Propagates time to the audio subsystem. --- Machines/Amiga/Amiga.cpp | 4 ++++ Machines/Amiga/Audio.cpp | 12 ++++++++---- Machines/Amiga/Audio.hpp | 15 +++++++++++++-- Machines/Amiga/Chipset.cpp | 9 +++++++-- Machines/Amiga/Chipset.hpp | 4 +++- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Machines/Amiga/Amiga.cpp b/Machines/Amiga/Amiga.cpp index ee638f454..dcaefae53 100644 --- a/Machines/Amiga/Amiga.cpp +++ b/Machines/Amiga/Amiga.cpp @@ -166,6 +166,10 @@ class ConcreteMachine: return access_delay; } + void flush() { + chipset_.flush(); + } + private: CPU::MC68000::Processor mc68000_; diff --git a/Machines/Amiga/Audio.cpp b/Machines/Amiga/Audio.cpp index 4a9ece054..d64f5b2fb 100644 --- a/Machines/Amiga/Audio.cpp +++ b/Machines/Amiga/Audio.cpp @@ -7,12 +7,16 @@ // #include "Audio.hpp" + +#define LOG_PREFIX "[Audio] " +#include "../../Outputs/Log.hpp" + #include using namespace Amiga; bool Audio::advance(int channel) { - if(channels_[channel].samples_remaining || !channels_[channel].length) { + if(channels_[channel].has_data || !channels_[channel].length) { return false; } @@ -40,10 +44,10 @@ void Audio::set_volume(int channel, uint16_t volume) { void Audio::set_data(int channel, uint16_t data) { assert(channel >= 0 && channel < 4); - if(!channels_[channel].samples_remaining) { + if(!channels_[channel].has_data) { channels_[channel].period_counter = channels_[channel].period; } - channels_[channel].samples_remaining = 2; + channels_[channel].has_data = true; channels_[channel].data = data; } @@ -57,7 +61,7 @@ void Audio::set_channel_enables(uint16_t enables) { void Audio::set_modulation_flags(uint16_t) { } -void Audio::run_for(HalfCycles) { +void Audio::run_for([[maybe_unused]] Cycles duration) { // TODO: // // Check whether any channel's period counter is exhausted and, if diff --git a/Machines/Amiga/Audio.hpp b/Machines/Amiga/Audio.hpp index 84c5aafb7..e595cf2fb 100644 --- a/Machines/Amiga/Audio.hpp +++ b/Machines/Amiga/Audio.hpp @@ -28,7 +28,7 @@ class Audio: public DMADevice<4> { /// Standard JustInTimeActor item; allows this class to track the /// amount of time between other events. - void run_for(HalfCycles); + void run_for(Cycles); /// Sets the total number of words to fetch for the given channel. void set_length(int channel, uint16_t); @@ -58,7 +58,7 @@ class Audio: public DMADevice<4> { // The data latch plus a count of unused samples // in the latch, which will always be 0, 1 or 2. uint16_t data = 0x0000; - int samples_remaining = 0; + bool has_data = false; // Number of words remaining in DMA data. uint16_t length = 0; @@ -73,6 +73,17 @@ class Audio: public DMADevice<4> { // Indicates whether DMA is enabled for this channel. bool dma_enabled = false; + + // Replicates the Hardware Reference Manual state machine; + // comments indicate which of the documented states each + // label refers to. + enum class State { + Disabled, // 000 + WaitingForDummyDMA, // 001 + WaitingForDMA, // 101 + PlayingHigh, // 010 + PlayingLow, // 011 + } state_; } channels_[4]; }; diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 083aa0e49..3dbf31217 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -140,6 +140,9 @@ template void Chipset::output() { constexpr int blank3 = 7 + burst; static_assert(blank3 == 43); + // Advance audio. + audio_ += Cycles(1); + // Trigger any sprite loads encountered. constexpr auto dcycle = cycle << 1; for(int c = 0; c < 8; c += 2) { @@ -444,8 +447,6 @@ template int Chipset::advance_slots(int first_slot, int last_ template Chipset::Changes Chipset::run(HalfCycles length) { Changes changes; - // TODO: incorporate audio timing here or deeper. - // This code uses 'pixels' as a measure, which is equivalent to one pixel clock time, // or half a cycle. auto pixels_remaining = length.as(); @@ -1286,3 +1287,7 @@ uint16_t Chipset::Mouse::get_position() { declared_position_[0] ); } + +void Chipset::flush() { + audio_.flush(); +} diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 67cd477f8..d9bc70493 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -102,6 +102,8 @@ class Chipset: private ClockingHint::Observer { return keyboard_; } + void flush(); + private: friend class DMADeviceBase; @@ -309,7 +311,7 @@ class Chipset: private ClockingHint::Observer { // MARK: - Audio. - JustInTimeActor