1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Propagates time to the audio subsystem.

This commit is contained in:
Thomas Harte 2021-11-12 15:30:52 -05:00
parent 0f6934a131
commit fffc03c4e4
5 changed files with 35 additions and 9 deletions

View File

@ -166,6 +166,10 @@ class ConcreteMachine:
return access_delay;
}
void flush() {
chipset_.flush();
}
private:
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;

View File

@ -7,12 +7,16 @@
//
#include "Audio.hpp"
#define LOG_PREFIX "[Audio] "
#include "../../Outputs/Log.hpp"
#include <cassert>
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

View File

@ -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];
};

View File

@ -140,6 +140,9 @@ template <int cycle> 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 <bool stop_on_cpu> int Chipset::advance_slots(int first_slot, int last_
template <bool stop_on_cpu> 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<int>();
@ -1286,3 +1287,7 @@ uint16_t Chipset::Mouse::get_position() {
declared_position_[0]
);
}
void Chipset::flush() {
audio_.flush();
}

View File

@ -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<Audio> audio_;
JustInTimeActor<Audio, Cycles> audio_;
// MARK: - Serial port.