; Motorola 6808 at 3.579545 MHz
;  http://electronics.stevenvh.net/6809/isd.php

; Cycle counter in MAME debugger wraps at 58


; Entry point
; {
    ; Disable interrupts
    F801: 0F            sei  

    ; Set stack base at $7f
    F802: 8E 00 7F      lds  #$007F
    ; Set X base reg to $400
    F805: CE 04 00      ldx  #$0400
    ; At $400 set $FF,00,00,00
    F808: 6F 01         clr  (x+$01)
    F80A: 6F 03         clr  (x+$03)
    F80C: 86 FF         lda  #$FF
    F80E: A7 00         sta  (x+$00)
    F810: 6F 02         clr  (x+$02)
    ; At $403 set $37
    F812: 86 37         lda  #$37
    F814: A7 03         sta  (x+$03)
    ; At $401 set $3C
    F816: 86 3C         lda  #$3C
    F818: A7 01         sta  (x+$01)
    ; At $9 set $3C
    F81A: 97 09         sta  $09
    ; Clear some more locations
    F81C: 4F            clra 
    F81D: 97 07         sta  $07
    F81F: 97 04         sta  $04
    F821: 97 05         sta  $05
    F823: 97 06         sta  $06
    F825: 97 08         sta  $08

    ; Reenable interrupts
    F827: 0E            cli  

    ; Loop forever
    ; {
        F828: 20 FE         bra  $F828
    ; }
; }


; sub
; Handler C preparation
; Copy one of the 9 byte records from the table at $fd76 to $0013
;
; Params:
;  a.b: Record number
; {
    ; Call sub to copy 9 bytes from ($fd76 + a*9) to $0013 .. $001C
    ;  a *= 9
    F82A: 16            tab  
    F82B: 48            asla 
    F82C: 48            asla 
    F82D: 48            asla 
    F82E: 1B            aba  
    ;  dest address = $0013
    F82F: CE 00 13      ldx  #$0013
    F832: DF 0F         stx  $0F
    ;  src address = #$fd76 + a
    F834: CE FD 76      ldx  #$FD76
    F837: BD FD 21      jsr  $FD21  ; x.w += a.b
    ;  copy 9 bytes
    F83A: C6 09         ldb  #$09
    ;  call subroutine
    F83C: 7E FB 0A      jmp  $FB0A
; }

; sub
; Handler C synth
; (boot / drop humanoid sound, extra life sound, robotron sound)
;
; Params:
;  $0013-$001B: record
; {
    ; Get volume (always $FF) and output to DAC
    F83F: 96 1B         lda  $1B
    F841: B7 04 00      sta  $0400

    ; {
        ; Copy byte from $13 (record[0].b) to $1c
        ; (length of low part of sound wave)
        ; and copy byte from $14 (record[1].b) to $1d
        ; (length of high part of sound wave)
        F844: 96 13         lda  $13
        F846: 97 1C         sta  $1C
        F848: 96 14         lda  $14
        F84A: 97 1D         sta  $1D

        ; Until record[1].b reaches record[4].b limit
        ; {
            ; Get $18 in X (record[5].w), maybe a duty cycle value,
            ; then while it has not yet reached 0
            F84C: DE 18         ldx  $18
            ; {
                ; Get record[0].b back from $1c to A
                F84E: 96 1C         lda  $1C
                ; Invert the sound wave (to $00)
                F850: 73 04 00      com  $0400
                ; {
                    ; Decrement the big record[5] number in X, and the small record[0] number in A,
                    ; until one reaches 0
                    ; If the big record[5] number reached 0, then break out of outer loop
                    F853: 09            dex  
                    F854: 27 10         beq  $F866
                    F856: 4A            deca 
                    F857: 26 FA         bne  $F853
                ; }

                ; Invert the sound wave (to $FF)
                F859: 73 04 00      com  $0400
                ; Get record[1].b back from $1d to A
                F85C: 96 1D         lda  $1D
                ; {
                    ; Decrement the big record[5] number in X, and the small record[1] number in A,
                    ; until one reaches 0
                    ; If the big record[5] number reached 0, then break out of outer loop
                    F85E: 09            dex  
                    F85F: 27 05         beq  $F866
                    F861: 4A            deca 
                    F862: 26 FA         bne  $F85E
                ; }

                F864: 20 E8         bra  $F84E
            ; }
            ; The big record[5] number reached 0

            ; If sound wave finished low then complement it back to high
            F866: B6 04 00      lda  $0400
            F869: 2B 01         bmi  $F86C
            ; {
                F86B: 43            coma 
            ; }
            F86C: 8B 00         adda #$00
            F86E: B7 04 00      sta  $0400

            ; Add record[2].b increment to running record[0].b value in $1C
            F871: 96 1C         lda  $1C
            F873: 9B 15         adda $15
            F875: 97 1C         sta  $1C
            ; Add record[3].b increment to running record[1].b value in $1D
            F877: 96 1D         lda  $1D
            F879: 9B 16         adda $16
            F87B: 97 1D         sta  $1D
            ; If the running record[1].b has not yet reached record[4].b,
            ; repeat
            F87D: 91 17         cmpa $17
            F87F: 26 CB         bne  $F84C
        ; }

        ; If $1a (record[7].b) is zero then return
        F881: 96 1A         lda  $1A
        F883: 27 06         beq  $F88B
        ; Add A (record[7].b) to $13 (record[0].b), if it's zero then return
        F885: 9B 13         adda $13
        F887: 97 13         sta  $13
        F889: 26 B9         bne  $F844
    ; }
    F88B: 39            rts  
; }

; sub
; Handler B vector 3
; mutant spawn
; {
    ; Choose args for and call $F89E sub
    ;  A: initial delay per LFSR iteration, start low, ie. high pitch
    F88C: 86 01         lda  #$01
    ;  ($1a).b: arg increment to delay per LFSR iteration, go upwards, ie. pitch downwards
    F88E: 97 1A         sta  $1A
    ;  B: count of LFSR iterations in the inner loop
    F890: C6 03         ldb  #$03
    ;  jsr
    F892: 20 0A         bra  $F89E
; }

; sub
; Handler B vector 7
; lander spawn
; {
    ; Choose args for and call $F89E sub
    ;  ($1a).b: arg increment to delay per LFSR iteration, go downward, ie. pitch upwards
    F894: 86 FE         lda  #$FE
    F896: 97 1A         sta  $1A
    ;  A: initial delay per LFSR iteration, start high, ie. low pitch
    F898: 86 C0         lda  #$C0
    ;  B: count of LFSR iterations in the inner loop
    F89A: C6 10         ldb  #$10
    ;  jsr
    F89C: 20 00         bra  $F89E
; }

; sub
; Common code for handler B vector 3 & 7
;
; Params:
;  A:
;   initial delay per LFSR iteration
;   (($1a).b is added to this at the end of each outer loop)
;   [effectively, initial pitch]
;  B:
;   count of LFSR iterations in the inner loop
;   [effectively, pitch bend]
;  ($1a).b:
;   increment to delay per LFSR iteration (A argument, initially) after every inner B loop
;   [effectively, overall length of sound]
; {
    ; Store A argument in ($19).b
    F89E: 97 19         sta  $19  ; 4~

    ; Set waveform to high
    F8A0: 86 FF         lda  #$FF  ; 3~
    F8A2: B7 04 00      sta  $0400  ; 5~

    ; Store B argument (count of LFSR iterations) in ($15).b
    F8A5: D7 15         stb  $15  ; 4~

    ; Until A argument reaches 0
    ; {
        ; Get B argument back from ($15).b
        ; and while B is not yet 0
        F8A7: D6 15         ldb  $15  ; 3~
        ; {
            ; + LFSR {{{

            ; Acting on LFSR register at ($9).w

            ; Get output in C flag,
            ; as LFSR register bit 0 ^ LFSR register bit 3
            F8A9: 96 0A         lda  $0A  ; 3~
            F8AB: 44            lsra   ; 2~
            F8AC: 44            lsra   ; 2~
            F8AD: 44            lsra   ; 2~
            F8AE: 98 0A         eora $0A  ; 3~
            F8B0: 44            lsra   ; 2~

            ; Rotate LFSR register right by 1 bit, pushing output (C) into the top bit
            F8B1: 76 00 09      ror  $0009  ; 6~
            F8B4: 76 00 0A      ror  $000A  ; 6~

            ; + }}}

            ; LFSR result is in C
            ; If it returned 0, do nothing
            ; else complement DAC output
            F8B7: 24 03         bcc  $F8BC  ; 4~
            ; {
                F8B9: 73 04 00      com  $0400  ; 6~
            ; }

            ; Restore A argument from ($19).b
            ; and delay for that time
            F8BC: 96 19         lda  $19  ; 3~
            ; {
                F8BE: 4A            deca  ; 2~
                F8BF: 26 FD         bne  $F8BE  ; 4~
            ; }

            ; Decrement length counter, loop back if not yet 0
            F8C1: 5A            decb  ; 2~
            F8C2: 26 E5         bne  $F8A9  ; 4~
        ; }

        ; Update A argument (delay per LFSR iteration)
        ; ($19).b (A argument) += ($1a).b
        ; Then if it's reached 0 then return, else outer loop
        F8C4: 96 19         lda  $19  ; 3~
        F8C6: 9B 1A         adda $1A  ; 3~
        F8C8: 97 19         sta  $19  ; 4~
        F8CA: 26 DB         bne  $F8A7  ; 4~
    ; }
    F8CC: 39            rts  
; }

