From 239ccde418959ed77e7e2ab763a1de7723353a51 Mon Sep 17 00:00:00 2001 From: neauoire Date: Sat, 18 Nov 2023 14:09:09 -0800 Subject: [PATCH] (lz) Progress --- cli/lz/ulzenc.tal | 102 +++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/cli/lz/ulzenc.tal b/cli/lz/ulzenc.tal index 403e641..678ff96 100644 --- a/cli/lz/ulzenc.tal +++ b/cli/lz/ulzenc.tal @@ -12,7 +12,7 @@ @output-ptr $2 @match-ctl $2 @dict-best $2 - @combine $2 + @combine $2 @dict $2 @dict-len $2 @@ -45,6 +45,61 @@ .output-ptr LDZ2 INC2k .output-ptr STZ2 STA JMP2r +@uxn_lz_compress ( input* length* -- ) + ( fill variables ) + ;raw .output-ptr STZ2 + ADD2k NIP2 SWP2 + &w ( -- ) + ( | get available dictionary size ) + DUP2 ;raw SUB2 #0100 LTH2k ?{ SWP2 } + POP2 .dict-len STZ2 + ( | size of the string to search for ) + SUB2k #3fff #0004 ADD2 LTH2k ?{ SWP2 } + POP2 ,&string-len STR2 + ( | debug ) + .dict-len LDZ2 phex #2018 DEO ,&string-len LDR2 phex #2018 DEO + ( | itterate through the dictionary ) + #0000 .match-len STZ2 + DUP2 .dict-len LDZ2 SUB2 .dict STZ2 + &for1 ( dict-len-- != 0 ) + .dict-len LDZ2 #0000 EQU2 ?&done-search + ( 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; ) + ( b ) DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA + ( a ) ADD2k LDA + NEQ ?&end + INC2 ORAk ?&for2 + &end + ( i > match_len ) + DUP2 .match-len LDZ2 GTH2 #00 EQU ?{ + DUP2 .match-len STZ2 + .dict LDZ2 .dict-best STZ2 } + POP2 + .dict LDZ2 INC2 .dict STZ2 + #0001 SUB2 !&for1 + POP2 + &done-search ( -- ) + + .match-len LDZ2 phex #0a18 DEO + + ( CPY ) .match-len LDZ2 #0003 GTH2 ?op-cpy + ( LIT ) op-lit + NEQ2k ?&w + JMP2r + + + +( +@|opcodes ) + @op-cpy ( in* -- ) ( More numeric range: treat 0 as 4, 1 as 5, etc. ) .match-len LDZ2 #0004 SUB2 .match-ctl STZ2 @@ -85,51 +140,6 @@ LDAk INC2 !uxn_lz_compress/w -@uxn_lz_compress ( input* length* -- ) - ADD2k NIP2 SWP2 - &w ( -- ) - ( | get available dictionary size ) - DUP2 ;raw SUB2 #0100 LTH2k ?{ SWP2 } - POP2 .dict-len STZ2 - ( | size of the string to search for ) - SUB2k #3fff #0004 ADD2 LTH2k ?{ SWP2 } - POP2 ,&string-len STR2 - ( | itterate through the dictionary ) - #0000 .match-len STZ2 - .dict-len LDZ2 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 LDZ2 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 #0003 GTH2 ?op-cpy - ( LIT ) op-lit - NEQ2k ?&w - JMP2r - ( @|stdlib )