The are 4 tiles compression methods:
- Direct transfer to VRAM via the tia instruction
- RLE compression
- RLE + XOR
- Copy to VRAM using a loop
Code: Select all
f796: LDA <$7d
ORA <$7e
BEQ f7e1
JSR f888
CMP #$00
BNE f7ac
; #1
TIA $3700, $0002, $0020
BRA f7d2
f7ac: CMP #$02
BNE f7bc
; #2
JSR f817
TIA $3700, $0002, $0020
BRA f7d2
f7bc: CMP #$03
BNE f7cf
; #3
JSR f817
JSR f857
TIA $3700, $0002, $0020
BRA f7d2
f7cf: ; #4
JSR f803
f7d2: LDA <$7d
SBC #$01
STA <$7d
LDA <$7e
SBC #$00
STA <$7e
BRA f796
f7e1:
The code above is more or less a simple switch/case.
The encoding type is store in 2 bits. It's packed in a byte. They are stored starting at $B0A3 (file offset $2f2a3). f888 is used to extract and store them in A.
Code: Select all
f888: LDX <$7f
CPX #$04
BNE f897
INC <$7a
BNE f894
INC <$7b
f894: STZ <$7f
CLX
f897: LDA [$7a]
f899: DEX
BMI f8a1
ROR A
ROR A
JMP f899
f8a1: AND #$03
INC <$7f
RTS
The "RLE" routine :
Code: Select all
f817: LDA [$78]
STA <$83
LDY #$04
LDA #$09
STA <$81
STZ <$80
CLX
LDA #$20
STA <$82
f828: DEC <$81
BNE f83a
PHY
LDA #$08
STA <$81
INC <$80
LDY <$80
LDA [$78], Y
STA <$83
PLY
f83a: ROR <$83 ; the rle counter
BCS f849
STZ $3740, X
INX
DEC <$82
BNE f828
JMP f7f6
f849: LDA [$78], Y
STA $3740, X
INY
INX
DEC <$82
BNE f828
JMP f7f6
The "XOR" routine:
Code: Select all
f857: PHX
PHY
LDY #$07
CLX
f85c: LDA $3740, X
EOR $3742, X
STA $3742, X
LDA $3741, X
EOR $3743, X
STA $3743, X
LDA $3750, X
EOR $3752, X
STA $3752, X
LDA $3751, X
EOR $3753, X
STA $3753, X
INX
INX
DEY
BNE f85c
PLY
PLX
RTS
And last but not least, the copy to VRAM loop:
Code: Select all
f803: CLY
f804: LDA [$78], Y
STA $0002
INY
LDA [$78], Y
STA $0003
INY
CPY #$20
BNE f804
JMP f7f6
For the curious ones here's f7f6:
Code: Select all
f7f6: TYA
CLC
ADC <$78
STA <$78
CLA
ADC <$79
STA <$79
CLY
RTS
You can find an example of RLE+XOR data at file offset $2ec0b.
More on next post