====== Sound Fx Routine (From Prince of Persia (C64)) ====== ===== Preface ===== Below is the full source code for the sound effect player routine made exclusively for Mr.SID's Commodore 64 EasyFlash conversion of "Prince of Persia". It consists of reading chunks of data that is written directly to each SID register at every frame, including the filter registers. This code is capable of using up to two voices each time a sound effect is initiated, without disrupting a currently running sound effect that may use up to two voices. This means that the program determines how many voices are available (either 1 or 2 in this case) and behaves differently depending on that condition. For example, if the currently playing sound effect is using voices 1 and 3, the next sound effect (assuming that it will start playing in parallel with the current) will select the avaiable voice (voice 2), disregarding the 2nd channel of data if there are no voices left available, due to the SID chip only having 3 voices in total. The reason for this complexity was for the sake of playing more fancy sound effects, such as the advantage of using the SYNC and RING-MOD bits for one of the voices used, rather than your simple boring 1-voice only sound effects. The trick is to assign NO sync/ring sound data to channel 1, just in case that only 1 voice is available at the time you call the init sub-routine. The following source code includes the main sound-routine, the sound-effect programs used for Prince of Persia (based as much as possible on the original PC/Amiga sound effects), some definition code, and a test harness program written for Mr.SID to test the sounds. All code is in 64Tass format, and is partially commented to help understand how it works. By Conrad/Samar/Onslaught/Viruz, in September/October 2011. ===== "sfxconfig.txt" ===== This file is just a couple of definition lines... BASE_SFX = $8000 ZP_SFX = $02 ===== "sfxplayer.asm" ===== The main routine code... ;;-------------------------------------- ;;-------------------------------------- ;; SIMPLE SFX-PLAYER ROUTINE ;;-------------------------------------- ;; Coded by Conrad/Viruz/Samar/[O] ;;-------------------------------------- ;; Purposely made for Mr.SID and the C64 ;; conversion game "Prince of Persia" ;;-------------------------------------- ;; September 2011 ;;-------------------------------------- ;;-------------------------------------- ;;------------------------- ;; Zero-page address buffer ;;------------------------- ZP_SFX_START = ZP_SFX+0 sfx_zp_tmp1 = ZP_SFX+0 sfx_zp_tmp2 = ZP_SFX+1 sfx_zp_tmp_lo = ZP_SFX+2 sfx_zp_tmp_hi = ZP_SFX+3 sfx_zp_playing = ZP_SFX+4 sfx_zp_filtering = ZP_SFX+5 sfx_zp_state_wave_lo = ZP_SFX+6 sfx_zp_state_wave_hi = ZP_SFX+9 sfx_zp_state_filter_lo = ZP_SFX+12 sfx_zp_state_filter_hi = ZP_SFX+13 sfx_zp_tmp3 = ZP_SFX+14 ZP_SFX_END = ZP_SFX+14 ;;------------------- ;; Player Jump Tables ;;------------------- *=BASE_SFX ;;--------------- ;; Player Routine ;;--------------- SFX_PLAY ; Voice section ldx #$02 ; Loop through all 3 voices - lda sfx_zp_state_wave_lo,x ; Set up wave data pointer address sta sfx_zp_tmp_lo ; lda sfx_zp_state_wave_hi,x ; sta sfx_zp_tmp_hi ; ldy #$00 ; Start at first byte lda (sfx_zp_tmp_lo),y ; Read byte 1 bne + ; If byte != 0, jump to branch. lda sfx_zp_playing ; this voice and make it available for and sfx_turnoff,x ; another sound effect setup. sta sfx_zp_playing ; bpl ++++++++++ ; Skip to next voice loop + sta sfx_zp_tmp2 ; Store this as control bits stx sfx_zp_tmp1 ; Keep a record of X lda sfx_voiceoffset,x ; Set X as the SID register offset, tax ; depending on which voice processed. iny + asl sfx_zp_tmp2 ; bit 8 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 2 sta $d402,x ; Set HIGH PULSE iny + asl sfx_zp_tmp2 ; bit 7 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 3 sta $d403,x ; Set LOW PULSE iny + asl sfx_zp_tmp2 ; bit 6 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 4 sta $d406,x ; Set SUSTAIN/RELEASE iny ; + asl sfx_zp_tmp2 ; bit 5 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 5 sta $d405,x ; Set ATTACK/DECAY iny ; + asl sfx_zp_tmp2 ; bit 4 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 6 sta $d400,x ; Set HIGH FREQUENCY iny ; + asl sfx_zp_tmp2 ; bit 3 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 7 sta $d401,x ; Set LOW FREQUENCY iny ; + asl sfx_zp_tmp2 ; bit 2 set? bcc + lda (sfx_zp_tmp_lo),y ; Read byte 8 sta $d404,x ; Set WAVE CONTROL iny + ldx sfx_zp_tmp1 ; Load back in the X state tya ; Now set the wave data point address clc ; to the new location. adc sfx_zp_state_wave_lo,x ; (i.e. ((OLD LOCATION) + 7 bytes)) sta sfx_zp_state_wave_lo,x ; bcc + ; inc sfx_zp_state_wave_hi,x ; + dex ; If X >= 0, then loop bpl - ; ; Filter section lda sfx_zp_state_filter_lo sta sfx_zp_tmp_lo lda sfx_zp_state_filter_hi sta sfx_zp_tmp_hi ldy #$00 lda (sfx_zp_tmp_lo),y beq ++ sta $d416 iny lda (sfx_zp_tmp_lo),y and #$f0 ora sfx_zp_filtering sta $d417 lda (sfx_zp_tmp_lo),y asl asl asl asl ora #$0f sta $d418 lda sfx_zp_state_filter_lo clc adc #$02 sta sfx_zp_state_filter_lo bcc + inc sfx_zp_state_filter_hi + rts + sty sfx_zp_filtering - rts ;;------------------------------------- ;; Init Routine ;;------------------------------------- ;; A = sfx number ($00-$3f/64 settings) ;;------------------------------------- SFX_INIT ldx sfx_zp_playing ldy sfx_available_voices,x beq - sty sfx_zp_tmp1 ldx sfx_voice_configaddress_hi-1,y stx sfx_zp_tmp_hi ldx sfx_voice_configaddress_lo-1,y stx sfx_zp_tmp_lo ldy sfx_zp_playing ldx sfx_voice_startposition,y tay lda sfx_lookupindex,y tay lda sfx_turnon,x sta sfx_zp_tmp3 - dec sfx_zp_tmp1 bmi + lda (sfx_zp_tmp_lo),y sta sfx_zp_state_wave_lo,x iny lda (sfx_zp_tmp_lo),y sta sfx_zp_state_wave_hi,x iny sty sfx_zp_tmp2 ldy sfx_voiceoffset,x lda #$00 sta $d406,y sta $d405,y sta $d404,y sta $d400,y sta $d401,y sta $d402,y sta $d403,y ldy sfx_zp_tmp2 lda sfx_zp_playing ora sfx_turnon,x sta sfx_zp_playing inx cpx #$03 bne - ldx #$00 beq - + lda sfx_zp_tmp3 ldx sfx_zp_filtering bne + sta sfx_zp_filtering lda (sfx_zp_tmp_lo),y sta sfx_zp_state_filter_lo iny lda (sfx_zp_tmp_lo),y sta sfx_zp_state_filter_hi + rts ;;-------------- ;; Reset Routine ;;-------------- SFX_RESET ldy #0 sty sfx_zp_filtering sty sfx_zp_playing lda #3 sta sfx_zp_tmp1 lda #sfx_reset_data sta sfx_zp_tmp_hi ldx #$00 lda sfx_turnon,x sta sfx_zp_tmp3 bpl - sound_blank = sfx_reset+1 sfx_reset_data .word sound_blank, sound_blank, sound_blank, sound_blank ;;--------------------------- ;; Lookup data used by player ;;--------------------------- sfx_available_voices .byte 2,2,2,1,2,1,1 sfx_voice_startposition .byte 0,1,2,2,0,1,0 sfx_voiceoffset .byte 0,7,14 sfx_turnon .byte 1,2,4 sfx_turnoff .byte %11111110, %11111101, %11111011 sfx_voice_configaddress_hi .byte >sfx_data_lookup_1voice .byte >sfx_data_lookup_2voice sfx_voice_configaddress_lo .byte ===== "sfxdata.asm" ===== The file contains the sound effect data. //Please note that this is the first revision of the sound data, meaning that all sounds are not 100% the same to the one's you heard in the released game.// sfx_data_lookup_2voice .word sound_footstep, sound_blank, sound_footstep_flt .word sound_bump_wall_v1, sound_blank, sound_bump_wall_flt .word sound_landing_v1, sound_landing_v2, sound_landing_flt .word sound_pressplate_v1, sound_pressplate_v2, sound_pressplate_flt .word sound_spikesup_v1, sound_spikesup_v2, sound_spikesup_flt .word sound_dooropen_v1, sound_dooropen_v2, sound_dooropen_flt .word sound_entranceclose_v1, sound_entranceclose_v2, sound_entranceclose_flt .word sound_gaterising_v1, sound_gaterising_v2, sound_gaterising_flt .word sound_gateclosing_v1, sound_gateclosing_v2, sound_gateclosing_flt .word sound_gateslam_v1, sound_gateslam_v2, sound_gateslam_flt .word sound_fallingfloorland_v1, sound_fallingfloorland_v2, sound_fallingfloorland_flt .word sound_stabbed_v1, sound_stabbed_v2, sound_stabbed_flt .word sound_swordhit_v1, sound_swordhit_v2, sound_swordhit_flt .word sound_swordstab_v1, sound_swordstab_v2, sound_swordstab_flt .word sound_drink_v1, sound_drink_v2, sound_drink_flt .word sound_jumpmirror_v1, sound_jumpmirror_v2, sound_jumpmirror_flt .word sound_jawclash_v1, sound_jawclash_v2, sound_jawclash_flt sfx_data_lookup_2voice_ sfx_data_lookup_1voice .word sound_footstep, sound_footstep_flt, sound_blank .word sound_bump_wall_v1, sound_bump_wall_flt, sound_blank .word sound_landing_v1, sound_bump_wall_flt, sound_blank .word sound_pressplate_v1, sound_pressplate_flt, sound_blank .word sound_spikesup_v1, sound_spikesup_flt, sound_blank .word sound_dooropen_v1, sound_dooropen_flt, sound_blank .word sound_entranceclose_v1, sound_entranceclose_flt, sound_blank .word sound_gaterising_v1, sound_gaterising_flt, sound_blank .word sound_gateclosing_v1, sound_gateclosing_flt, sound_blank .word sound_gateslam_v1, sound_gateslam_flt, sound_blank .word sound_fallingfloorland_v1, sound_fallingfloorland_flt, sound_blank .word sound_stabbed_v1, sound_stabbed_flt, sound_blank .word sound_swordhit_v1, sound_swordhit_flt, sound_blank .word sound_swordstab_v1, sound_swordstab_flt, sound_blank .word sound_drink_v1, sound_drink_flt, sound_blank .word sound_jumpmirror_v1, sound_jumpmirror_v2, sound_jumpmirror_flt, sound_blank .word sound_jawclash_v1, sound_jawclash_flt sfx_lookupindex .for i=0,i<17,i=i+1 .byte i*6 .next ; Jaw-Clash sound_jawclash_v1 .byte %00111110 .word $00f8 .word $3482 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1,1,1,1 .byte %00000010 .byte $80 .byte 0 sound_jawclash_v2 .byte %11111110 .word $0200 .word $00c8 .word $2000 .byte $09 .byte %00000010 .byte $57 .byte 1,1,1,1 .byte %00001110 .word $2900 .byte $10 .byte 0 sound_jawclash_flt .word $f1ff .byte 0 ; Jump-Mirror sound_jumpmirror_v1 .byte %00111110 .word $90f7 .word $0a00 .byte $09 .byte %00000010 .byte $21 .byte %00001100 .word $1a10 .byte %00001100 .word $1a40 .byte %00001100 .word $1a80 .byte %00001100 .word $1ac0 .byte %00001100 .word $1b00 .byte %00001100 .word $1b20 .byte %00001100 .word $1b50 .byte %00001100 .word $1b80 .byte %00001100 .word $1ba0 .byte %00000010 .byte $20 .byte %00001100 .word $1b60 .byte %00001100 .word $1b40 .byte 0 sound_jumpmirror_v2 .byte %00111110 .word $90f7 .word $2000 .byte $09 .byte %00000010 .byte $15 .byte %00001100 .word $2100 .byte %00001100 .word $2200 .byte %00001100 .word $2300 .byte %00001100 .word $2400 .byte %00001100 .word $2500 .byte %00001100 .word $2600 .byte %00001100 .word $2700 .byte %00001100 .word $2800 .byte %00000010 .byte $14 .byte %00001100 .word $2700 .byte %00001100 .word $2600 .byte %00001100 .word $2500 .byte %00001100 .word $2400 .byte %00001100 .word $2300 .byte %00001100 .word $2200 .byte %00001100 .word $2100 .byte %00001100 .word $2000 .byte 0 sound_jumpmirror_flt .word $f510 .word $f520 .word $f530 .word $f540 .word $f550 .word $f560 .word $f570 .word $f580 .word $f590 .word $f5a0 .word $f5b0 .word $f5c0 .word $f5d0 .word $f5e0 .word $f5f0 .byte 0 ; Drink-Poison sound_drink_v1 .byte %00111110 .word $20f2 .word $1000 .byte $09 .byte %00001110 .word $0700 .byte $11 .byte %00001100 .word $0800 .byte %00001100 .word $0900 .byte %00001110 .word $0a70 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $0a00 .byte $11 .byte %00001100 .word $0b00 .byte %00001100 .word $0c00 .byte %00001110 .word $0d00 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $0c00 .byte $11 .byte %00001100 .word $0d00 .byte %00001100 .word $0e00 .byte %00001110 .word $0f00 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $0e00 .byte $11 .byte %00001100 .word $0f00 .byte %00001100 .word $1000 .byte %00001110 .word $1200 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $1000 .byte $11 .byte %00001100 .word $1200 .byte %00001100 .word $1400 .byte %00001110 .word $1500 .byte $10 .byte 0 sound_drink_v2 .byte %00111110 .word $d012 .word $1000 .byte $09 .byte %00001110 .word $0810 .byte $17 .byte %00001100 .word $0810 .byte %00001100 .word $0910 .byte %00001110 .word $0a10 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $0a10 .byte $17 .byte %00001100 .word $0b10 .byte %00001100 .word $0c10 .byte %00001110 .word $0d10 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $0c10 .byte $17 .byte %00001100 .word $0d10 .byte %00001100 .word $0e10 .byte %00001110 .word $0f10 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $0e10 .byte $17 .byte %00001100 .word $0f10 .byte %00001100 .word $1010 .byte %00001110 .word $1210 .byte $10 .byte 1,1,1,1,1,1,1 .byte %00001110 .word $1020 .byte $17 .byte %00001100 .word $1220 .byte %00001100 .word $1420 .byte %00001110 .word $1520 .byte $10 .byte 0 sound_drink_flt .word $f104 .byte 0 ; Sword-Hit sound_swordhit_v1 .byte %11111110 .word $0050 .word $80f8 .word $ffff .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1 .byte %00001110 .word $3c00 .byte $41 .byte 1,1,1,1 .byte %00000010 .byte $40 .byte 0 sound_swordhit_v2 .byte %11111110 .word $0010 .word $0086 .word $0000 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1 .byte %00001110 .word $ffff .byte $15 .byte 1,1,1,1 .byte %00000010 .byte $14 .byte 0 sound_swordhit_flt .word $f410 .word $f411 .word $f412 .word $f413 .word $f414 .word $f4ff .byte 0 ; Sword-Stab sound_swordstab_v1 .byte %11111110 .word $0020 .word $00f2 .word $1000 .byte $09 .byte %00000010 .byte $11 .byte %00001110 .word $6fff .byte $81 .byte 1 .byte %00001110 .word $1000 .byte $41 .byte %00001100 .word $0ff0 .byte %00001100 .word $0f80 .byte %00001100 .word $0f80 .byte %00001100 .word $0e00 .byte %00001100 .word $0d00 .byte %00001110 .word $0c00 .byte $40 .byte %00001100 .word $0b80 .byte %00001100 .word $0b00 .byte 0 sound_swordstab_v2 .byte %11111110 .word $0000 .word $0052 .word $0000 .byte $09 .byte %00000010 .byte $11 .byte 1,1,1 .byte %00001110 .word $5000 .byte $57 .byte 1,1,1,1,1,1 .byte %00001110 .word $4000 .byte $56 .byte $00 sound_swordstab_flt .word $f113 .word $f113 .word $f110 .word $f104 .word $f104 .word $f240 .byte 0 ; Stabbed sound_stabbed_v1 .byte %00111110 .word $00f2 .word $2000 .byte $09 .byte %00000010 .byte $11 .byte %00001110 .word $6fff .byte $81 .byte 1 .byte %00001110 .word $1000 .byte $10 sound_stabbed_v2 .byte $00 sound_stabbed_flt .word $f113 .word $f113 .word $f110 .word $f104 .byte 0 ; Falling-Floor-Land sound_fallingfloorland_v1 .byte %00111110 .word $00f8 .word $0600 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1,1,1 .byte %00000010 .byte $80 .byte 0 sound_fallingfloorland_v2 .byte %00111110 .word $00f9 .word $2000 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1 .byte %00000010 .byte $80 .byte 0 sound_fallingfloorland_flt .word $f110 .byte 0 ; Footstep sound_footstep .byte %00111110 .word $1052 .word $08ff .byte $09 .byte %00000010 .byte $81 .byte 1 .byte %00001110 .word $0800 .byte $80 .byte 0 sound_footstep_flt .word $f2ff .word $f2c0 .word $f2ff .word $f4c0 .byte 0 ; Bump Wall sound_bump_wall_v1 .byte %11111110 .word $0780 .word $0422 .word $a000 .byte $09 .byte %00001110 .word $2100 .byte $11 .byte %00001110 .word $1000 .byte $41 .byte %00001100 .word $0f00 .byte %00001100 .word $0e00 .byte %00001100 .word $0d00 .byte %00001100 .word $0c00 .byte %11001100 .word $0600 .word $0b00 .byte %00101110 .byte $12 .word $0a10 .byte $40 .byte 0 sound_bump_wall_flt .word $8110 .word $8110 .word $8308 .word $8303 .byte $00 ; Landing sound_landing_v1 .byte %11111110 .word $0780 .word $00f2 .word $a000 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1 .byte %11111110 .word $0780 .word $0082 .word $a000 .byte $09 .byte %00001110 .word $2100 .byte $11 .byte %00001110 .word $1000 .byte $41 .byte %00001100 .word $0f00 .byte %00001100 .word $0e00 .byte %00001100 .word $0d00 .byte %00001100 .word $0c00 .byte %11001100 .word $0600 .word $0b00 .byte %00101110 .byte $12 .word $0a10 .byte $40 .byte 0 sound_landing_v2 .byte %00111110 .word $0029 .word $0100 .byte $91 .byte %00000010 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1,1 .byte %00000010 .byte $80 .byte 1,1,1 .byte %00100000 .byte $28 .byte 0 sound_landing_flt .word $f115 .word $f108 .word $f103 .word $f103 .word $f103 .word $0102 .byte 0 ; Press Plate sound_pressplate_v1 .byte %00111110 .word $0082 .word $8000 .byte $09 .byte %00000010 .byte $81 .byte 1,1 .byte %00000010 .byte $80 .byte 0 sound_pressplate_v2 .byte %00111110 .word $00e2 .word $2000 .byte $09 .byte %00000010 .byte $15 .byte 1 .byte %00000010 .byte $14 .byte 0 sound_pressplate_flt .word $f130 .byte 0 ; Spikes-up sound_spikesup_v1 .byte %00111110 .word $90f5 .word $ffff .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1,1,1,1,1 .byte %00001110 .word $3000 .byte $80 .byte 0 sound_spikesup_v2 .byte %00111110 .word $90f4 .word $0c00 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1,1,1,1,1 .byte %00001110 .word $0300 .byte $14 .byte 0 sound_spikesup_flt .word $f1ff .word $f1ff .word $f1ff .word $f1ff .word $f1ff .word $f1ff .word $f1ff .word $f1ff .word $f408 .byte 0 ; Door-Open sound_dooropen_v2 .byte %11111110 .word $001c .word $0076 .word $2fff .byte $09 .byte %00000010 .byte $81 .byte %00001110 .word $0800 .byte $11 .byte %00001100 .word $0400 .byte %00001100 .word $0200 .byte %00001110 .word $3000 .byte $41 .byte %00001100 .word $2e00 .byte %00001100 .word $2d00 .byte %00001100 .word $2c00 .byte %00001100 .word $2a00 .byte %00001100 .word $2800 .byte %00001100 .word $2500 .byte %00001100 .word $2200 .byte %00001100 .word $1e00 .byte %00001100 .word $1800 .byte %00001100 .word $1400 .byte %00001100 .word $1000 .byte %00001100 .word $0c00 .byte %00001100 .word $0a00 .byte %00001100 .word $0800 .byte %00001100 .word $0600 .byte %00001100 .word $0400 .byte %00001100 .word $0200 .byte 1 .byte %00000010 .byte $40 .byte 0 sound_dooropen_v1 .byte %11111110 .word $0008 .word $d0f8 .word $1000 .byte $09 .byte %00000010 .byte $81 .byte 1,1,1,1,1,1,1,1,1,1,1,1 .byte %00000010 .byte $80 .byte 0 sound_dooropen_flt .word $f110 .byte 0 ; Entrance-Close sound_entranceclose_v1 .byte %00111110 .word $00f9 .word $ffff .byte $91 .byte %00000010 .byte $09 .byte %00000010 .byte $81 .byte %00001100 .word $1600 .byte %00001100 .word $0200 .byte 1,1,1 .byte %00000010 .byte $80 .byte 0 sound_entranceclose_v2 .byte %00111110 .word $00f9 .word $ffff .byte $91 .byte %00000010 .byte $09 .byte %00000010 .byte $81 .byte %00001100 .word $1610 .byte %00001100 .word $0208 .byte 1,1,1 .byte %00000010 .byte $80 .byte 0 sound_entranceclose_flt .word $f510 .byte 0 ; Gate-Rising sound_gaterising_v1 .byte %00111110 .word $0413 .word $ffff .byte $09 .byte %00000010 .byte $81 .byte %00001100 .word $1670 .byte 1,1,1 .byte %00000010 .byte $80 .byte 0 sound_gaterising_v2 .byte %00111110 .word $0053 .word $5400 .byte $09 .byte %00000010 .byte $15 .byte 1,1 .byte %00000010 .byte $14 .byte 0 sound_gaterising_flt .word $f402 .byte 0 ; Gate-Closing sound_gateclosing_v1 .byte %00111110 .word $0413 .word $1fff .byte $09 .byte %00000010 .byte $81 .byte %00001100 .word $0a00 .byte 1,1,1 .byte %00000010 .byte $80 .byte 0 sound_gateclosing_v2 .byte %00111110 .word $0053 .word $5000 .byte $09 .byte %00000010 .byte $15 .byte 1,1 .byte %00000010 .byte $14 .byte 0 sound_gateclosing_flt .word $f402 .byte 0 ; Gate-Slam-Shut sound_gateslam_v1 .byte %00111110 .word $50f9 .word $ffff .byte $91 .byte %00000010 .byte $09 .byte %00000010 .byte $81 .byte %00001100 .word $1600 .byte %00001100 .word $2800 .byte 1,1,1 .byte %00001110 .word $1800 .byte $80 .byte 0 sound_gateslam_v2 .byte %00111110 .word $50f9 .word $ffff .byte $91 .byte %00000010 .byte $09 .byte %00000010 .byte $15 .byte %00001100 .word $5510 .byte %00001100 .word $2310 .byte %00001100 .word $1408 .byte 1 .byte %00001110 .word $1808 .byte $80 .byte 0 sound_gateslam_flt .word $f1f0 .word $f1c0 .word $f180 .word $f160 .word $f130 .word $f110 .byte 0 ===== "test harness.asm" ===== An additional program to test the sound effect routine. Coded exclusively for Mr.SID. ;;----------------------------------------- ;;----------------------------------------- ;; SIMPLE SFX-PLAYER TEST HARNESS PROGRAM ;;----------------------------------------- ;; Coded by Conrad/Viruz/Samar/[O] ;;----------------------------------------- ;; Note: DON'T INCLUDE THIS IN YOUR PROJECT ;;----------------------------------------- ;;----------------------------------------- ; Includes .include "sfxconfig.txt" ; Read config file .include "sfxplayer.asm" ; Include sfx player code ; Macros KEYCHECK .macro lda #\2 sta $dc00 lda $dc01 eor #\3 bne + ldy #\1 + .endm HEX2STR .macro .if \2 = 4 .if (\1 >> 12)<10 .byte (\1 >> 12) + $30 .else .byte (\1 >> 12) - 10 + $41 .endif .fi .if \2 >= 3 .if ((\1 >> 8) & $f)<10 .byte ((\1 >> 8) & $f) + $30 .else .byte ((\1 >> 8) & $f) - 10 + $41 .endif .fi .if \2 >= 2 .if ((\1 >> 4) & $f)<10 .byte ((\1 >> 4) & $f) + $30 .else .byte ((\1 >> 4) & $f) - 10 + $41 .endif .fi .if \2 >= 1 .if (\1 & $f)<10 .byte (\1 & $f) + $30 .else .byte (\1 & $f) - 10 + $41 .endif .fi .endm ; Screen *=$0400 .text "SFX TESTER INIT: LDA#--, JSR $" #HEX2STR SFX_INIT,4 .text "---------- PLAY: $" #HEX2STR SFX_PLAY,4 .text ", RESET: $" #HEX2STR SFX_RESET,4 .text " ZERO-PAGE BUFFER: $" #HEX2STR ZP_SFX_START,2 .text "-$" #HEX2STR ZP_SFX_END,2 .text "- GREEN BAR REPRESENTS PLAYER RASTERTIME" .text "- YELLOW BAR REPRESENTS INIT RASTERTIME " .text "- PRESS SPACE TO RESET SFX PLAYER " .text "PRESS THE FOLLOWING KEYS TO TEST SOUNDS:" .text "----------------------------------------" .text " '0' -> LDA #$00 -> 'FOOTSTEP' " .text " '1' -> LDA #$01 -> 'BUMP INTO WALL' " .text " '2' -> LDA #$02 -> 'LAND ON GROUND' " .text " '3' -> LDA #$03 -> 'PRESS ON PLATE' " .text " '4' -> LDA #$04 -> 'SPIKES RISE UP' " .text " '5' -> LDA #$05 -> 'DOOR OPEN' " .text " '6' -> LDA #$06 -> 'ENTRANCE CLOSE' " .text " '7' -> LDA #$07 -> 'GATE RISING' " .text " '8' -> LDA #$08 -> 'GATE CLOSING' " .text " '9' -> LDA #$09 -> 'GATE SLAMS SHUT' " .text " 'A' -> LDA #$0A -> 'FALLING FLOOR LAND'" .text " 'B' -> LDA #$0B -> 'STABBED' " .text " 'C' -> LDA #$0C -> 'SWORD HIT' " .text " 'D' -> LDA #$0D -> 'SWORD STAB' " .text " 'E' -> LDA #$0E -> 'DRINK POISON' " .text " 'F' -> LDA #$0F -> 'JUMP-THRU-MIRROR' " .text " 'G' -> LDA #$10 -> 'JAW CLASH' " ; Run *=$0803 sei ldx #$00 stx $d011 stx $d020 stx $d021 lda #$0f - sta $d800,x sta $d900,x sta $da00,x sta $db00,x inx bne - lda #$03 sta $dd00 lda #$00 sta $d015 lda #$16 sta $d018 lda #$06 sta $d020 sta $d021 jsr SFX_RESET test_loop lda #$ff sta $dc00 - bit $d011 bpl - - bit $d011 bmi - lda #$1b sta $d011 lda #$18 - cmp $d012 bne - dec $d020 jsr SFX_PLAY inc $d020 ldy #$ff #KEYCHECK $09,%11101111,%11111110 #KEYCHECK $00,%11101111,%11110111 #KEYCHECK $01,%01111111,%11111110 #KEYCHECK $02,%01111111,%11110111 #KEYCHECK $03,%11111101,%11111110 #KEYCHECK $04,%11111101,%11110111 #KEYCHECK $0a,%11111101,%11111011 #KEYCHECK $0e,%11111101,%10111111 #KEYCHECK $05,%11111011,%11111110 #KEYCHECK $06,%11111011,%11110111 #KEYCHECK $0c,%11111011,%11101111 #KEYCHECK $0d,%11111011,%11111011 #KEYCHECK $0f,%11111011,%11011111 #KEYCHECK $07,%11110111,%11111110 #KEYCHECK $08,%11110111,%11110111 #KEYCHECK $10,%11110111,%11111011 #KEYCHECK $0b,%11110111,%11101111 cpy #$ff beq + pressed lda #$00 beq ++ lda #$28 - cmp $d012 bne - inc $d020 tya jsr SFX_INIT dec $d020 ldy #$00 + sty pressed+1 + lda #$7f sta $dc00 lda $dc01 cmp #$ef bne + jsr SFX_RESET + jmp test_loop Happy hacking! :) /Conrad (7th March 2012)