134 lines
2.3 KiB
Plaintext
134 lines
2.3 KiB
Plaintext
; -*- 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,v 1.2 2004/12/17 07:52:54 hpa Exp $
|
|
|
|
;
|
|
; 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
|