; sub
; Handler B vector 6
; player shoot
; {
    ; Store #$20 in ($15).b
    ; Number of noise values to write before changing volume
    F8CD: 86 20         lda  #$20
    F8CF: 97 15         sta  $15
    ; Store #$20 in ($18).b
    ; Never changes [perhaps this is for other CPU to be able to cut sound off]
    F8D1: 97 18         sta  $18

    ; Loadup some constants in a, x, b and then save them in memory
    ; a in ($13.b)
    ;  $1
    ;  amount to subtract from the volume
    ; x in ($16).w
    ;  delay after writing each sample to DAC
    ;  $0001
    ; b in ($14).w
    ;  value for the DAC, when the LFSR returns 1
    ;  $FF
    F8D3: 86 01         lda  #$01
    F8D5: CE 00 01      ldx  #$0001
    F8D8: C6 FF         ldb  #$FF
    F8DA: 20 00         bra  $F8DC
    F8DC: 97 13         sta  $13

    ; {
        F8DE: DF 16         stx  $16  ; 5~
        F8E0: D7 14         stb  $14  ; 4~

        ; For each LFSR repetition / noise value (of 32) at this volume
        ; for (b = ($15); b != 0; --b)
        F8E2: D6 15         ldb  $15  ; 3~
        ; {
            ; + LFSR {{{

            ; Acting on LFSR register at ($9).w

            ; Get output in C flag,
            ; as LFSR register bit 0 ^ LFSR register bit 3
            F8E4: 96 0A         lda  $0A  ; 3~
            F8E6: 44            lsra  ; 2~
            F8E7: 44            lsra  ; 2~
            F8E8: 44            lsra  ; 2~
            F8E9: 98 0A         eora $0A  ; 3~
            F8EB: 44            lsra  ; 2~

            ; Rotate LFSR register right by 1 bit, pushing output (C) into the top bit
            F8EC: 76 00 09      ror  $0009  ; 6~
            F8EF: 76 00 0A      ror  $000A  ; 6~

            ; + }}}

            ; LFSR result is in C
            ; If it returned 0, set A to 0
            ; else set A to current volume from ($14).b
            F8F2: 86 00         lda  #$00  ; 2~
            F8F4: 24 02         bcc  $F8F8  ; 4~
            ; {
                F8F6: 96 14         lda  $14  ; 3~
            ; }

            ; Send sample value to DAC
            F8F8: B7 04 00      sta  $0400  ; 5~

            ; Delay for ($16).w which was initially 1
            F8FB: DE 16         ldx  $16  ; 4~
            ; for (var delayTickNo = ($16); delayTickNo != 0; --delayTickNo)
            ; {
                F8FD: 09            dex  ; 4~
                F8FE: 26 FD         bne  $F8FD  ; 4~
            ; }

            ; Decrement b / ($15).b loop counter (initially $20) and loop back
            F900: 5A            decb   ; 2~
            F901: 26 E1         bne  $F8E4  ; 4~ taken
        ; }

        ; Subtract from volume, if now zero then return
        F903: D6 14         ldb  $14  ; 3~
        F905: D0 13         subb $13  ; 3~
        F907: 27 09         beq  $F912  ; 4~ not taken

        ; Get delay in x and increment it
        F909: DE 16         ldx  $16  ; 4~
        F90B: 08            inx    ; 4~
        ;
        F90C: 96 18         lda  $18  ; 3~
        F90E: 27 D0         beq  $F8E0  ; 4~  ; don't save x back to $16
        F910: 20 CC         bra  $F8DE  ; 4~  ; save x back to $16
    ; }

    F912: 39            rts  
; }


; sub
; Handler B vector 1
; thrust quiet
;  B: filter cutoff: 1
F913: C6 01         ldb  #$01
;  $4: 1, [not sure this does anything] [class 2 sound selection for after this finishes?]
F915: D7 04         stb  $04
;  A: 0: repeat loop indefinitely
F917: 4F            clra 
;  $19: 0: don't randomize filter cutoff
F918: 97 19         sta  $19
;  X: length
F91A: 20 14         bra  $F930

; sub
; Handler B vector 8
; thrust loud
;  A: 0: repeat loop indefinitely
F91C: 4F            clra 
;  $19: 0: don't randomize filter cutoff
F91D: 97 19         sta  $19
;  B: filter cutoff: 3
F91F: C6 03         ldb  #$03
;  X: length
F921: 20 0D         bra  $F930

; sub
; Handler B vector 9
; end of explosion (player death, smart bomb)
;  $19: 1: randomize filter cutoff
F923: 86 01         lda  #$01
F925: 97 19         sta  $19
;  X: length: 1000
F927: CE 03 E8      ldx  #$03E8
;  A: 1: don't repeat loop indefinitely
F92A: 86 01         lda  #$01
;  B: filter cutoff: 255
F92C: C6 FF         ldb  #$FF
F92E: 20 00         bra  $F930

; sub
; Common code for handler B vector 1, 8 & 9
; Params:
;  A:
;   [0 or 1]
;   0: repeat loop indefinitely
;  ($19).b:
;   [always same as A in practice]
;   0: don't randomize filter cutoff
;   else: randomize filter cutoff
;  B:
;   filter cutoff
;   speed of movement of DAC toward high byte of LFSR
;   1: low
;   255: high
;  X:
;   [F913, F91C, F923]
;   [< by listening
;     length of sound]
;   ...
; {
    ; Save args
    ;  A (repeat loop indefinitely) in ($18).b
    F930: 97 18         sta  $18  ; 4~
    ;  B (filter cutoff) in ($13).b
    F932: D7 13         stb  $13  ; 4~
    ;  X (length of sound[?]) in ($16).w
    F934: DF 16         stx  $16  ; 5~

    ; "Local incrementer"
    ; Low byte of 16-bit filter cutoff
    F936: 7F 00 15      clr  $0015  ; 6~

    ; {
        ; Retrieve X (length) argument
        F939: DE 16         ldx  $16  ; 4~

        ; Get DAC in A, ready for LFSR-like at F93E and comparison at F958
        F93B: B6 04 00      lda  $0400  ; 4~

        ; do
        ; {
            ; while (true)
            ; {
                ; + LFSR-like {{{

                ; Acting on LFSR register at ($9).w

                ; Get output in C flag,
                ; as LFSR register bit 0 ^ DAC (not LFSR as usual!) register bit 3
                F93E: 16            tab  ; 2~
                F93F: 54            lsrb  ; 2~
                F940: 54            lsrb  ; 2~
                F941: 54            lsrb  ; 2~
                F942: D8 0A         eorb $0A  ; 3~
                F944: 54            lsrb  ; 2~

                ; Rotate LFSR register right by 1 bit, pushing output (C) into the top bit
                F945: 76 00 09      ror  $0009  ; 6~
                F948: 76 00 0A      ror  $000A  ; 6~

                ; + }}}

                ; LFSR result is in C [but not used, before lost at $F94D]
                ; Instead, value of low byte of LFSR will be used as target to slide DAC towards

                ; Set ($14).b to filter cutoff, possibly-masked with LFSR high byte
                ;  If ($19).b (ie. randomize filter cutoff) is zero,
                ;   ($14).b = ($13).b (B argument, ie. filter cutoff)
                ;  else if ($19).b is not zero,
                ;   ($14).b = ($13).b (B argument, ie. filter cutoff) & ($09).b (LFSR high byte)
                F94B: D6 13         ldb  $13  ; 3~  // [doesn't affect C]
                F94D: 7D 00 19      tst  $0019  ; 6~  // [clears C]
                F950: 27 02         beq  $F954  ; 4~ taken
                ; {
                    F952: D4 09         andb $09  ; 3~
                ; }
                F954: D7 14         stb  $14  ; 4~

                ; Get ($15).b (low byte of 16-bit filter cutoff) in B to expand DAC value to 16-bit while sliding
                F956: D6 15         ldb  $15  ; 3~

                ; If A (current DAC) is not higher than ($A).b (low byte of LFSR register)
                ; slide DAC up to that value
                F958: 91 0A         cmpa $0A  ; 3~
                F95A: 22 12         bhi  $F96E  ; 4~ not taken
                ; {
                    ; {
                        ; Decrement length and if 0 then break outer loop (to go back to $F93E)
                        F95C: 09            dex  ; 4~
                        F95D: 27 26         beq  $F985  ; 4~

                        ; Write DAC value back out (unchanged in first iteration)
                        F95F: B7 04 00      sta  $0400  ; 5~

                        ; 16-bit add filter cutoff in ($14.w) to AB,
                        ; and if unsigned overflow, break loop
                        ; [Add 16-bit value at $14.w to 16-bit value formed by registers A and B,
                        ;  and if unsigned overflow, break to $F97E]
                        F962: DB 15         addb $15  ; 3~
                        F964: 99 14         adca $14  ; 3~
                        F966: 25 16         bcs  $F97E  ; 4~ not taken

                        ; If DAC has reached the target,
                        ; break loop
                        F968: 91 0A         cmpa $0A  ; 3~
                        F96A: 23 F0         bls  $F95C  ; 4~ not taken
                    ; }
                    F96C: 20 10         bra  $F97E  ; 4~
                ; }
                ; else if A (current DAC) was higher than ($A).b (low byte of LFSR register)
                ; slide DAC down to that value
                ; {
                    ; {
                        ; Decrement length and if 0 then break outer loop (to go back to $F93E)
                        F96E: 09            dex  ; 4~
                        F96F: 27 14         beq  $F985  ; 4~ not taken

                        ; Write DAC value back out (unchanged in first iteration)
                        F971: B7 04 00      sta  $0400  ; 5~

                        ; 16-bit subtract filter cutoff in ($14.w) from AB,
                        ; and if unsigned underflow, break loop
                        ; [Subtract 16-bit value at $14.w from 16-bit value formed by registers A and B,
                        ;  and if unsigned borrow, break to $F97E]
                        F974: D0 15         subb $15  ; 3~
                        F976: 92 14         sbca $14  ; 3~
                        F978: 25 04         bcs  $F97E  ; 4~ not taken

                        ; If DAC has reached the target,
                        ; break loop
                        F97A: 91 0A         cmpa $0A  ; 3~
                        F97C: 22 F0         bhi  $F96E  ; 4~ taken
                    ; }
                ; }

                ; Load target value from low byte of LFSR register
                ; and store it directly in DAC to undo any overshoot
                F97E: 96 0A         lda  $0A  ; 3~
                F980: B7 04 00      sta  $0400  ; 5~
                ;
                F983: 20 B9         bra  $F93E  ; 4~
            ; }

            ; X (length) counter expired
            ; If want to repeat loop indefinitely, loop
            F985: D6 18         ldb  $18  ; 3~
            F987: 27 B5         beq  $F93E  ; 4~ taken
        ; }
        ; while (($18).b == 0)

        ; Tweak parameters and maybe go again

        ; Multiply 16-bit value formed by filter cutoff parameter in $13.b and local incrementer in $15.b by 0.875
        ;  Get original filter cutoff arg and local incrementer in AB
        F989: 96 13         lda  $13  ; 3~
        F98B: D6 15         ldb  $15  ; 3~
        ;  Shift AB right by 3
        F98D: 44            lsra  ; 2~
        F98E: 56            rorb  ; 2~
        F98F: 44            lsra  ; 2~
        F990: 56            rorb  ; 2~
        F991: 44            lsra  ; 2~
        F992: 56            rorb  ; 2~
        ;  Negate AB
        F993: 43            coma  ; 2~
        F994: 50            negb  ; 2~
        F995: 82 FF         sbca #$FF  ; 2~
        ;  Add original value back
        F997: DB 15         addb $15  ; 3~
        F999: 99 13         adca $13  ; 3~
        ;  Store back in memory
        F99B: D7 15         stb  $15  ; 4~
        F99D: 97 13         sta  $13  ; 4~

        ; If high byte of filter cutoff not 0 yet,
        ; and low byte not 7,
        ; loop to start again
        F99F: 26 98         bne  $F939  ; 4~ taken
        F9A1: C1 07         cmpb #$07  ; 2~
        F9A3: 26 94         bne  $F939  ; 4~ taken
    ; }
    F9A5: 39            rts  
; }

