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

453 lines
15 KiB
NASM

; -----------------------------------------------------------------------------
; ZX0 decoder by Einar Saukas
; "Mega" version (673 bytes, 28% faster)
; -----------------------------------------------------------------------------
; Parameters:
; HL: source address (compressed data)
; DE: destination address (decompressing)
; -----------------------------------------------------------------------------
dzx0_mega:
ld bc, $ffff ; preserve default offset 1
ld (dzx0m_last_offset+1), bc
inc bc
jr dzx0m_literals0
dzx0m_new_offset6:
ld c, $fe ; prepare negative offset
add a, a ; obtain offset MSB
jp c, dzx0m_new_offset5
add a, a
rl c
add a, a
jp c, dzx0m_new_offset3
add a, a
rl c
add a, a
jp c, dzx0m_new_offset1
dzx0m_elias_offset1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp nc, dzx0m_elias_offset7
dzx0m_new_offset7:
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 (dzx0m_last_offset+1), bc ; preserve new offset
ld bc, 1
jp c, dzx0m_length7 ; obtain length
add a, a
rl c
add a, a
jp c, dzx0m_length5
add a, a
rl c
add a, a
jp c, dzx0m_length3
dzx0m_elias_length3:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_length1
dzx0m_length1:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
inc c
ldi ; copy one more from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr c, dzx0m_new_offset0
dzx0m_literals0:
inc c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a ; obtain length
jp c, dzx0m_literals7
add a, a
rl c
add a, a
jp c, dzx0m_literals5
add a, a
rl c
add a, a
jp c, dzx0m_literals3
dzx0m_elias_literals3:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_literals1
dzx0m_literals1:
ldir ; copy literals
add a, a ; copy from last offset or new offset?
jr c, dzx0m_new_offset0
inc c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a ; obtain length
jp c, dzx0m_reuse7
add a, a
rl c
add a, a
jp c, dzx0m_reuse5
add a, a
rl c
add a, a
jp c, dzx0m_reuse3
dzx0m_elias_reuse3:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_reuse1
dzx0m_reuse1:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0m_literals0
dzx0m_new_offset0:
ld c, $fe ; prepare negative offset
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a ; obtain offset MSB
jp c, dzx0m_new_offset7
add a, a
rl c
add a, a
jp c, dzx0m_new_offset5
add a, a
rl c
add a, a
jp c, dzx0m_new_offset3
dzx0m_elias_offset3:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_offset1
dzx0m_new_offset1:
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 (dzx0m_last_offset+1), bc ; preserve new offset
ld bc, 1
jp c, dzx0m_length1 ; obtain length
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_length7
add a, a
rl c
add a, a
jp c, dzx0m_length5
dzx0m_elias_length5:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_length3
dzx0m_length3:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
inc c
ldi ; copy one more from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr c, dzx0m_new_offset2
dzx0m_literals2:
inc c
add a, a ; obtain length
jp c, dzx0m_literals1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_literals7
add a, a
rl c
add a, a
jp c, dzx0m_literals5
dzx0m_elias_literals5:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_literals3
dzx0m_literals3:
ldir ; copy literals
add a, a ; copy from last offset or new offset?
jr c, dzx0m_new_offset2
inc c
add a, a ; obtain length
jp c, dzx0m_reuse1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_reuse7
add a, a
rl c
add a, a
jp c, dzx0m_reuse5
dzx0m_elias_reuse5:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_reuse3
dzx0m_reuse3:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0m_literals2
dzx0m_new_offset2:
ld c, $fe ; prepare negative offset
add a, a ; obtain offset MSB
jp c, dzx0m_new_offset1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_new_offset7
add a, a
rl c
add a, a
jp c, dzx0m_new_offset5
dzx0m_elias_offset5:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_offset3
dzx0m_new_offset3:
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 (dzx0m_last_offset+1), bc ; preserve new offset
ld bc, 1
jp c, dzx0m_length3 ; obtain length
add a, a
rl c
add a, a
jp c, dzx0m_length1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_length7
dzx0m_elias_length7:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_length5
dzx0m_length5:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
inc c
ldi ; copy one more from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr c, dzx0m_new_offset4
dzx0m_literals4:
inc c
add a, a ; obtain length
jp c, dzx0m_literals3
add a, a
rl c
add a, a
jp c, dzx0m_literals1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_literals7
dzx0m_elias_literals7:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_literals5
dzx0m_literals5:
ldir ; copy literals
add a, a ; copy from last offset or new offset?
jr c, dzx0m_new_offset4
inc c
add a, a ; obtain length
jp c, dzx0m_reuse3
add a, a
rl c
add a, a
jp c, dzx0m_reuse1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_reuse7
dzx0m_elias_reuse7:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_reuse5
dzx0m_reuse5:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0m_literals4
dzx0m_new_offset4:
ld c, $fe ; prepare negative offset
add a, a ; obtain offset MSB
jp c, dzx0m_new_offset3
add a, a
rl c
add a, a
jp c, dzx0m_new_offset1
add a, a
rl c
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp c, dzx0m_new_offset7
dzx0m_elias_offset7:
add a, a
rl c
rl b
add a, a
jp nc, dzx0m_elias_offset5
dzx0m_new_offset5:
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 (dzx0m_last_offset+1), bc ; preserve new offset
ld bc, 1
jp c, dzx0m_length5 ; obtain length
add a, a
rl c
add a, a
jp c, dzx0m_length3
add a, a
rl c
add a, a
jp c, dzx0m_length1
dzx0m_elias_length1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp nc, dzx0m_elias_length7
dzx0m_length7:
push hl ; preserve source
ld hl, (dzx0m_last_offset+1)
add hl, de ; calculate destination - offset
ldir ; copy from offset
inc c
ldi ; copy one more from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jp c, dzx0m_new_offset6
dzx0m_literals6:
inc c
add a, a ; obtain length
jp c, dzx0m_literals5
add a, a
rl c
add a, a
jp c, dzx0m_literals3
add a, a
rl c
add a, a
jp c, dzx0m_literals1
dzx0m_elias_literals1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp nc, dzx0m_elias_literals7
dzx0m_literals7:
ldir ; copy literals
add a, a ; copy from last offset or new offset?
jp c, dzx0m_new_offset6
inc c
add a, a ; obtain length
jp c, dzx0m_reuse5
add a, a
rl c
add a, a
jp c, dzx0m_reuse3
add a, a
rl c
add a, a
jp c, dzx0m_reuse1
dzx0m_elias_reuse1:
add a, a
rl c
rl b
ld a, (hl) ; load another group of 8 bits
inc hl
add a, a
jp nc, dzx0m_elias_reuse7
dzx0m_reuse7:
push hl ; preserve source
dzx0m_last_offset:
ld hl, 0
add hl, de ; calculate destination - offset
ldir ; copy from offset
pop hl ; restore source
add a, a ; copy from literals or new offset?
jr nc, dzx0m_literals6
jp dzx0m_new_offset6
; -----------------------------------------------------------------------------