blob: 9d2aab30fedaf80694d21f75f89f864983852408 [file] [log] [blame]
; -*- fundamental -*-
; -----------------------------------------------------------------------
;
; Copyright 2004 H. Peter Anvin - All Rights Reserved
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
; Boston MA 02111-1307, USA; either version 2 of the License, or
; (at your option) any later version; incorporated herein by reference.
;
; -----------------------------------------------------------------------
; $Id$
;
; rllpack.inc
;
; Very simple RLL compressor/decompressor, used to pack binary structures
; together.
;
; Format of leading byte
; 1-128 = x verbatim bytes follow
; 129-255 = (x-126) times subsequent byte
; 0 = end of data
;
section .text
;
; rllpack:
; Pack CX bytes from DS:SI into ES:DI
; Returns updated SI, DI and CX = number of bytes output
;
rllpack:
push ax
push bx
push cx
push bp
push di
.startseq:
xor ax,ax ; Zero byte
xor bx,bx ; Run length zero
mov bp,di ; Pointer to header byte
stosb ; Store header byte (might be zero)
jcxz .done_null
.stdbyte:
lodsb
stosb
dec cx
cmp ah,al
je .same
.diff:
mov ah,al
xor bx,bx
.plainbyte:
inc bx
inc byte [es:bp]
jcxz .done
jns .stdbyte
jmp .startseq
.same:
cmp bl,2
jb .plainbyte
; 3 bytes or more in a row, time to convert sequence
sub byte [es:bp],bl
jnz .normal
dec di ; We killed a whole stretch, remove start byte
.normal:
inc bx
sub di,bx
mov bp,di
mov al,bl
add al,126
stosb
mov al,ah
stosb
.getrun:
jcxz .done
cmp bl,255-126
jae .startseq
lodsb
cmp al,ah
jne .nomatch
inc bx
inc byte [es:bp]
dec cx
jmp .getrun
.nomatch:
dec si
jmp .startseq
.done:
xor al,al
stosb
.done_null:
pop dx
sub dx,di
neg dx
pop bp
pop cx
pop bx
pop ax
ret
;
; rllunpack:
; Unpack bytes from DS:SI into ES:DI
; On return SI, DI are updated and CX contains number of bytes output
;
rllunpack:
push ax
push di
xor cx,cx
.header:
lodsb
and al,al
jz .done
cmp al,129
jae .isrun
; Not a run
mov cl,al
rep movsb
jmp .header
.isrun:
sub al,126
mov cl,al
lodsb
rep stosb
jmp .header
.done:
pop cx
sub cx,di
neg cx
pop ax
ret