syslinux-3.08-2 sources from FC4
[bootcd.git] / syslinux / rllpack.inc
1 ; -*- fundamental -*-
2 ; -----------------------------------------------------------------------
3 ;   
4 ;   Copyright 2004 H. Peter Anvin - All Rights Reserved
5 ;
6 ;   This program is free software; you can redistribute it and/or modify
7 ;   it under the terms of the GNU General Public License as published by
8 ;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 ;   Boston MA 02111-1307, USA; either version 2 of the License, or
10 ;   (at your option) any later version; incorporated herein by reference.
11 ;
12 ; -----------------------------------------------------------------------
13 ; $Id: rllpack.inc,v 1.2 2004/12/17 07:52:54 hpa Exp $
14
15 ;
16 ; rllpack.inc
17 ;
18 ; Very simple RLL compressor/decompressor, used to pack binary structures
19 ; together.
20 ;
21 ; Format of leading byte
22 ; 1-128         = x verbatim bytes follow
23 ; 129-255       = (x-126) times subsequent byte
24 ; 0             = end of data
25 ;
26
27                 section .text
28
29 ;
30 ; rllpack:
31 ;       Pack CX bytes from DS:SI into ES:DI
32 ;       Returns updated SI, DI and CX = number of bytes output
33 ;
34 rllpack:
35                 push ax
36                 push bx
37                 push cx
38                 push bp
39                 push di
40 .startseq:
41                 xor ax,ax               ; Zero byte
42                 xor bx,bx               ; Run length zero
43                 mov bp,di               ; Pointer to header byte
44                 stosb                   ; Store header byte (might be zero)
45                 jcxz .done_null
46 .stdbyte:
47                 lodsb
48                 stosb
49                 dec cx
50                 cmp ah,al
51                 je .same
52 .diff:
53                 mov ah,al
54                 xor bx,bx
55 .plainbyte:
56                 inc bx
57                 inc byte [es:bp]
58                 jcxz .done
59                 jns .stdbyte
60                 jmp .startseq
61 .same:
62                 cmp bl,2
63                 jb .plainbyte
64                 ; 3 bytes or more in a row, time to convert sequence
65                 sub byte [es:bp],bl
66                 jnz .normal
67                 dec di                  ; We killed a whole stretch, remove start byte
68 .normal:
69                 inc bx  
70                 sub di,bx
71                 mov bp,di
72                 mov al,bl
73                 add al,126
74                 stosb
75                 mov al,ah
76                 stosb
77 .getrun:
78                 jcxz .done
79                 cmp bl,255-126
80                 jae .startseq
81                 lodsb
82                 cmp al,ah
83                 jne .nomatch
84                 inc bx
85                 inc byte [es:bp]
86                 dec cx
87                 jmp .getrun
88 .nomatch:
89                 dec si
90                 jmp .startseq
91 .done:
92                 xor al,al
93                 stosb
94 .done_null:
95                 pop dx
96                 sub dx,di
97                 neg dx
98                 pop bp
99                 pop cx
100                 pop bx
101                 pop ax
102                 ret
103 ;
104 ; rllunpack:
105 ;       Unpack bytes from DS:SI into ES:DI
106 ;       On return SI, DI are updated and CX contains number of bytes output
107 ;       
108 rllunpack:
109                 push ax
110                 push di
111                 xor cx,cx
112 .header:
113                 lodsb
114                 and al,al
115                 jz .done
116                 cmp al,129
117                 jae .isrun
118                 ; Not a run
119                 mov cl,al
120                 rep movsb
121                 jmp .header
122 .isrun:
123                 sub al,126
124                 mov cl,al
125                 lodsb
126                 rep stosb
127                 jmp .header
128 .done:
129                 pop cx
130                 sub cx,di
131                 neg cx
132                 pop ax
133                 ret