From 9101bda743a2c23758cc51a7f76038ea290271ce Mon Sep 17 00:00:00 2001 From: neauoire Date: Sat, 18 Nov 2023 12:19:30 -0800 Subject: [PATCH] (lz) * --- cli/lz/ulzenc.c | 6 +++-- cli/lz/ulzenc.tal | 66 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/cli/lz/ulzenc.c b/cli/lz/ulzenc.c index 5621ee9..38ba59b 100644 --- a/cli/lz/ulzenc.c +++ b/cli/lz/ulzenc.c @@ -36,15 +36,17 @@ uxn_lz_compress(const void *input, int input_size) /* DEBUG: printf("%04x %04x \n", dict_len, string_len); */ /* Iterate through the dictionary */ - for(dict = in - dict_len, match_len = 0; dict_len; dict++, dict_len -= 1) { + match_len = 0; + dict = in - dict_len; + for(; dict_len; dict++, dict_len -= 1) { /* Find common prefix length with the string */ + /* If we reach the end of the string, this is the best possible match. End. */ for(i = 0;; i++) { if(i == string_len) { match_len = i; dict_best = dict; goto done_search; } - /* ^ If we reach the end of the string, this is the best possible match. End. */ /* Dictionary repeats if we hit the end */ if(in[i] != dict[i % dict_len]) break; diff --git a/cli/lz/ulzenc.tal b/cli/lz/ulzenc.tal index bd69ce6..89c1500 100644 --- a/cli/lz/ulzenc.tal +++ b/cli/lz/ulzenc.tal @@ -8,6 +8,7 @@ @src $30 @dst $30 @ptr $1 + @match-len $2 |0100 @@ -34,6 +35,10 @@ ( halt ) #800f DEO BRK +@ ( byte -- ) + .output-ptr LDZ2 INC2k .output-ptr STZ2 STA + JMP2r + @uxn_lz_compress ( input* length* -- ) ADD2k NIP2 SWP2 &w ( -- ) @@ -44,8 +49,63 @@ SUB2k #3fff #0004 ADD2 LTH2k ?{ SWP2 } POP2 ,&string-len STR2 ( | itterate through the dictionary ) - [ LIT2 &dict-len $2 ] phex #2018 DEO - [ LIT2 &string-len $2 ] phex #0a18 DEO + #0000 .match-len STZ2 + [ LIT2 &dict-len $2 ] SUB2k .dict STZ2 + ( | create a few inlines ) + DUP2 ,&in STR2 + &for1 ( dict-len != 0 ) + ( Find common prefix length with the string ) + #0000 + &for2 ( i != 0 ) + ( If we reach the end of the string, it's the best possible match. ) + DUP2 [ LIT2 &string-len $2 ] NEQ2 ?{ + DUP2 .match-len STZ2 + .dict LDZ2 .dict-best STZ2 + POP2 POP2 !&done-search } + ( Dictionary repeats if we hit the end ) + ( in[i] != dict[i % dict_len] break; ) + DUP2 [ LIT2 &in $2 ] ADD2 LDA2 + OVR2 ,&dict-len LDR2 DIV2k MUL2 SUB2 + .dict LDZ2 ADD2 LDA2 NEQ2 ?&end + INC2 ORAk ?&for2 + &end + ( i > match_len ) + DUP2 .match-len LDZ2 GTH2 #00 EQU ?{ + DUP2 .match-len STZ2 + .dict-len LDZ2 .dict STZ2 } + POP2 + .dict LDZ2 INC2 .dict STZ2 + #0001 SUB2 ORAk ?&for1 + POP2 + + &done-search ( -- ) + + ( CPY ) + .match-len LDZ2 #0004 LTH2 ?&no-cpy + ( More numeric range: treat 0 as 4, 1 as 5, etc. ) + .match-len LDZ2 #0004 SUB2 .match-ctl STZ2 + ( CPY2 ) + .match-ctl LDZ2 #003f GTH2 ?&cpy2 + ( CPY1 ) + ( *output_ptr++ = match_ctl | 0x80; ) + .match-ctl LDZ2 #0080 ORA2 + !&cpy-resume + &cpy2 + ( TODO ) + &cpy-resume + ( *output_ptr++ = in - dict_best - 1; ) + DUP2 .dict-best LDZ2 #0001 SUB2 SUB2 + + + &no-cpy + + + + ( LIT ) + + + phex #2018 DEO + phex #0a18 DEO ( TODO: remove me!! ) INC2 NEQ2k ?&w JMP2r @@ -78,7 +138,7 @@ &c ( -- ) #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO JMP2r - + ( @|memory )