Prev: 9AA9 Up: Map Next: 9B0C
9AB4: 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 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 9AB4 AND %00111111 Keep the note number.
9AB6 JR Z,PlayNote_Rest Jump to PlayNote_Rest if the note is a rest.
9AB8 LD L,A Set HL to the note number.
9AB9 LD H,$00
9ABB ADD HL,HL Double the number.
Add the address of the table of notes at NoteTable.
9ABC CALL AddAToHL Call AddAToHL.
9ABF LD BC,$9B0C Point BC at NoteTable.
9AC2 ADD HL,BC Find the entry for the note.
9AC3 LD B,(HL) Fetch the first delay.
9AC4 INC HL Move on.
9AC5 LD C,(HL) Fetch the second delay.
9AC6 INC HL Move on.
9AC7 LD L,(HL) Fetch the number of cycles.
9AC8 LD H,$00 Set H to 00.
Bits 6 and 7 are the length, less one.
9ACA LD A,(DE) Fetch the note again.
9ACB RLCA Move bits 6 and 7 to bits 0 and 1.
9ACC RLCA
9ACD AND %00000011 Keep bits 0 and 1.
9ACF INC A Add one.
9AD0 PUSH DE Save the address of the note.
9AD1 LD E,L Copy the number of cycles to DE.
9AD2 LD D,H
Multiply the number of cycles by the length.
PlayNote_Multiply 9AD3 DEC A Count down the length.
9AD4 JR Z,PlayNote_Play Jump to PlayNote_Play if it is zero.
9AD6 ADD HL,DE Add the number of cycles again.
9AD7 JR PlayNote_Multiply Jump back to PlayNote_Multiply.
PlayNote_Play 9AD9 POP DE Restore the note address from the stack.
Each pass makes one cycle of the note.
PlayNote_Cycle 9ADA PUSH BC Stash the delays on the stack.
9ADB XOR A Set A to 00.
9ADC OUT ($FE),A Send it to the speaker.
PlayNote_Low 9ADE DJNZ PlayNote_Low Wait for the first half of the cycle.
9AE0 DEC C Count down the second delay.
9AE1 JR NZ,PlayNote_Low Jump back to PlayNote_Low until none remain.
9AE3 POP BC Restore the delays from the stack.
9AE4 PUSH BC Stash the delays on the stack.
9AE5 LD A,$10 Set bit 4.
9AE7 OUT ($FE),A Send it to the speaker.
PlayNote_High 9AE9 DJNZ PlayNote_High Wait for the second half of the cycle.
9AEB DEC C Count down the second delay.
9AEC JR NZ,PlayNote_High Jump back to PlayNote_High until none remain.
9AEE POP BC Restore the delays from the stack.
9AEF DEC HL Decrease the number of cycles.
9AF0 LD A,H Combine the high and low bytes.
9AF1 OR L
9AF2 JR NZ,PlayNote_Cycle Jump back to PlayNote_Cycle until the note is over.
9AF4 INC DE Move on to the next note.
9AF5 RET Return.
A rest is a silence of the same length as the other notes.
PlayNote_Rest 9AF6 LD A,(DE) Fetch the note byte.
9AF7 INC DE Move on to the next note.
9AF8 RLCA Move the top two bits to the bottom.
9AF9 RLCA
9AFA AND %00000011 Keep them.
9AFC INC A Add one to get a multiplier.
9AFD LD L,A Use it as a counter.
PlayNote_RestLoop 9AFE LD BC,$430B Set the delay.
PlayNote_Loop 9B01 PUSH BC Save the delay.
PlayNote_Delay 9B02 DEC BC Count down.
9B03 LD A,B Combine the high and low bytes.
9B04 OR C
9B05 JR NZ,PlayNote_Delay Jump back to PlayNote_Delay until the delay is over.
9B07 POP BC Restore the delay.
9B08 DEC L Decrease the multiplier by one.
9B09 JR NZ,PlayNote_Loop Jump back to PlayNote_Loop until none remain.
9B0B RET Return.
Prev: 9AA9 Up: Map Next: 9B0C