realdmx: Johannes Bjerregaard's own player — the James Bond 3 demo (a Maniacs of Noise commission) and Myth
Two of johannes-bjerregaard's own Turbo Assembler sources from 1989, in the realdmx collection (s-realdmx-sid-players) under Bjerregaard_Johannes_MON — but the player is his, not charles-deenen's musicfile: nothing in the code is shared with the MoN driver, which fits VGMPF's note that he "preferred his own driver" (s-vgmpf-maniacs-of-noise). What the James Bond file does show is a maniacs-of-noise job sheet at the top of a Danish composer's source. Cheat sheet on bjerregaard-player.
Key claims#
Provenance — a commission in the header
- James Bond 3, Bjerregaard's own header:
;RECEIVED : 18/6,;LATEST DELIVERY : 19/6,;ROOM : …,;ZERO PAGE : …,;SPECIFICATIONS : 30 SECS OF JAMES BOND TITLE TUNE INCLUDING A DEMO OF THE MANIACS OF NOISE MUSIC STYLE(line-wrapped in the source). Instrument 9 is named;JEROEN PLOINK— a jeroen-tel-style sound by name. A commented-out BASIC stub at$0801decodes, with the standard BASIC tokens, to1989 SYS2083 STORM LORD MUSIC (C)MON.(reading of the bytes$21,$08,$C5,$07,$9E,$32,$30,$38,$33,$20,$53,$A4 …; interpretation, not a comment in the file) — the same player shell was used for a Stormlord music demo credited to MoN. The demo screen text reads "Player and music by Jozz Bjerregaard" (PETSCII, decoded). - Above the job sheet an
;IMPROVEMENTS:list:;"2ND SUSTAIN"/;SET1+7 BIT 4-7 = LEVEL/;RELEASE ONLY WHILE RESTING/;(!)CHIP RESET ALWAYS/;AUTO SUSTAIN DELAY/;SET1+6 BIT 5-7 = TIME=FRAMES/;RELEASE TRIGGER/;SET1+3 BIT 4-7 = 2*TIME=FRAMES/;DON'T FORGET:/;FILTER SEQUENCE END/STOP/;RECOGNITION BYTES CHANGED!— a change log of the player between jobs. - Entry points, both files:
jmp setmus ;init(.a=music no)at$1000,jmp musoff ;stops playing tuneat$1003,jmp play ;jsr in irq-interruptat$1006; a fade-rate byte (faderate !by 0 ;store fade rate(1-127)) the game can poke; Myth additionally keeps three raster-time bytesrtimeat$1009($d012sampled at the start and end of each voice) — a rastertime meter shipped in the player (sid-player-routine). The JB3 file also carries its commented-out test harness: border colour whilePLAYruns, keys 1–3 for tunes, space to fade, a key held for fast-forward, and a frames/seconds/minutes clock. - Not the same version. Same command ranges, track format and frequency table, and six leftover instrument rows byte-identical in both files; but JB3 packs instrument bytes 3/5/6 as nibbles and addresses its wave/note/pulse/filter programs through pointer tables with
$FE(keep last) /$FF(repeat) and$7E/$7Ffor filters (the "RECOGNITION BYTES CHANGED!" warning), while Myth uses whole-byte offsets fromp0/f0/w0/n0and only$ff. Myth has a voice-count byte, writes AD/SR every frame and has a working tie; JB3 has the second-sustain machinery. Which is older the files do not say.
Song → tracks → patterns (orderlist)
- Song table: 8 bytes per song —
!by 2,4 ;TITLE THEME/!wo V0,V1,V2(byte 1 = tempo; frames per tick = value + 1; Myth reads byte 0 as voices − 1). Track bytes:< $80pattern number,$80–$FDtranspose =(byte & $7F) − $40($C0= 0,$CC= +12,$BC= −4),$FEstop,$FFrestart all three voices. Example:V0 !by $C0,$01,$CC,$04,$C0,$06,$09,$09,$09,$09,$FF. - Pattern bytes (
& $1Fwhere a range is given):$00–$5Fnote (+ transpose);$60–$7Fselect arpeggio/note program;$80–$9Fselect instrument;$A0–$BFglide speed, next byte the target note;$C0–$DFnote length ($C0= 1 tick,$C7= 8);$E0–$FFrest of that length; Myth only:$fctie/legato,$fe xxoverride sustain/release for the following notes ($fe,$39,$fe,$95— used all through the bass lines);$FFend. Excerpt (JB3S0B):$E1 / $C1,$88,$34,$39,$3B / $3C,$E1,$3E,$E1,$C2 / $A2,$3C,$3B …= rest, then 2-tick notes on instrument 8, a glide of speed 2 to note$3C. - New data is read one tick before it is applied — the tick in between is where the hard-restart writes go.
Instrument = 8 bytes (JB3's header: ;0=ATK/DCY ;1=SUS1/REL ;2=VIB1 ;3=PULSE/DLY ;4=NOTES ;5=FILTER ;6=WAVES ;7=VIB2/SUS2; Myth's: attack/decay, sus/rel, vib delay/speed, pulse block pointer, notes program# selector with bit 7 shutup notes, filter block pointer, waves block pointer, vib steady/rate) (instrument-tables):
- JB3 rows:
;INTROFILTERBASS+DRUM $0A,$A7,$17,$01,$05,$22,$04,$31;;GUITAR $08,$6C,$79,$02,$04,$80,$05,$01;;ORCH HIT ......HMMM $06,$59,$10,$03,$0C,$00,$06,$10;;DRUMM $06,$A9,$00,$00,$03,$00,$01,$00;;MELODY $06,$50,$17,$04,$04,$20,$07,$51;;JEROEN PLOINK $08,$86,$17,$00,$04,$20,$08,$23. - Myth rows (pointers as label differences):
;chord $02,$79,$19,p0-p0,$84,f0-f0,w0-w0,$00;;boring 41-sound $00,$36,$00,p0-p0,$84,f0-f0,w1-w0,$00;;bazedrum $08,$66,$00,p1-p0,$05,f0-f0,w2-w0,$00;;baze $0a,$a3,$00,p2-p0,$04,f1-f0,w3-w0,$00;;plonk $04,$56,$17,p0-p0,$0b,f0-f0,w4-w0,$14; also;shortsnare,;tom,;guitar,;filterbazedrum,;soft guitar wo vib,;zzzzooooow f.x.,;wierd solo guitar.
Programs — one byte per frame, byte 0 = repeat point:
- Waveform:
W0 ;BASSDRUM $01,$81,$41,$40,$FE;W1 ;LONGSNARE $01,$81,$11,$40,$80,$40,$80,$FE;W5 ;GUITAR $01,$43,$43,$43,$40,$FE; Mythw2 ;bazedrum $01,$81,$41,$11,$40,$40,$40,$40,$40,$80,$ff— every Myth program starts with$01(gate, no waveform) (wavetable-programming). - Note/arpeggio: entries
< $80are semitone offsets,≥ $80absolute notes; JB3N0 $01,$04,$04,$00,$FF,N5 $01,$BF,$A2,$9A,$00,$FE(absolute notes, then offset 0); with bit 7 in byte 0 the entries are raw$D401bytes —N2 $81 / $58,$08,$06,$04,$03,$02,$03,$04,$03,$FE, a drum sweep; Mythn0 $07,$03,$00,$07,$ff(minor),n5 ;bazedrum $01,$ca,$aa,$b1,$a6,$a2,$9f,$9c,$9e,$df,$da,$ff,n7 ;tom $08,$05,$03,$02,$01,$01,$00,$ff(chord-arpeggio). Drums are ordinary instruments: noise-first wave program plus a falling note program — no drum routine. - Pulse:
;BYTE 0 = REPEAT POINT / ;BYTE 1 = LO/HI PULSE WIDTH, then (delta, frames) pairs, bit 7 of the delta = add: JB3P2 ;GUITAR $01,$E0, $C0,$01, $B0,$01, $A0,$02, $10,$03, $08,$04,$FE; Mythp1 ;skwear polls waive $08,$00,$7f,$ff(fixed$0800),p2 ;filterbaze $e2, $83,$01, $87,$01, $8a,$01, $90,$0a, $70,$0a,$ff(pulse-width-modulation). - Filter:
;BYTE 1=CUTOFF TRIGGER VALUE / ;BYTE 2=FILTER PASS (0=OFF)(the$D418mode nibble), then signed (delta, frames) pairs moving one global cutoff; JB3F1 $01,$80,$10, $F0,$06,$7E; Mythf1 ;filterbass $90,$10,$d0,$03,$00,$7f,$ff. Resonance is hard-wired to$F(FONT !by $F1,$F2,$F4) (filter-programming). - Vibrato has no table: the depth is the semitone distance at the current note taken from the frequency table and shifted by the rate nibble, ramped in over N frames — constant in cents across octaves (vibrato).
Envelope tricks — the "improvements" (read from the code; the mechanism is not commented beyond the header list)
- Second sustain (JB3): after
SET1+6bits 5–7 frames the gate is dropped and re-raised in the same frame with AD = 0 and the high nibble ofSET1+7as a new sustain — the SID re-attacks instantly to a second level; then, after 2 × (SET1+3high nibble) frames, the gate is released regardless of note length ("AUTO SUSTAIN DELAY", "RELEASE TRIGGER"); a rest performs the same release write if it has not happened ("RELEASE ONLY WHILE RESTING") (adsr-envelope). - Hard restart, two ways: JB3 writes AD = SR =
$00two ticks before every new note and$F0to the control register one tick before, then$09(test + gate) on the note frame; Myth zeroes ADSR one tick early only for instruments whose byte 4 has bit 7 set (;4 : bit 7 shutup notes), never sends the test bit (its gate mask is$f7/$f6), and uses the program's first$01frame as the silent restart. Bit 3 of a Myth wave entry means "force pulse width$0800", not "test bit" (hard-restart). - Myth rewrites
$d405/$d406every frame from per-voice variables, which is what makes its$fe xxsustain/release command possible mid-pattern.
Practical takeaways#
- Bjerregaard's sound in one instrument:
$01for a frame, a noise frame, then the waveform; a pulse program that steps down in unequal (delta, frames) pairs; a filter program on one global cutoff; vibrato proportional to the semitone. - The "second sustain" is a two-stage envelope done in software — the same result later trackers get from ADSR tables or a gate-off/gate-on pair in a wave table.
- Drums as instruments (noise wave program + raw-frequency note program) instead of a drum routine: portable to any tracker with an absolute-pitch wave table (wavetable-programming).
- Sizes (estimated from the listings, no assembler available): JB3 ≈ 1.6 KB code + 1.3 KB data; Myth ≈ 1.5 KB code + 2.7 KB data.
Notable quotes#
;SPECIFICATIONS : 30 SECS OF JAMES BOND TITLE TUNE INCLUDING A DEMO OF THE MANIACS OF NOISE MUSIC STYLE(JB3 header).;JEROEN PLOINK,;ORCH HIT ......HMMM,;boring 41-sound,;zzzzooooow f.x.,;wierd solo guitar,p1 ;skwear polls waive(instrument and table names).
Relevance to the wiki#
Primary source for bjerregaard-player and the first first-hand document of how a MoN job was specified (maniacs-of-noise, johannes-bjerregaard); adds a scene composer's own driver to the comparison on sid-player-routine; hard-restart and two-stage-envelope ancestors for hard-restart and adsr-envelope; table shapes for instrument-tables, wavetable-programming, chord-arpeggio, pulse-width-modulation, filter-programming, vibrato.
To verify#
- (unverified) Whether "Myth" is System 3's Myth: History in the Making (1989) — the file says only
intro tune/ending tune; the PSID header says "1989 Johannes Bjerregaard". - (unverified) The BASIC-stub reading "STORM LORD MUSIC (C)MON." is a decoding of commented-out bytes, not a statement in the file.
Pages touched#
bjerregaard-player · johannes-bjerregaard · maniacs-of-noise · jeroen-tel · musicfile · sid-player-routine · sidid · instrument-tables · hard-restart · adsr-envelope · wavetable-programming · chord-arpeggio · pulse-width-modulation · filter-programming · vibrato · orderlist · song-init-and-looping · semitone-math