; sub
; Handler B vector 10
; (robotron) hiscore aliased sweep
; {
    ; Set ($F).b to $FD, high byte base address for wavetable
    F9A6: 86 FD         lda  #$FD  ; 2~
    F9A8: 97 0F         sta  $0F  ; 4~
    ; ($B).w = $0064
    F9AA: CE 00 64      ldx  #$0064  ; 3~
    F9AD: DF 0B         stx  $0B  ; 5~
    ; {
        ; 16-bit add, ($11).b,B += ($B).w
        ; [($11).b,B doesn't seem to be initialized, guess it doesn't matter]
        ;  Add low byte of ($B).w to B [which is initially 0]
        F9AF: DB 0C         addb $0C  ; 3~
        ;  Add the carry from the above and the high byte of ($B).w to ($11).b [which was initially $A]
        F9B1: 96 11         lda  $11  ; 3~
        F9B3: 99 0B         adca $0B  ; 3~
        F9B5: 97 11         sta  $11  ; 4~

        ; If the above operation carried
        ; increment ($B).w and if it's reached 0, return
        F9B7: DE 0B         ldx  $0B  ; 4~  ?
        F9B9: 25 04         bcs  $F9BF  ; 4~
        F9BB: 20 00         bra  $F9BD  ; 4~
        F9BD: 20 03         bra  $F9C2  ; 4~
        ; {
            F9BF: 08            inx  ; 4~
            F9C0: 27 11         beq  $F9D3  ; 4~
        ; }
        F9C2: DF 0B         stx  $0B  ; 5~

        ; And A with $F then
        ; use it at offset into 16-byte wavetable at $FD9A
        F9C4: 84 0F         anda #$0F  ; 2~
        ;  Store it at ($10.b) to make 16-bit address at ($9).w
        F9C6: 8B 9A         adda #$9A  ; 2~
        F9C8: 97 10         sta  $10  ; 4~

        ; Read back 16-bit wavetable pointer,
        ; get sample from there and send to DAC
        F9CA: DE 0F         ldx  $0F  ; 4~
        F9CC: A6 00         lda  (x+$00)  ; 5~
        F9CE: B7 04 00      sta  $0400  ; 5~

        ;
        F9D1: 20 DC         bra  $F9AF  ; 4~
    ; }
    F9D3: 39            rts  
; }

; sub
; Handler B vector 11
; insert credit
; {
    ; Set DAC to low
    F9D4: 4F            clra  ; 2~
    F9D5: B7 04 00      sta  $0400  ; 5~

    ; ($11).b will be pulse width / duty cycle
    ; Start it out at 0
    F9D8: 97 11         sta  $11  ; 4~

    ; {
        ; A will be phase
        ; Start it at 0
        F9DA: 4F            clra  ; 2~
        ; {
            ; If A == ($11).b,
            ; complement DAC to be 1
            F9DB: 91 11         cmpa $11  ; 3~
            F9DD: 26 03         bne  $F9E2  ; 4~
            ; {
                F9DF: 73 04 00      com  $0400  ; 6~
            ; }

            ; Delay for 12 loops
            F9E2: C6 12         ldb  #$12  ; 2~
            ; {
                F9E4: 5A            decb  ; 2~
                F9E5: 26 FD         bne  $F9E4  ; 4~
            ; }

            ; Increment A and if it's not yet 0x80,
            ; loop
            F9E7: 4C            inca  ; 2~
            F9E8: 2A F1         bpl  $F9DB  ; 4~
        ; }

        ; Complement DAC back to 0
        F9EA: 73 04 00      com  $0400  ; 6~
        ; Increment pulse width
        F9ED: 7C 00 11      inc  $0011  ; 6~
        ; If it's not yet 0x80 then loop
        F9F0: 2A E8         bpl  $F9DA  ; 4~
    ; }
    F9F2: 39            rts  
; }

; sub
; Handler B vector 12
; humanoid fall
; {
    ; Clear memory from $13 to $1A inclusive
    ; (8 bytes, 4 pairs of 2 bytes)
    F9F3: CE 00 13      ldx  #$0013  ; 3~
    ; {
        F9F6: 6F 00         clr  (x+$00)  ; 7~
        F9F8: 08            inx    ; 4~
        F9F9: 8C 00 1B      cmpx #$001B  ; 3~
        F9FC: 26 F8         bne  $F9F6  ; 4~ taken
    ; }

    ; Store 64 in $13, the first number of the first pair in the working memory
    F9FE: 86 40         lda  #$40  ; 2~
    FA00: 97 13         sta  $13  ; 4~

    ; {
        ; {
            ; Get working memory pointer in x
            FA02: CE 00 13      ldx  #$0013  ; 3~

            ; Store 128 in $11
            FA05: 86 80         lda  #$80  ; 2~
            FA07: 97 11         sta  $11  ; 4~

            ; Clear B
            FA09: 5F            clrb   ; 2~

            ; For each of the 4 pairs of bytes in the working memory
            ; (($11).b will take values $80, $40, $20, $10)
            ; {
                ; For the next pair of bytes pointed to by x, add the first byte to the second
                FA0A: A6 01         lda  (x+$01)  ; 5~
                FA0C: AB 00         adda (x+$00)  ; 5~
                FA0E: A7 01         sta  (x+$01)  ; 6~
                ; If the second byte is now negative, add ($11) (initially 128) to b (initially 0)
                ; ie. set a bit in b
                FA10: 2A 02         bpl  $FA14  ; 4~ taken
                ; {
                    FA12: DB 11         addb $11  ; 3~
                ; }
                ; Shift ($11) to the next bit down
                FA14: 74 00 11      lsr  $0011  ; 6~
                ; Move to the next pair of bytes in x
                FA17: 08            inx    ; 4~
                FA18: 08            inx    ; 4~
                FA19: 8C 00 1B      cmpx #$001B  ; 3~
                FA1C: 26 EC         bne  $FA0A  ; 4~ taken
            ; }
            ; Send B to DAC
            FA1E: F7 04 00      stb  $0400  ; 5~
            ; Increment ($12) and repeat if not 0
            ; [not sure where initialized but in test, $12 seems to have started at 0,
            ; so this loop runs 256 times]
            FA21: 7C 00 12      inc  $0012  ; 6~
            FA24: 26 DC         bne  $FA02  ; 4~ taken
        ; }

        ; Get the start of the working memory area again
        FA26: CE 00 13      ldx  #$0013  ; 3~
        ; Clear b, which will count how many of the 4 samples/pairs are active
        FA29: 5F            clrb   ; 2~
        ; For each of the 4 pairs of bytes in the working memory
        ; {
            ; If first byte in current pair isn't 0
            ; (ie. this one of the 4 samples has started yet,
            ;      and this one of the 4 samples has not finished (first byte run down to 0) yet)
            FA2A: A6 00         lda  (x+$00)  ; 5~
            FA2C: 27 0B         beq  $FA39  ; 4~ not taken
            ; {
                ; If first byte in current pair is 55,
                ; store 65 in first byte of the next pair
                ; (ie. now generating 1 more out of the 4 samples in the above loop, fattening the sound)
                FA2E: 81 37         cmpa #$37  ; 2~
                FA30: 26 04         bne  $FA36  ; 4~ taken
                ; {
                    FA32: C6 41         ldb  #$41  ; 2~
                    FA34: E7 02         stb  (x+$02)  ; 6~
                ; }
                ; Decrement first byte
                FA36: 6A 00         dec  (x+$00)  ; 7~
                ; Count this sample/pair as being active
                FA38: 5C            incb   ; 2~
            ; }
            ; Move to next pair
            FA39: 08            inx    ; 4~
            FA3A: 08            inx    ; 4~
            ;
            FA3B: 8C 00 1B      cmpx #$001B  ; 3~
            FA3E: 26 EA         bne  $FA2A  ; 4~ taken
        ; }
        FA40: 5D            tstb   ; 2~
        FA41: 26 BF         bne  $FA02  ; 4~ taken
    ; }
    FA43: 39            rts    ; ~
; }


