mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-25 11:17:26 +00:00
Gives the SN76489 its proper dividers and personalities.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
using namespace TI;
|
||||
|
||||
SN76489::SN76489(Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_(task_queue) {
|
||||
SN76489::SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_(task_queue) {
|
||||
// Build a volume table.
|
||||
double multiplier = pow(10.0, -0.1);
|
||||
double volume = 8191.0f;
|
||||
@@ -22,6 +22,21 @@ SN76489::SN76489(Concurrency::DeferringAsyncTaskQueue &task_queue) : task_queue_
|
||||
}
|
||||
volumes_[15] = 0;
|
||||
evaluate_output_volume();
|
||||
|
||||
switch(personality) {
|
||||
case Personality::SN76494:
|
||||
master_divider_period_ = 2;
|
||||
shifter_is_16bit_ = false;
|
||||
break;
|
||||
case Personality::SN76489:
|
||||
master_divider_period_ = 16;
|
||||
shifter_is_16bit_ = false;
|
||||
break;
|
||||
case Personality::SMS:
|
||||
master_divider_period_ = 16;
|
||||
shifter_is_16bit_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SN76489::set_register(uint8_t value) {
|
||||
@@ -72,10 +87,8 @@ void SN76489::evaluate_output_volume() {
|
||||
}
|
||||
|
||||
void SN76489::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
// For now: assume a divide by eight.
|
||||
|
||||
std::size_t c = 0;
|
||||
while((master_divider_&7) && c < number_of_samples) {
|
||||
while((master_divider_& (master_divider_period_ - 1)) && c < number_of_samples) {
|
||||
target[c] = output_volume_;
|
||||
master_divider_++;
|
||||
c++;
|
||||
@@ -124,12 +137,12 @@ void SN76489::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
|
||||
evaluate_output_volume();
|
||||
|
||||
for(int ic = 0; ic < 8 && c < number_of_samples; ic++) {
|
||||
for(int ic = 0; ic < master_divider_period_ && c < number_of_samples; ++ic) {
|
||||
target[c] = output_volume_;
|
||||
c++;
|
||||
master_divider_++;
|
||||
}
|
||||
}
|
||||
|
||||
master_divider_ &= 7;
|
||||
master_divider_ &= (master_divider_period_ - 1);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@ namespace TI {
|
||||
|
||||
class SN76489: public Outputs::Speaker::SampleSource {
|
||||
public:
|
||||
enum class Personality {
|
||||
SN76489,
|
||||
SN76494,
|
||||
SMS
|
||||
};
|
||||
|
||||
/// Creates a new SN76489.
|
||||
SN76489(Concurrency::DeferringAsyncTaskQueue &task_queue);
|
||||
SN76489(Personality personality, Concurrency::DeferringAsyncTaskQueue &task_queue);
|
||||
|
||||
/// Writes a new value to the SN76489.
|
||||
void set_register(uint8_t value);
|
||||
@@ -26,8 +32,9 @@ class SN76489: public Outputs::Speaker::SampleSource {
|
||||
void get_samples(std::size_t number_of_samples, std::int16_t *target);
|
||||
|
||||
private:
|
||||
std::size_t master_divider_ = 0;
|
||||
int16_t output_volume_ = 0;;
|
||||
int master_divider_ = 0;
|
||||
int master_divider_period_ = 16;
|
||||
int16_t output_volume_ = 0;
|
||||
void evaluate_output_volume();
|
||||
int volumes_[16];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user