1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Dave: apply ring modulation even in sync mode.

This commit is contained in:
Thomas Harte 2021-07-06 23:11:30 -04:00
parent 6a15b8f695
commit 264b8dfb28

View File

@ -21,12 +21,14 @@ void Audio::write(uint16_t address, uint8_t value) {
switch(address) {
case 0: case 2: case 4:
channels_[address >> 1].reload = (channels_[address >> 1].reload & 0xff00) | value;
printf("Low Channel %d -> %04x\n", address >> 1, channels_[address >> 1].reload);
break;
case 1: case 3: case 5:
channels_[address >> 1].reload = uint16_t((channels_[address >> 1].reload & 0x00ff) | ((value & 0xf) << 8));
channels_[address >> 1].distortion = Channel::Distortion((value >> 4)&3);
channels_[address >> 1].high_pass = value & 0x40;
channels_[address >> 1].ring_modulate = value & 0x80;
printf("High Channel %d -> %04x\n", address >> 1, channels_[address >> 1].reload);
break;
case 6:
noise_.frequency = Noise::Frequency(value&3);
@ -44,6 +46,8 @@ void Audio::write(uint16_t address, uint8_t value) {
use_direct_output_[0] = value & 0x08;
use_direct_output_[1] = value & 0x10;
// Interrupt bits are handled separately.
printf("A7: %02x\n", value);
break;
case 8: case 9: case 10:
@ -69,30 +73,31 @@ void Audio::set_sample_volume_range(int16_t range) {
}
void Audio::update_channel(int c) {
if(channels_[c].sync) {
channels_[c].count = channels_[c].reload;
channels_[c].output <<= 1;
return;
}
auto output = channels_[c].output & 1;
channels_[c].output <<= 1;
if(!channels_[c].count) {
if(channels_[c].sync) {
channels_[c].count = channels_[c].reload;
output = 0;
} else {
if(!channels_[c].count) {
channels_[c].count = channels_[c].reload;
if(channels_[c].distortion == Channel::Distortion::None)
output ^= 1;
else
output = poly_state_[int(channels_[c].distortion)];
if(channels_[c].distortion == Channel::Distortion::None)
output ^= 1;
else
output = poly_state_[int(channels_[c].distortion)];
} else {
--channels_[c].count;
}
if(channels_[c].high_pass && (channels_[(c+1)%3].output&3) == 2) {
output = 0;
}
if(channels_[c].ring_modulate) {
output = ~(output ^ channels_[(c+2)%3].output) & 1;
}
} else {
--channels_[c].count;
}
// Ring modulation applies even when sync is enabled, per SIDBasic.
if(channels_[c].ring_modulate) {
output = ~(output ^ channels_[(c+2)%3].output) & 1;
}
channels_[c].output |= output;