Prev: BD79 Up: Map Next: BDD2
BD7B: Play Note
Used by the routines at PlayMusic_WaitKey and PlayMusic.
Plays a single note, or a rest if the note is zero. A note is looked up in the table at MusicNotes, which has four bytes per note: two bytes which set the length of the delays between speaker changes (the pitch), followed by a 16-bit count of the number of cycles to play. The count is multiplied by the length held in bits 6-7 of the music data byte plus one.
Each cycle sets the border (and speaker) to black for a delay and then turns the speaker on for the same delay.
Input
A Music data byte
DE Music data terminated by FF
PlayNote BD7B AND %00111111 Keep only bits 0-5 (the note).
BD7D JR Z,PlayMusic_Rest Jump to PlayMusic_Rest if the note is a rest (zero).
BD7F LD L,A Use the note as the offset into the table of notes.
BD80 LD H,$00
BD82 ADD HL,HL Multiply the offset by four (the size of an entry) and add the table of notes at MusicNotes.
BD83 ADD HL,HL
BD84 LD BC,$BDD2
BD87 ADD HL,BC
Read the table entry for the note: two bytes of pitch delay and then the 16-bit number of cycles.
BD88 LD B,(HL) Fetch the pitch delay of the note into B and C.
BD89 INC HL
BD8A LD C,(HL)
BD8B INC HL
BD8C LD A,(HL) Fetch the number of cycles of the note into HL.
BD8D INC HL
BD8E LD H,(HL)
BD8F LD L,A
Multiply the number of cycles by the length of the note.
BD90 LD A,(DE) Fetch the music data byte.
BD91 RLCA Rotate bits 6-7 (the length of the note) into bits 0-1.
BD92 RLCA
BD93 AND %00000011 Keep only bits 0-1.
BD95 INC A Add one, so A holds the length of the note.
BD96 PUSH DE Stash the music data pointer on the stack.
BD97 LD E,L Copy the number of cycles into DE.
BD98 LD D,H
PlayMusic_Multiply BD99 DEC A Decrease the length counter by one and jump to PlayMusic_MultiplyDone once the length has been multiplied in.
BD9A JR Z,PlayMusic_MultiplyDone
BD9C ADD HL,DE Add the number of cycles to the total.
BD9D JR PlayMusic_Multiply Jump back to PlayMusic_Multiply.
PlayMusic_MultiplyDone BD9F POP DE Restore the music data pointer from the stack.
Play one cycle: the speaker is off for the delay and then on for the same delay.
PlayMusic_Cycle BDA0 PUSH BC Stash the pitch delay on the stack.
BDA1 XOR A Set the speaker to off.
BDA2 OUT ($FE),A Write A to port FE (border black, speaker off).
PlayMusic_OffDelay BDA4 DJNZ PlayMusic_OffDelay Decrease B by one and loop back to PlayMusic_OffDelay until it is zero.
BDA6 DEC C Decrease C by one and jump back to PlayMusic_OffDelay until it is zero.
BDA7 JR NZ,PlayMusic_OffDelay
BDA9 POP BC Restore the pitch delay from the stack.
BDAA PUSH BC Stash the pitch delay on the stack.
BDAB LD A,$10 Set the speaker to on (bit 4).
BDAD OUT ($FE),A Write A to port FE (border black, speaker on).
PlayMusic_OnDelay BDAF DJNZ PlayMusic_OnDelay Decrease B by one and loop back to PlayMusic_OnDelay until it is zero.
BDB1 DEC C Decrease C by one and jump back to PlayMusic_OnDelay until it is zero.
BDB2 JR NZ,PlayMusic_OnDelay
BDB4 POP BC Restore the pitch delay from the stack.
BDB5 DEC HL Decrease the cycle counter by one.
BDB6 LD A,H Loop back to PlayMusic_Cycle until all of the cycles of the note have been played.
BDB7 OR L
BDB8 JR NZ,PlayMusic_Cycle
BDBA INC DE Move on to the next note.
BDBB RET Return.
A rest is a silent delay, which lasts for as many units as the length of the note.
PlayMusic_Rest BDBC LD A,(DE) Fetch the music data byte.
BDBD INC DE Move on to the next note.
BDBE RLCA Rotate left twice, so bits 6-7 become bits 0-1.
BDBF RLCA
BDC0 AND %00000011 Keep only bits 0-1.
BDC2 INC A Add one, so A holds the length of the rest.
BDC3 LD L,A Store the length of the rest in L.
BDC4 LD BC,$430B Set the length of one unit of the rest in BC to 430B.
PlayMusic_RestUnit BDC7 PUSH BC Stash the length of the unit on the stack.
PlayMusic_RestDelay BDC8 DEC BC Decrease the unit counter by one.
BDC9 LD A,B Loop back to PlayMusic_RestDelay until the unit has passed.
BDCA OR C
BDCB JR NZ,PlayMusic_RestDelay
BDCD POP BC Restore the length of the unit from the stack.
BDCE DEC L Decrease the length of the rest by one and loop back to PlayMusic_RestUnit until the rest is over.
BDCF JR NZ,PlayMusic_RestUnit
BDD1 RET Return.
View the equivalent code in;
Prev: BD79 Up: Map Next: BDD2