Prev: $BAA3 Up: Map Next: $BBB4
$BAB4: Tune-playing interrupt routine
The address of this routine is placed at $FFFE by the routines at $BA00 and $BA48.
$BAB4 PHA Push A onto the stack.
$BAB5 TXA Push X onto the stack.
$BAB6 PHA
$BAB7 TYA Push Y onto the stack.
$BAB8 PHA
$BAB9 INC $BBCA Increment the timing counter at $BBCA and pick up the new value.
$BABC LDA $BBCA
$BABF CMP #$04 Is it 4?
$BAC1 BEQ $BAC6 Branch if so.
$BAC3 JMP $BBB1 Otherwise jump to the regular interrupt routine.
$BAC6 LDX #$00 X indicates the voice being dealt with.
$BAC8 STX $BBCA Reset the timing counter at $BBCA to 0.
$BACB STX $4E Pointlessly store X at $4E.
$BACD STX $BBBF Save the voice indicator at $BBBF.
$BAD0 LDA $BBC6,X Copy the tune data address for the current voice to $4E.
$BAD3 STA $4F
$BAD5 LDA $BBC3,X
$BAD8 STA $4E
$BADA LDA $BBB6,X Is it time to play the next note for the current voice?
$BADD BEQ $BAE5 Branch if so.
$BADF DEC $BBB6,X Decrement the note duration counter for the current voice.
$BAE2 JMP $BB6B Jump forward to consider the next voice.
$BAE5 LDA $BBCB,X Pick up the stored value of the control register for the current voice.
$BAE8 AND #$FE Reset bit 0: voice off, release cycle.
$BAEA CPX #$02 Are we dealing with voice #3?
$BAEC BEQ $BAFE Branch if so.
$BAEE CPX #$01 Are we dealing with voice #2?
$BAF0 BEQ $BAF8 Branch if so.
$BAF2 STA $D404 Set voice #1 control register: voice off, release cycle.
$BAF5 JMP $BB01 Jump forward.
$BAF8 STA $D40B Set voice #2 control register: voice off, release cycle.
$BAFB JMP $BB01 Jump forward.
$BAFE STA $D412 Set voice #3 control register: voice off, release cycle.
$BB01 JSR $BAA3 Collect a byte (the note frequency specifier) from the tune data table.
$BB04 STA $BBB4 Store the note frequency specifier at $BBB4.
$BB07 ASL A Have we reached the end of the tune data table for this voice?
$BB08 BCS $BB60 Branch if so.
$BB0A JSR $BAA3 Collect the next byte (the note duration specifier) from the tune data table.
$BB0D STA $BBB6,X Store the note duration specifier at the appropriate location for the current voice and decrement it.
$BB10 DEC $BBB6,X
$BB13 LDA $BBB4 Pick up the note frequency specifier just collected from the tune data table; call it F.
$BB16 BEQ $BB55 Branch if F is zero (this never happens).
$BB18 AND #$F0 Store 7-F/16 at $BBB5.
$BB1A LSR A
$BB1B LSR A
$BB1C LSR A
$BB1D LSR A
$BB1E STA $BBB5
$BB21 LDA #$07
$BB23 SEC
$BB24 SBC $BBB5
$BB27 STA $BBB5
$BB2A LDA $BBB4 Pick up the note frequency specifier (F) again.
$BB2D AND #$0F Bits 0-3 of F indicate the base note frequency. Transfer them to Y.
$BB2F TAY
$BB30 LDA $BBD4,Y Pick up the corresponding frequency value from the table at $BBD4 and copy it into the tune buffer at the appropriate location for the current voice.
$BB33 STA $BBB9,X
$BB36 LDA $BBE0,Y
$BB39 STA $BBBC,X
$BB3C LDY $BBB5 Pick up 7-F/16 from $BBB5.
$BB3F BEQ $BB4A Branch if it's zero (this never happens).
$BB41 LSR $BBBC,X Divide the frequency by 2**(7-F/16).
$BB44 ROR $BBB9,X
$BB47 DEY
$BB48 BNE $BB41
$BB4A LDA $BBCB,X Set bit 0 of the stored control register for the current voice: voice on, attack-decay-sustain cycle.
$BB4D ORA #$01
$BB4F STA $BBCB,X
$BB52 JMP $BB6B Jump forward.
$BB55 LDA $BBCB,X Reset bit 0 of the stored control register for the current voice: voice off, release cycle.
$BB58 AND #$FE
$BB5A STA $BBCB,X
$BB5D JMP $BB6B Jump forward.
$BB60 LDA #$FF Set the tune status indicator at $BBCE to $FF: the tune has finished playing.
$BB62 STA $BBCE
$BB65 JMP $BBB1 Jump to the regular interrupt routine.
$BB68 LDX $BBBF Pick up the voice indicator (0, 1, 2) from $BBBF. This instruction is never executed.
$BB6B LDA $4F Copy the tune data table address MSB from $4F into the tune buffer in case it was incremented.
$BB6D STA $BBC6,X
$BB70 INX Next voice.
$BB71 CPX #$03 Have we done voices #1, #2 and #3 now?
$BB73 BEQ $BB78 Branch if so.
$BB75 JMP $BACD Otherwise jump back to deal with the next voice.
$BB78 DEX X=2 (voice #3).
$BB79 LDA $BBB9,X Set voice #3 frequency.
$BB7C STA $D40E
$BB7F LDA $BBBC,X
$BB82 STA $D40F
$BB85 LDA $BBCB,X Set voice #3 control register.
$BB88 STA $D412
$BB8B DEX X=1 (voice #2).
$BB8C LDA $BBB9,X Set voice #2 frequency.
$BB8F STA $D407
$BB92 LDA $BBBC,X
$BB95 STA $D408
$BB98 LDA $BBCB,X Set voice #2 control register.
$BB9B STA $D40B
$BB9E DEX X=0 (voice #1).
$BB9F LDA $BBB9,X Set voice #1 frequency.
$BBA2 STA $D400
$BBA5 LDA $BBBC,X
$BBA8 STA $D401
$BBAB LDA $BBCB,X Set voice #1 control register.
$BBAE STA $D404
$BBB1 JMP $39CC Jump to the regular interrupt routine.
Prev: $BAA3 Up: Map Next: $BBB4