diff --git a/cli/lz/ulzenc.tal b/cli/lz/ulzenc.tal index 678ff96..36616ac 100644 --- a/cli/lz/ulzenc.tal +++ b/cli/lz/ulzenc.tal @@ -47,51 +47,84 @@ @uxn_lz_compress ( input* length* -- ) ( fill variables ) - ;raw .output-ptr STZ2 + ;compressed .output-ptr STZ2 + + ADD2k NIP2 SWP2 - &w ( -- ) + &w ( end* start* -- ) + ( | 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 + + LIT "[ #18 DEO + LDAk #18 DEO + LIT "] #18 DEO + + &for1 ( for ; dict_len; dict++, dict_len-- ) + .dict-len LDZ2 #0000 EQU2 ?&end-for1 + ( Find common prefix length with the string ) #0000 - &for2 ( i++ != 0 ) + &for2 ( for i = 0;; i++ ) ( 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 } + POP2 !&done-search } + ( Dictionary repeats if we hit the end ) + LIT "( #18 DEO + DUP phex/b #2018 DEO + OVR2 ;raw SUB2 phex #2018 DEO + ADD2k LDA #18 DEO #2018 DEO + DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA #18 DEO + LIT ") #18 DEO #0a18 DEO + ( in[i] != dict[i % dict_len] break; ) - ( b ) DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA - ( a ) ADD2k LDA - NEQ ?&end + ( a ) ADD2k LDA STH + ( b ) DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA STHr + NEQ ?&end-for2 INC2 ORAk ?&for2 - &end + &end-for2 + ( i > match_len ) - DUP2 .match-len LDZ2 GTH2 #00 EQU ?{ + DUP2 .match-len LDZ2 LTH2 ?{ DUP2 .match-len STZ2 .dict LDZ2 .dict-best STZ2 } POP2 + .dict LDZ2 INC2 .dict STZ2 - #0001 SUB2 !&for1 - POP2 + .dict-len LDZ2 #0001 SUB2 .dict-len STZ2 !&for1 + + &end-for1 + &done-search ( -- ) + LIT "- #18 DEO .match-len LDZ2 phex #0a18 DEO + ( [ LIT &break $1 ] INCk ,&break STR #03 NEQ ?{ BREAK } ) + + ( CPY ) .match-len LDZ2 #0003 GTH2 ?op-cpy ( LIT ) op-lit + + LIT "> #18 DEO + DUP2 ;raw SUB2 phex #0a18 DEO + + #010f DEO BRK NEQ2k ?&w JMP2r @@ -101,6 +134,7 @@ @|opcodes ) @op-cpy ( in* -- ) + #2222 phex ( More numeric range: treat 0 as 4, 1 as 5, etc. ) .match-len LDZ2 #0004 SUB2 .match-ctl STZ2 ( CPY2 ) @@ -170,6 +204,15 @@ #0f AND DUP #09 GTH #27 MUL ADD [ LIT "0 ] ADD #18 DEO JMP2r +@BREAK + #0a18 DEO + #010e DEO #010f DEO BRK + +@DEBUG1 + LIT "> #18 DEO + DUP phex/b #0a18 DEO + JMP2r + ( @|memory )