var long vsync_addr long random_addr long stack[40] byte music byte mute byte amoeba byte magic_wall byte v1cnt, v1ctl byte v2cnt, v2ctl byte v3cnt, v3ctl obj sd : "SIDemu" pub start(video_params, pin, rnd_addr) vsync_addr := long[video_params + constant(6 * 4)] random_addr := rnd_addr v1cnt := 0 v2cnt := 0 v3cnt := 0 mute := false music := false amoeba := false magic_wall := false cognew(process, @stack) sd.start(pin) sd.set_register(23, $07) 'turn main volume half-up pub music_on v1cnt := 0 v2cnt := 0 v3cnt := 0 music_init music := true pub music_off sd.set_register(4, sd#CREG_TRIANGLE) 'gate off sd.set_register(11, sd#CREG_TRIANGLE) 'gate off music := false pub moving_sound(surface) if mute return if surface == $00 sd.set_register(7, $00) 'freq sd.set_register(8, $35) else ' $01 sd.set_register(7, $00) 'freq sd.set_register(8, $A5) sd.set_register(12, $30) 'attack/decay sd.set_register(13, $C0) 'sustain/release sd.set_register(11, sd#CREG_NOISE | sd#CREG_GATE) v2ctl := sd#CREG_NOISE v2cnt := 2 pub boulder_sound if mute return if v1cnt return sd.set_register(0, $32) 'freq sd.set_register(1, $09) sd.set_register(5, $00) 'attack/decay sd.set_register(6, $F9) 'sustain/release sd.set_register(4, sd#CREG_NOISE | sd#CREG_GATE) v1ctl := sd#CREG_NOISE v1cnt := 1 pub diamond_sound if mute return if v1cnt return sd.set_register(0, byte[random_addr]) 'freq sd.set_register(1, $86 + byte[random_addr] & $07) sd.set_register(5, $00) 'attack/decay sd.set_register(6, $F0) 'sustain/release sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) v1ctl := sd#CREG_TRIANGLE v1cnt := 2 pub pick_sound if mute return if v1cnt return sd.set_register(0, $78) 'freq sd.set_register(1, $14) sd.set_register(5, $00) 'attack/decay sd.set_register(6, $F9) 'sustain/release sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) v1ctl := sd#CREG_TRIANGLE v1cnt := 1 pub explosion_sound if mute return if v1cnt return sd.set_register(0, $32) 'freq sd.set_register(1, $14) sd.set_register(5, $19) '$1D 'attack/decay sd.set_register(6, $00) 'sustain/release sd.set_register(4, sd#CREG_NOISE | sd#CREG_GATE) v1ctl := sd#CREG_NOISE v1cnt := 200 pub crack_sound if mute return if v3cnt return sd.set_register(19, $19) 'attack/decay sd.set_register(20, $01) 'sustain/release sd.set_register(14, $32) 'freq sd.set_register(15, $2F) sd.set_register(18, sd#CREG_NOISE | sd#CREG_GATE) v3ctl := sd#CREG_NOISE v3cnt := 80 pub magic_wall_sound_on if not magic_wall magic_wall := true sd.set_register(18, sd#CREG_TRIANGLE) pub magic_wall_sound_off if magic_wall magic_wall := false v3ctl := sd#CREG_TRIANGLE v3cnt := 1 pub amoeba_sound_on if not amoeba amoeba := true sd.set_register(18, sd#CREG_TRIANGLE) pub amoeba_sound_off if amoeba amoeba := false v3ctl := sd#CREG_TRIANGLE v3cnt := 1 var byte last_val pub time_ending_sound(sec_left) mute := true if sec_left == last_val return last_val := sec_left if sec_left == 0 mute := false sd.set_register(4, sd#CREG_TRIANGLE) waitcnt(clkfreq / 1000 + cnt) sd.set_register(0, $00) sd.set_register(1, $27 - sec_left) sd.set_register(5, $0A) 'attack/decay sd.set_register(6, $00) 'sustain/release sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) v1cnt := 0 pub bonus_point_sound(pts) | i sd.set_register(5, $00) 'attack/decay sd.set_register(6, $A0) 'sustain/release sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) repeat i from 2 to 30 step 2 sd.set_register(0, $00) sd.set_register(1, $B0 - pts + i) waitcnt(clkfreq / 500 + cnt) sd.set_register(4, sd#CREG_TRIANGLE) pub cover_sound if v2cnt return sd.set_register(12, $05) 'attack/decay sd.set_register(13, $00) 'sustain/release sd.set_register(7, $00) sd.set_register(8, $64 + byte[random_addr] & $7F) 'freq sd.set_register(11, sd#CREG_TRIANGLE | sd#CREG_GATE) v2ctl := sd#CREG_TRIANGLE v2cnt := 1 pub process | r repeat 'wait for vsync repeat while byte[vsync_addr] == 0 repeat while byte[vsync_addr] <> 0 if music play_note if v1cnt if --v1cnt == 0 sd.set_register(4, v1ctl) if v2cnt if --v2cnt == 0 sd.set_register(11, v2ctl) if v3cnt if --v3cnt == 0 sd.set_register(18, v3ctl) if amoeba if mute sd.set_register(18, sd#CREG_TRIANGLE) else sd.set_register(19, $00) 'attack/decay sd.set_register(20, $40) 'sustain/release repeat r := byte[random_addr] & $1F while r < $07 sd.set_register(14, $00) 'freq sd.set_register(15, r) sd.set_register(18, sd#CREG_TRIANGLE | sd#CREG_GATE) v3cnt := 2 elseif magic_wall if mute sd.set_register(18, sd#CREG_TRIANGLE) else sd.set_register(19, $00) 'attack/decay sd.set_register(20, $A0) 'sustain/release r := byte[random_addr] & $03 sd.set_register(14, $00) 'freq sd.set_register(15, $86 + (r << 3)) sd.set_register(18, sd#CREG_TRIANGLE | sd#CREG_GATE) v3cnt := 2 dat notes byte $16, $22, $1D, $26, $22, $29, $25, $2E, $14, $24, $1F, $27, $20, $29, $27, $30 byte $12, $2A, $12, $2C, $1E, $2E, $12, $31, $20, $2C, $33, $37, $21, $2D, $31, $35 byte $16, $22, $16, $2E, $16, $1D, $16, $24, $14, $20, $14, $30, $14, $24, $14, $20 byte $16, $22, $16, $2E, $16, $1D, $16, $24, $1E, $2A, $1E, $3A, $1E, $2E, $1E, $2A byte $14, $20, $14, $2C, $14, $1B, $14, $22, $1C, $28, $1C, $38, $1C, $2C, $1C, $28 byte $11, $1D, $29, $2D, $11, $1F, $29, $2E, $0F, $27, $0F, $27, $16, $33, $16, $27 byte $16, $2E, $16, $2E, $16, $2E, $16, $2E, $22, $2E, $22, $2E, $16, $2E, $16, $2E byte $14, $2E, $14, $2E, $14, $2E, $14, $2E, $20, $2E, $20, $2E, $14, $2E, $14, $2E byte $16, $2E, $32, $2E, $16, $2E, $33, $2E, $22, $2E, $32, $2E, $16, $2E, $33, $2E byte $14, $2E, $32, $2E, $14, $2E, $33, $2E, $20, $2C, $30, $2C, $14, $2C, $31, $2C byte $16, $2E, $16, $3A, $16, $2E, $35, $38, $22, $2E, $22, $37, $16, $2E, $31, $35 byte $14, $2C, $14, $38, $14, $2C, $14, $38, $20, $2C, $20, $33, $14, $2C, $14, $38 byte $16, $2E, $32, $2E, $16, $2E, $33, $2E, $22, $2E, $32, $2E, $16, $2E, $33, $2E byte $14, $2E, $32, $2E, $14, $2E, $33, $2E, $20, $2C, $30, $2C, $14, $2C, $31, $2C byte $2E, $32, $29, $2E, $26, $29, $22, $26, $2C, $30, $27, $2C, $24, $27, $14, $20 byte $35, $32, $32, $2E, $2E, $29, $29, $26, $27, $30, $24, $2C, $20, $27, $14, $20 freqs word $02DC, $030A, $033A, $036C, $03A0, $03D2, $0412, $044C word $0492, $04D6, $0520, $056E, $05B8, $0614, $0674, $06D8 word $0740, $07A4, $0824, $0898, $0924, $09AC, $0A40, $0ADC word $0B70, $0C28, $0CE8, $0DB0, $0E80, $0F48, $1048, $1130 word $1248, $1358, $1480, $15B8, $16E0, $1850, $19D0, $1B60 word $1D00, $1E90, $2090, $2260, $2490, $26B0, $2900, $2B70 word $2DC0, $0100, $0200, $0101, $0105, $0100, $0101, $0306 word $0101, $0102, $0101 var long note byte v1sr pri music_init note := 0 v1sr := $B0 sd.set_register(4, sd#CREG_TRIANGLE) sd.set_register(5, $4F) sd.set_register(6, $00) sd.set_register(11, sd#CREG_TRIANGLE) sd.set_register(12, $24) '$78) sd.set_register(13, $75) '$78) pub play_note | n, f if v1sr == $B0 sd.set_register(4, sd#CREG_TRIANGLE) sd.set_register(11, sd#CREG_TRIANGLE) n := notes.byte[note++] f := word[@freqs + 2*n - $14] sd.set_register(0, f & $FF) sd.set_register(1, f >> 8) n := notes.byte[note++] f := word[@freqs + 2*n - $14] sd.set_register(7, f & $FF) sd.set_register(8, f >> 8) v1sr := $A0 return if note == 256 note := 0 sd.set_register(6, v1sr | $01) sd.set_register(4, sd#CREG_TRIANGLE | sd#CREG_GATE) sd.set_register(11, sd#CREG_TRIANGLE | sd#CREG_GATE) v1sr -= $10 if v1sr < $40 v1sr := $B0