zx_cartridge/Content/tools/zx0/z80/dzx0_mega_back.asm
MichailKaa 7aaf4a7b21 ext version
batty start, but not work
2026-02-19 23:33:01 +03:00

460 lines
15 KiB
NASM

; -----------------------------------------------------------------------------
; ZX0 decoder by Einar Saukas & introspec
; "Mega" version (676 bytes, 28% faster) - BACKWARDS VARIANT
; -----------------------------------------------------------------------------
; Parameters:
; HL: last source address (compressed data)
; DE: last destination address (decompressing)
; -----------------------------------------------------------------------------
dzx0_mega_back:
ld bc, 1 ; preserve default offset 1
ld (dzx0mb_last_offset+1), bc
jr dzx0mb_literals0
dzx0mb_new_offset6:
add a, a ; obtain offset MSB
jp nc, dzx0mb_new_offset5
add a, a
rl c
add a, a
jp nc, dzx0mb_new_offset3
add a, a
rl c
add a, a
jp nc, dzx0mb_new_offset1
dzx0mb_elias_offset1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp c, dzx0mb_elias_offset7
dzx0mb_new_offset7:
dec b
ret z ; check end marker
dec c ; adjust for positive offset
ld b, c
ld c, (hl) ; obtain offset LSB
dec hl
srl b ; last offset bit becomes first length bit
rr c
inc bc
ld (dzx0mb_last_offset+1), bc ; preserve new offset
ld bc, 1
jp nc, dzx0mb_length7 ; obtain length
add a, a
rl c
add a, a
jp nc, dzx0mb_length5
add a, a
rl c
add a, a
jp nc, dzx0mb_length3
dzx0mb_elias_length3:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_length1
dzx0mb_length1:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
ldd ; copy one more from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr c, dzx0mb_new_offset0
dzx0mb_literals0:
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a ; obtain length
jp nc, dzx0mb_literals7
add a, a
rl c
add a, a
jp nc, dzx0mb_literals5
add a, a
rl c
add a, a
jp nc, dzx0mb_literals3
dzx0mb_elias_literals3:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_literals1
dzx0mb_literals1:
lddr ; copy literals
inc c
add a, a ; copy from last offset or new offset?
jr c, dzx0mb_new_offset0
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a ; obtain length
jp nc, dzx0mb_reuse7
add a, a
rl c
add a, a
jp nc, dzx0mb_reuse5
add a, a
rl c
add a, a
jp nc, dzx0mb_reuse3
dzx0mb_elias_reuse3:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_reuse1
dzx0mb_reuse1:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0mb_literals0
dzx0mb_new_offset0:
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a ; obtain offset MSB
jp nc, dzx0mb_new_offset7
add a, a
rl c
add a, a
jp nc, dzx0mb_new_offset5
add a, a
rl c
add a, a
jp nc, dzx0mb_new_offset3
dzx0mb_elias_offset3:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_offset1
dzx0mb_new_offset1:
dec b
ret z ; check end marker
dec c ; adjust for positive offset
ld b, c
ld c, (hl) ; obtain offset LSB
dec hl
srl b ; last offset bit becomes first length bit
rr c
inc bc
ld (dzx0mb_last_offset+1), bc ; preserve new offset
ld bc, 1
jp nc, dzx0mb_length1 ; obtain length
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_length7
add a, a
rl c
add a, a
jp nc, dzx0mb_length5
dzx0mb_elias_length5:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_length3
dzx0mb_length3:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
ldd ; copy one more from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr c, dzx0mb_new_offset2
dzx0mb_literals2:
add a, a ; obtain length
jp nc, dzx0mb_literals1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_literals7
add a, a
rl c
add a, a
jp nc, dzx0mb_literals5
dzx0mb_elias_literals5:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_literals3
dzx0mb_literals3:
lddr ; copy literals
inc c
add a, a ; copy from last offset or new offset?
jr c, dzx0mb_new_offset2
add a, a ; obtain length
jp nc, dzx0mb_reuse1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_reuse7
add a, a
rl c
add a, a
jp nc, dzx0mb_reuse5
dzx0mb_elias_reuse5:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_reuse3
dzx0mb_reuse3:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0mb_literals2
dzx0mb_new_offset2:
add a, a ; obtain offset MSB
jp nc, dzx0mb_new_offset1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_new_offset7
add a, a
rl c
add a, a
jp nc, dzx0mb_new_offset5
dzx0mb_elias_offset5:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_offset3
dzx0mb_new_offset3:
dec b
ret z ; check end marker
dec c ; adjust for positive offset
ld b, c
ld c, (hl) ; obtain offset LSB
dec hl
srl b ; last offset bit becomes first length bit
rr c
inc bc
ld (dzx0mb_last_offset+1), bc ; preserve new offset
ld bc, 1
jp nc, dzx0mb_length3 ; obtain length
add a, a
rl c
add a, a
jp nc, dzx0mb_length1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_length7
dzx0mb_elias_length7:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_length5
dzx0mb_length5:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
ldd ; copy one more from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr c, dzx0mb_new_offset4
dzx0mb_literals4:
add a, a ; obtain length
jp nc, dzx0mb_literals3
add a, a
rl c
add a, a
jp nc, dzx0mb_literals1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_literals7
dzx0mb_elias_literals7:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_literals5
dzx0mb_literals5:
lddr ; copy literals
inc c
add a, a ; copy from last offset or new offset?
jr c, dzx0mb_new_offset4
add a, a ; obtain length
jp nc, dzx0mb_reuse3
add a, a
rl c
add a, a
jp nc, dzx0mb_reuse1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_reuse7
dzx0mb_elias_reuse7:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_reuse5
dzx0mb_reuse5:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0mb_literals4
dzx0mb_new_offset4:
add a, a ; obtain offset MSB
jp nc, dzx0mb_new_offset3
add a, a
rl c
add a, a
jp nc, dzx0mb_new_offset1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp nc, dzx0mb_new_offset7
dzx0mb_elias_offset7:
add a, a
rl c
rl b
add a, a
jp c, dzx0mb_elias_offset5
dzx0mb_new_offset5:
dec b
ret z ; check end marker
dec c ; adjust for positive offset
ld b, c
ld c, (hl) ; obtain offset LSB
dec hl
srl b ; last offset bit becomes first length bit
rr c
inc bc
ld (dzx0mb_last_offset+1), bc ; preserve new offset
ld bc, 1
jp nc, dzx0mb_length5 ; obtain length
add a, a
rl c
add a, a
jp nc, dzx0mb_length3
add a, a
rl c
add a, a
jp nc, dzx0mb_length1
dzx0mb_elias_length1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp c, dzx0mb_elias_length7
dzx0mb_length7:
push hl ; preserve source
ld hl, (dzx0mb_last_offset+1)
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
ldd ; copy one more from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jp c, dzx0mb_new_offset6
dzx0mb_literals6:
add a, a ; obtain length
jp nc, dzx0mb_literals5
add a, a
rl c
add a, a
jp nc, dzx0mb_literals3
add a, a
rl c
add a, a
jp nc, dzx0mb_literals1
dzx0mb_elias_literals1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp c, dzx0mb_elias_literals7
dzx0mb_literals7:
lddr ; copy literals
inc c
add a, a ; copy from last offset or new offset?
jp c, dzx0mb_new_offset6
add a, a ; obtain length
jp nc, dzx0mb_reuse5
add a, a
rl c
add a, a
jp nc, dzx0mb_reuse3
add a, a
rl c
add a, a
jp nc, dzx0mb_reuse1
dzx0mb_elias_reuse1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
dec hl
add a, a
jp c, dzx0mb_elias_reuse7
dzx0mb_reuse7:
push hl ; preserve source
dzx0mb_last_offset:
ld hl, 0
add hl, de ; calculate destination - offset
lddr ; copy from offset
inc c
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0mb_literals6
jp dzx0mb_new_offset6
; -----------------------------------------------------------------------------