fhpack/LZ4FH65816.S

143 lines
3.2 KiB
ArmAsm

*********************************
* *
* LZ4FH uncompression for 65816 *
* By Andy McFadden *
* Version 1.0.1, August 2015 *
* *
* Refactored for size & speed *
* by Peter Ferrie. *
* *
* Developed with Merlin-16 *
* *
*********************************
lst off
org $0300
xc ;allow 65c02 opcodes
xc ;allow 65816 opcodes
*
* Constants
*
lz4fh_magic equ $66 ;ascii 'f'
tok_empty equ 253
tok_eod equ 254
*
* Variable storage
*
savmix equ $00 ;2b
savlen equ $02 ;2b
*
* ROM routines
*
bell equ $ff3a
monitor equ $ff69
*
* Parameters.
*
* in_dst must be $2000 or $4000
*
in_src equ $2fc ;2b
in_dst equ $2fe ;2b
* Main entry point.
entry
clc ;go native
xce
rep #$30 ;16-bit acc/index
mx %00 ; tell Merlin
ldx in_src
ldy in_dst
sty _dstmod+1
lda $0000,x
inx
and #$00ff
cmp #lz4fh_magic
beq mainloop
fail
jsr bell
jmp monitor
notempty
cmp #tok_eod ;end-of-data or error
* exit
sec ;return to emulation mode
xce
bne fail
rts
mx %00 ;undo the sec/xce
* handle "special" match length values (in A)
specialmatch
cmp #tok_empty
bne notempty
mainloop
lda $0000,x
inx
sta savmix
and #$00f0
beq noliteral
lsr A
lsr A
lsr A
lsr A
cmp #$000f
bne shortlit
lda $0000,x ;length >= 15, get next
inx
and #$00ff
adc #14 ;(carry set) +15 - won't exceed 255
* At this point, Y holds the address of the next
* compressed data byte, X has the address of the
* next output position, and A has the length of
* the literal.
*
* The MVN instruction moves (A+1) bytes from X
* to Y, advancing X and Y.
shortlit
dec A ;MVN wants length-1
mvn $00,$00 ;7 cycles/byte
* Now handle the match.
noliteral
lda savmix
and #$000f
cmp #$000f
blt :shortmatch ;BCC
lda $0000,x ;add length extension
inx
and #$00ff
cmp #237 ;"normal" values are 0-236
bge specialmatch
adc #15 ;carry clear; won't exceed 255
:shortmatch
adc #3 ;min match, -1 for MVN
sta savlen ;spill A while we get offset
lda $0000,x ;load source buffer offset
inx
inx
phx ;save srcptr for later
_dstmod ora #$ff00 ;OR in hi-res page
tax
lda savlen
mvn $00,$00
plx ;restore srcptr
bra mainloop
lst on
sav LZ4FH65816
lst off