compression { sub decode_rle(uword @zp compressed, uword @zp target, uword maxsize) -> uword { cx16.r0 = target ; original target cx16.r1 = target+maxsize ; decompression limit while target uword { ; -- Compress the given data block using ByteRun1 aka PackBits RLE encoding. ; Returns the size of the compressed RLE data. Worst case result storage size needed = (size + (size+126) / 127) + 1. ; is_last_block = usually true, but you can set it to false if you want to concatenate multiple ; compressed blocks (for instance if the source data is >64Kb) ; This routine is not optimized for speed but for readability and ease of use. uword idx = 0 uword literals_start_idx = 0 ubyte literals_length = 0 uword orig_target = target sub next_same_span() { ; returns length in cx16.r1L, and the byte value in cx16.r1H cx16.r1H = data[idx] cx16.r1L = 0 while data[idx]==cx16.r1H and cx16.r1L<128 and idx1 { ; a replicate run if literals_length>0 output_literals() @(target) = (cx16.r1L^255)+2 ; 257-cx16.r1L target++ @(target) = cx16.r1H target++ } else { ; add more to the literals run if literals_length==128 output_literals() if literals_length==0 literals_start_idx = idx-1 literals_length++ } } if literals_length>0 output_literals() if is_last_block { @(target) = 128 target ++ } return target-orig_target } }