Prev: B4BA Up: Map Next: B51D
B4C5: Play Note
Used by the routines at PlayMusic_WaitKey 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 MusicNotes 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 B4C5 AND %00111111 Keep bits 0 to 5.
B4C7 JR Z,PlayNote_Rest Jump to PlayNote_Rest if the note is a rest.
B4C9 LD L,A Set HL to the note number.
B4CA LD H,$00
B4CC ADD HL,HL Double the number.
B4CD CALL AddAToHL Call AddAToHL.
B4D0 LD BC,$B51D Point BC at MusicNotes.
B4D3 ADD HL,BC Find the entry for the note.
B4D4 LD B,(HL) Fetch the first delay.
B4D5 INC HL Move on.
B4D6 LD C,(HL) Fetch the second delay.
B4D7 INC HL Move on.
B4D8 LD L,(HL) Fetch the number of cycles.
B4D9 LD H,$00 Set H to 00.
Bits 6 and 7 are the length, less one.
B4DB LD A,(DE) Fetch the note again.
B4DC RLCA Move bits 6 and 7 to bits 0 and 1.
B4DD RLCA
B4DE AND %00000011 Keep bits 0 and 1.
B4E0 INC A Add one.
B4E1 PUSH DE Stash the note address on the stack.
B4E2 LD E,L Copy the number of cycles to DE.
B4E3 LD D,H
Multiply the number of cycles by the length.
PlayNote_MultiplyLength B4E4 DEC A Count down the length.
B4E5 JR Z,PlayNote_PlayCycle Jump to PlayNote_PlayCycle if the length has been used up.
B4E7 ADD HL,DE Add the number of cycles again.
B4E8 JR PlayNote_MultiplyLength Jump to PlayNote_MultiplyLength.
PlayNote_PlayCycle B4EA POP DE Restore the note address from the stack.
Each pass makes one cycle of the note.
PlayNote_Cycle B4EB PUSH BC Stash the delays on the stack.
B4EC XOR A Set A to 00.
B4ED OUT ($FE),A Turn the speaker off.
PlayNote_FirstDelay B4EF DJNZ PlayNote_FirstDelay Wait for the first half of the cycle.
B4F1 DEC C Count down the second delay.
B4F2 JR NZ,PlayNote_FirstDelay Jump to PlayNote_FirstDelay until it has finished.
B4F4 POP BC Restore the delays from the stack.
B4F5 PUSH BC Stash the delays on the stack.
B4F6 LD A,$10 Set bit 4.
B4F8 OUT ($FE),A Turn the speaker on.
PlayNote_SecondDelay B4FA DJNZ PlayNote_SecondDelay Wait for the second half of the cycle.
B4FC DEC C Count down the second delay.
B4FD JR NZ,PlayNote_SecondDelay Jump to PlayNote_SecondDelay until it has finished.
B4FF POP BC Restore the delays from the stack.
B500 DEC HL Count down the cycles.
B501 LD A,H Jump to PlayNote_Cycle until all of the cycles have been played.
B502 OR L
B503 JR NZ,PlayNote_Cycle
B505 INC DE Move on to the next note.
B506 RET Return.
A rest is a silent pause of one to four units.
PlayNote_Rest B507 LD A,(DE) Fetch the length of the rest.
B508 INC DE Move on to the next note.
B509 RLCA Move bits 6 and 7 to bits 0 and 1.
B50A RLCA
B50B AND %00000011 Keep bits 0 and 1.
B50D INC A Add one.
B50E LD L,A Keep it in L.
B50F LD BC,$430B Set BC to 430B.
PlayNote_RestUnit B512 PUSH BC Stash the pause length on the stack.
PlayNote_Pause B513 DEC BC Count down the pause.
B514 LD A,B Jump to PlayNote_Pause until it has finished.
B515 OR C
B516 JR NZ,PlayNote_Pause
B518 POP BC Restore the pause length from the stack.
B519 DEC L Count down the units of the rest.
B51A JR NZ,PlayNote_RestUnit Jump to PlayNote_RestUnit until the rest has finished.
B51C RET Return.
Prev: B4BA Up: Map Next: B51D