diff --git a/Machines/Apple/AppleIIgs/Sound.cpp b/Machines/Apple/AppleIIgs/Sound.cpp index d7c12fb9c..5c52d0ed9 100644 --- a/Machines/Apple/AppleIIgs/Sound.cpp +++ b/Machines/Apple/AppleIIgs/Sound.cpp @@ -60,9 +60,14 @@ void GLU::EnsoniqState::set_register(uint16_t address, uint8_t value) { case 0x80: oscillators[address & 0x1f].address = value; break; - case 0xa0: + case 0xa0: { oscillators[address & 0x1f].control = value; - break; + + // Halt + M0 => reset position. + if((oscillators[address & 0x1f].control & 0x3) == 3) { + oscillators[address & 0x1f].control |= 1; + } + } break; case 0xc0: oscillators[address & 0x1f].table_size = value; break; @@ -199,8 +204,16 @@ void GLU::generate_audio(size_t number_of_samples, std::int16_t *target, int16_t assert(false); break; - case 6: // Swap mode. - assert(false); + case 6: // Swap mode; possibly trigger partner, and update sample. + // TODO: possibly this function argues in favour of summing the output + // in a separate loop? + if(remote_.oscillators[c].position & 0xff000000) { + remote_.oscillators[c].control |= 1; + remote_.oscillators[c].position = 0; + remote_.oscillators[c^1].control &= ~1; + } else { + output += remote_.oscillators[c].output(remote_.ram_); + } break; } } @@ -238,8 +251,16 @@ uint8_t GLU::EnsoniqState::Oscillator::sample(uint8_t *ram) { } int16_t GLU::EnsoniqState::Oscillator::output(uint8_t *ram) { + const auto level = sample(ram); + + // "An oscillator will halt when a zero is encountered in its waveform table." + if(!level) { + control |= 1; + return 0; + } + // Samples are unsigned 8-bit; do the proper work to make volume work correctly. - return int8_t(sample(ram) ^ 128) * volume; + return int8_t(level ^ 128) * volume; } void GLU::skip_audio(EnsoniqState &state, size_t number_of_samples) {