Rob Hubbard's driver (the Monty on the Run player)
The 6502 music routine rob-hubbard wrote in 1985 and, per Anthony McSweeney's disassembly, "used (with small modifications) for his first approx. 30 tunes" — the player of monty-on-the-run, commando, Crazy Comets, Thing on a Spring and the rest of the 1985–86 run. About 1 KB of code: three voices, a 3-byte note format, 8-byte instruments and three flag-bit effects (drum, "skydive", octave arpeggio) that became the "Hubbard sound" (source: s-realdmx-hubbard-player). Hubbard's own description of the method: "I just used an assembler and edit the source code" (source: s-sidmusic-hubbard-interviews); SIDwave's: load the last tune, "swap the patches", improve the player a little — "Rob's 'Monty on the Run' player, has been used in almost 30 games" (source: s-recollection-brief-history-of-sid).
Facts#
- Two disassemblies are public in the realdmx collection: McSweeney's commented Monty on the Run driver (the one Newman summarised in 1993 as 900–1000 bytes with "notework"/"soundwork" halves) and a Commando title file whose labels keep the original addresses — code plus note table at
$1000–$14a1, 1186 bytes (sources: s-realdmx-hubbard-player, s-newman-driving-the-sid-chip). - Runs once per frame from the game's interrupt; a tempo counter (
$01in Monty, a per-song table in Commando) sets how many frames make a tick; note lengths count ticks, effects run every frame (source: s-realdmx-hubbard-player). - Delivered to publishers as "a block containing both the player and the sound data, typically with several tunes and jingles as well as an array of sound effects" — the freelance product JCH credits him with inventing (source: s-chordian-sid-musicians). Sound effects steal notes from the music (Commando; source: s-newman-driving-the-sid-chip).
- The driver got around: jeroen-tel "hacked into Hubbard's routine to compose music in machine-code" before the MoN driver existed; Red (Jeroen Kimmel) and laxity started in it; a "licensable SID player" offered to matt-gray "turned out to be just a disassembled Rob Hubbard routine which they'd re-commented and labelled up" (sources: s-hugi38-interview-jeroen-tel, s-recollection-brief-history-of-sid, s-c64com-matt-gray-interview). matt-gray: drums by waveform switching "was originally Rob Hubbard's idea" (source: s-rvg-matt-gray-interview). SIDId names it
Rob_Hubbard, with(Rob_Hubbard_Digi),Paradroid/HubbardEd(1991) and Jason Page'sRobTrackeras descendants (source: s-sidid-player-list).
Cheat sheet#
All values from the two disassemblies (source: s-realdmx-hubbard-player).
Song structure: init (A = song) copies three track pointers; a track is a list of pattern numbers, $ff = restart the track, $fe = stop. A pattern is a stream of notes ended by $ff.
Note entry (1–3 bytes):
| byte | bits | meaning |
|---|---|---|
| 1 | 0–4 | length in ticks, 0–31 |
| 1 | 5 | "no release": do not clear the gate (and do not zero AD/SR) when the length runs out |
| 1 | 6 | extension: a one-byte entry that adds its length to the current note; the registers are re-written with the gate off, so the tail is the release ($7f = +32 ticks, keep ADSR; $5f = +32 ticks, then cut) |
| 1 | 7 | a second byte follows |
| 2 | 7 = 0 | instrument number |
| 2 | 7 = 1 | portamento: bits 1–6 the frequency step per frame, bit 0 the direction (0 = up, 1 = down) — e.g. $90 = +16/frame, $99 = −24/frame, $e8 = +104/frame |
| 3 | note, $00 = C-0 … $5f = B-7 (frequency table $0116 … $fd2e) |
Examples: $83,$00,$37 = 4 ticks, instrument 0, G-4; $bf,$0c,$56,$7f,$7f = a 32-tick note held for 64 more ticks in release; $af,$90,$35 = 16 ticks of pitch bend up. Note-off is the end of the length, and without bit 5 it writes $00 to AD and SR — an instant cut (hard-restart).
Instrument (8 bytes):
| # | byte | values |
|---|---|---|
| 0 | pulse width lo | |
| 1 | pulse width hi | $08–$0e if the pulse sweep is used |
| 2 | control register with gate | $41 pulse, $81 noise, $11 triangle |
| 3 | attack/decay | |
| 4 | sustain/release | $ff for skydive notes that must keep sounding through their extensions |
| 5 | vibrato depth | 0 = off; n = step of a semitone ÷ 2^(n+1); needs a note of 8+ ticks (Commando: 6+) |
| 6 | pulse modulation | bits 0–4 delay in frames between steps, bits 5–7 step ($20, $40 …); the width bounces between $0800 and $0eff; with flag $08 (Commando only) the whole byte is added to the low byte every frame instead |
| 7 | effect flags | $01 drum, $02 skydive, $04 octave arpeggio, $08 pulse-lo modulation (Commando); they combine ($05 = drum + arpeggio) |
Rows from Monty on the Run: $80,$09,$41,$48,$60,$03,$81,$00 (lead: pulse, vibrato 3, slow PWM) · $00,$08,$81,$02,$08,$00,$00,$01 (noise drum) · $00,$09,$41,$3f,$ff,$01,$e7,$02 ("first skydive") · $00,$08,$41,$08,$50,$02,$00,$04 (pulse + octave arpeggio) · $00,$00,$11,$0a,$fa,$00,$00,$05 (triangle drum + arpeggio). From Commando: $52,$01,$41,$09,$9f,$00,$16,$08 (bass, pulse-lo modulation) · $00,$02,$81,$0a,$09,$00,$00,$05 (snare).
The effects
| effect | what the code does |
|---|---|
| vibrato | 8-frame sequence 0,1,2,3,3,2,1,0 × step, added to the note frequency (bends upward only) |
| pulse sweep | add the step every delay frames; reverse at hi byte $0e / $08; modifies the instrument bytes in place |
| portamento | add/subtract the step to the 16-bit frequency every frame for the length of the note |
drum $01 | first tick noise ($80), then each frame the instrument waveform with the gate off while the frequency high byte decrements by 1 — "fast attack/decay and a rapid downwards frequency slide" (wavetable-programming) |
skydive $02 | every 2nd frame decrement the frequency high byte until 0 (Commando's variant increments by 2) |
octave arpeggio $04 | odd frames note + 12, even frames the note — a 25 Hz octave trill (octave-bass) |
Processing order per frame: note fetch → vibrato → pulse → portamento → drum → skydive → arpeggio.
Related#
rob-hubbard · monty-on-the-run · commando · sanxion · galway-player · musicfile · matt-gray-player · sid-player-routine · instrument-tables · wavetable-programming · sidid
Sources#
s-realdmx-hubbard-player · s-newman-driving-the-sid-chip · s-sidmusic-hubbard-interviews · s-recollection-brief-history-of-sid · s-chordian-sid-musicians · s-c64com-matt-gray-interview · s-hugi38-interview-jeroen-tel · s-sidid-player-list · s-rvg-matt-gray-interview