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

Provides feedback on interrupt flags, starts on state machine.

This commit is contained in:
Thomas Harte 2021-11-13 11:05:39 -05:00
parent fffc03c4e4
commit f906bab1a5
3 changed files with 31 additions and 1 deletions

View File

@ -8,6 +8,8 @@
#include "Audio.hpp"
#include "Flags.hpp"
#define LOG_PREFIX "[Audio] "
#include "../../Outputs/Log.hpp"
@ -61,10 +63,31 @@ void Audio::set_channel_enables(uint16_t enables) {
void Audio::set_modulation_flags(uint16_t) {
}
void Audio::set_interrupt_requests(uint16_t requests) {
channels_[0].interrupt_pending = requests & uint16_t(InterruptFlag::AudioChannel0);
channels_[1].interrupt_pending = requests & uint16_t(InterruptFlag::AudioChannel1);
channels_[2].interrupt_pending = requests & uint16_t(InterruptFlag::AudioChannel2);
channels_[3].interrupt_pending = requests & uint16_t(InterruptFlag::AudioChannel3);
}
void Audio::run_for([[maybe_unused]] Cycles duration) {
// TODO:
//
// Check whether any channel's period counter is exhausted and, if
// so, attempt to consume another sample. If there are no more samples
// and length is 0, trigger an interrupt.
using State = Channel::State;
for(int c = 0; c < 4; c++) {
switch(channels_[c].state) {
case State::Disabled:
if(channels_[c].has_data && !channels_[c].dma_enabled && !channels_[c].interrupt_pending) {
channels_[c].state = Channel::State::PlayingHigh;
// TODO: [volcntrld, percntrld, pbufldl, AUDxID]
}
break;
default: break;
}
}
}

View File

@ -53,6 +53,9 @@ class Audio: public DMADevice<4> {
/// their neighbours.
void set_modulation_flags(uint16_t);
/// Sets which interrupt requests are currently active.
void set_interrupt_requests(uint16_t);
private:
struct Channel {
// The data latch plus a count of unused samples
@ -74,6 +77,9 @@ class Audio: public DMADevice<4> {
// Indicates whether DMA is enabled for this channel.
bool dma_enabled = false;
// Records whether this audio interrupt is pending.
bool interrupt_pending = false;
// Replicates the Hardware Reference Manual state machine;
// comments indicate which of the documented states each
// label refers to.
@ -83,7 +89,7 @@ class Audio: public DMADevice<4> {
WaitingForDMA, // 101
PlayingHigh, // 010
PlayingLow, // 011
} state_;
} state = State::Disabled;
} channels_[4];
};

View File

@ -750,6 +750,7 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) {
case Write(0x09c): // INTREQ
ApplySetClear(interrupt_requests_, 0x7fff);
update_interrupts();
audio_->set_interrupt_requests(interrupt_requests_);
break;
case Read(0x01e): // INTREQR
cycle.set_value16(interrupt_requests_);