1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-24 05:18:36 +00:00

Block and synchronise threads for voice 3 readback.

This commit is contained in:
Thomas Harte
2025-11-13 17:34:57 -05:00
parent fd32e63459
commit d01e1f3bb1
2 changed files with 19 additions and 11 deletions
+16 -3
View File
@@ -133,8 +133,18 @@ void SID::update_filter() {
}
uint8_t SID::read(const Numeric::SizedInt<5> address) {
(void)address;
return last_write_;
switch(address.get()) {
default: return last_write_;
case 0x19: return 0x00; // TODO: potentometer x.
case 0x1a: return 0x00; // TODO: potentometer y.
case 0x1b:
case 0x1c:
// Ensure all channels are entirely up to date.
audio_queue_.flush();
return (address == 0x1c) ? voices_[2].adsr.envelope : uint8_t(voices_[2].output(voices_[1]) >> 4);
}
}
// MARK: - Oscillators.
@@ -160,7 +170,7 @@ uint16_t Voice::Oscillator::sawtooth_output() const {
uint16_t Voice::NoiseGenerator::output() const {
// Uses bits: 20, 18, 14, 11, 9, 5, 2 and 0, plus four more zero bits.
return
const uint16_t output =
((noise >> 9) & 0b1000'0000'0000) | // b20 -> b11
((noise >> 8) & 0b0100'0000'0000) | // b18 -> b10
((noise >> 5) & 0b0010'0000'0000) | // b14 -> b9
@@ -169,6 +179,9 @@ uint16_t Voice::NoiseGenerator::output() const {
((noise << 1) & 0b0000'0100'0000) | // b5 -> b6
((noise << 3) & 0b0000'0010'0000) | // b2 -> b5
((noise << 4) & 0b0000'0001'0000); // b0 -> b4
assert(output <= Voice::MaxWaveformValue);
return output;
}
void Voice::NoiseGenerator::update(const bool test) {
+3 -8
View File
@@ -17,6 +17,8 @@
namespace MOS::SID {
struct Voice {
static constexpr uint16_t MaxWaveformValue = (1 << 12) - 1;
struct Oscillator {
// Programmer inputs.
uint32_t pitch = 0;
@@ -84,8 +86,6 @@ private:
bool sync() const;
bool gate() const;
static constexpr uint16_t MaxWaveformValue = (1 << 12) - 1;
uint16_t pulse_output() const;
uint16_t triangle_output(const Voice &prior) const;
};
@@ -99,17 +99,12 @@ public:
// Outputs::Speaker::BufferSource.
template <Outputs::Speaker::Action action>
void apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target);
void apply_samples(std::size_t, Outputs::Speaker::MonoSample *);
bool is_zero_level() const;
void set_sample_volume_range(std::int16_t);
private:
Concurrency::AsyncTaskQueue<false> &audio_queue_;
// TODO: an emulator thread copy of voices needs to be kept too, to do the digital stuff, as
// the current output of voice 3 can be read. Probably best if the audio thread posts its most
// recent copy atomically and the emulator thread just catches up from whatever it has? I don't
// think that spinning on voice 3 is common.
Voice voices_[3];
uint8_t last_write_;