Prev: C656 Up: Map Next: C6B9
C661: Play Note
Used by the routines at PlayMusicOnce and PlayMusic.
Plays a note of a tune, or a rest if the note number is zero. Bits 0 to 5 select the entry in NoteTable that holds the two delays of a cycle and the number of cycles. Bits 6 and 7 are the length less one, which multiplies the number of cycles, so the note is one to four times as long.
Input
A The note
DE Address of the note
Output
DE Address of the next note
Look up the delays and the number of cycles.
PlayNote C661 AND %00111111 Keep bits 0 to 5.
C663 JR Z,PlayNote_Rest Jump to PlayNote_Rest if the note is a rest.
C665 LD L,A Set HL to the note number.
C666 LD H,$00
C668 ADD HL,HL Double the number.
C669 CALL AddAToHL Call AddAToHL.
Point HL at the entry for the note.
C66C LD BC,$C6B9 Point BC at NoteTable.
C66F ADD HL,BC Find the entry for the note.
C670 LD B,(HL) Fetch the first delay.
C671 INC HL Move on.
C672 LD C,(HL) Fetch the second delay.
C673 INC HL Move on.
C674 LD L,(HL) Fetch the number of cycles.
C675 LD H,$00 Set H to 00.
Bits 6 and 7 are the length, less one.
C677 LD A,(DE) Fetch the note again.
C678 RLCA Move bits 6 and 7 to bits 0 and 1.
C679 RLCA
C67A AND %00000011 Keep bits 0 and 1.
C67C INC A Add one.
C67D PUSH DE Stash the note address on the stack.
C67E LD E,L Copy the number of cycles to DE.
C67F LD D,H
Multiply the number of cycles by the length.
PlayNote_Length C680 DEC A Count down the length.
C681 JR Z,PlayNote_Start Jump to PlayNote_Start if the length has been used up.
C683 ADD HL,DE Add the number of cycles again.
C684 JR PlayNote_Length Jump to PlayNote_Length.
PlayNote_Start C686 POP DE Restore the note address from the stack.
Each pass makes one cycle of the note.
PlayNote_Cycle C687 PUSH BC Stash the delays on the stack.
C688 XOR A Set A to 00.
C689 OUT ($FE),A Turn the speaker off.
PlayNote_Low C68B DJNZ PlayNote_Low Wait for the first half of the cycle.
C68D DEC C Count down the second delay.
C68E JR NZ,PlayNote_Low Jump to PlayNote_Low until it has finished.
C690 POP BC Restore the delays from the stack.
C691 PUSH BC Stash the delays on the stack.
C692 LD A,$10 Set bit 4.
C694 OUT ($FE),A Turn the speaker on.
PlayNote_High C696 DJNZ PlayNote_High Wait for the second half of the cycle.
C698 DEC C Count down the second delay.
C699 JR NZ,PlayNote_High Jump to PlayNote_High until it has finished.
C69B POP BC Restore the delays from the stack.
C69C DEC HL Count down the cycles.
C69D LD A,H Jump to PlayNote_Cycle until all of the cycles have been played.
C69E OR L
C69F JR NZ,PlayNote_Cycle
C6A1 INC DE Move on to the next note.
C6A2 RET Return.
A rest is a silent pause of one to four units.
PlayNote_Rest C6A3 LD A,(DE) Fetch the length of the rest.
C6A4 INC DE Move on to the next note.
C6A5 RLCA Move bits 6 and 7 to bits 0 and 1.
C6A6 RLCA
C6A7 AND %00000011 Keep bits 0 and 1.
C6A9 INC A Add one.
C6AA LD L,A Keep it in L.
C6AB LD BC,$430B Set BC to 430B.
PlayNote_RestLoop C6AE PUSH BC Stash the pause length on the stack.
PlayNote_RestWait C6AF DEC BC Count down the pause.
C6B0 LD A,B Jump to PlayNote_RestWait until it has finished.
C6B1 OR C
C6B2 JR NZ,PlayNote_RestWait
C6B4 POP BC Restore the pause length from the stack.
C6B5 DEC L Count down the units of the rest.
C6B6 JR NZ,PlayNote_RestLoop Jump to PlayNote_RestLoop until the rest has finished.
C6B8 RET Return.
Prev: C656 Up: Map Next: C6B9