Commented by Peekin - Feburary 22nd, 2001

; 65816 SNES Disassembler   v2.0a (C)opyright 1994 by John Corey
; Begin: $00E7A3  End: $00E852
; Hirom: Yes Quiet: Yes Comments: 2  DCB: Yes Symbols: Yes 65816: Yes
00E7A3 20 43 E8      JSR $E843      ; get next byte
00E7A6 C9 FF         CMP #$FF       ; end of compressed stream if code = 0FFh
00E7A8 D0 03         BNE $E7AD      ; continue if any other code
00E7AA E2 10         SEP #$10       ; Index (8 bit)
00E7AC 60            RTS            ; end of compression routine
; get code and length (code is upper 3 bits, length is lower 5)
00E7AD 85 CD         STA $CD        ; save byte
00E7AF 29 E0         AND #$E0       ; get code (upper 3 bits)
00E7B1 C9 E0         CMP #$E0       ; special code for longer run count
00E7B3 F0 0A         BEQ $E7BF     
00E7B5 48            PHA            ; save code
00E7B6 A5 CD         LDA $CD        ; retrieve byte
00E7B8 C2 20         REP #$20       ; Accum (16 bit)
00E7BA 29 1F 00      AND #$001F     ; mask byte to get length (lower 5 bits)
00E7BD 80 12         BRA $E7D1
; long run count
00E7BF A5 CD         LDA $CD        ; retrieve byte
00E7C1 0A            ASL            ; shift byte left 3 times for new code
00E7C2 0A            ASL      
00E7C3 0A            ASL      
00E7C4 29 E0         AND #$E0       ; get new code (upper 3 bits)
00E7C6 48            PHA            ; save code
00E7C7 A5 CD         LDA $CD        ; retrieve original byte
00E7C9 29 03         AND #$03       ; select lowest two bits for count
00E7CB EB            XBA            ; save count's two msb in AH (*256)
00E7CC 20 43 E8      JSR $E843      ; read next byte for a total 10bit count
00E7CF C2 20         REP #$20     	; Accum (16 bit)
; depending on if the code was E0, the count will either be 0-63 or 0-1023
00E7D1 1A            INC            ; count++
00E7D2 85 CB         STA $CB        ; store count
00E7D4 E2 20         SEP #$20       ; Accum (8 bit)
00E7D6 68            PLA            ; retrieve code
00E7D7 F0 16         BEQ $E7EF      ; transfer bytes from source
00E7D9 30 4A         BMI $E825      ; transfer bytes from output buffer
00E7DB 0A            ASL      
00E7DC 10 20         BPL $E7FE      ; repeat single byte
00E7DE 0A            ASL      
00E7DF 10 2A         BPL $E80B      ; repeat two alternating bytes
; repeat single incrementing byte??
00E7E1 20 43 E8      JSR $E843      ; read single byte
00E7E4 A6 CB         LDX $CB        ; load count
00E7E6 97 00         STA [$00],Y    ; write byte
00E7E8 1A            INC            ; increment byte value??
00E7E9 C8            INY            ; destination ptr++
00E7EA CA            DEX            ; count--
00E7EB D0 F9         BNE $E7E6      ; loop while count <> 0
00E7ED 80 B4         BRA $E7A3      ; go to top of loop for next code
; transfer bytes directly
00E7EF 20 43 E8      JSR $E843      ; read next byte to transfer
00E7F2 97 00         STA [$00],Y    ; write byte
00E7F4 C8            INY            ; destination ptr++
00E7F5 A6 CB         LDX $CB        ; reload count (since ReadByte changed it)
00E7F7 CA            DEX            ; count--
00E7F8 86 CB         STX $CB        ; store count
00E7FA D0 F3         BNE $E7EF      ; loop while count <> 0
00E7FC 80 A5         BRA $E7A3      ; go to top of loop for next code
; repeat single byte
00E7FE 20 43 E8      JSR $E843      ; read single byte to repeat
00E801 A6 CB         LDX $CB        ; load count
00E803 97 00         STA [$00],Y    ; write byte
00E805 C8            INY            ; destination ptr++
00E806 CA            DEX            ; count--
00E807 D0 FA         BNE $E803      ; loop while count <> 0
00E809 80 98         BRA $E7A3      ; go to top of loop for next code
; repeat run of alternating even/odd bytes
00E80B 20 43 E8      JSR $E843      ; read first byte
00E80E EB            XBA            ; save first byte into AH
00E80F 20 43 E8      JSR $E843      ; read second byte
00E812 A6 CB         LDX $CB        ; load count
00E814 EB            XBA            ; swap first byte with second
00E815 97 00         STA [$00],Y    ; write first byte
00E817 C8            INY            ; destination ptr++
00E818 CA            DEX            ; count--
00E819 F0 07         BEQ $E822      ; exit loop if count = 0
00E81B EB            XBA            ; swap first byte with second
00E81C 97 00         STA [$00],Y    ; write second byte
00E81E C8            INY            ; destination ptr++
00E81F CA            DEX            ; count--
00E820 D0 F2         BNE $E814      ; loop while count <> 0
00E822 4C A3 E7      JMP $E7A3      ; go to top of loop for next code
; copy run of bytes already in output buffer to end
00E825 20 43 E8      JSR $E843      ; read low byte ptr
00E828 EB            XBA      
00E829 20 43 E8      JSR $E843      ; read high byte ptr
00E82C EB            XBA      
00E82D AA            TAX            ; copy buffer source to X
00E82E 5A            PHY            ; save destination ptr
00E82F 9B            TXY            ; move buffer source to Y for indexing
00E830 B7 00         LDA [$00],Y    ; read existing buffer byte
00E832 BB            TYX            ; copy back to X, why??
00E833 7A            PLY            ; retrieve destination ptr
00E834 97 00         STA [$00],Y    ; write byte
00E836 C8            INY            ; destination ptr++
00E837 E8            INX            ; buffer source++
00E838 C2 20         REP #$20       ; Accum (16 bit)
00E83A C6 CB         DEC $CB        ; count--
00E83C E2 20         SEP #$20       ; Accum (8 bit)
00E83E D0 EE         BNE $E82E      ; loop while count <> 0
00E840 4C A3 E7      JMP $E7A3      ; go to top of loop for next code
; read next byte
00E843 A7 C8         LDA [$C8]      ; read single byte from ROM
00E845 A6 C8         LDX $C8        ; load source ptr
00E847 E8            INX            ; source ptr++
00E848 D0 05         BNE $E84F      ; if not beyond end of bank
00E84A A2 00 80      LDX #$8000     ; wrap source to beginning of next bank
00E84D E6 CA         INC $CA        ; increment to next source bank
00E84F 86 C8         STX $C8        ; store source ptr
00E851 60            RTS            ; end of read byte
00E852 FF FF FF FF   SBC $FFFFFF,X  ; those familiar separating FF's

Compression Codes

Code Address Description
000..... 00E7EF transfer bytes from source<br/>transfer Count bytes after code to buffer
001..... 00E7FE repeat single byte<br/>read next byte and repeat Count times
010..... 00E80B repeat two alternating bytes<br/>read next two bytes and alternately repeat
011..... 00E7E1 repeat single incrementing byte<br/>read next byte and repeat incrementing each time
111..... 00E7BF long count<br/>bits 2-4 become 5-7 for the new code.<br/>bottom 2 bits become top two bits of count.<br/>read next byte for lower 8 bits of count +1.
1xx..... 00E825 transfer bytes from output buffer<br/>read next two bytes for buffer source pointer (low/high)
11111111 00E7AA end of compressed stream

Examples

Transfer bytes from source

03 12 34 56         -> 12 34 56

Repeat single byte

23 12               -> 12 12 12

Repeat two alternating bytes

45 12 34            -> 12 34 12 34 12

Repeat single incrementing byte

63 12               -> 12 13 14

Long count (followed by source transfer of 302h bytes)

E3 01 12 34 56 ..   -> 12 34 56 78 90 12 34 ...

Transfer byte from output buffer (starting at offset 4)

83 00 04            -> 90 12 34