Prev: C041 Up: Map Next: C0B0
C049: Play one note of the loading tune
Used by the routine at LOADING_TUNE.
Both voices' next notes are taken and their pitches looked up. Unless both are resting, the note is played for 18 passes of 256 turns of a loop that sends a byte to the speaker's port twice a turn, one for each voice. Each voice keeps its own copy of the port byte (voice one's in A', voice two's in A) and its own countdown (E, and L), and toggles the speaker bit in its copy when the countdown runs out; so each is a square wave at its own pitch, and the two sound together. The two ways round the loop take the same time, 96 T-states (the JR Z that never jumps and the NOPs pad the shorter), so neither voice's pitch depends on the other's.
Once both voices rest, it returns at once. That never ran in the sessions (the sounds page's runs reach it), and nor did the end of a note by way of the first DJNZ: which of the two ends a note depends only on voice two's countdown in the note's last turn.
TUNE_PLAY_NOTE C049 LD HL,VOICE_ONE_AT Voice one's next note.
C04C CALL TUNE_NEXT_NOTE
C04F LD (VOICE_ONE_NOTE),A
C052 LD HL,VOICE_TWO_AT Voice two's.
C055 CALL TUNE_NEXT_NOTE
C058 LD (VOICE_TWO_NOTE),A
C05B LD HL,VOICE_ONE_NOTE Voice one's pitch, on the stack.
C05E CALL TUNE_PITCH
C061 PUSH HL
C062 LD HL,VOICE_TWO_NOTE Voice two's: H its pitch, L its countdown; D and E voice one's.
C065 CALL TUNE_PITCH
C068 POP DE
C069 LD A,H Both resting: nothing to play.
C06A CP $01
C06C JR NZ,TUNE_PLAY_NOTE_0
C06E LD A,D
C06F CP $01
C071 RET Z
TUNE_PLAY_NOTE_0 C072 LD A,(NOTE_LENGTH) BC counts the note's turns: B 256 at a time, C up from $EE to 0.
C075 LD C,A
C076 LD B,$00
C078 LD A,(TUNE_PORT) Both voices start from the same port byte: voice one's copy in A', voice two's in A.
C07B EX AF,AF'
C07C LD A,(TUNE_PORT)
C07F LD IXh,D Voice one's pitch in IXh, to reload its countdown from.
C081 LD D,$10 D: the speaker bit (bit 4 of port $FE).
TUNE_PLAY_NOTE_1 C083 NOP Padding.
C084 NOP
TUNE_PLAY_NOTE_2 C085 EX AF,AF' Voice one: its port byte out, and its countdown down; not run out, the other way round.
C086 DEC E
C087 OUT ($FE),A
C089 JR NZ,TUNE_PLAY_NOTE_4
C08B LD E,IXh Run out: reload it, and toggle voice one's speaker bit.
C08D XOR D
C08E EX AF,AF' Voice two: its countdown down; not run out, out with its port byte as it is.
C08F DEC L
C090 JP NZ,TUNE_PLAY_NOTE_5
TUNE_PLAY_NOTE_3 C093 OUT ($FE),A Run out: out with voice two's port byte; reload its countdown and toggle its speaker bit.
C095 LD L,H
C096 XOR D
C097 DJNZ TUNE_PLAY_NOTE_1 Next turn; next 256; the note is over.
C099 INC C
C09A JP NZ,TUNE_PLAY_NOTE_2
C09D RET
TUNE_PLAY_NOTE_4 C09E JR Z,TUNE_PLAY_NOTE_4 As long as the reload above, and never jumps: Z is clear here.
C0A0 EX AF,AF' Voice two: its countdown down; run out, go and toggle it.
C0A1 DEC L
C0A2 JP Z,TUNE_PLAY_NOTE_3
TUNE_PLAY_NOTE_5 C0A5 OUT ($FE),A Out with voice two's port byte, and padding.
C0A7 NOP
C0A8 NOP
C0A9 DJNZ TUNE_PLAY_NOTE_1 Next turn; next 256; the note is over.
C0AB INC C
C0AC JP NZ,TUNE_PLAY_NOTE_2
C0AF RET
Prev: C041 Up: Map Next: C0B0