mirror of
https://github.com/fadden/fhpack.git
synced 2024-06-01 08:41:32 +00:00
dcabf12d97
I split the "small" source into its own file. I think it could become smaller, but not without changes that make #ifdefs untenable. The "small" version need a couple of fixes (define "savsrc", branch to "advsrc1" not "advsrc"). Merlin apparently detects SEC+XCE and automatically switches back to 8-bit registers, so I added an MX %00 to the 65816 version after the exit section. Added comments. This just updates the git copy of the sources. An updated set of disk images will appear soonish.
143 lines
3.2 KiB
ArmAsm
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
|