From 2682bc5d1d864341aaeb42a449db73c3ecd16d70 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Wed, 30 Dec 2020 19:07:31 +0000 Subject: Initial import --- tools/rasm/decrunch/dzx7_turbo.asm | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tools/rasm/decrunch/dzx7_turbo.asm (limited to 'tools/rasm/decrunch/dzx7_turbo.asm') diff --git a/tools/rasm/decrunch/dzx7_turbo.asm b/tools/rasm/decrunch/dzx7_turbo.asm new file mode 100644 index 0000000..779ced5 --- /dev/null +++ b/tools/rasm/decrunch/dzx7_turbo.asm @@ -0,0 +1,80 @@ +; ----------------------------------------------------------------------------- +; ZX7 decoder by Einar Saukas & Urusergi +; "Turbo" version (88 bytes, 25% faster) +; ----------------------------------------------------------------------------- +; Parameters: +; HL: source address (compressed data) +; DE: destination address (decompressing) +; ----------------------------------------------------------------------------- + +dzx7_turbo: + ld a, $80 +dzx7t_copy_byte_loop: + ldi ; copy literal byte +dzx7t_main_loop: + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + jr nc, dzx7t_copy_byte_loop ; next bit indicates either literal or sequence + +; determine number of bits used for length (Elias gamma coding) + push de + ld bc, 1 + ld d, b +dzx7t_len_size_loop: + inc d + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + jr nc, dzx7t_len_size_loop + jp dzx7t_len_value_start + +; determine length +dzx7t_len_value_loop: + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + rl c + rl b + jr c, dzx7t_exit ; check end marker +dzx7t_len_value_start: + dec d + jr nz, dzx7t_len_value_loop + inc bc ; adjust length + +; determine offset + ld e, (hl) ; load offset flag (1 bit) + offset value (7 bits) + inc hl + defb $cb, $33 ; opcode for undocumented instruction "SLL E" aka "SLS E" + jr nc, dzx7t_offset_end ; if offset flag is set, load 4 extra bits + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + rl d ; insert first bit into D + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + rl d ; insert second bit into D + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + rl d ; insert third bit into D + add a, a ; check next bit + call z, dzx7t_load_bits ; no more bits left? + ccf + jr c, dzx7t_offset_end + inc d ; equivalent to adding 128 to DE +dzx7t_offset_end: + rr e ; insert inverted fourth bit into E + +; copy previous sequence + ex (sp), hl ; store source, restore destination + push hl ; store destination + sbc hl, de ; HL = destination - offset - 1 + pop de ; DE = destination + ldir +dzx7t_exit: + pop hl ; restore source address (compressed data) + jp nc, dzx7t_main_loop + +dzx7t_load_bits: + ld a, (hl) ; load another group of 8 bits + inc hl + rla + ret + +; ----------------------------------------------------------------------------- -- cgit v1.2.3