; sub
; Handler B vector 13
; silent?
FA44: 7A 00 08      dec  $0008
FA47: 39            rts  

; sub: Play tune
; [Called from near start of switchboard, if ($08).b < 0]
; [at start of music I think]
;
; Params:
;  a.b:
;   song no
;   1: 3 descending notes
;   2: bach
; {
    ; Clear ($08).b which was < 0 to get to this sub [-1 seen so far)
    FA48: 7F 00 08      clr  $0008  ; 6~
    ; Save the A param
    FA4B: 97 11         sta  $11  ; 4~

    ; Get address of song data in X
    ;  Start at first song
    FA4D: CE FD AA      ldx  #$FDAA  ; 3~
    ; while (true)
    ; {
        ; Get length of song in A, if 0 then abort to class 2 sounds [for silence most likely]
        FA50: A6 00         lda  (x+$00)  ; 5~
        FA52: 27 2D         beq  $FA81  ; 4~ not taken
        ;
        FA54: 7A 00 11      dec  $0011  ; 6~
        ; break
        FA57: 27 06         beq  $FA5F  ; 4~ not taken
        FA59: 4C            inca  ; 2~
        FA5A: BD FD 21      jsr  $FD21  ; x.w += a.b  ; 9~ + approx 25~ for subroutine content
        FA5D: 20 F1         bra  $FA50  ; 4~
    ; }

    ; Skip song length byte
    FA5F: 08            inx
    ; Store song data start address in ($0f).w
    FA60: DF 0F         stx  $0F
    ; Add song length to X to get song data end address and store that in ($0d).w
    FA62: BD FD 21      jsr  $FD21  ; x.w += a.b
    FA65: DF 0D         stx  $0D  ; 5~
    ; Get song start address back in X
    FA67: DE 0F         ldx  $0F  ; 4~
    ; While not yet reached end of song data
    ; {
        ; Timbre bitmask
        ; ($15).b = note[0].b
        FA69: A6 00         lda  (x+$00)  ; 5~
        FA6B: 97 15         sta  $15  ; 4~
        ; Note period
        ; A = note[1].b
        FA6D: A6 01         lda  (x+$01)  ; 5~
        ; Note length
        ; ($13).w = note[2].w
        FA6F: EE 02         ldx  (x+$02)  ; 6~
        FA71: DF 13         stx  $13  ; 5~
        ; Play note
        FA73: 8D 3E         bsr  $FAB3  ; 8~
        FA75: DE 0F         ldx  $0F  ; 4~
        ; x += 4
        FA77: 08            inx    ; 4~
        FA78: 08            inx    ; 4~
        FA79: 08            inx    ; 4~
        FA7A: 08            inx    ; 4~
        ; If not yet reached end of song data, loop back
        FA7B: DF 0F         stx  $0F  ; 5~
        FA7D: 9C 0D         cmpx $0D  ; 4~
        FA7F: 26 E8         bne  $FA69  ; 4~ taken
    ; }
    ; Return to class 2 sounds
    FA81: 7E FD 0E      jmp  $FD0E
; }

; sub
; Handler B vector 14
; silent?
FA84: 86 03         lda  #$03
FA86: 97 08         sta  $08
FA88: 39            rts  

