mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Makes first attempt at actually implementing the SCC.
This commit is contained in:
parent
655b971976
commit
fc16e8eb8c
@ -25,14 +25,83 @@ void SCC::get_samples(std::size_t number_of_samples, std::int16_t *target) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
std::size_t c = 0;
|
||||
while((master_divider_&7) && c < number_of_samples) {
|
||||
target[c] = output_volume_;
|
||||
master_divider_++;
|
||||
c++;
|
||||
}
|
||||
|
||||
while(c < number_of_samples) {
|
||||
for(int channel = 0; channel < 5; ++channel) {
|
||||
if(channels_[channel].tone_counter) channels_[channel].tone_counter--;
|
||||
else {
|
||||
channels_[channel].offset = (channels_[channel].offset + 1) & 0x1f;
|
||||
channels_[channel].tone_counter = channels_[channel].period;
|
||||
}
|
||||
}
|
||||
|
||||
evaluate_output_volume();
|
||||
|
||||
for(int ic = 0; ic < 8 && c < number_of_samples; ++ic) {
|
||||
target[c] = output_volume_;
|
||||
c++;
|
||||
master_divider_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SCC::write(uint16_t address, uint8_t value) {
|
||||
// TODO
|
||||
address &= 0xff;
|
||||
if(address < 0x80) ram_[address] = value;
|
||||
|
||||
task_queue_.defer([=] {
|
||||
// Check for a write into waveform memory.
|
||||
if(address < 0x80) {
|
||||
waves_[address >> 5].samples[address & 0x1f] = value;
|
||||
} else switch(address) {
|
||||
default: break;
|
||||
|
||||
case 0x80: case 0x82: case 0x84: case 0x86: case 0x88: {
|
||||
int channel = (address - 0x80) >> 1;
|
||||
channels_[channel].period = (channels_[channel].period & ~0xff) | value;
|
||||
} break;
|
||||
|
||||
case 0x81: case 0x83: case 0x85: case 0x87: case 0x89: {
|
||||
int channel = (address - 0x80) >> 1;
|
||||
channels_[channel].period = (channels_[channel].period & 0xff) | ((value & 0xf) << 8);
|
||||
} break;
|
||||
|
||||
case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e:
|
||||
channels_[address - 0x8a].amplitude = value;
|
||||
break;
|
||||
|
||||
case 0x8f:
|
||||
channel_enable_ = value;
|
||||
break;
|
||||
}
|
||||
|
||||
evaluate_output_volume();
|
||||
});
|
||||
}
|
||||
|
||||
void SCC::evaluate_output_volume() {
|
||||
output_volume_ =
|
||||
static_cast<int16_t>(
|
||||
((
|
||||
(channel_enable_ & 0x01) ? static_cast<int8_t>(waves_[0].samples[channels_[0].offset]) * channels_[0].amplitude : 0 +
|
||||
(channel_enable_ & 0x02) ? static_cast<int8_t>(waves_[1].samples[channels_[1].offset]) * channels_[1].amplitude : 0 +
|
||||
(channel_enable_ & 0x04) ? static_cast<int8_t>(waves_[2].samples[channels_[2].offset]) * channels_[2].amplitude : 0 +
|
||||
(channel_enable_ & 0x08) ? static_cast<int8_t>(waves_[3].samples[channels_[3].offset]) * channels_[3].amplitude : 0 +
|
||||
(channel_enable_ & 0x10) ? static_cast<int8_t>(waves_[3].samples[channels_[4].offset]) * channels_[4].amplitude : 0
|
||||
) * 16) / 5
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t SCC::read(uint16_t address) {
|
||||
// TODO
|
||||
address &= 0xff;
|
||||
if(address < 0x80) {
|
||||
return ram_[address];
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
@ -39,19 +39,32 @@ class SCC: public ::Outputs::Speaker::SampleSource {
|
||||
uint8_t read(uint16_t address);
|
||||
|
||||
private:
|
||||
Concurrency::DeferringAsyncTaskQueue &task_queue_;
|
||||
|
||||
// State from here on down is accessed ony from the audio thread.
|
||||
int master_divider_ = 0;
|
||||
int16_t output_volume_ = 0;
|
||||
|
||||
struct Channel {
|
||||
int period = 0;
|
||||
int amplitude = 0;
|
||||
|
||||
int tone_counter = 0;
|
||||
int offset = 0;
|
||||
} channels_[5];
|
||||
|
||||
struct Wavetable {
|
||||
std::int16_t samples[32];
|
||||
std::uint8_t samples[32];
|
||||
} waves_[4];
|
||||
|
||||
std::uint8_t channel_enable_ = 0;
|
||||
std::uint8_t test_register_ = 0;
|
||||
|
||||
Concurrency::DeferringAsyncTaskQueue &task_queue_;
|
||||
void evaluate_output_volume();
|
||||
|
||||
// This keeps a copy of wave memory that is accessed from the
|
||||
// main emulation thread.
|
||||
std::uint8_t ram_[128];
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user