Prev: A1C1 Up: Map Next: A20F
A1CC: Play Note
Used by the routines at PlayMusic_WaitKey and PlayMusic.
Plays a note of a piece of music, using the table at NoteTable. Each entry in the table has three bytes: the lengths of the inner and outer delay loops, which set the pitch, and the number of cycles.
Input
A The next byte of the music
DE The address of the byte of the music
Output
DE The address of the next byte of the music
PlayNote A1CC AND %00111111 Use bits 0-5, the number of the note.
A1CE JR Z,PlayRest Jump to PlayRest if it is a rest.
Look up the delays and the number of cycles in the table at NoteTable.
A1D0 LD L,A Set HL to the note number.
A1D1 LD H,$00
A1D3 ADD HL,HL Double it.
A1D4 CALL AddToAddress Add the note number to make three times the number.
A1D7 LD BC,$A226 Point BC at NoteTable.
A1DA ADD HL,BC Find the entry of the note.
A1DB LD B,(HL) Fetch the length of the inner delay loop.
A1DC INC HL Move onto the next byte.
A1DD LD C,(HL) Fetch the length of the outer delay loop.
A1DE INC HL Move onto the next byte.
A1DF LD L,(HL) Fetch the number of cycles.
A1E0 LD H,$00 Clear H.
Bits 6 and 7 of the note are the length, less one.
A1E2 LD A,(DE) Fetch the byte of the music again.
A1E3 RLCA Rotate bits 6 and 7 of the note down...
A1E4 RLCA ...to bits 0 and 1.
A1E5 AND %00000011 Keep them, but the result is not used.
A1E7 XOR A Set the multiplier to zero...
A1E8 INC A ...and then to one.
Multiply the number of cycles by the length of the note.
PlayNote_Multiply A1E9 PUSH DE Save the address of the music.
A1EA LD E,L Copy the low byte of the number of cycles into E.
A1EB LD D,H Copy the high byte into D.
PlayNote_MultiplyLoop A1EC DEC A Decrease the multiplier by one.
A1ED JR Z,PlayNote_Multiplied Jump to PlayNote_Multiplied if it is zero.
A1EF ADD HL,DE Add the number of cycles again.
A1F0 JR PlayNote_MultiplyLoop Jump back to count the multiplier down.
PlayNote_Multiplied A1F2 POP DE Restore the address of the music.
Each pass of this loop makes one cycle of the note, so the length of the note is the number of cycles.
PlayNote_Cycle A1F3 PUSH BC Save the lengths of the delay loops.
A1F4 XOR A Clear the speaker bit.
A1F5 OUT ($FE),A Write to the port.
PlayNote_LowDelay A1F7 DJNZ PlayNote_LowDelay Wait for the inner delay loop.
A1F9 DEC C Decrease the outer loop count by one.
A1FA JR NZ,PlayNote_LowDelay Jump back until the outer delay loop has finished.
A1FC POP BC Restore the lengths of the delay loops.
A1FD PUSH BC Save them again.
A1FE LD A,$10 Set the speaker bit.
A200 OUT ($FE),A Write to the port.
PlayNote_HighDelay A202 DJNZ PlayNote_HighDelay Wait for the inner delay loop.
A204 DEC C Decrease the outer loop count by one.
A205 JR NZ,PlayNote_HighDelay Jump back until the outer delay loop has finished.
A207 POP BC Restore the lengths of the delay loops.
A208 DEC HL Decrease the number of cycles by one.
A209 LD A,H Fetch the high byte of the number of cycles left.
A20A OR L Combine it with the low byte, to test whether it is zero.
A20B JR NZ,PlayNote_Cycle Jump back for the next cycle until the note has finished.
A20D INC DE Move onto the next byte of the music.
A20E RET Return.
View the equivalent code in;
Prev: A1C1 Up: Map Next: A20F