Routines |
Prev: $BAA3 | Up: Map | Next: $BBB4 |
$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 |