Paul Hughes's Ocean music driver (Jonathan Dunn's player)
The 1988 in-house music system of Ocean Software: "Oh wow (paroxism!) programming by Paul Hughes", with jonathan-dunn's "Orchestration, blood, sweat & tears" — known from two original sources in the realdmx collection, the six-tune Daley Thompson '88 soundtrack and the loader tune "LOADING MUSIC IV, THE REMIX!" (HVSC's Ocean Loader 5) (source: s-realdmx-ocean-dunn-hughes-driver). Like galway-player it is a per-voice byte-code language with subroutines, loops and transposed calls; unlike it, the music is written in a readable notation of note names, command names and note-value constants, and the source states its memory budget.
Facts#
ALLOCATION = 5*1024+512— 5632 bytes for driver, data and variables, withTOGOreported by the assembler; DT88 uses 5514 (driver 3783, data 1540, variables 191). The loader build is 5061 bytes and carries the text "LOADER4 THE REMIX! BY JONATHAN DUNN DRIVER BY PAUL HUGHES" inside the driver (source: s-realdmx-ocean-dunn-hughes-driver).- API:
JSR REFRESHevery frame;LDX #tune / JSR TUNE; DT88's tunes0 DISQUALIFIED, 1 SUCCESS, 2 FAIL, 3 NEXT EVENT, 4 TITLE MUSIC, 5 QUALIFY. Init writes8then0to every SID register "so there's no grotty clicking". Everything is once per frame; durations are frame counts, there is no tempo counter (source: s-realdmx-ocean-dunn-hughes-driver). - Handlers are compiled in or out per tune to fit the budget (DT88: bend on voice A only, effect on C only, modulators paused on a note's last frame; the loader: bend on A and B, effect on all three). The filter commands are empty and a "skip N bars" tester is missing — the missing "Music Driver development framework" (source: s-realdmx-ocean-dunn-hughes-driver).
- Jammer, in JCH's comments, defends "Jonathan Dunn's sounds ('use of $55 for example')" —
$55= triangle + pulse + ring modulation + gate, the gate-on byte of DT88's patches 02 and 04 (sources: s-chordian-sid-musicians, s-realdmx-ocean-dunn-hughes-driver). - SIDId knows
Paul_HughesandMusDriver/Paul_Hughes("Music Driver", with a link to pauliehughes.com) and has noJonathan_Dunnentry (source: s-sidid-player-list) — which suggests, without proving it, that the "Paulie" who ported the sources to DASM in 2004–2006 is Hughes himself (inference).
Cheat sheet#
All from the two sources (source: s-realdmx-ocean-dunn-hughes-driver).
Voice program — bytes $00–$5d notes (C0 = 0 … A7 = 93, sharps CS4), 94 = REST; in manual mode every note/rest is followed by its duration in frames, after LENGTH n (auto mode) each note lasts n. Commands:
| byte | name | arguments | effect |
|---|---|---|---|
$80 | JUMP | addr | go to |
$81 | CALL | addr | call a phrase (5-deep stack shared with LOOP) |
$82 | RET | return, and reset the transpose | |
$83 … $84 | LOOP n … NEXT | repeat | |
$85 | BEND | dir, step, length, offset16 | bend into the next note: the frequency is pre-offset by step × length and climbs to the written pitch |
$86 | PATCH | n | select a 5-byte patch |
$87 | LENGTH | frames | auto-duration mode |
$88 / $89 | VIBON / VIBOFF | delay, rate, depth | triangle vibrato on the 16-bit frequency (cancels an arpeggio) |
$8a / $8b | ARPON / ARPOFF | addr | arpeggio table (suppresses vibrato and bend while active) |
$8c | MANUAL | back to note,duration pairs | |
$8d | PWM | n | select a 5-byte pulse-sweep entry |
$8e / $92 | FILTER / FILTOFF | empty handlers | |
$8f | END | stop the voice | |
$90 | TRANSPOSE | n | signed semitones |
$91 | CT | n, addr | transposed CALL — the harmony device |
$93 | MODE | mask | bit 7 of the mask = set, else clear: gate writes, pulse retrigger per note, "pluck" mode |
$94 | DRUM | n, transpose[, duration] | voice C only |
$95 | PORT | value, sid-offset | write any SID register (volume $18) |
$96 | CODE | addr | JSR into the music data (fades, ramps) |
$97 | EFFECT | note | every note starts at that (absolute or relative) pitch until its release point — a pluck |
Durations: TEMPO = 5 → SQ 5, QV 10, CR 20, MN 40, SB 80; TEMPO2 = 6 → SQ2 6, QV2 12, DQV2 18, CR2 24, DCR2 36, MN2 48, SB2 96 (a 4/4 bar). Example: DITTY2: PATCH,1,PWM,1 / ARPON ARP2 / LENGTH,SQ / CALL MEL1 / CT,-5 MEL1 / CT,-12 MEL1 / CT,-17 MEL1 / D4 / END with MEL1: LOOP,2 / F4,G4,F4,D5 / NEXT / RET. The loader: MANUAL / PATCH,1,PWM,1 / VIBON,0,9,6 / EFFECT,12 / BEND,UP,$10,48 / !wo $10*48 / C2,192 ….
Patch = 5 bytes: gate-on control byte, AD, SR, hold (frames; bit 7 GAP = "N frames before the next note" instead of "N frames after note-on"), gate-off control byte — two waveforms per instrument:
| patch | bytes | sound |
|---|---|---|
| DT88 00 | $51,$00,$C8,3,$40 | triangle + pulse, 3 frames, released as pulse |
| DT88 01 | $01,$00,$88,2,$42 | gate with no waveform for 2 frames, then pulse + sync — heard only in release |
| DT88 02 | $55,$00,$99,3,$40 | triangle + pulse + ring |
| DT88 05 | $81,$00,$A8,3,$10 | 3 frames of noise, then triangle — a click transient |
| DT88 09 | $11,$AA,$79,QV2+SQ2+GAP,$10 | the only patch with an attack — the title pad |
| DT88 13 | $41,$00,$88,4+GAP,$14 | pulse, released as triangle + ring |
| Loader 0 | $43,$00,$7B,96+GAP,$22 | pulse + sync, gate off 96 frames before the end, released as sawtooth + sync — the lead |
| Loader 1 | $41,$00,$AD,3,$40 | the bend bass |
PWM entry (5 bytes): rate, frames up, frames down, initial width (word) — $80,$00,$02 / $0F50; $F0,$04,$04 / $0800; loader $40,48,42 / $0000. Arpeggio table: frames per step, steps, offsets… — ARP1 !by 3,4,0,4,7,9, ARP2 !by 1,3,24,12,0, TARP1 !by 2,3,0,3,7. Drum (7-byte entry: wave ptr, freq ptr, length, SR, pulse-hi; AD forced $00): BASS DRUM $41,$41,$10,$80 / $0E,$06,$0F,$10; SNARE $41,$41,$40,$80,$80,$80,$10,$80,$10,$80,$80,$10,$80 / $11,$0C,$08,$70,$70,$2F,$0C,$2E,$0C,$2D,$BC,$0C,$2B; HI-HAT $11,$11,$80,$80,$80 / $10,$10,$70,$20,$30. Fades are self-modifying data: FADEPOS !by PORT,$0F,$18 with TFADEAWAY DEC FADEPOS+1 in a loop.
Related#
jonathan-dunn · martin-galway · galway-player · hubbard-player · sid-player-routine · instrument-tables · pitch-slide-and-portamento · wavetable-programming · chord-arpeggio · sidid
Sources#
s-realdmx-ocean-dunn-hughes-driver · s-chordian-sid-musicians · s-sidid-player-list