Homeentitytool

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, with TOGO reported 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 REFRESH every frame; LDX #tune / JSR TUNE; DT88's tunes 0 DISQUALIFIED, 1 SUCCESS, 2 FAIL, 3 NEXT EVENT, 4 TITLE MUSIC, 5 QUALIFY. Init writes 8 then 0 to 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_Hughes and MusDriver/Paul_Hughes ("Music Driver", with a link to pauliehughes.com) and has no Jonathan_Dunn entry (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:

bytenameargumentseffect
$80JUMPaddrgo to
$81CALLaddrcall a phrase (5-deep stack shared with LOOP)
$82RETreturn, and reset the transpose
$83$84LOOP n … NEXTrepeat
$85BENDdir, step, length, offset16bend into the next note: the frequency is pre-offset by step × length and climbs to the written pitch
$86PATCHnselect a 5-byte patch
$87LENGTHframesauto-duration mode
$88 / $89VIBON / VIBOFFdelay, rate, depthtriangle vibrato on the 16-bit frequency (cancels an arpeggio)
$8a / $8bARPON / ARPOFFaddrarpeggio table (suppresses vibrato and bend while active)
$8cMANUALback to note,duration pairs
$8dPWMnselect a 5-byte pulse-sweep entry
$8e / $92FILTER / FILTOFFempty handlers
$8fENDstop the voice
$90TRANSPOSEnsigned semitones
$91CTn, addrtransposed CALL — the harmony device
$93MODEmaskbit 7 of the mask = set, else clear: gate writes, pulse retrigger per note, "pluck" mode
$94DRUMn, transpose[, duration]voice C only
$95PORTvalue, sid-offsetwrite any SID register (volume $18)
$96CODEaddrJSR into the music data (fades, ramps)
$97EFFECTnoteevery note starts at that (absolute or relative) pitch until its release point — a pluck

Durations: TEMPO = 5SQ 5, QV 10, CR 20, MN 40, SB 80; TEMPO2 = 6SQ2 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:

patchbytessound
DT88 00$51,$00,$C8,3,$40triangle + pulse, 3 frames, released as pulse
DT88 01$01,$00,$88,2,$42gate with no waveform for 2 frames, then pulse + sync — heard only in release
DT88 02$55,$00,$99,3,$40triangle + pulse + ring
DT88 05$81,$00,$A8,3,$103 frames of noise, then triangle — a click transient
DT88 09$11,$AA,$79,QV2+SQ2+GAP,$10the only patch with an attack — the title pad
DT88 13$41,$00,$88,4+GAP,$14pulse, released as triangle + ring
Loader 0$43,$00,$7B,96+GAP,$22pulse + sync, gate off 96 frames before the end, released as sawtooth + sync — the lead
Loader 1$41,$00,$AD,3,$40the 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.

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

source file wiki/entities/ocean-music-driver.md · graph