summaryrefslogtreecommitdiff
path: root/rllpack.inc
blob: da5618db07f5f780e4254b7e4b88a327f8cb79c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
; -*- 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.
;
; -----------------------------------------------------------------------

;
; 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