; sub
; [play tune, 2]
; [Called from near start of switchboard, if $08.b != 0]
; Params:
;  a.b:
;   If ($08).b > 1, low nybble to add into ($15).b
;   If ($08).b == 1, a pitch from 1 to 12
; {?
FA89: 7A 00 08      dec  $0008
; Decrement ($08).b, and if not 0
FA8C: 27 0C         beq  $FA9A
; {
    ; Get byte from ($15) in B,
    ; shift low nybble to high,
    ; add A [can we presume this is itself nybble sized?] to it (with result in A)
    ; store result back in $15
    FA8E: D6 15         ldb  $15
    FA90: 58            aslb 
    FA91: 58            aslb 
    FA92: 58            aslb 
    FA93: 58            aslb 
    FA94: 1B            aba  
    FA95: 97 15         sta  $15
    ; Clear A and stop
    FA97: 4F            clra 
    FA98: 20 FE         bra  $FA98
; }
; else if ($08).b [was 1 on sub entry and] is now 0
; {
    ; Decrement A (pitch) and if it's >11, make it 0
    FA9A: 4A            deca 
    FA9B: 81 0B         cmpa #$0B
    FA9D: 23 01         bls  $FAA0
    FA9F: 4F            clra 
    ; Get [period?] value in A for this pitch from note table
    FAA0: CE FE 41      ldx  #$FE41
    FAA3: BD FD 21      jsr  $FD21  ; x.w += a.b
    FAA6: A6 00         lda  (x+$00)
    ; x.w = #$FFFF
    FAA8: CE FF FF      ldx  #$FFFF
    FAAB: DF 13         stx  $13
    FAAD: 8D 04         bsr  $FAB3  ; play note
    ; {
        FAAF: 8D 2A         bsr  $FADB
        FAB1: 20 FC         bra  $FAAF
    ; }
; }

; sub: play note
; [Called from either of above two subs]
; Params:
;  A: note period
;  ($13).w: length of note (eg. ffff)
;  ($15).b: timbre bitmask
; {
    ; Start of code out buffer
    FAB3: CE 00 16      ldx  #$0016  ; 3~

    ; While A is not 0
    FAB6: 81 00         cmpa #$00  ; 2~
    FAB8: 27 15         beq  $FACF  ; 4~ not taken
    ; {
        ; If A is not 3
        FABA: 81 03         cmpa #$03  ; 2~
        FABC: 27 09         beq  $FAC7  ; 4~
        ; {
            ; Append 1 (instruction: NOP, 2~) to buffer starting at $16 and increment buffer pointer
            FABE: C6 01         ldb  #$01  ; 2~
            FAC0: E7 00         stb  (x+$00)  ; 6~
            FAC2: 08            inx  ; 4~
            ; Subtract 2 from A and loop
            FAC3: 80 02         suba #$02  ; 2~
            FAC5: 20 EF         bra  $FAB6  ; 4~
        ; }
        ; Else if A is 3
        ; Append $91 and 0 (instruction: CMPA $00, 3~) to the buffer
        FAC7: C6 91         ldb  #$91  ; 2~
        FAC9: E7 00         stb  (x+$00)  ; 6~
        FACB: 6F 01         clr  (x+$01)  ; 7~
        FACD: 08            inx  ; 4~
        FACE: 08            inx  ; 4~
    ; }

    ; Append $7E, $FA, $DD (instruction: JMP $FADD, 3~) to the buffer
    FACF: C6 7E         ldb  #$7E  ; 2~
    FAD1: E7 00         stb  (x+$00)  ; 6~
    FAD3: C6 FA         ldb  #$FA  ; 2~
    FAD5: E7 01         stb  (x+$01)  ; 6~
    FAD7: C6 DD         ldb  #$DD  ; 2~
    FAD9: E7 02         stb  (x+$02)  ; 6~

    ; Get the ($13).w parameter in x
    FADB: DE 13         ldx  $13  ; 4~

    ; {
        ; Clear A ready for count below
        FADD: 4F            clra   ; 2~
        ; Increment ($12).b
        FADE: F6 00 12      ldb  $0012  ; 4~
        FAE1: 5C            incb   ; 2~
        FAE2: D7 12         stb  $12  ; 4~
        ; AND the new value of ($12).b in register with ($15).b [was $1E just now]
        FAE4: D4 15         andb $15  ; 3~
        ; In A, get count how many of bits are set in B
        FAE6: 54            lsrb   ; 2~
        FAE7: 89 00         adca #$00  ; 2~
        FAE9: 54            lsrb   ; 2~
        FAEA: 89 00         adca #$00  ; 2~
        FAEC: 54            lsrb   ; 2~
        FAED: 89 00         adca #$00  ; 2~
        FAEF: 54            lsrb   ; 2~
        FAF0: 89 00         adca #$00  ; 2~
        FAF2: 54            lsrb   ; 2~
        FAF3: 89 00         adca #$00  ; 2~
        FAF5: 54            lsrb   ; 2~
        FAF6: 89 00         adca #$00  ; 2~
        FAF8: 54            lsrb   ; 2~
        FAF9: 89 00         adca #$00  ; 2~
        FAFB: 1B            aba    ; 2~
        ; Multiply count by 16
        FAFC: 48            asla   ; 2~
        FAFD: 48            asla   ; 2~
        FAFE: 48            asla   ; 2~
        FAFF: 48            asla   ; 2~
        ; Send to DAC
        FB00: B7 04 00      sta  $0400  ; 5~
        ; Decrement X (($13).w parameter) and if not expired, jump
        FB03: 09            dex    ; 4~
        FB04: 27 03         beq  $FB09  ; 4~ not taken
        ; {
            FB06: 7E 00 16      jmp  $0016  ; 3~
        ; }
    ; }
    ; Else if expired, return
    FB09: 39            rts  ; 5~
; }

; Copy memory
;
; Params:
;  x.w: src address
;  ($f).w: dest address
;  b.b: count of bytes to copy (0 means 256 bytes)
;
; Returns:
;  ($f).w: end of dest
; {
    ; save a
    FB0A: 36            psha   ; 4~
    ; {
        ; get first value from struct then save struct address at $d
        ; load src value from x pointer
        FB0B: A6 00         lda  (x+$00)  ; 5~
        ; save src pointer, load dest pointer
        FB0D: DF 0D         stx  $0D  ; 5~
        FB0F: DE 0F         ldx  $0F  ; 4~
        ; store value in dest
        FB11: A7 00         sta  (x+$00)  ; 6~
        ; increment dest pointer, save dest pointer
        FB13: 08            inx    ; 4~
        FB14: DF 0F         stx  $0F  ; 5~
        ; restore src pointer, increment src pointer
        FB16: DE 0D         ldx  $0D  ; 4~
        FB18: 08            inx    ; 4~
        ; decrement byte count, loop if not finished
        FB19: 5A            decb   ; 2~
        FB1A: 26 EF         bne  $FB0B  ; 4~
    ; }
    ; restore a
    FB1C: 32            pula   ; 4~
    FB1D: 39            rts    ; 5~

    ; total cycles:
    ;  4 + b*43 + 9
; }

; sub
; Handler B vector 5
; silent?
FB1E: 4F            clra 
FB1F: 97 04         sta  $04
FB21: 97 05         sta  $05
FB23: 39            rts  

; sub
; Handler B vector 2
; (not defender) quiet wobble
; {
    ;
    FB24: 7F 00 04      clr  $0004

    ; Mask ($5).b to lowest 7 bits,
    ; and increment it with wrap around to stay in range [1 .. 28]
    FB27: 96 05         lda  $05
    FB29: 84 7F         anda #$7F
    FB2B: 81 1D         cmpa #$1D
    FB2D: 26 01         bne  $FB30
    FB2F: 4F            clra 
    FB30: 4C            inca 
    FB31: 97 05         sta  $05
    ; (used as a parameter for speed/depth of wobble)

    ; [($5).b not being 0 means we'll continue at FB34 shortly]
    FB33: 39            rts  
; }

; Variant on handler A (for "(not defender) quiet wobble")
; {
    ; Call handler A preparation
    FB34: 86 0E         lda  #$0E
    FB36: BD FB 81      jsr  $FB81

    ; Multiply parameter at ($5).b by 4, complement,
    ; then jump into middle of handler A, where that value will be used as the sample period bias
    ; (instead of accepting the default 0 value for that from the preparation function)
    FB39: 96 05         lda  $05
    FB3B: 48            asla 
    FB3C: 48            asla 
    FB3D: 43            coma 

    FB3E: BD FC 39      jsr  $FC39
    ; {
        FB41: 7C 00 17      inc  $0017  ; 6~
        ; jump into middle of handler A
        FB44: BD FC 3B      jsr  $FC3B  ; 9~
        FB47: 20 F8         bra  $FB41  ;
    ; }
; }

; sub
; Handler B vector 0
; (not defender) electric sound
; {
    ; Call handler C preparation sub, choosing record number 3
    FB49: 86 03         lda  #$03
    FB4B: BD F8 2A      jsr  $F82A

    ; Increment ($6).b, with wrap around to stay in range [1 .. 31]
    FB4E: D6 06         ldb  $06
    FB50: C1 1F         cmpb #$1F
    FB52: 26 01         bne  $FB55
    ; {
        FB54: 5F            clrb 
    ; }
    FB55: 5C            incb 
    FB56: D7 06         stb  $06

    ; A = 32 - B
    FB58: 86 20         lda  #$20
    FB5A: 10            sba  

    ; Set ($13).b (first byte of Handler C's record argument) to
    ;  Clear B
    FB5B: 5F            clrb 
    ;  While A > 20, add 14 to B and decrement A
    ;  ie. B = (A - 20) * 14, and clamp A at upper bound of 20
    FB5C: 81 14         cmpa #$14
    FB5E: 23 05         bls  $FB65
    ; {
        FB60: CB 0E         addb #$0E
        FB62: 4A            deca 
        FB63: 20 F7         bra  $FB5C
    ; }

    ;  While A > 0, add 5 to B and decrement A
    ;  ie. B += A * 5
    ; {
        FB65: CB 05         addb #$05
        FB67: 4A            deca 
        FB68: 26 FB         bne  $FB65
    ; }

    FB6A: D7 13         stb  $13

    ; Call handler C synth, repeatedly
    ; {
        FB6C: BD F8 3F      jsr  $F83F
        FB6F: 20 FB         bra  $FB6C
    ; }
; }

; sub
; Handler B vector 4
; (robotron) bubble
; {
    FB71: 96 07         lda  $07
    FB73: 26 09         bne  $FB7E
    ; {
        ; Set handler A early exit flag
        FB75: 7C 00 07      inc  $0007

        ; Call handler A preparation to set sound number $d
        FB78: 86 0D         lda  #$0D
        FB7A: 8D 05         bsr  $FB81

        ; Call handler A synth
        FB7C: 20 69         bra  $FBE7
    ; }

    ; Call handler A synth from after early exit point
    FB7E: 7E FC 2E      jmp  $FC2E

; sub
; Handler A preparation
; 7 byte preparation records from the table at $feec ...
;
; Params:
;  a.b: Sound number, [0 .. 13]
; {
    ; Set x to the start of the sound preparation record
    ;  a *= 7
    FB81: 16            tab  
    FB82: 58            aslb 
    FB83: 1B            aba  
    FB84: 1B            aba  
    FB85: 1B            aba  
    ;  x = #$feec + a
    FB86: CE FE EC      ldx  #$FEEC
    FB89: BD FD 21      jsr  $FD21  ; x.w += a.b

    ; Get record[0]
    ; save high nibble (overall number of times to repeat) in $13
    ; save low nibble (number of times to play waveform per period curve delay value) in $14
    FB8C: A6 00         lda  (x+$00)
    FB8E: 16            tab  
    FB8F: 84 0F         anda #$0F
    FB91: 97 14         sta  $14
    FB93: 54            lsrb 
    FB94: 54            lsrb 
    FB95: 54            lsrb 
    FB96: 54            lsrb 
    FB97: D7 13         stb  $13

    ; Get record[1]
    ; save high nibble (number of decay repetitions) in $15
    ; save low nibble (waveform number) in $11
    FB99: A6 01         lda  (x+$01)
    FB9B: 16            tab  
    FB9C: 54            lsrb 
    FB9D: 54            lsrb 
    FB9E: 54            lsrb 
    FB9F: 54            lsrb 
    FBA0: D7 15         stb  $15
    FBA2: 84 0F         anda #$0F
    FBA4: 97 11         sta  $11

    ; Save preparation record address for now
    FBA6: DF 0B         stx  $0B

    ; Skip through waveform records at $fe4d,
    ; to desired one (selected in ($11)) 
    FBA8: CE FE 4D      ldx  #$FE4D
    ; {
        FBAB: 7A 00 11      dec  $0011
        FBAE: 2B 08         bmi  $FBB8
        FBB0: A6 00         lda  (x+$00)
        FBB2: 4C            inca 
        FBB3: BD FD 21      jsr  $FD21  ; x.w += a.b
        FBB6: 20 F3         bra  $FBAB
    ; }
    ; Save address of ROM waveform record at $18
    ; as src param, call sub to copy waveform record to $0024
    ; (also acts as src param to sub $FC87 below)
    FBB8: DF 18         stx  $18
    FBBA: BD FC 75      jsr  $FC75

    ; Restore preparation record address,
    ; get record[2].b (count of subtractions), and store it in ($1A),
    ; call decay sub
    FBBD: DE 0B         ldx  $0B
    FBBF: A6 02         lda  (x+$02)
    FBC1: 97 1A         sta  $1A
    FBC3: BD FC 87      jsr  $FC87

    ; Restore preparation record address,
    ; get record[3].b and store it in ($16).b,
    ; get record[4].b and store it in ($17).b
    FBC6: DE 0B         ldx  $0B
    FBC8: A6 03         lda  (x+$03)
    FBCA: 97 16         sta  $16
    FBCC: A6 04         lda  (x+$04)
    FBCE: 97 17         sta  $17

    ; + Get start of period curve in ($1b).w,
    ;   end of it in ($1d).w,
    ;   and clear $0023 (sample period bias) {{{

    ; Get selected area length (record[5].b) in b
    FBD0: A6 05         lda  (x+$05)
    FBD2: 16            tab  
    ; Get period curves area start (#$ff55) in x, add start offset (record[6].b) to it
    FBD3: A6 06         lda  (x+$06)
    FBD5: CE FF 55      ldx  #$FF55
    FBD8: BD FD 21      jsr  $FD21  ; x.w += a.b
    ; Get selected area length back in a
    FBDB: 17            tba  
    ; Store earlier selected area start result to ($1b).w
    FBDC: DF 1B         stx  $1B
    ; clear $0023 (sample period bias)
    FBDE: 7F 00 23      clr  $0023
    ; Add selected area length from a to area start in x to get end position and store in ($1d).w
    FBE1: BD FD 21      jsr  $FD21  ; x.w += a.b
    FBE4: DF 1D         stx  $1D

    ; + }}}

    FBE6: 39            rts  
; }

; sub
; Handler A synth
; {
    ; For ...
    ; // while (true)
    ; {
        ; Copy from ($13).b (record[0].b first nibble) to ($22).b
        ; use as counter to repeat next block that many times
        ; (successively decaying plays)
        FBE7: 96 13         lda  $13
        FBE9: 97 22         sta  $22
        ; {
            ; Recall start of period curve from ($1b).w to ($d).w, then
            ; for each period in period curve, using ($d).w as iterator
            FBEB: DE 1B         ldx  $1B
            FBED: DF 0D         stx  $0D
            ; {
                ; Get current period from period curve,
                ; add period bias from ($23).b (initially 0) to it and store result in ($21).b
                FBEF: DE 0D         ldx  $0D
                FBF1: A6 00         lda  (x+$00)
                FBF3: 9B 23         adda $23
                FBF5: 97 21         sta  $21

                ; If period curve iterator in x has reached its end, break
                ; [probably would have been better to do this at the top of the loop]
                FBF7: 9C 1D         cmpx $1D
                FBF9: 27 26         beq  $FC21

                ; Get record[0].b second nibble in B
                ; (number of times to play waveform per period)
                FBFB: D6 14         ldb  $14

                ; Increment period curve iterator and save it
                ; [this would have been better above too]
                FBFD: 08            inx  
                FBFE: DF 0D         stx  $0D

                ; For each time that want to play waveform per period
                ; // while (true)
                ; {
                    ; Get the waveform start in x
                    FC00: CE 00 24      ldx  #$0024

                    ; Play whole of waveform once
                    ; with each sample at the current period from ($21).b
                    ; {
                        ; Delay by value from ($21).b
                        ; (from the period curve, plus initially zero period bias at $23)
                        FC03: 96 21         lda  $21
                        ; {
                            FC05: 4A            deca 
                            FC06: 26 FD         bne  $FC05
                        ; }

                        ; Get value from waveform and send to DAC
                        FC08: A6 00         lda  (x+$00)
                        FC0A: B7 04 00      sta  $0400

                        ; Increment waveform pointer, if not reached end yet then jump back
                        FC0D: 08            inx  
                        FC0E: 9C 1F         cmpx $1F
                        FC10: 26 F1         bne  $FC03
                    ; }

                    ; Decrement "number of times to play waveform per period" counter in B (from record[0].b second nibble and $14),
                    ;  if reached zero then break
                    ;   (outer loop also ends immediately and will jump back to get the next period value)
                    FC12: 5A            decb 
                    FC13: 27 DA         beq  $FBEF  ;  // break;

                    ; Wait a little time,
                    ; between the repeated waveforms at this period curve value
                    FC15: 08            inx  
                    FC16: 09            dex  
                    FC17: 08            inx  
                    FC18: 09            dex  
                    FC19: 08            inx  
                    FC1A: 09            dex  
                    FC1B: 08            inx  
                    FC1C: 09            dex  
                    FC1D: 01            nop  
                    FC1E: 01            nop  

                    ; Loop to play the waveform again with the same value from the period curve
                    FC1F: 20 DF         bra  $FC00
                ; }
            ; }

            ; Get number of decay repetitions from ($15).b, and apply decay to RAM copy of waveform
            FC21: 96 15         lda  $15
            FC23: 8D 62         bsr  $FC87

            ; Repeat this loop ($22).b times (which was initialized from record[0].b first nibble)
            FC25: 7A 00 22      dec  $0022
            FC28: 26 C1         bne  $FBEB
        ; }


        ; Early exit
        ; If ($07).b is not 0 then rts [always is 0 I think so this never rts's]
        ; ($07).b is not a direct part of the Handler A setup
        ; So ($07).b is an external disable switch for this kind of repetition
        FC2A: 96 07         lda  $07
        FC2C: 26 46         bne  $FC74


        ; Get ($16).b (record[3].b) (sample period bias increment) in A and if 0 then rts
        FC2E: 96 16         lda  $16
        FC30: 27 42         beq  $FC74

        ; Decrement ($17).b (record[4].b), if 0 then rts
        FC32: 7A 00 17      dec  $0017
        FC35: 27 3D         beq  $FC74

        ; Add A (record[3].b) to ($23).b (the sample period bias)
        FC37: 9B 23         adda $23
        ; sub
        ;
        ; Params:
        ;  a.b:
        ;   ...
        ;
        FC39: 97 23         sta  $23

        ; sub
        ;
        ; Params:
        ;  ($23).b:
        ;   ...
        ;
        ; Get start of period curve in x
        FC3B: DE 1B         ldx  $1B  ; 4~
        ; Clear B
        ; When 0, change start of period curve if want to
        ; Else (when 1), change end of period curve if want to
        ; (first byte of period curve which will not lead to over or under flow is fixed as the new start)
        FC3D: 5F            clrb   ; 2~

        ; (in loop $FC3E-$FC5F) For every period curve value
        ; {
            ; Get sample period bias
            FC3E: 96 23         lda  $23  ; 3~

            ; Test record[3].b (sample period bias increment)
            ;
            ; If sample period bias increment is positive [or 0, though would have exited above in this case],
            ; add current period curve value to the current period bias in A
            ; to find out what it would be in the normal loop above, and
            ;  if it's reached max (ie. 256 or beyond) goto $FC51 (next period or change end of period curve)
            ;  else if didn't reach max yet goto $FC56 (change start of period curve, if B is 0)
            FC40: 7D 00 16      tst  $0016  ; 6~
            FC43: 2B 06         bmi  $FC4B  ; 4~
            ; {
                FC45: AB 00         adda (x+$00)  ; 5~
                FC47: 25 08         bcs  $FC51  ; 4~
                FC49: 20 0B         bra  $FC56  ; 4~
            ; }
            ; Else if sample period bias increment is negative
            ; add current period curve value to the current period bias in A
            ; to find out what it would be in the normal loop above, and
            ;  if it's reached min (ie. 0 or beyond) goto $FC51 (next period or change end of period curve)
            ;  else if didn't reach max yet goto $FC56 (change start of period curve, if B is 0)
            ; {
                FC4B: AB 00         adda (x+$00)  ; 5~
                FC4D: 27 02         beq  $FC51  ; 4~  ;; if hit 0, or gone negative  ; [probably should be bcc]
                FC4F: 25 05         bcs  $FC56  ; 4~  ;; if not yet reached 0  ; [probably should be bra]
            ; }

            ; "next period or change end of period curve"
            ; Jump from above: current period curve value hit max from below or min from above
            ; If B is 0 (initially it is) goto $FC5C (just continue the loop with the next period)
            ; else goto $FC65 (change end of period curve) (which is actually outside the current 'loop')
            FC51: 5D            tstb   ; 2~
            FC52: 27 08         beq  $FC5C  ; 4~
            FC54: 20 0F         bra  $FC65  ; 4~

            ; "maybe change start of period curve"
            ; Jump from above: current period curve value did not hit max or min yet
            ; If B is 0 (initially it is) (ie. first value in period curve this time that doesn't
            ; over/underflow), run block
            ; which changes start of period curve to start from here in future
            ; else continue to $FC5C (just continue the loop with the next period)
            FC56: 5D            tstb   ; 2~
            FC57: 26 03         bne  $FC5C  ; 4~
            ; {
                FC59: DF 1B         stx  $1B  ; 5~
                ;; Set flag to not do this again next time
                FC5B: 5C            incb    ; 2~
            ; }

            ; "just continue the loop with the next period"
            ; Jump from above: current period curve value hit max from below or min from above, and B was 0
            ; Increment period curve iterator in x
            ; and loop back if it has not reached end of data
            FC5C: 08            inx    ; 4~
            FC5D: 9C 1D         cmpx $1D  ; 4~
            FC5F: 26 DD         bne  $FC3E  ; 4~
        ; }

        ; If B is 0 (if didn't find any byte in period curve which will not lead to over or under flow),
        ; rts
        FC61: 5D            tstb   ; 2~
        FC62: 26 01         bne  $FC65  ; 4~
        ; {
            FC64: 39            rts    ; 5~
        ; }

        ; Jump from above: current period curve value hit max from below or min from above, and B was not 0:
        ;  change end of period curve to end here in future
        ; Flow from end of above loop: 
        ;  'change' end of period curve to same value as it already was
        FC65: DF 1D         stx  $1D  ; 5~

        ; If number of decay repetitions is not 0,
        ; recopy waveform from ROM to RAM
        ; and do one decay
        FC67: 96 15         lda  $15  ; 3~
        FC69: 27 06         beq  $FC71  ; 4~
        ; {
            FC6B: 8D 08         bsr  $FC75  ; 8~
            FC6D: 96 1A         lda  $1A  ; 3~
            FC6F: 8D 16         bsr  $FC87  ; 8~
        ; }

        ; Loop back to start of sub
        FC71: 7E FB E7      jmp  $FBE7
    ; }
    FC74: 39            rts  
; }


; Copy waveform record from ROM to RAM
;
; Copy waveform record (not including its embedded length) to memory starting at $24
; Put address of waveform end in ($1F).w
;
; Used by:
;  Handler A
;
; Params:
;  ($18).w:
;   Waveform record address in ROM
; {
    ; Setup dest, src and byte count params, call copy memory sub
    FC75: CE 00 24      ldx  #$0024  ; 3~
    FC78: DF 0F         stx  $0F  ; 5~
    FC7A: DE 18         ldx  $18  ; 4~
    FC7C: E6 00         ldb  (x+$00)  ; 5~
    FC7E: 08            inx  ; 4~
    FC7F: BD FB 0A      jsr  $FB0A  ; 9~
    ; fb0a subroutine cycles:
    ;  4 + b*43 + 9

    ; Store end of dest copy in ($1F)
    FC82: DE 0F         ldx  $0F  ; 4~
    FC84: DF 1F         stx  $1F  ; 5~
    FC86: 39            rts    ; 5~

    ; total cycles:
    ;  30 + (4 + waveform_length*43 + 9) + 14
; }

; Decay waveform
;
; Subtract high nibble of ROM waveform from RAM copy of waveform,
; some number of times
;
; Used by:
;  Handler A
;
; Params:
;  a.b:
;   Count of subtractions
;  ($18).w:
;   Waveform address in ROM
; {
    ; If don't want any subtractions then return doing nothing
    FC87: 4D            tsta 
    FC88: 27 2B         beq  $FCB5

    ; Get ROM waveform address, store address in ($d)
    ; ($d).w: ROM waveform iterator
    FC8A: DE 18         ldx  $18
    FC8C: DF 0D         stx  $0D
    ; Get place in RAM where data of RAM waveform may be copied, (inside loop) store it in ($f)
    ; ($f).w: RAM waveform iterator
    FC8E: CE 00 24      ldx  #$0024
    ; Store count of subtractions in ($12)
    FC91: 97 12         sta  $12
    ; {
        ; Save address of RAM waveform
        FC93: DF 0F         stx  $0F
        ; Retrieve ROM waveform iterator in x
        FC95: DE 0D         ldx  $0D
        ; Copy count of subtractions argument from ($12).b to ($11).b
        FC97: D6 12         ldb  $12
        FC99: D7 11         stb  $11
        ; Get current byte of ROM waveform and isolate high nibble
        FC9B: E6 01         ldb  (x+$01)
        FC9D: 54            lsrb 
        FC9E: 54            lsrb 
        FC9F: 54            lsrb 
        FCA0: 54            lsrb 
        ; Increment ROM waveform iterator in x and save it
        FCA1: 08            inx  
        FCA2: DF 0D         stx  $0D
        ; Restore address of RAM waveform
        FCA4: DE 0F         ldx  $0F

        ; Subtract high nibble of current ROM waveform byte,
        ; from current RAM waveform byte, A times
        ; ie. waveform value - (high nibble of waveform value * a)
        FCA6: A6 00         lda  (x+$00)
        ; {
            FCA8: 10            sba  
            FCA9: 7A 00 11      dec  $0011
            FCAC: 26 FA         bne  $FCA8
        ; }
        ; Write value back to RAM
        FCAE: A7 00         sta  (x+$00)
        FCB0: 08            inx  
        ; Repeat till got to end of waveform
        FCB1: 9C 1F         cmpx $1F
        FCB3: 26 DE         bne  $FC93
    ; }
    FCB5: 39            rts  
; }

; sub: switchboard
; {
    ; Set stack base at $7f
    FCB6: 8E 00 7F      lds  #$007F

    ; Get sound number from $402 in A, complemented and masked to 0..31
    FCB9: B6 04 02      lda  $0402
    FCBC: 0E            cli  
    FCBD: 43            coma 
    FCBE: 84 1F         anda #$1F

    ; [Think this might be for music]
    ; Get ($08).b, and if not 0
    FCC0: D6 08         ldb  $08
    FCC2: 27 09         beq  $FCCD
    ; {
        ; If ($08).b < 0 [in practice, -1],
        ; A is song number to play,
        ;  1: 3 descending notes
        ;  2: bach
        ;  so call play tune sub
        FCC4: 2A 03         bpl  $FCC9
        ; {
            FCC6: BD FA 48      jsr  $FA48
        ; }

        ; Else if the ($08).b switch was turned on but with a positive number,
        ; decrement A and call the other 'play tune' sub
        FCC9: 4A            deca 
        FCCA: BD FA 89      jsr  $FA89
    ; }

    ; Clear b, then
    FCCD: 5F            clrb 

    ; if a != 14 (decremented later to 13, ie. handler B "(not defender) electric sound"),
    ; store b (ie. 0) in $6
    FCCE: 81 0E         cmpa #$0E
    FCD0: 27 02         beq  $FCD4
    ; {
        FCD2: D7 06         stb  $06
    ; }

    ; if a != 18 (decremented later to 17, ie. handler B "(robotron) bubble"),
    ; store b (ie. 0) in $7
    FCD4: 81 12         cmpa #$12
    FCD6: 27 02         beq  $FCDA
    ; {
        FCD8: D7 07         stb  $07
    ; }

    ; if $effd = $7e, jsr there
    FCDA: F6 EF FD      ldb  $EFFD
    FCDD: C1 7E         cmpb #$7E
    FCDF: 26 03         bne  $FCE4
    ; {
        FCE1: BD EF FD      jsr  $EFFD
    ; }

    ; if a != 0
    FCE4: 4D            tsta 
    FCE5: 27 27         beq  $FD0E  ; to class 2 sounds
    ; {
        ;
        FCE7: 4A            deca 

        ; At this point, A:
        ;  handler A at $fb81, $fbe7
        ;   $0: bomber die
        ;   $1: (not defender)
        ;   $2: lander shoot
        ;   $3: mutant shoot (angrier)
        ;   $4: pod die
        ;   $5: lander die
        ;   $6: swarmer die
        ;   $7: humanoid catch (one cycle only)
        ;   $8: mutant shoot
        ;   $9: game start
        ;   $a: humanoid scream
        ;   $b: swarmer shoot
        ;   $c: (robotron) get human
        ;  handler B, from table
        ;   $d: (not defender) electric sound
        ;   $e: thrust quiet
        ;   $f: (not defender) quiet wobble
        ;   $10: mutant spawn
        ;   $11: (robotron) bubble
        ;   $12: silent?
        ;   $13: player shoot
        ;   $14: lander spawn
        ;   $15: thrust loud
        ;   $16: end of explosion (player death, smart bomb)
        ;   $17: (robotron) hiscore aliased sweep
        ;   $18: insert credit
        ;   $19: humanoid fall
        ;   $1a: silent?
        ;   $1b: silent?
        ;  handler C, preparation sub at $f82a, synth sub at $f83f
        ;   $1c: (robotron) sound
        ;   $1d: extra life
        ;   $1e: boot / drop humanoid sound

        ; Class 1 sounds

        ; if a <= $c
        FCE8: 81 0C         cmpa #$0C
        FCEA: 22 08         bhi  $FCF4
        ; {
            ; Call handler A
            FCEC: BD FB 81      jsr  $FB81
            FCEF: BD FB E7      jsr  $FBE7
            FCF2: 20 1A         bra  $FD0E  ; to class 2 sounds
        ; }
        ; else if a > $c, if a <= $1b
        FCF4: 81 1B         cmpa #$1B
        FCF6: 22 0E         bhi  $FD06
        ; {
            ; Call handler B
            ; rebase at $d and look up jump vector from table at $fd58, and call it
            FCF8: 80 0D         suba #$0D
            FCFA: 48            asla 
            FCFB: CE FD 58      ldx  #$FD58
            FCFE: 8D 21         bsr  $FD21  ; x.w += a.b
            ; Get the address stored at (x) and call it
            FD00: EE 00         ldx  (x+$00)
            FD02: AD 00         jsr  (x+$00)
            FD04: 20 08         bra  $FD0E  ; to class 2 sounds
        ; }
        ; else // if a > $1b
        ; {
            ; Call handler C
            ; rebase at $1c, do a memory copy, and call handler C preparation and synth subs
            FD06: 80 1C         suba #$1C
            FD08: BD F8 2A      jsr  $F82A
            FD0B: BD F8 3F      jsr  $F83F
        ; }

        ; End of class 1 sounds
    ; }


    ; Class 2 sounds

    ; If ($4).b and ($5).b are 0,
    ; wait at FD12 until sound is needed (guess other CPU moves the PC of this one via an interrupt or something)
    FD0E: 96 04         lda  $04
    FD10: 9A 05         ora  $05
    FD12: 27 FE         beq  $FD12
    ; Else if either ($4).b or ($5).b is not 0,

    ; Clear ($7).b (disable 'early exit' in handler A)
    FD14: 4F            clra 
    FD15: 97 07         sta  $07

    ; If ($4).b != 0
    FD17: 96 04         lda  $04
    FD19: 27 03         beq  $FD1E
    ; {
        FD1B: 7E F9 13      jmp  $F913  ; Handler B vector 1 (thrust quiet)
    ; }
    ; else if ($5).b != 0
    ; {
        FD1E: 7E FB 34      jmp  $FB34  ; Variant on handler A
    ; }
; }


; Add 8 bit number to 16 bit number
;
; Params:
;  x.w: base address
;  a.b: offset
; Returns:
;  x.w: base address + offset
; {
    ; At $D.w store x + a
    FD21: DF 0D         stx  $0D  ; 5~
    ; Add low byte
    FD23: 9B 0E         adda $0E  ; 3~
    FD25: 97 0E         sta  $0E  ; 4~
    ; Apply carry
    FD27: 24 03         bcc  $FD2C  ; 4~ taken
    ; {
        FD29: 7C 00 0D      inc  $000D
    ; }
    ; Get result back in x
    FD2C: DE 0D         ldx  $0D  ; 4~
    FD2E: 39            rts  ; 5~
; }
; total cycles 25 if branch taken

; sub
; [not sure where called from]
FD2F: 0F            sei  
; Setup stack
FD30: 8E 00 7F      lds  #$007F
;
FD33: CE FF FF      ldx  #$FFFF
FD36: 5F            clrb 
FD37: E9 00         adcb (x+$00)
FD39: 09            dex  
FD3A: 8C F8 00      cmpx #$F800
FD3D: 26 F8         bne  $FD37
FD3F: E1 00         cmpb (x+$00)
FD41: 27 01         beq  $FD44
FD43: 3E            wai  
; Call handler C preparation sub, choosing record 1, then call synth sub
FD44: 86 01         lda  #$01
FD46: BD F8 2A      jsr  $F82A
FD49: BD F8 3F      jsr  $F83F
;
FD4C: F6 EF FA      ldb  $EFFA
FD4F: C1 7E         cmpb #$7E
FD51: 26 DC         bne  $FD2F
FD53: BD EF FA      jsr  $EFFA
FD56: 20 D7         bra  $FD2F

; Handler B vector table
; 15 vectors
FD58: FB 49  ; $d: (not defender) electric sound
FD5A: F9 13  ; $e: quiet thrust
FD5C: FB 24  ; $f: (not defender) quiet wobble
FD5E: F8 8C  ; $10: mutant spawn
FD60: FB 71  ; $11: (robotron) bubble
FD62: FB 1E  ; $12: silent?
FD64: F8 CD  ; $13: player shoot
FD66: F8 94  ; $14: lander spawn
FD68: F9 1C  ; $15: loud thrust
FD6A: F9 23  ; $16: (robotron) explosion
FD6C: F9 A6  ; $17: (robotron) hiscore aliased sweep
FD6E: F9 D4  ; $18: insert credit
FD70: F9 F3  ; $19: humanoid fall
FD72: FA 44  ; $1a: silent?
FD74: FA 84  ; $1b: silent?

; handler C preparation records
;
; From one of these records
;  [0].b
;   working copy goes to $1C
;   length of low part of sound wave
;  [1].b
;   working copy goes to $1D
;   length of high part of sound wave
;
;  [2].b
;   increment for low part of sound wave
;  [3].b
;   increment for high part of sound wave
;
;  [4].b
;   end when high part of sound wave reaches this
;
;  [5].w
;   large number length counter
;   total number of samples in one timbre formed by current record[0] and [1]
;
;  [7].b
;   in outermost repetition loop,
;   increment to record[0].b, length of low part of sound wave
;   no more loops when record[0].b thus reaches 0
;   if this is 0, don't do this type of repetition
;   typically the period of this loop is in some tenths of seconds
;
;  [8].b
;   volume

; $1c: enforcer fire (robotron)
FD76: 40 01  00 10  E1  00 80  FF  FF
; $1d: extra life sound
FD7F: 28 01  00 08  81  02 00  FF  FF
; $1e: boot / drop humanoid sound
FD88: 28 81  00 FC  01  02 00  FC  FF
; Used via handler B vector 0 (new level (robotron))
FD91: FF 01  00 18  41  04 80  00  FF


; Wavetable for handler B vector 10
FD9A: 8C 5B B6 40 BF 49 A4 73
FDA2: 73 A4 49 BF 40 B6 5B 8C

; + Music {{{

; Each note is 4 bytes:
;  0.b:
;   Timbre bitmask
;  1.b:
;   Note period
;  2.w:
;   Note length

; Song 1
FDAA: 0C  ; song byte count
FDAB: 7F 1D 0F FB
FDAF: 7F 23 0F 15
FDB3: FE 08 50 8B
; Song 2
FDB7: 88  ; song byte count
FDB8: 3E 3F 02 3E
FDBC: 7C 04 03 FF
FDC0: 3E 3F 2C E2
FDC4: 7C 12 0D 74
FDC8: 7C 0D 0E 41
FDCC: 7C 23 0B 50
FDD0: 7C 1D 29 F2
FDD4: 7C 3F 02 3E
FDD8: F8 04 03 FF
FDDC: 7C 3F 2C E2
FDE0: F8 12 0D 74
FDE4: F8 0D 0E 41
FDE8: F8 23 0B 50
FDEC: F8 1D 2F F2
FDF0: F8 23 05 A8
FDF4: F8 12 06 BA
FDF8: F8 04 07 FF
FDFC: 7C 37 04 C1
FE00: 7C 23 05 A8
FE04: 7C 12 06 BA
FE08: 3E 04 07 FF
FE0C: 3E 37 04 C1
FE10: 3E 23 05 A8
FE14: 1F 12 06 BA
FE18: 1F 04 07 FF
FE1C: 1F 37 04 C1
FE20: 1F 23 16 A0
FE24: FE 1D 17 F9
FE28: 7F 37 13 06
FE2C: 7F 3F 08 FA
FE30: FE 04 0F FF
FE34: FE 0D 0E 41
FE38: FE 23 0B 50
FE3C: FE 1D 5F E4
; Songs end marker
FE40: 00

; Note pitches x 12
FE41: 47 3F 37 30 29 23 1D 17 12 0D 08 04

; + }}}

; + Waveforms {{{

; struct
; Handler A waveforms
; first byte in each record is length of record
; 0: sine
FE4D: 08 7F D9 FF D9 7F 24 00 24
; 1: triangle fragments?
FE56: 08 00 40 80 00 FF 00 80 40
; 2: sine
FE5F: 10 7F B0 D9 F5 FF F5 D9 B0 7F 4E 24 09 00 09 24 4E
; 3: sine plus one harmonic
FE70: 10 7F C5 EC E7 BF 8D 6D 6A 7F 94 92 71 40 17 12 39
; 4: square
FE81: 10 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00
; 5: sine
FE92: 48 8A 95 A0 AB B5 BF C8 D1 DA E1 E8 EE F3 F7 FB FD FE FF FE FD FB F7 F3 EE E8 E1 DA D1 C8 BF B5 AB A0 95 8A 7F 75 6A 5F 54 4A 40 37 2E 25 1E 17 11 0C 08 04 02 01 00 01 02 04 08 0C 11 17 1E 25 2E 37 40 4A 54 5F 6A 75 7F
; 6: sine
FEDB: 10 59 7B 98 AC B3 AC 98 7B 59 37 19 06 00 06 19 37

; + }}}

; array of struct
; Handler A preparation records
;
; From one of these records
;  [0].b high nibble
;   goes to $13
;   overall number of times to repeat
;  [0].b low nibble
;   goes to $14
;   number of times to play waveform per period curve delay value (with a small delay in between)
;   ie. speed
;  [1].b high nibble
;   goes to $15
;   number of decay repetitions
;  [1].b low nibble
;   goes to $11
;   waveform number (actual waveforms located at $FE4D)
;  [2].b
;   decay speed (count of subtractions in $FC87 sub)
;
;  [3].b
;   goes to $16
;   change to per-sample period in successive outer replays
;   has values 00, 01, FF, FD
;   0 means don't do this kind of repetition
;  [4].b
;   goes to $17
;   overall number of successive outer replays with per-sample period changed by [3].b
;   has values 00, 01, 02, 0F, 10
;   0 means 256 replays
;
;  [5].b
;   length within $FF55 waveform fragments area
;   $FF55 + this + [5].b goes to ($1d).w
;  [6].b
;   start position within $FF55 waveform fragments area
;   $FF55 + this goes to ($1b).w
; {
    ;   $0: bomber die
    FEEC: 81 24 00  00 00  16 31
    ;   $1: (not defender)
    FEF3: 12 05 1A  FF 00  27 6D
    ;   $2: lander shoot
    FEFA: 11 05 11  01 0F  01 47
    ;   $3: mutant shoot (angrier)
    FF01: 11 31 00  01 00  0D 1B
    ;   $4: pod die
    FF08: F4 12 00  00 00  14 47
    ;   $5: lander die
    FF0F: 41 45 00  00 00  0F 5B
    ;   $6: swarmer die
    FF16: 21 35 11  FF 00  0D 1B
    ;   $7: humanoid catch (one cycle only)
    FF1D: 15 00 00  FD 00  01 69
    ;   $8: mutant shoot
    FF24: 31 11 00  01 00  03 6A
    ;   $9: game start
    FF2A: 01 15 01  01 01  01 47
    ;   $a: humanoid scream
    FF32: F6 53 03  00 02  06 94
    ;   $b: swarmer shoot
    FF39: 6A 10 02  00 02  06 9A
    ;   $c: (robotron) get human
    FF40: 1F 12 00  FF 10  04 69
    ;   $d: used via Handler B vector 4 (robotron bubble)
    FF47: 31 11 00 FF 00 0D 00
    ;   $e: used via Handler B vector 2 (not defender) quiet wobble -> variant on handler A at $FB34
    FF4E: 12 06 00 FF 01 09 28
; }

; Period curves area
; A bunch of period (inverse of pitch) curves
; 160 bytes
FF55: A0 98 90 88 80 78 70 68
FF5D: 60 58 50 44 40 01 01 02
FF65: 02 04 04 08 08 10 10 30
FF6D: 60 C0 E0 01 01 02 02 03
FF75: 04 05 06 07 08 09 0A 0C
FF7D: 80 7C 78 74 70 74 78 7C
FF85: 80 01 01 02 02 04 04 08
FF8D: 08 10 20 28 30 38 40 48
FF95: 50 60 70 80 A0 B0 C0 08
FF9D: 40 08 40 08 40 08 40 08
FFA5: 40 08 40 08 40 08 40 08
FFAD: 40 08 40 01 02 04 08 09
FFB5: 0A 0B 0C 0E 0F 10 12 14
FFBD: 16 40 10 08 01 01 01 01
FFC5: 01 02 02 03 03 04 04 05
FFCD: 06 08 0A 0C 10 14 18 20
FFD5: 30 40 50 40 30 20 10 0C
FFDD: 0A 08 07 06 05 04 03 02
FFE5: 02 01 01 01 07 08 09 0A
FFED: 0C 08 17 18 19 1A 1B 1C

FFF5: 00            illegal
FFF6: 00            illegal
FFF7: 00            illegal
FFF8: FC            illegal
FFF9: B6 F8 01      lda  $F801
FFFC: FD            illegal
FFFD: 2F F8         ble  $FFF7
FFFF: 01            nop  
0000: 00            illegal
