1 |
; -*- fundamental -*- |
; -*- fundamental -*- --------------------------------------------------- |
2 |
; ----------------------------------------------------------------------- |
; |
3 |
; |
; Copyright 2007-2009 H. Peter Anvin - All Rights Reserved |
4 |
; Copyright 2004 H. Peter Anvin - All Rights Reserved |
; Copyright 2009 Intel Corporation; author: H. Peter Anvin |
5 |
; |
; |
6 |
; This program is free software; you can redistribute it and/or modify |
; 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 |
; it under the terms of the GNU General Public License as published by |
10 |
; (at your option) any later version; incorporated herein by reference. |
; (at your option) any later version; incorporated herein by reference. |
11 |
; |
; |
12 |
; ----------------------------------------------------------------------- |
; ----------------------------------------------------------------------- |
|
; $Id: rllpack.inc,v 1.1 2007-09-01 22:44:05 niro Exp $ |
|
13 |
|
|
14 |
; |
; |
15 |
; rllpack.inc |
; rllpack.inc |
19 |
; |
; |
20 |
; Format of leading byte |
; Format of leading byte |
21 |
; 1-128 = x verbatim bytes follow |
; 1-128 = x verbatim bytes follow |
22 |
; 129-255 = (x-126) times subsequent byte |
; 129-223 = (x-126) times subsequent byte |
23 |
|
; 224-255 = (x-224)*256+(next byte) times the following byte |
24 |
; 0 = end of data |
; 0 = end of data |
25 |
; |
; |
26 |
|
; These structures are stored *in reverse order* in high memory. |
27 |
|
; High memory pointers point to one byte beyond the end. |
28 |
|
; |
29 |
|
|
30 |
section .text |
section .text |
31 |
|
|
32 |
; |
; |
33 |
; rllpack: |
; rllpack: |
34 |
; Pack CX bytes from DS:SI into ES:DI |
; Pack ECX bytes from ESI into EDI. |
35 |
; Returns updated SI, DI and CX = number of bytes output |
; Returns updated ESI and EDI. |
36 |
; |
; |
37 |
rllpack: |
rllpack: |
38 |
push ax |
push word .pmentry |
39 |
push bx |
call simple_pm_call |
40 |
push cx |
ret |
41 |
push bp |
|
42 |
push di |
bits 32 |
43 |
|
.pmentry: |
44 |
|
push ecx |
45 |
|
push ebx |
46 |
|
push edx |
47 |
.startseq: |
.startseq: |
48 |
xor ax,ax ; Zero byte |
xor eax,eax ; Zero byte |
49 |
xor bx,bx ; Run length zero |
xor ebx,ebx ; Run length zero |
50 |
mov bp,di ; Pointer to header byte |
dec edi |
51 |
stosb ; Store header byte (might be zero) |
mov edx,edi ; Pointer to header byte |
52 |
jcxz .done_null |
mov [edi],al ; Create header byte |
53 |
|
jcxz .done ; If done, this was the terminator |
54 |
.stdbyte: |
.stdbyte: |
55 |
lodsb |
lodsb |
56 |
stosb |
dec edi |
57 |
dec cx |
mov [edi],al |
58 |
|
dec ecx |
59 |
cmp ah,al |
cmp ah,al |
60 |
je .same |
je .same |
61 |
.diff: |
.diff: |
62 |
mov ah,al |
mov ah,al |
63 |
xor bx,bx |
xor ebx,ebx |
64 |
.plainbyte: |
.plainbyte: |
65 |
inc bx |
inc ebx |
66 |
inc byte [es:bp] |
inc byte [edx] |
67 |
jcxz .done |
jcxz .startseq |
68 |
jns .stdbyte |
jns .stdbyte |
69 |
jmp .startseq |
jmp .startseq |
70 |
.same: |
.same: |
71 |
cmp bl,2 |
cmp bl,2 |
72 |
jb .plainbyte |
jb .plainbyte |
73 |
; 3 bytes or more in a row, time to convert sequence |
; 3 bytes or more in a row, time to convert sequence |
74 |
sub byte [es:bp],bl |
sub [edx],bl |
75 |
jnz .normal |
jnz .normal |
76 |
dec di ; We killed a whole stretch, remove start byte |
inc edi ; We killed a whole stretch, |
77 |
|
; drop start byte |
78 |
.normal: |
.normal: |
79 |
inc bx |
inc ebx |
80 |
sub di,bx |
add edi,ebx ; Remove the stored run bytes |
|
mov bp,di |
|
|
mov al,bl |
|
|
add al,126 |
|
|
stosb |
|
|
mov al,ah |
|
|
stosb |
|
81 |
.getrun: |
.getrun: |
82 |
jcxz .done |
jcxz .nomatch |
|
cmp bl,255-126 |
|
|
jae .startseq |
|
83 |
lodsb |
lodsb |
84 |
cmp al,ah |
cmp al,ah |
85 |
jne .nomatch |
jne .nomatch |
86 |
inc bx |
cmp bx,(256-224)*256-1 ; Maximum run size |
87 |
inc byte [es:bp] |
jae .nomatch |
88 |
dec cx |
inc ebx |
89 |
|
dec ecx |
90 |
jmp .getrun |
jmp .getrun |
91 |
.nomatch: |
.nomatch: |
92 |
dec si |
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 |
jmp .startseq |
108 |
.done: |
.done: |
109 |
xor al,al |
pop edx |
110 |
stosb |
pop ebx |
111 |
.done_null: |
pop ecx |
|
pop dx |
|
|
sub dx,di |
|
|
neg dx |
|
|
pop bp |
|
|
pop cx |
|
|
pop bx |
|
|
pop ax |
|
112 |
ret |
ret |
113 |
|
|
114 |
|
bits 16 |
115 |
; |
; |
116 |
; rllunpack: |
; rllunpack: |
117 |
; Unpack bytes from DS:SI into ES:DI |
; Unpack bytes from ESI into EDI |
118 |
; On return SI, DI are updated and CX contains number of bytes output |
; On return ESI, EDI are updated and |
119 |
; |
; ECX contains number of bytes output. |
120 |
|
; |
121 |
rllunpack: |
rllunpack: |
122 |
push ax |
push word .pmentry |
123 |
push di |
call simple_pm_call |
124 |
xor cx,cx |
ret |
125 |
|
|
126 |
|
bits 32 |
127 |
|
.pmentry: |
128 |
|
push edi |
129 |
|
xor ecx,ecx |
130 |
.header: |
.header: |
131 |
lodsb |
dec esi |
132 |
and al,al |
mov cl,[esi] |
133 |
jz .done |
jcxz .done |
134 |
cmp al,129 |
cmp cl,129 |
135 |
jae .isrun |
jae .isrun |
136 |
; Not a run |
; Not a run |
137 |
mov cl,al |
.copy: |
138 |
rep movsb |
dec esi |
139 |
|
mov al,[esi] |
140 |
|
stosb |
141 |
|
loop .copy |
142 |
jmp .header |
jmp .header |
143 |
.isrun: |
.isrun: |
144 |
sub al,126 |
cmp cl,224 |
145 |
mov cl,al |
jae .longrun |
146 |
lodsb |
sub cl,126 |
147 |
|
.dorun: |
148 |
|
dec esi |
149 |
|
mov al,[esi] |
150 |
rep stosb |
rep stosb |
151 |
jmp .header |
jmp .header |
152 |
|
.longrun: |
153 |
|
sub cl,224 |
154 |
|
mov ch,cl |
155 |
|
dec esi |
156 |
|
mov cl,[esi] |
157 |
|
jmp .dorun |
158 |
.done: |
.done: |
159 |
pop cx |
pop ecx |
160 |
sub cx,di |
sub ecx,edi |
161 |
neg cx |
neg ecx |
|
pop ax |
|
162 |
ret |
ret |
163 |
|
|
164 |
|
bits 16 |