Prev: 48505 Up: Map Next: 48594
48507: 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 255
PlayNote 48507 AND %00111111 Keep only bits 0-5 (the note).
48509 JR Z,PlayMusic_Rest Jump to PlayMusic_Rest if the note is a rest (zero).
48511 LD L,A Use the note as the offset into the table of notes.
48512 LD H,0
48514 ADD HL,HL Multiply the offset by four (the size of an entry) and add the table of notes at MusicNotes.
48515 ADD HL,HL
48516 LD BC,48594
48519 ADD HL,BC
Read the table entry for the note: two bytes of pitch delay and then the 16-bit number of cycles.
48520 LD B,(HL) Fetch the pitch delay of the note into B and C.
48521 INC HL
48522 LD C,(HL)
48523 INC HL
48524 LD A,(HL) Fetch the number of cycles of the note into HL.
48525 INC HL
48526 LD H,(HL)
48527 LD L,A
Multiply the number of cycles by the length of the note.
48528 LD A,(DE) Fetch the music data byte.
48529 RLCA Rotate bits 6-7 (the length of the note) into bits 0-1.
48530 RLCA
48531 AND %00000011 Keep only bits 0-1.
48533 INC A Add one, so A holds the length of the note.
48534 PUSH DE Stash the music data pointer on the stack.
48535 LD E,L Copy the number of cycles into DE.
48536 LD D,H
PlayMusic_Multiply 48537 DEC A Decrease the length counter by one and jump to PlayMusic_MultiplyDone once the length has been multiplied in.
48538 JR Z,PlayMusic_MultiplyDone
48540 ADD HL,DE Add the number of cycles to the total.
48541 JR PlayMusic_Multiply Jump back to PlayMusic_Multiply.
PlayMusic_MultiplyDone 48543 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 48544 PUSH BC Stash the pitch delay on the stack.
48545 XOR A Set the speaker to off.
48546 OUT (254),A Write A to port 254 (border black, speaker off).
PlayMusic_OffDelay 48548 DJNZ PlayMusic_OffDelay Decrease B by one and loop back to PlayMusic_OffDelay until it is zero.
48550 DEC C Decrease C by one and jump back to PlayMusic_OffDelay until it is zero.
48551 JR NZ,PlayMusic_OffDelay
48553 POP BC Restore the pitch delay from the stack.
48554 PUSH BC Stash the pitch delay on the stack.
48555 LD A,16 Set the speaker to on (bit 4).
48557 OUT (254),A Write A to port 254 (border black, speaker on).
PlayMusic_OnDelay 48559 DJNZ PlayMusic_OnDelay Decrease B by one and loop back to PlayMusic_OnDelay until it is zero.
48561 DEC C Decrease C by one and jump back to PlayMusic_OnDelay until it is zero.
48562 JR NZ,PlayMusic_OnDelay
48564 POP BC Restore the pitch delay from the stack.
48565 DEC HL Decrease the cycle counter by one.
48566 LD A,H Loop back to PlayMusic_Cycle until all of the cycles of the note have been played.
48567 OR L
48568 JR NZ,PlayMusic_Cycle
48570 INC DE Move on to the next note.
48571 RET Return.
A rest is a silent delay, which lasts for as many units as the length of the note.
PlayMusic_Rest 48572 LD A,(DE) Fetch the music data byte.
48573 INC DE Move on to the next note.
48574 RLCA Rotate left twice, so bits 6-7 become bits 0-1.
48575 RLCA
48576 AND %00000011 Keep only bits 0-1.
48578 INC A Add one, so A holds the length of the rest.
48579 LD L,A Store the length of the rest in L.
48580 LD BC,17163 Set the length of one unit of the rest in BC to 17163.
PlayMusic_RestUnit 48583 PUSH BC Stash the length of the unit on the stack.
PlayMusic_RestDelay 48584 DEC BC Decrease the unit counter by one.
48585 LD A,B Loop back to PlayMusic_RestDelay until the unit has passed.
48586 OR C
48587 JR NZ,PlayMusic_RestDelay
48589 POP BC Restore the length of the unit from the stack.
48590 DEC L Decrease the length of the rest by one and loop back to PlayMusic_RestUnit until the rest is over.
48591 JR NZ,PlayMusic_RestUnit
48593 RET Return.
View the equivalent code in;
Prev: 48505 Up: Map Next: 48594