Adding upstream version 3.35.
[syslinux-debian/hramrach.git] / rllpack.inc
blobe31f9498f41826f3f34b331974e1077719508ac9
1 ; -*- fundamental -*-
2 ; -----------------------------------------------------------------------
4 ;   Copyright 2004 H. Peter Anvin - All Rights Reserved
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.
12 ; -----------------------------------------------------------------------
15 ; rllpack.inc
17 ; Very simple RLL compressor/decompressor, used to pack binary structures
18 ; together.
20 ; Format of leading byte
21 ; 1-128         = x verbatim bytes follow
22 ; 129-255       = (x-126) times subsequent byte
23 ; 0             = end of data
26                 section .text
29 ; rllpack:
30 ;       Pack CX bytes from DS:SI into ES:DI
31 ;       Returns updated SI, DI and CX = number of bytes output
33 rllpack:
34                 push ax
35                 push bx
36                 push cx
37                 push bp
38                 push di
39 .startseq:
40                 xor ax,ax               ; Zero byte
41                 xor bx,bx               ; Run length zero
42                 mov bp,di               ; Pointer to header byte
43                 stosb                   ; Store header byte (might be zero)
44                 jcxz .done_null
45 .stdbyte:
46                 lodsb
47                 stosb
48                 dec cx
49                 cmp ah,al
50                 je .same
51 .diff:
52                 mov ah,al
53                 xor bx,bx
54 .plainbyte:
55                 inc bx
56                 inc byte [es:bp]
57                 jcxz .done
58                 jns .stdbyte
59                 jmp .startseq
60 .same:
61                 cmp bl,2
62                 jb .plainbyte
63                 ; 3 bytes or more in a row, time to convert sequence
64                 sub byte [es:bp],bl
65                 jnz .normal
66                 dec di                  ; We killed a whole stretch, remove start byte
67 .normal:
68                 inc bx
69                 sub di,bx
70                 mov bp,di
71                 mov al,bl
72                 add al,126
73                 stosb
74                 mov al,ah
75                 stosb
76 .getrun:
77                 jcxz .done
78                 cmp bl,255-126
79                 jae .startseq
80                 lodsb
81                 cmp al,ah
82                 jne .nomatch
83                 inc bx
84                 inc byte [es:bp]
85                 dec cx
86                 jmp .getrun
87 .nomatch:
88                 dec si
89                 jmp .startseq
90 .done:
91                 xor al,al
92                 stosb
93 .done_null:
94                 pop dx
95                 sub dx,di
96                 neg dx
97                 pop bp
98                 pop cx
99                 pop bx
100                 pop ax
101                 ret
103 ; rllunpack:
104 ;       Unpack bytes from DS:SI into ES:DI
105 ;       On return SI, DI are updated and CX contains number of bytes output
107 rllunpack:
108                 push ax
109                 push di
110                 xor cx,cx
111 .header:
112                 lodsb
113                 and al,al
114                 jz .done
115                 cmp al,129
116                 jae .isrun
117                 ; Not a run
118                 mov cl,al
119                 rep movsb
120                 jmp .header
121 .isrun:
122                 sub al,126
123                 mov cl,al
124                 lodsb
125                 rep stosb
126                 jmp .header
127 .done:
128                 pop cx
129                 sub cx,di
130                 neg cx
131                 pop ax
132                 ret