mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-09 06:29:33 +00:00
Provides feedback on interrupt flags, starts on state machine.
This commit is contained in:
parent
fffc03c4e4
commit
f906bab1a5
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "Audio.hpp"
|
#include "Audio.hpp"
|
||||||
|
|
||||||
|
#include "Flags.hpp"
|
||||||
|
|
||||||
#define LOG_PREFIX "[Audio] "
|
#define LOG_PREFIX "[Audio] "
|
||||||
#include "../../Outputs/Log.hpp"
|
#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_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) {
|
void Audio::run_for([[maybe_unused]] Cycles duration) {
|
||||||
// TODO:
|
// TODO:
|
||||||
//
|
//
|
||||||
// Check whether any channel's period counter is exhausted and, if
|
// Check whether any channel's period counter is exhausted and, if
|
||||||
// so, attempt to consume another sample. If there are no more samples
|
// so, attempt to consume another sample. If there are no more samples
|
||||||
// and length is 0, trigger an interrupt.
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,9 @@ class Audio: public DMADevice<4> {
|
|||||||
/// their neighbours.
|
/// their neighbours.
|
||||||
void set_modulation_flags(uint16_t);
|
void set_modulation_flags(uint16_t);
|
||||||
|
|
||||||
|
/// Sets which interrupt requests are currently active.
|
||||||
|
void set_interrupt_requests(uint16_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Channel {
|
struct Channel {
|
||||||
// The data latch plus a count of unused samples
|
// 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.
|
// Indicates whether DMA is enabled for this channel.
|
||||||
bool dma_enabled = false;
|
bool dma_enabled = false;
|
||||||
|
|
||||||
|
// Records whether this audio interrupt is pending.
|
||||||
|
bool interrupt_pending = false;
|
||||||
|
|
||||||
// Replicates the Hardware Reference Manual state machine;
|
// Replicates the Hardware Reference Manual state machine;
|
||||||
// comments indicate which of the documented states each
|
// comments indicate which of the documented states each
|
||||||
// label refers to.
|
// label refers to.
|
||||||
@ -83,7 +89,7 @@ class Audio: public DMADevice<4> {
|
|||||||
WaitingForDMA, // 101
|
WaitingForDMA, // 101
|
||||||
PlayingHigh, // 010
|
PlayingHigh, // 010
|
||||||
PlayingLow, // 011
|
PlayingLow, // 011
|
||||||
} state_;
|
} state = State::Disabled;
|
||||||
} channels_[4];
|
} channels_[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -750,6 +750,7 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) {
|
|||||||
case Write(0x09c): // INTREQ
|
case Write(0x09c): // INTREQ
|
||||||
ApplySetClear(interrupt_requests_, 0x7fff);
|
ApplySetClear(interrupt_requests_, 0x7fff);
|
||||||
update_interrupts();
|
update_interrupts();
|
||||||
|
audio_->set_interrupt_requests(interrupt_requests_);
|
||||||
break;
|
break;
|
||||||
case Read(0x01e): // INTREQR
|
case Read(0x01e): // INTREQR
|
||||||
cycle.set_value16(interrupt_requests_);
|
cycle.set_value16(interrupt_requests_);
|
||||||
|
Loading…
Reference in New Issue
Block a user