rllpack: make all pointers 32 bits wide
[syslinux.git] / core / rllpack.inc
blobc3bca696662050b54d2551849b4bab8c2c8e04c5
1 ; -*- fundamental -*- ---------------------------------------------------
3 ;   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
4 ;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
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-223       = (x-126) times subsequent byte
23 ; 224-255       = (x-224)*256+(next byte) times the following byte
24 ; 0             = end of data
26 ; These structures are stored *in reverse order* in high memory.
27 ; High memory pointers point to one byte beyond the end.
30                 section .text
33 ; rllpack:
34 ;       Pack ECX bytes from ESI into EDI.
35 ;       Returns updated ESI and EDI.
37 rllpack:
38                 push word .pmentry
39                 call simple_pm_call
40                 ret
42                 bits 32
43 .pmentry:
44                 push ecx
45                 push ebx
46                 push edx
47 .startseq:
48                 xor eax,eax             ; Zero byte
49                 xor ebx,ebx             ; Run length zero
50                 dec edi
51                 mov edx,edi             ; Pointer to header byte
52                 mov [edi],al            ; Create header byte
53                 jcxz .done              ; If done, this was the terminator
54 .stdbyte:
55                 lodsb
56                 dec edi
57                 mov [edi],al
58                 dec ecx
59                 cmp ah,al
60                 je .same
61 .diff:
62                 mov ah,al
63                 xor ebx,ebx
64 .plainbyte:
65                 inc ebx
66                 inc byte [edx]
67                 jcxz .startseq
68                 jns .stdbyte
69                 jmp .startseq
70 .same:
71                 cmp bl,2
72                 jb .plainbyte
73                 ; 3 bytes or more in a row, time to convert sequence
74                 sub [edx],bl
75                 jnz .normal
76                 inc edi                 ; We killed a whole stretch,
77                                         ; drop start byte
78 .normal:
79                 inc ebx
80                 add edi,ebx             ; Remove the stored run bytes
81 .getrun:
82                 jcxz .nomatch
83                 lodsb
84                 cmp al,ah
85                 jne .nomatch
86                 cmp bx,(256-224)*256-1  ; Maximum run size
87                 jae .nomatch
88                 inc ebx
89                 dec ecx
90                 jmp .getrun
91 .nomatch:
92                 cmp bx,224-126
93                 jae .twobyte
94 .onebyte:
95                 add bl,126
96                 dec edi
97                 mov [edi],bl
98                 jmp .storebyte
99 .twobyte:
100                 add bh,224
101                 sub edi,2
102                 mov [edi],bx
103 .storebyte:
104                 dec edi
105                 mov [edi],ah
106                 dec esi                 ; Reload subsequent byte
107                 jmp .startseq
108 .done:
109                 pop edx
110                 pop ebx
111                 pop ecx
112                 ret
114                 bits 16
116 ; rllunpack:
117 ;       Unpack bytes from ESI into EDI
118 ;       On return ESI, EDI are updated and
119 ;       ECX contains number of bytes output.
121 rllunpack:
122                 push word .pmentry
123                 call simple_pm_call
124                 ret
126                 bits 32
127 .pmentry:
128                 push edi
129                 xor ecx,ecx
130 .header:
131                 dec esi
132                 mov cl,[esi]
133                 jcxz .done
134                 cmp cl,129
135                 jae .isrun
136                 ; Not a run
137 .copy:
138                 dec esi
139                 mov al,[esi]
140                 stosb
141                 loop .copy
142                 jmp .header
143 .isrun:
144                 cmp cl,224
145                 jae .longrun
146                 sub cl,126
147 .dorun:
148                 dec esi
149                 mov al,[esi]
150                 rep stosb
151                 jmp .header
152 .longrun:
153                 sub cl,224
154                 mov ch,cl
155                 dec esi
156                 mov cl,[esi]
157                 jmp .dorun
158 .done:
159                 pop ecx
160                 sub ecx,edi
161                 neg ecx
162                 ret
164                 bits 16