1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-12-20 06:16:41 +00:00

Attempt some basic voice details.

This commit is contained in:
Thomas Harte
2025-11-08 21:54:41 -05:00
parent fe7a206fc5
commit 5e98e6502d
4 changed files with 52 additions and 2 deletions

View File

@@ -44,7 +44,7 @@ struct BBCMicroTarget: public ::Analyser::Static::Target, public Reflection::Str
bool has_1770dfs = false; bool has_1770dfs = false;
bool has_adfs = false; bool has_adfs = false;
bool has_sideways_ram = true; bool has_sideways_ram = true;
bool has_beebsid = true; bool has_beebsid = true; // TODO: false is a much better default.
ReflectableEnum(TubeProcessor, None, WDC65C02, Z80); ReflectableEnum(TubeProcessor, None, WDC65C02, Z80);
TubeProcessor tube_processor = TubeProcessor::None; TubeProcessor tube_processor = TubeProcessor::None;

View File

@@ -12,6 +12,30 @@ using namespace MOS::SID;
SID::SID(Concurrency::AsyncTaskQueue<false> &audio_queue) : audio_queue_(audio_queue) {} SID::SID(Concurrency::AsyncTaskQueue<false> &audio_queue) : audio_queue_(audio_queue) {}
void SID::write(const Numeric::SizedInt<5> address, const uint8_t value) {
switch(address.get()) {
case 0x00: case 0x07: case 0x0e: voices_[address.get() / 7].frequency.load<0>(value); break;
case 0x01: case 0x08: case 0x0f: voices_[address.get() / 7].frequency.load<8>(value); break;
case 0x02: case 0x09: case 0x10: voices_[address.get() / 7].pulse_width.load<0>(value); break;
case 0x03: case 0x0a: case 0x11: voices_[address.get() / 7].pulse_width.load<8>(value); break;
case 0x04: case 0x0b: case 0x12: voices_[address.get() / 7].control = value; break;
case 0x05: case 0x0c: case 0x13:
voices_[address.get() / 7].attack = value >> 4;
voices_[address.get() / 7].decay = value;
break;
case 0x06: case 0x0d: case 0x14:
voices_[address.get() / 7].sustain = value >> 4;
voices_[address.get() / 7].release = value;
break;
}
}
uint8_t SID::read(const Numeric::SizedInt<5> address) {
(void)address;
return 0xff;
}
void SID::set_sample_volume_range(const std::int16_t range) { void SID::set_sample_volume_range(const std::int16_t range) {
(void)range; (void)range;
} }

View File

@@ -8,6 +8,8 @@
#pragma once #pragma once
#include "Numeric/SizedInt.hpp"
#include "Concurrency/AsyncTaskQueue.hpp" #include "Concurrency/AsyncTaskQueue.hpp"
#include "Outputs/Speaker/Implementation/BufferSource.hpp" #include "Outputs/Speaker/Implementation/BufferSource.hpp"
@@ -17,6 +19,10 @@ class SID: public Outputs::Speaker::BufferSource<SID, false> {
public: public:
SID(Concurrency::AsyncTaskQueue<false> &audio_queue); SID(Concurrency::AsyncTaskQueue<false> &audio_queue);
void write(Numeric::SizedInt<5> address, uint8_t value);
uint8_t read(Numeric::SizedInt<5> address);
// Outputs::Speaker::BufferSource.
template <Outputs::Speaker::Action action> template <Outputs::Speaker::Action action>
void apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target); void apply_samples(std::size_t number_of_samples, Outputs::Speaker::MonoSample *target);
bool is_zero_level() const; bool is_zero_level() const;
@@ -24,6 +30,18 @@ public:
private: private:
Concurrency::AsyncTaskQueue<false> &audio_queue_; Concurrency::AsyncTaskQueue<false> &audio_queue_;
struct Voice {
Numeric::SizedInt<16> frequency;
Numeric::SizedInt<12> pulse_width;
Numeric::SizedInt<8> control;
Numeric::SizedInt<4> attack;
Numeric::SizedInt<4> decay;
Numeric::SizedInt<4> sustain;
Numeric::SizedInt<4> release;
};
Voice voices_[3];
}; };
} }

View File

@@ -109,6 +109,8 @@ private:
/*! /*!
Combines an SN76489 with an appropriate asynchronous queue and filtering speaker. Combines an SN76489 with an appropriate asynchronous queue and filtering speaker.
*/ */
// TODO: generalise the below and clean up across the project.
template <bool has_beebsid> template <bool has_beebsid>
struct Audio { struct Audio {
private: private:
@@ -147,7 +149,7 @@ public:
return sn76489_; return sn76489_;
} }
if constexpr (std::is_same_v<TargetT, MOS::SID::SID>) { if constexpr (std::is_same_v<TargetT, MOS::SID::SID>) {
return sn76489_; return sid_;
} }
} }
@@ -1027,6 +1029,12 @@ public:
} }
break; break;
} }
} else if(has_beebsid && address >= 0xfc20 && address < 0xfc40) {
if constexpr (is_read(operation)) {
value = audio_.template get<MOS::SID::SID>().read(+address);
} else {
audio_.template get<MOS::SID::SID>().write(+address, value);
}
} else { } else {
Logger::error() Logger::error()
.append("Unhandled IO %s at %04x", is_read(operation) ? "read" : "write", address) .append("Unhandled IO %s at %04x", is_read(operation) ? "read" : "write", address)