Asger Alstrup — Examination of SID triangle waveform / noise waveform (The SID Homepage, 1995)
Two pages of measurements from andreas-varga's SID Homepage (sid-homepage). asger-alstrup read voice 3's waveform output register $D41B on a real C64 once per clock cycle — a REU (RAM Expansion Unit) DMA transfer of $10000 bytes from $D41B into REU bank 0 — and worked out from the data how the triangle/sawtooth counter and the noise generator behave. They are primary measurements: what the wiki says about oscillator-3 readback, the test bit and the noise generator on sid rests on them.
Key claims#
Method#
- Voice 3's output is readable because "the SID provides a 8-bit output register of the waveform of voice 3 in register $1b", and the test bit (bit 3 of
$D412) resets the waveform, so a recording can start from a known state ("The waveforms of the SID in the c64 and c128 can be examined"). Programs: Cyclewise (REU sampling every cycle), aSTA $D412 / LDA $D41Bconstruct that reads the value 4 cycles after the write ("the time, the sta $d412 takes"), and Loopchecker (records 256 values and waits until they recur). - The programs wait 50 frames after setting the test bit, "so waveform can be reset — nescessary on my machine".
Triangle and sawtooth ($10, $20)#
- The triangle "starts with value $00 and goes to $ff linearly. Then it goes from $ff to $00 linearly"; the sawtooth counts
02 03 03 04 04 … FE FE FF FF 00 00 01 01 …and wraps. At frequency$8000the triangle value changes every cycle (04 05 06 07 … FD FE FF FF FE …); at$4000every second cycle,$2000every fourth,$1000every eighth; at$FFFFit skips (07 09 0B 0D …). His model: a delay of$8000decremented by the frequency each cycle; on each underflow add$8000back and step a 9-bit counter 0–511; output = counter below 256, else 511 − counter; sawtooth = counter ÷ 2. - Test bit: with the test bit cleared before the waveform bit is set, the recording runs 4 cycles ahead — so "the triangle counter counts all the time, whether or not the waveform is activated. The counter is held reset to 0 when the test bit is 1 (supposedly), and as soon as the test bit is 0, the counter starts counting" (or is reset on the falling edge — same result). Sawtooth and pulse were not checked, "but my bet is, this is the case".
- Open questions (1995): whether the analogue output at pin 27 is really 8-bit digital ("People have used oscilloscopes and concluded that this is the output is digital and probably 8 bit"; a listening test at frequency
1is given — each step of the slow waveform is audible as a tick) and whether it is aligned to the Ø2 clock ("My feeling is that the output is aligned … I have no access to an oscilloscope").
Noise ($80)#
- The noise value changes every
$100000 ÷ Fncycles — 32 cycles at$8000, 16 at$FFFF,$100at$1000,$1000at$0100(Table 1; the first value after the write lasts "probably 1.5 times longer"). "The highest frequency that is 100% cycle-aligned is $8000, which gives us a wavelength of 32 cycles." - The waveform loops: with 256 values sampled every 32 cycles at
$8000, Loopchecker finds the same sequence again after "approximately 4 minutes and 32 seconds or 272 seconds" ≈ (272 × 980000 ÷ 32) ≈ 8.0 M values — "an internal register length of log2(8.0 MB) = 23 bits". A first attempt with Marko Mäkelä over IRC gave 2 min 15 s but was inconsistent: 16-cycle sampling is not cycle-aligned, and "the reseting of a waveform with the TEST-bit does not reset the waveform immediately, but rather $2000-$8000 cycles later (this figure varies greatly, does anybody know of a way to reset the waveform fast?)". The loop occurs "nomatter where in the waveform cycle you are". - The algorithm: a 23-bit shift register, shifted left one bit per step, fed at bit 0 by bit 22 XOR bit 17; initial value after reset
$7FFFF8(bits 3–22 set, bits 0–2 clear); the 8-bit output takes register bits 22, 20, 16, 13, 11, 7, 4 and 2 as output bits 7 … 0. The first values after reset read11111110,11111100,11111100,11111100,11111000… — "some kind of shifting scheme". "All in all, I find that the above program can sufficiently reproduce the output from the noise-waveform in the SID." - Quality as a random source: every 23-bit pattern occurs, so all 8-bit outputs "will appear equally many times over time"; the scheme is "one of the better ones for doing pseudo-random numbers … based on polynomiums, much like the CRCs". But it is reproducible: for games, reset the noise only when the game loads, start sampling after the user presses a key or fire (an unpredictable offset into the stream), read at a sensible rate ("every 32 cycle with a frequency of $8000"), or build "a table of say $2000 values before the game starts, so that voice 3 can be used in the game-music or for sound-effects in the game".
Practical takeaways#
For a musician: the test bit resets the triangle/saw phase immediately and the noise generator only after $2000–$8000 cycles — roughly 8 to 33 ms on a PAL machine, i.e. up to more than a frame — so a noise "reset" written for one frame does not always restart the noise from the same point; that is also why the "metallic noise" trick ($F9 then $81, s-chipmusic-sid-music-hints-n-tips) sounds different "depending on … running SID cycles". Noise pitch is a shift rate that follows the frequency register linearly (2^20 ÷ Fn cycles per new value), so "tuning" a noise drum means choosing how fast the register shifts. Voice 3's readback is exact enough to be used as a modulation or random source (randomization-and-probability).
Notable quotes#
"The triangle counter counts all the time, whether or not the waveform is activated."
"the reseting of a waveform with the TEST-bit does not reset the waveform immediately, but rather $2000-$8000 cycles later"
Relevance#
The hardware truth behind ring-modulation-and-sync's test-bit section, sid's readback registers and noise generator, the noise-as-random-source idea on randomization-and-probability, and the noise reset behaviour that wavetable-programming relies on for drums. Author page: asger-alstrup.
Pages touched#
sid · ring-modulation-and-sync · randomization-and-probability · wavetable-programming · commodore-64 · sid-homepage · asger-alstrup · andreas-varga