realdmx: three smaller drivers — Fred Gray's Mutants (song as code), Jeroen Kimmel's 'Red's music player' (1989) and David Whittaker's Panther driver

author Fred Gray (Mutants, 1987 Ocean; an unsigned disassembly 'A work in progress'); Jeroen Kimmel / Red ('Red's music player (C) 1989 J.Kimmel', original Turbo Assembler source, ACME by dmx87); David Whittaker (Panther, 1986 Mastertronic; 'Reversed by dmx87')
date 2023-06-24
article Gray_Fred_Mutants.asm (1232 lines, PSID 2 songs, load $e000), Kimmel_Jeroen_Test.asm (973 lines, 'A test tune', header note 'Something is missing here, there's a bass but inaudible'), Whittaker_David_Panther.asm (1476 lines, PSID 'Panther', 1986 Mastertronic, load $9000). The date is the repository's last push
created 2026-08-30 · updated 2026-08-31

The remaining three players of the realdmx collection (s-realdmx-sid-players), each a different answer to the same problem. fred-gray's Mutants is not a sequencer at all but a song written as code — 26 hand-written section routines — inside Ocean's game driver, complete with a sound-effect chaining engine. jeroen-kimmel's "Red's music player" is a scener's 1989 Turbo Assembler source with Hubbard-style drums and a per-voice instrument table. david-whittaker's Panther driver is a byte-command language without instruments — and, against the wiki's earlier assumption, not the primitive Lazy Jones routine of SIDin #2 (s-sidin02-matt-gray-driller). Cheat sheet for the Whittaker driver on whittaker-player.

Key claims#

Fred Gray — Mutants (1987 Ocean)

  • "Mutants by Fred Gray / A work in progress"; no reverse-engineer named in the file. The tune table !by $01,$19,$04,$00,$28,$31,$30,$30,$25,$20,$52,$49,$50,$29 ends in the ASCII string (100% RIP), and live state bytes in the data show the block was dumped from memory during playback. Two songs (init maps song 0 → step $01, song 1 → $19); load $e000, under the KERNAL — a game driver's address. SIDId's Fred_Gray signature is its note-trigger idiom (sta V1CTRL,x; inc V1CTRL,x).
  • Song as code: no pattern interpreter. A 32-entry step table of routine addresses and a rows-per-step table; each section routine writes the AD registers itself, picks three instruments, sets the rows' length in frames (8 or 10) and reads one-byte-per-row note tables — le0df: lda #9 / sta $d405 / sta $d40c / lda #$0b / sta $d413 / ldy #$10 / lda #$10 / ldx #8 / jsr le9fd / lda #8 / jsr leb0a … then per row lda le51f,y / jsr le9d9 (voice 3), lda le5c0,y / ldx #$0c / jsr le9c7 (voice 1, transposed +12) and a masked noise hit. No zero page, no filter code, no fade. This is the literal form of "typed their tunes directly into their assembler" (s-matt-gray-dominator-source).
  • Pitch is kept in quarter-semitones (asl asl on the note, $30 per octave, a 48-word frequency table for one octave, lower octaves by shifts), so one 16-entry table lea36 serves as chord arpeggio and as vibrato: rows $00,$1c,$14,… (root, +7, +5 semitones), $00,$1c,$10,… (root, +7, +4), $01,$01,$01,$01,$ff,$fe,$fe,$ff,$01,$02,$02,$01,$ff,$ff,$ff,$ff (a vibrato of ±half a semitone), $30,$00,$1c,$00,$00,$01,$02,$01 … (octave, fifth and wobble in one row) (chord-arpeggio, vibrato).
  • Instrument = 8 bytes (waveform, PW init, PW add per frame, arp delay, arp-table offset, glide speed, SR, unused) — AD is not in the instrument, the section writes it: $40,$80,$02,$08,$50,$04,$2c,$00; $40,$88,$0a,$0c,$50,$02,$4c,$00; $10,$01,$d0,$00,$80,$02,$00,$00 (triangle, PW add $d0 = a fast sweep); $80,$80,$02,$00,$20,$04,$00,$00 (noise); $14,$01,$81,$08,$50,$2d,$00,$00 (triangle + ring). The pulse is a free-running 8-bit accumulator (PW += add every frame, low byte OR-ed with $3f) reset to the instrument's init at every note — the "jumping pulsating settings for subsequent note triggers" JCH hears in Fred Gray (s-chordian-sid-musicians; pulse-width-modulation, instrument-tables).
  • A resident sound-effect engine: 32 rows of 8 bytes (instrument, start pitch, target note (bit 7 = glide), AD, timer × 4 frames, next effect) chained by the driver; the game writes an effect number into a per-voice slot. Note bytes: bits 0–5 the note, bit 7 = glide from the previous pitch, $00 = keep sounding. Size ≈ 3.8 KB ($e000–$eeb5).

Jeroen Kimmel (Red) — "Red's music player (C) 1989 J.Kimmel"

  • Original source with Dutch labels (stem voice, snelheid speed, stuk piece, accoorden chords, "; ] Last vary's, if not used crunch ]"); PSID "Red's Player", 1989; snelheid = $03 (a note event every 3 frames), volbyte = $6f (high-pass + band-pass, volume $f), fd417 = $f1 ; filter !!!. dmx87's note: "Something is missing here, there's a bass but inaudible". SIDId's Jeroen_Kimmel signature is its instrument-load code.
  • Model: one sequence per voice of words — a pattern address, $xx,tp (tp = $ff) = transpose, 0,0 = repeat; a pattern is note, (instrument << 5 | duration) pairs ended by 0,0: stuk1 !by c1,$03,c1,$01 / c1,$01,dis1,$23 / c1,$01,f1,$03 / c1,$01,g1,$01 / c1,$01,c2,$21 / c1,$01,g1,$21 / dis1,$01 / 0,0 ($23 = instrument 1, 3 ticks; $21 = instrument 1, 1 tick) — the instrument number lives in the duration byte, three bits, so at most eight per voice (orderlist).
  • A separate 8-byte instrument table per voice (adsr1/2/3): PW hi + glide nibble, waveform with gate, AD, SR (its low nibble ×16 = filter cutoff start), pulse add + filter speed, chord row, unused, flags; flags: bit 7 waveform switch $41/$81 every frame, bit 0 glide down, bit 1 filter down, bits 2–3 the two vibrato tables, bits 4–5 the two drum sets, bit 6 a two-frame noise burst. Rows: adsr1 !by $00,$41,$08,$30 / $00,0,0,%01000000; adsr2 !by $03,$41,$bc,$40 / $10,0,0,%01001000; adsr3 !by $00,$11,$09,$00 / $00,0,0,%00000000.
  • Effects (read from the code): chords from three 12-byte rows ($00 …, $00,$03,$07 …, $00,$04,$07 …) on a free-running 12-step counter; vibrato tables vibtab1 $00,$30,$60,$90,$c0,$f0,$f0,$c0,$90,$60,$30,$00 and vibtab2 $00,$10,$20,$30,$20,$10 … added to the frequency low byte after $1a frames (one-sided, upward); drums as three frames of fixed-pitch noise/triangle — digifreq 0,$55,$0a,$44 with digiwave $00,$81,$11,$81 — then the real waveform and pitch are restored (setreal), or a two-frame $81 burst at frequency-high $ff; gate off and on in the same call, no hard restart. Those are the Hubbard-style traits the scene attributes to Red's first work in Hubbard's player (s-recollection-brief-history-of-sid); the per-voice tables and the instrument-in-duration byte are his own (wavetable-programming, hubbard-player).
  • Why the bass is inaudible (inference): stemselect = $03 masks voice 3 off entirely, voice 1's instruments have pulse width $000$001 with the width zeroed at every note and no sweep, and voice 1 is the filtered voice with the cutoff reset to 0 — and sta filtstand,x for X = 7/14 overruns into the frequency table. Size ≈ 1.4 KB (estimated).

David Whittaker — Panther (1986 Mastertronic)

  • "Reversed by dmx87"; labels L_9xxx keep the original addresses ($9000–$9cff, 3328 bytes: engine ≈ 1.7 KB, tracks 354 bytes, patterns 1022). Unlabelled bytes after init decode to a sub-tune selector (X = 6 × tune, copies three track pointers from a table) — the original driver handles several tunes; this rip carries one plus 24 unexplained trailing bytes. SIDId's David_Whittaker signature is its gate write (stx SIDV1CTRL / inx / stx SIDV1CTRL).
  • Not the Lazy Jones engine: SIDin #2 describes Lazy Jones as raw two-voice frequency lists with equal note lengths and no effects; Panther, by the same author in 1986, is a full three-voice driver — tracks of pattern addresses (53/65/53 entries, !wo 0 = loop), patterns as byte streams with commands, per-note ADSR, tempo, arpeggio lists, vibrato, accelerating slides, pulse bounce and an alternate-frame noise drum.
  • Byte classes (derived from the arithmetic — dmx87's range comments in the file disagree with it): $00–$7f note; $80–$93 command; $b8–$bf tempo (value − $b7, 1–8); $c0–$cf arpeggio list; $d0–$df "ADSR follows" (two bytes); $e0–$ff duration (value − $df, 1–32 ticks). Commands: $80 hold the note (no retrigger), $81/$82 vibrato off/on, $83 v volume, $84/$85 lo,hi,delay slide down/up (quadratic: the step accumulates), $86/$87 bend a semitone down/up per tick, $88 end of pattern, $89 speed,depth vibrato, $8a/$8b/$8c/$8d noise/pulse/saw/triangle, $8e drum flag, $8f n pulse high byte, $90 min,max,speed pulse bounce, $91 stop music, $92 triangle + ring, $93 pulse + sync. FLAGS is zeroed at every note, so arpeggio, slide and drum are re-issued per note (orderlist).
  • No instrument table: the timbre is whatever the last prefixes set, kept in a 36-byte voice struct — PC_PULSE,$90,$02,$08,$28,$d0,$0a,$40 = pulse, bounce between high bytes $02 and $08 at speed $28, AD $0a, SR $40; L_9902 !by $be,$d0,$00,$00,$ff,$80,$88 = tempo 7, ADSR $00/$00, 32 ticks, hold, end; L_9CBD !by $8d,$89,$28,$50,$82,$d0,$0d,$70 / $f7,$c0,$3c,$e7,$c1,$3a … = triangle, vibrato, AD/SR $0d/$70, 24 ticks of a minor arpeggio on $3c, 8 ticks of a major one on $3a; a siren intro $92,$90,$02,$08,$14,$89,$7f,$fe,$82,$d0,$df,$00,$ff,$84,$80,$00,$01 (ring-triangle, pulse bounce, deep vibrato, slide down) (instrument-tables, pulse-width-modulation, pitch-slide-and-portamento).
  • Arpeggio lists, one step per frame, restart at any byte ≥ $54: $00,$03,$07,$88 (minor), $00,$04,$07,$88 (major), $00,$03,$07,$0c,$88, $00,$04,$07,$0c,$88, $07,$0c,$0f,$88, $07,$0c,$10,$88, $00,$0c,$88 (octave), $00,$04, $00,$03, $00,$05, $00,$07 (chord-arpeggio). The drum ($8e): on odd frames control $80 (noise) with the frequency high byte + $31; vibrato depth is doubled once per two octaves the note lies below $60. Every frame writes frequency, pulse, AD, SR and control (gate off then on at note starts), so silence is made with SR = 0, not with the gate (hard-restart).

Practical takeaways#

  • Fred Gray's Mutants shows the cheapest possible arrangement: a routine per section, notes as one byte per row, everything else hard-coded — and still with quarter-tone glides and combined arpeggio/vibrato tables.
  • Red's drums (three frames of fixed-pitch noise/triangle, then the real note) are a compact wave-table drum on an ordinary instrument.
  • Whittaker's player is an effects language: to copy a Panther sound you need the prefix string, not an instrument — the same design as galway-player's streams, at a fraction of the size.

Notable quotes#

  • "Mutants by Fred Gray / A work in progress"; (100% RIP) in the data.
  • "Red's music player (C) 1989 J.Kimmel"; "Something is missing here, there's a bass but inaudible"; "; ] Last vary's, if not used crunch ]".
  • "Reversed by dmx87"; "VD_WAVE = $22 ; Waveform (without gate bit)"; "; Reset arp if >= $54".

Relevance to the wiki#

Primary source for whittaker-player, david-whittaker, jeroen-kimmel and fred-gray; corrects sidin's and the plan's assumption that a Whittaker source would match the Lazy Jones routine; the "song as code" extreme for sid-player-routine and tracking-workflow; effect-language and drum recipes for the technique pages; SIDId names for sidid.

To verify#

  • (unverified) Who disassembled Mutants — the file is unsigned; the repository credits dmx87 for its conversions.
  • (unverified) Whether Kimmel's original disabled voice 3, or the conversion changed the voice mask.

Pages touched#

whittaker-player · david-whittaker · jeroen-kimmel · fred-gray · hubbard-player · galway-player · sid-player-routine · sidid · sidin · instrument-tables · chord-arpeggio · vibrato · pulse-width-modulation · pitch-slide-and-portamento · wavetable-programming · hard-restart · orderlist · tracking-workflow · sound-effects

source file wiki/summaries/s-realdmx-fredgray-kimmel-whittaker.md · 2 unverified · graph