Prev: D6B5 Up: Map Next: D718
D6C0: 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 D6C0 AND %00111111 Keep bits 0 to 5.
D6C2 JR Z,PlayNote_Rest Jump to PlayNote_Rest if the note is a rest.
D6C4 LD L,A Set HL to the note number.
D6C5 LD H,$00
D6C7 ADD HL,HL Double the number.
D6C8 CALL AddAToHL Call AddAToHL.
D6CB LD BC,$D718 Point BC at NoteTable.
D6CE ADD HL,BC Find the entry for the note.
D6CF LD B,(HL) Fetch the first delay.
D6D0 INC HL Move on.
D6D1 LD C,(HL) Fetch the second delay.
D6D2 INC HL Move on.
D6D3 LD L,(HL) Fetch the number of cycles.
D6D4 LD H,$00 Set H to 00.
Bits 6 and 7 are the length, less one.
D6D6 LD A,(DE) Fetch the note again.
D6D7 RLCA Move bits 6 and 7 to bits 0 and 1.
D6D8 RLCA
D6D9 AND %00000011 Keep bits 0 and 1.
D6DB INC A Add one.
D6DC PUSH DE Stash the note address on the stack.
D6DD LD E,L Copy the number of cycles to DE.
D6DE LD D,H
Multiply the number of cycles by the length.
PlayNote_Multiply D6DF DEC A Count down the length.
D6E0 JR Z,PlayNote_Start Jump to PlayNote_Start if the length has been used up.
D6E2 ADD HL,DE Add the number of cycles again.
D6E3 JR PlayNote_Multiply Jump to PlayNote_Multiply.
PlayNote_Start D6E5 POP DE Restore the note address from the stack.
Each pass makes one cycle of the note.
PlayNote_Cycle D6E6 PUSH BC Stash the delays on the stack.
D6E7 XOR A Set A to 00.
D6E8 OUT ($FE),A Turn the speaker off.
PlayNote_LowWait D6EA DJNZ PlayNote_LowWait Wait for the first half of the cycle.
D6EC DEC C Count down the second delay.
D6ED JR NZ,PlayNote_LowWait Jump to PlayNote_LowWait until it has finished.
D6EF POP BC Restore the delays from the stack.
D6F0 PUSH BC Stash the delays on the stack.
D6F1 LD A,$10 Set bit 4.
D6F3 OUT ($FE),A Turn the speaker on.
PlayNote_HighWait D6F5 DJNZ PlayNote_HighWait Wait for the second half of the cycle.
D6F7 DEC C Count down the second delay.
D6F8 JR NZ,PlayNote_HighWait Jump to PlayNote_HighWait until it has finished.
D6FA POP BC Restore the delays from the stack.
D6FB DEC HL Count down the cycles.
D6FC LD A,H Jump to PlayNote_Cycle until all of the cycles have been played.
D6FD OR L
D6FE JR NZ,PlayNote_Cycle
D700 INC DE Move on to the next note.
D701 RET Return.
A rest is a silent pause of one to four units.
PlayNote_Rest D702 LD A,(DE) Fetch the length of the rest.
D703 INC DE Move on to the next note.
D704 RLCA Move bits 6 and 7 to bits 0 and 1.
D705 RLCA
D706 AND %00000011 Keep bits 0 and 1.
D708 INC A Add one.
D709 LD L,A Keep it in L.
D70A LD BC,$430B Set BC to 430B.
PlayNote_RestOuter D70D PUSH BC Stash the pause length on the stack.
PlayNote_RestWait D70E DEC BC Count down the pause.
D70F LD A,B Jump to PlayNote_RestWait until the delay is over.
D710 OR C
D711 JR NZ,PlayNote_RestWait
D713 POP BC Restore the pause length from the stack.
D714 DEC L Count down the units of the rest.
D715 JR NZ,PlayNote_RestOuter Jump to PlayNote_RestOuter until the rest is over.
D717 RET Return.
Prev: D6B5 Up: Map Next: D718