|
@@ -21,15 +21,15 @@
|
21
|
21
|
*/
|
22
|
22
|
|
23
|
23
|
/****************************************************************************
|
24
|
|
- * This file provides the decompress_block() and decompress_block16()
|
25
|
|
- * functions which can be called in order to decompress an image
|
26
|
|
- * compressed with the nrv2b utility in src/util.
|
|
24
|
+ * This file provides the decompress() and decompress16() functions
|
|
25
|
+ * which can be called in order to decompress an image compressed with
|
|
26
|
+ * the nrv2b utility in src/util.
|
27
|
27
|
*
|
28
|
28
|
* These functions are designed to be called by the prefix. They are
|
29
|
29
|
* position-independent code.
|
30
|
30
|
*
|
31
|
31
|
* The same basic assembly code is used to compile both
|
32
|
|
- * decompress_block() and decompress_block16().
|
|
32
|
+ * decompress() and decompress16().
|
33
|
33
|
****************************************************************************
|
34
|
34
|
*/
|
35
|
35
|
|
|
@@ -39,57 +39,58 @@
|
39
|
39
|
|
40
|
40
|
#ifdef CODE16
|
41
|
41
|
/****************************************************************************
|
42
|
|
- * decompress_block16 (real-mode near call, position independent)
|
|
42
|
+ * decompress16 (real-mode near call, position independent)
|
|
43
|
+ *
|
|
44
|
+ * Decompress data in 16-bit mode
|
43
|
45
|
*
|
44
|
46
|
* Parameters (passed via registers):
|
45
|
|
- * %ds:%si - Pointer to compressed input data
|
46
|
|
- * %es:%di - Pointer to output buffer
|
|
47
|
+ * %ds:%esi - Start of compressed input data
|
|
48
|
+ * %es:%edi - Start of output buffer
|
47
|
49
|
* Returns:
|
48
|
|
- * All registers are preserved
|
|
50
|
+ * %ds:%esi - End of compressed input data
|
|
51
|
+ * %es:%edi - End of decompressed output data
|
|
52
|
+ * All other registers are preserved
|
49
|
53
|
*
|
50
|
|
- * NOTE: The compressed data size must be in the range [1,65533-%si]
|
|
54
|
+ * NOTE: It would be possible to build a smaller version of the
|
|
55
|
+ * decompression code for -DKEEP_IT_REAL by using
|
|
56
|
+ * #define REG(x) x
|
|
57
|
+ * to use 16-bit registers where possible. This would impose limits
|
|
58
|
+ * that the compressed data size must be in the range [1,65533-%si]
|
51
|
59
|
* and the uncompressed data size must be in the range [1,65536-%di]
|
52
|
60
|
* (where %si and %di are the input values for those registers). Note
|
53
|
61
|
* particularly that the lower limit is 1, not 0, and that the upper
|
54
|
62
|
* limit on the input (compressed) data really is 65533, since the
|
55
|
63
|
* algorithm may read up to three bytes beyond the end of the input
|
56
|
64
|
* data, since it reads dwords.
|
57
|
|
- *
|
58
|
|
- * Although splitting up the data into (almost) 64kB chunks for
|
59
|
|
- * compression is awkward and worsens the compression ratio, it has
|
60
|
|
- * little to no practical effect since our image size is currently
|
61
|
|
- * <64kB for all single drivers. Having a decompression routine that
|
62
|
|
- * can run in real-mode avoids the need to duplicate RM-to-PM
|
63
|
|
- * transition code from librm (or have part of librm kept
|
64
|
|
- * uncompressed, which is itself awkward) and means that we don't need
|
65
|
|
- * to set up the PM stack until we hit the setup routine itself.
|
66
|
65
|
****************************************************************************
|
67
|
66
|
*/
|
68
|
67
|
|
69
|
|
-#define REG(x) x
|
|
68
|
+#define REG(x) e ## x
|
70
|
69
|
|
71
|
70
|
.code16
|
72
|
|
- .globl decompress_block16
|
73
|
|
-decompress_block16:
|
|
71
|
+ .globl decompress16
|
|
72
|
+decompress16:
|
74
|
73
|
|
75
|
74
|
#else /* CODE16 */
|
76
|
75
|
|
77
|
76
|
/****************************************************************************
|
78
|
|
- * decompress_block (32-bit protected-mode near call, position independent)
|
|
77
|
+ * decompress (32-bit protected-mode near call, position independent)
|
79
|
78
|
*
|
80
|
79
|
* Parameters (passed via registers):
|
81
|
|
- * %ds:%esi - Pointer to compressed input data
|
82
|
|
- * %es:%edi - Pointer to output buffer
|
|
80
|
+ * %ds:%esi - Start of compressed input data
|
|
81
|
+ * %es:%edi - Start of output buffer
|
83
|
82
|
* Returns:
|
84
|
|
- * All registers are preserved
|
|
83
|
+ * %ds:%esi - End of compressed input data
|
|
84
|
+ * %es:%edi - End of decompressed output data
|
|
85
|
+ * All other registers are preserved
|
85
|
86
|
****************************************************************************
|
86
|
87
|
*/
|
87
|
88
|
|
88
|
89
|
#define REG(x) e ## x
|
89
|
90
|
|
90
|
91
|
.code32
|
91
|
|
- .globl decompress_block
|
92
|
|
-decompress_block:
|
|
92
|
+ .globl decompress
|
|
93
|
+decompress:
|
93
|
94
|
|
94
|
95
|
#endif /* CODE16 */
|
95
|
96
|
|
|
@@ -100,7 +101,10 @@ decompress_block:
|
100
|
101
|
#define xDI REG(di)
|
101
|
102
|
|
102
|
103
|
/* Save registers */
|
103
|
|
- pushal
|
|
104
|
+ push %xAX
|
|
105
|
+ pushl %ebx
|
|
106
|
+ push %xCX
|
|
107
|
+ push %xBP
|
104
|
108
|
/* Do the decompression */
|
105
|
109
|
cld
|
106
|
110
|
xor %xBP, %xBP
|
|
@@ -169,5 +173,8 @@ getbit32:
|
169
|
173
|
|
170
|
174
|
decompr_end_n2b:
|
171
|
175
|
/* Restore registers and return */
|
172
|
|
- popal
|
|
176
|
+ pop %xBP
|
|
177
|
+ pop %xCX
|
|
178
|
+ popl %ebx
|
|
179
|
+ pop %xAX
|
173
|
180
|
ret
|