Liber VII · Capitulum IX

The sound

A three-voice AY chip imitated with a volume register.

AUDV0 as a 4-bit converter

With AUDC0 = 0 the TIA channel is held fixed and AUDV0 works as a 4-bit converter. The game writes a sample on every line: 15,700 samples per second. In the 199 kernel lines the write is one more event for the scheduler; in the 63 of the overblank they are written by the program the 6507 runs from the RIOT RAM, reading some nibbles that are uploaded in two kernel lines (the ROM patches one byte of that program so that it writes to AUDV0). Silence is the value 7, the centre, so there is no thump at the start.

The synthesiser

Once per frame, in the overblank, the ARM calculates the samples from the 14 registers of the Spectrum's AY: three square waves with a 16-bit phase, the amplitude with the AY's logarithmic table and a 17-bit noise that advances at most once per line. Each voice is summed around the centre of the converter: if it were summed from zero, the average level would rise and fall with each note and, because of the TV's AC coupling, it would sound like a volume going up and down. Noise too high-pitched for 15.7 kHz is replaced by its mean value, which is what the ear hears. The music runs at 50 Hz and the frame at 60: the synthesizer splits the frame at the sample where each step of the player falls (it keeps count in three-hundredths of a second) and calls it between the two halves, so each note changes at its instant and not at the start of the frame, as before, up to 1/60 s late. In PAL 50 the step always falls at the start. Each channel's phase is kept whole between frames.

Each square wave is not sampled at a single point: the fraction of the line during which it is high is added up. It is a box filter that keeps the harmonics above 7.85 kHz from folding back into tones that are not part of the note; with the vibrato of the in-game background music they sounded like a noisy echo. If the sum of the three channels does not fit in the 4 bits of AUDV0, that stretch is played at a lower gain instead of being clipped, like a limiter. And since each part of the frame writes AUDV0 on a different cycle, the synthesiser adjusts the phases at each change of section so that every sample matches its instant.

Scores and recordings

The 11 tunes and effects of the game use the original's score player, translated to C and checked byte by byte: 506 bytes of scores and envelopes and 1.4 KB of code. The intro and the ending use another player whose scores have not been deciphered, so they go as the sequence of changes of the AY registers from frame to frame, compressed with a custom LZ77 that is decompressed on the fly, with no window in RAM and a limit on reads per frame: the intro goes from 2.9 to 1.5 KB and the ending from 11.6 to 3 KB.

On the music page you can listen to the pieces on the AY and on the imitation of the 2600 synthesiser.