Prev: B2CF Up: Map Next: B332
B2DA: 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 B2DA AND %00111111 Isolate the number of the note.
B2DC JR Z,PlayNote_Rest Jump to PlayNote_Rest if the note is a rest.
B2DE LD L,A Set HL to the note number.
B2DF LD H,$00
B2E1 ADD HL,HL Double the number.
B2E2 CALL AddAToHL Call AddAToHL.
Point HL at the entry of the note in the table, MusicNotes.
B2E5 LD BC,$B332 Point BC at MusicNotes.
B2E8 ADD HL,BC Find the entry for the note.
Fetch the first byte of the delay between the clicks of the speaker.
B2E9 LD B,(HL) Fetch the first delay.
B2EA INC HL Move on.
Fetch the second byte of the delay.
B2EB LD C,(HL) Fetch the second delay.
B2EC INC HL Move on.
Fetch the basic length of the note.
B2ED LD L,(HL) Fetch the number of cycles.
B2EE LD H,$00 Set H to 00.
Bits 6 and 7 are the length, less one.
B2F0 LD A,(DE) Fetch the note again.
B2F1 RLCA Move bits 6 and 7 to bits 0 and 1.
B2F2 RLCA
Isolate the length of the note.
B2F3 AND %00000011 Isolate the length of the note.
Make it 01 to 04.
B2F5 INC A Add one.
B2F6 PUSH DE Stash the note address on the stack.
B2F7 LD E,L Copy the number of cycles to DE.
B2F8 LD D,H
Multiply the number of cycles by the length.
PlayNote_Multiply B2F9 DEC A Count down the length.
B2FA JR Z,PlayNote_MultiplyDone Jump to PlayNote_MultiplyDone if the length has been used up.
B2FC ADD HL,DE Add the number of cycles again.
B2FD JR PlayNote_Multiply Jump to PlayNote_Multiply.
PlayNote_MultiplyDone B2FF POP DE Restore the note address from the stack.
Each pass makes one cycle of the note.
PlayNote_Cycle B300 PUSH BC Stash the delays on the stack.
B301 XOR A Set A to 00.
B302 OUT ($FE),A Turn the speaker off.
PlayNote_OffDelay B304 DJNZ PlayNote_OffDelay Wait with the speaker off, using the first byte of the delay for the first pass and 0100 for each pass after it.
B306 DEC C Count down the second delay.
B307 JR NZ,PlayNote_OffDelay Jump to PlayNote_OffDelay until it has finished.
B309 POP BC Restore the delays from the stack.
B30A PUSH BC Stash the delays on the stack.
B30B LD A,$10 Set bit 4.
B30D OUT ($FE),A Turn the speaker on.
PlayNote_OnDelay B30F DJNZ PlayNote_OnDelay Wait with the speaker on for the same length of time.
B311 DEC C Count down the second delay.
B312 JR NZ,PlayNote_OnDelay Jump to PlayNote_OnDelay until it has finished.
B314 POP BC Restore the delays from the stack.
B315 DEC HL Decrease the number of cycles left to play.
B316 LD A,H Jump to PlayNote_Cycle until there are none left.
B317 OR L
B318 JR NZ,PlayNote_Cycle
B31A INC DE Point at the next note.
B31B RET Return.
A rest is a silent pause of one to four units.
PlayNote_Rest B31C LD A,(DE) Fetch the length of the rest.
B31D INC DE Point at the next note.
B31E RLCA Rotate bits 6-7 of the note into the low bits.
B31F RLCA
B320 AND %00000011 Keep bits 0 and 1.
B322 INC A Add one.
B323 LD L,A Keep it in L.
B324 LD BC,$430B Set BC to 430B.
PlayNote_RestUnit B327 PUSH BC Stash the pause length on the stack.
PlayNote_RestDelay B328 DEC BC Count down the pause.
B329 LD A,B Jump to PlayNote_RestDelay until the length of the wait is zero.
B32A OR C
B32B JR NZ,PlayNote_RestDelay
B32D POP BC Restore the pause length from the stack.
B32E DEC L Count down the units of the rest.
B32F JR NZ,PlayNote_RestUnit Jump to PlayNote_RestUnit until it is zero.
B331 RET Return.
View the equivalent code in;
Prev: B2CF Up: Map Next: B332