snake6502/src/lzgmini.asm

247 lines
3.8 KiB
NASM
Raw Permalink Normal View History

2021-11-07 17:14:59 +00:00
SEG zeropageSegment
srcPointer WORD
dstPointer WORD
inEnd WORD
offset WORD
length BYTE
symbol BYTE
marker1 BYTE
marker2 BYTE
marker3 BYTE
marker4 BYTE
copy WORD
SEG loaderSegment
inflate SUBROUTINE
clc
ldy #10
lda (srcPointer),y
adc srcPointer
2021-11-07 17:14:59 +00:00
sta inEnd
dey
lda (srcPointer),y
adc srcPointer + 1
2021-11-07 17:14:59 +00:00
sta inEnd + 1
clc
2021-11-07 17:14:59 +00:00
lda inEnd
adc #16
2021-11-07 17:14:59 +00:00
sta inEnd
lda inEnd + 1
adc #0
2021-11-07 17:14:59 +00:00
sta inEnd + 1
; Get the marker symbols
ldy #16
lda (srcPointer),y
2021-11-07 17:14:59 +00:00
sta marker1
iny
lda (srcPointer),y
2021-11-07 17:14:59 +00:00
sta marker2
iny
lda (srcPointer),y
2021-11-07 17:14:59 +00:00
sta marker3
iny
lda (srcPointer),y
2021-11-07 17:14:59 +00:00
sta marker4
; Skip header + marker symbols (16 + 4 bytes)
clc
lda srcPointer
adc #20
sta srcPointer
lda srcPointer + 1
adc #0
sta srcPointer + 1
; Main decompression loop
ldy #0 ; Make sure that Y is zero
.mainloop:
lda srcPointer ; done?
2021-11-07 17:14:59 +00:00
cmp inEnd
bne .notdone
lda srcPointer + 1
2021-11-07 17:14:59 +00:00
cmp inEnd + 1
bne .notdone
rts
.notdone:
lda (srcPointer),y ; A = symbol
2021-11-07 17:14:59 +00:00
sta symbol
sta $d020
inc srcPointer
bne .noinc1
inc srcPointer + 1
.noinc1:
2021-11-07 17:14:59 +00:00
cmp marker1 ; Marker1?
beq .domarker1
2021-11-07 17:14:59 +00:00
cmp marker2 ; Marker2?
beq .domarker2
2021-11-07 17:14:59 +00:00
cmp marker3 ; Marker3?
beq .domarker3
2021-11-07 17:14:59 +00:00
cmp marker4 ; Marker4?
beq .domarker4
.literal:
2021-11-07 17:14:59 +00:00
lda symbol
sta (dstPointer),y ; Plain copy
inc dstPointer
bne .mainloop
inc dstPointer + 1
bne .mainloop
.domarker1:
jmp .domarker1b
; marker4 - "Near copy (incl. RLE)"
.domarker4:
lda (srcPointer),y
inc srcPointer
bne .noinc3
inc srcPointer + 1
.noinc3:
cmp #0
beq .literal ; Single occurance of the marker symbol (rare)
tax
lsr
lsr
lsr
lsr
lsr
2021-11-07 17:14:59 +00:00
sta offset
inc offset
lda #0
2021-11-07 17:14:59 +00:00
sta offset + 1 ; offset = (b >> 5) + 1
txa
and #$1f
tax
lda .LZG_LENGTH_DECODE_LUT,x
2021-11-07 17:14:59 +00:00
sta length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
jmp .docopy
; marker3 - "Short copy"
.domarker3:
lda (srcPointer),y
inc srcPointer
bne .noinc4
inc srcPointer + 1
.noinc4:
cmp #0
beq .literal ; Single occurance of the marker symbol (rare)
tax
lsr
lsr
lsr
lsr
lsr
lsr
clc
adc #3
2021-11-07 17:14:59 +00:00
sta length ; length = (b >> 6) + 3
txa
and #$3f
adc #8
2021-11-07 17:14:59 +00:00
sta offset
lda #0
2021-11-07 17:14:59 +00:00
sta offset + 1 ; offset = (b & 0x3f) + 8
beq .docopy
; marker2 - "Medium copy"
.domarker2:
lda (srcPointer),y
inc srcPointer
bne .noinc5
inc srcPointer + 1
.noinc5:
cmp #0
beq .literal ; Single occurance of the marker symbol (rare)
tax
lsr
lsr
lsr
lsr
lsr
2021-11-07 17:14:59 +00:00
sta offset + 1
lda (srcPointer),y
inc srcPointer
bne .noinc6
inc srcPointer + 1
.noinc6:
clc
adc #8
2021-11-07 17:14:59 +00:00
sta offset
bcc .noinc7
2021-11-07 17:14:59 +00:00
inc offset + 1 ; offset = (((b & 0xe0) << 3) | b2) + 8
.noinc7:
txa
and #$1f
tax
lda .LZG_LENGTH_DECODE_LUT,x
2021-11-07 17:14:59 +00:00
sta length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
bne .docopy
.literal2:
jmp .literal
; marker1 - "Distant copy"
.domarker1b:
lda (srcPointer),y
inc srcPointer
bne .noinc8
inc srcPointer + 1
.noinc8:
cmp #0
beq .literal2 ; Single occurance of the marker symbol (rare)
and #$1f
tax
lda .LZG_LENGTH_DECODE_LUT,x
2021-11-07 17:14:59 +00:00
sta length ; length = .LZG_LENGTH_DECODE_LUT[b & 0x1f]
lda (srcPointer),y
inc srcPointer
bne .noinc9
inc srcPointer + 1
.noinc9:
2021-11-07 17:14:59 +00:00
sta offset + 1
lda (srcPointer),y
inc srcPointer
bne .noinc10
inc srcPointer + 1
.noinc10:
clc
adc #$08
2021-11-07 17:14:59 +00:00
sta offset
lda offset + 1
adc #$08
2021-11-07 17:14:59 +00:00
sta offset + 1 ; offset = ((b2 << 8) | (*src++)) + 2056
; Copy corresponding data from history window
.docopy:
sec
lda dstPointer
2021-11-07 17:14:59 +00:00
sbc offset
sta copy
lda dstPointer + 1
2021-11-07 17:14:59 +00:00
sbc offset + 1
sta copy + 1
.loop1:
2021-11-07 17:14:59 +00:00
lda (copy),y
sta (dstPointer),y
iny
2021-11-07 17:14:59 +00:00
cpy length
bne .loop1
ldy #0 ; Make sure that Y is zero
clc
lda dstPointer
2021-11-07 17:14:59 +00:00
adc length
sta dstPointer
bcc .noinc11
inc dstPointer + 1
.noinc11:
jmp .mainloop
; Lookup Table for decoding the copy length parameter
.LZG_LENGTH_DECODE_LUT
BYTE 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,35,48,72,128