101 lines
3.4 KiB
NASM
101 lines
3.4 KiB
NASM
; -----------------------------------------------------------------------------
|
|
; ZX0 decoder by Einar Saukas & introspec
|
|
; "Turbo" version (126 bytes, 21% faster)
|
|
; -----------------------------------------------------------------------------
|
|
; Parameters:
|
|
; HL: source address (compressed data)
|
|
; DE: destination address (decompressing)
|
|
; -----------------------------------------------------------------------------
|
|
|
|
dzx0_turbo:
|
|
ld bc, $ffff ; preserve default offset 1
|
|
ld (dzx0t_last_offset+1), bc
|
|
inc bc
|
|
ld a, $80
|
|
jr dzx0t_literals
|
|
dzx0t_new_offset:
|
|
ld c, $fe ; prepare negative offset
|
|
add a, a
|
|
jp nz, dzx0t_new_offset_skip
|
|
ld a, (hl) ; load another group of 8 bits
|
|
inc hl
|
|
rla
|
|
dzx0t_new_offset_skip:
|
|
call nc, dzx0t_elias ; obtain offset MSB
|
|
inc c
|
|
ret z ; check end marker
|
|
ld b, c
|
|
ld c, (hl) ; obtain offset LSB
|
|
inc hl
|
|
rr b ; last offset bit becomes first length bit
|
|
rr c
|
|
ld (dzx0t_last_offset+1), bc ; preserve new offset
|
|
ld bc, 1 ; obtain length
|
|
call nc, dzx0t_elias
|
|
inc bc
|
|
dzx0t_copy:
|
|
push hl ; preserve source
|
|
dzx0t_last_offset:
|
|
ld hl, 0 ; restore offset
|
|
add hl, de ; calculate destination - offset
|
|
ldir ; copy from offset
|
|
pop hl ; restore source
|
|
add a, a ; copy from literals or new offset?
|
|
jr c, dzx0t_new_offset
|
|
dzx0t_literals:
|
|
inc c ; obtain length
|
|
add a, a
|
|
jp nz, dzx0t_literals_skip
|
|
ld a, (hl) ; load another group of 8 bits
|
|
inc hl
|
|
rla
|
|
dzx0t_literals_skip:
|
|
call nc, dzx0t_elias
|
|
ldir ; copy literals
|
|
add a, a ; copy from last offset or new offset?
|
|
jr c, dzx0t_new_offset
|
|
inc c ; obtain length
|
|
add a, a
|
|
jp nz, dzx0t_last_offset_skip
|
|
ld a, (hl) ; load another group of 8 bits
|
|
inc hl
|
|
rla
|
|
dzx0t_last_offset_skip:
|
|
call nc, dzx0t_elias
|
|
jp dzx0t_copy
|
|
dzx0t_elias:
|
|
add a, a ; interlaced Elias gamma coding
|
|
rl c
|
|
add a, a
|
|
jr nc, dzx0t_elias
|
|
ret nz
|
|
ld a, (hl) ; load another group of 8 bits
|
|
inc hl
|
|
rla
|
|
ret c
|
|
add a, a
|
|
rl c
|
|
add a, a
|
|
ret c
|
|
add a, a
|
|
rl c
|
|
add a, a
|
|
ret c
|
|
add a, a
|
|
rl c
|
|
add a, a
|
|
ret c
|
|
dzx0t_elias_loop:
|
|
add a, a
|
|
rl c
|
|
rl b
|
|
add a, a
|
|
jr nc, dzx0t_elias_loop
|
|
ret nz
|
|
ld a, (hl) ; load another group of 8 bits
|
|
inc hl
|
|
rla
|
|
jr nc, dzx0t_elias_loop
|
|
ret
|
|
; -----------------------------------------------------------------------------
|