movebits: rewrite significant chunks of the algorithm
[syslinux.git] / rllpack.inc
bloba556e00aac047d5ff8a737b1fbc4f125c89dda6c
1 ; -*- fundamental -*- ---------------------------------------------------
3 ;   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
5 ;   This program is free software; you can redistribute it and/or modify
6 ;   it under the terms of the GNU General Public License as published by
7 ;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;   (at your option) any later version; incorporated herein by reference.
11 ; -----------------------------------------------------------------------
14 ; rllpack.inc
16 ; Very simple RLL compressor/decompressor, used to pack binary structures
17 ; together.
19 ; Format of leading byte
20 ; 1-128         = x verbatim bytes follow
21 ; 129-223       = (x-126) times subsequent byte
22 ; 224-255       = (x-224)*256+(next byte) times the following byte
23 ; 0             = end of data
25 ; These structures are stored *in reverse order* in high memory.
26 ; High memory pointers point to one byte beyond the end.
29                 section .text
32 ; rllpack:
33 ;       Pack CX bytes from SI into EDI.
34 ;       Returns updated SI and EDI.
36 rllpack:
37                 push word .pmentry
38                 call simple_pm_call
39                 ret
41 .pmentry:
42                 push cx
43                 push ebx
44                 push edx
45 .startseq:
46                 xor ax,ax               ; Zero byte
47                 xor ebx,ebx             ; Run length zero
48                 dec edi
49                 mov edx,edi             ; Pointer to header byte
50                 mov [edi],al            ; Create header byte
51                 jcxz .done              ; If done, this was the terminator
52 .stdbyte:
53                 lodsb
54                 dec edi
55                 mov [edi],al
56                 dec cx
57                 cmp ah,al
58                 je .same
59 .diff:
60                 mov ah,al
61                 xor bx,bx
62 .plainbyte:
63                 inc bx
64                 inc byte [edx]
65                 jcxz .startseq
66                 jns .stdbyte
67                 jmp .startseq
68 .same:
69                 cmp bl,2
70                 jb .plainbyte
71                 ; 3 bytes or more in a row, time to convert sequence
72                 sub [edx],bl
73                 jnz .normal
74                 inc edi                 ; We killed a whole stretch,
75                                         ; drop start byte
76 .normal:
77                 inc bx
78                 add edi,ebx             ; Remove the stored run bytes
79 .getrun:
80                 jcxz .nomatch
81                 lodsb
82                 cmp al,ah
83                 jne .nomatch
84                 cmp bx,(256-224)*256-1  ; Maximum run size
85                 jae .nomatch
86                 inc bx
87                 dec cx
88                 jmp .getrun
89 .nomatch:
90                 cmp bx,224-126
91                 jae .twobyte
92 .onebyte:
93                 add bl,126
94                 dec edi
95                 mov [edi],bl
96                 jmp .storebyte
97 .twobyte:
98                 add bh,224
99                 sub edi,2
100                 mov [edi],bx
101 .storebyte:
102                 dec edi
103                 mov [edi],ah
104                 dec si                  ; Reload subsequent byte
105                 jmp .startseq
106 .done:
107                 pop edx
108                 pop ebx
109                 pop cx
110                 ret
112 ; rllunpack:
113 ;       Unpack bytes from ESI into DI
114 ;       On return ESI, DI are updated and CX contains number of bytes output.
116 rllunpack:
117                 push word .pmentry
118                 call simple_pm_call
119                 ret
121 .pmentry:
122                 push di
123                 xor cx,cx
124 .header:
125                 dec esi
126                 mov cl,[esi]
127                 jcxz .done
128                 cmp cl,129
129                 jae .isrun
130                 ; Not a run
131 .copy:
132                 dec esi
133                 mov al,[esi]
134                 stosb
135                 loop .copy
136                 jmp .header
137 .isrun:
138                 cmp cl,224
139                 jae .longrun
140                 sub cl,126
141 .dorun:
142                 dec esi
143                 mov al,[esi]
144                 rep stosb
145                 jmp .header
146 .longrun:
147                 sub cl,224
148                 mov ch,cl
149                 dec esi
150                 mov cl,[esi]
151                 jmp .dorun
152 .done:
153                 pop cx
154                 sub cx,di
155                 neg cx
156                 ret