Difference between revisions of "Snippet:Playsong"
m (1 revision)
Revision as of 21:23, 16 November 2012
This code is taken from cart #24. It plays a song from memory using the address stored in DC0. It starts a loop through the data, taking two bytes at a time; the first is the duration of the note, and the second is the frequency. It outputs it through the ports, delays, and takes another two bytes. If it finds the duration byte is equal to 0, it exits, so a 0 byte marks the end of a song. If it finds the frequency byte is 255, it instead generates a pause for the specified duration. (note: using a frequency of 254 or 255 otherwise outputs the same note) The pausing functionality isn't in the original disassembly, but was added afterwards.
;-----------; ; Play Song ; ;-----------; ; plays a song from memory ; song address stored in DC0 ; uses r3, r4, r5, r7 playSong: ; taken from Pro Football lis 3 ; A = 3 lr 4, A ; A -> r4, r4 = 3 .playSongDelay1: inc ; increase A bnz .playSongDelay1 ; [Branch if not zero] back to .psdly1 am ; Memory adressed by DC0 is added to A, flags set - get duration data lr 7, A ; A -> r7 bz .playSongEnd ; Go to end if zero lm ; Load memory into A (adressed by DC0) - get frequency data lr 5, A ; A -> r5 ; check to see if we should pause inc bnc .playSongLoop ; it didn't roll over, play a note instead .playSongPause: li $ff lr 6, A .playSongPauseLoop: ds 6 ; pause counter bnz .playSongPauseLoop ds 7 ; duration of the pause bnz .playSongPause ; play the next note br playSong .playSongLoop: li $80 ; A= $80 outs 5 ; Send A -> port 5 lr A, 5 ; r5 -> A .playSongDelay2: inc ; increase A bnz .playSongDelay2 ; [Branch if not zero] back to .psdly2 outs 5 ; A -> port 5 lr A, 5 ; r5 -> A .playSongDelay3: inc ; increase A bnz .playSongDelay3 ; [Branch if not zero] back to .psdly3 ds 4 ; decrease r4 bnz .playSongLoop ; [Branch if not zero] back to .psloop lis 3 ; A = 3 lr 4, A ; A -> r4 ds 7 ; decrease r7 bnz .playSongLoop ; [Branch if not zero] back to .psloop br playSong ; start over - branch to beginning .playSongEnd: pop ; return from the subroutine