![]() |
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 |