1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Inline functions (MSVC style 386 asm).
12 *
13 * By Stefan Schimanski.
14 *
15 * See readme.txt for copyright information.
16 */
17
18
19 #if (!defined ALLEGRO_MSVC) || (!defined ALLEGRO_I386)
20 #error bad include
21 #endif
22
23
24 #pragma warning (disable: 4035)
25
26
27 #ifdef ALLEGRO_IMPORT_GFX_ASM
28
29 /* _default_ds:
30 * Return a copy of the current %ds selector.
31 */
_default_ds(void)32 INLINE _AL_DLL int _default_ds(void)
33 {
34 _asm {
35 mov eax, 0
36 mov ax, ds
37 }
38 }
39
40 END_OF_INLINE(_default_ds);
41
42
43
44 /* bmp_write_line:
45 * Bank switch function.
46 */
bmp_write_line(BITMAP * bmp,int lyne)47 INLINE _AL_DLL uintptr_t bmp_write_line(BITMAP *bmp, int lyne)
48 {
49 _asm {
50 mov edx, bmp
51 mov ecx, [edx]BITMAP.write_bank
52 mov eax, lyne
53 call ecx
54 }
55 }
56
57 END_OF_INLINE(bmp_write_line);
58
59
60
61 /* bmp_read_line:
62 * Bank switch function.
63 */
bmp_read_line(BITMAP * bmp,int lyne)64 INLINE _AL_DLL uintptr_t bmp_read_line(BITMAP *bmp, int lyne)
65 {
66 _asm {
67 mov edx, bmp
68 mov ecx, [edx]BITMAP.read_bank
69 mov eax, lyne
70 call ecx
71 }
72 }
73
74 END_OF_INLINE(bmp_read_line);
75
76
77
78 /* bmp_unwrite_line:
79 * Terminate bank switch function.
80 */
bmp_unwrite_line(BITMAP * bmp)81 INLINE _AL_DLL void bmp_unwrite_line(BITMAP *bmp)
82 {
83 _asm {
84 mov edx, bmp
85 mov ecx, [edx]BITMAP.vtable
86 mov ecx, [ecx]GFX_VTABLE.unwrite_bank
87 call ecx
88 }
89 }
90
91 END_OF_INLINE(bmp_unwrite_line);
92
93
94 #endif /* ALLEGRO_IMPORT_GFX_ASM */
95
96
97 #ifdef ALLEGRO_IMPORT_MATH_ASM
98
99 /* _set_errno_erange:
100 */
_set_errno_erange(void)101 INLINE void _set_errno_erange(void)
102 {
103 *allegro_errno = ERANGE;
104 }
105
106 END_OF_INLINE(_set_errno_erange);
107
108
109
110 /* fixadd:
111 * Fixed point (16.16) addition.
112 */
fixadd(fixed x,fixed y)113 INLINE _AL_DLL fixed fixadd(fixed x, fixed y)
114 {
115 _asm {
116 mov eax, x
117 add eax, y
118 jno Out1
119 call _set_errno_erange
120 mov eax, 0x7FFFFFFF
121 cmp y, 0
122 jg Out1
123 neg eax
124 Out1:
125 }
126 }
127
128 END_OF_INLINE(fixadd);
129
130
131
132 /* fixsub:
133 * Fixed point (16.16) subtraction.
134 */
fixsub(fixed x,fixed y)135 INLINE _AL_DLL fixed fixsub(fixed x, fixed y)
136 {
137 _asm {
138 mov eax, x
139 sub eax, y
140 jno Out1
141 call _set_errno_erange
142 mov eax, 0x7FFFFFFF
143 cmp y, 0
144 jl Out1
145 neg eax
146 Out1:
147 }
148 }
149
150 END_OF_INLINE(fixsub);
151
152
153
154 /* fixmul:
155 * Fixed point (16.16) multiplication.
156 */
fixmul(fixed x,fixed y)157 INLINE _AL_DLL fixed fixmul(fixed x, fixed y)
158 {
159 _asm {
160 mov eax, x
161 imul y
162 shrd eax, edx, 16
163 sar edx, 15
164 jz Out2
165 cmp edx, -1
166 jz Out2
167 call _set_errno_erange
168 mov eax, 0x7FFFFFFF
169 cmp x, 0
170 jge Out1
171 neg eax
172 Out1:
173 cmp y, 0
174 jge Out2
175 neg eax
176 Out2:
177 }
178 }
179
180 END_OF_INLINE(fixmul);
181
182
183
184 /* fixdiv:
185 * Fixed point (16.16) division.
186 */
fixdiv(fixed x,fixed y)187 INLINE _AL_DLL fixed fixdiv(fixed x, fixed y)
188 {
189 _asm {
190 mov ecx, y
191 xor ebx, ebx
192 mov eax, x
193 or eax, eax
194 jns Out1
195 neg eax
196 inc ebx
197 Out1:
198 or ecx, ecx
199 jns Out2
200 neg ecx
201 inc ebx
202 Out2:
203 mov edx, eax
204 shr edx, 0x10
205 shl eax, 0x10
206 cmp edx, ecx
207 jae Out3
208 div ecx
209 or eax, eax
210 jns Out4
211 Out3:
212 call _set_errno_erange
213 mov eax, 0x7FFFFFFF
214 Out4:
215 test ebx, 1
216 je Out5
217 neg eax
218 Out5:
219 }
220 }
221
222 END_OF_INLINE(fixdiv);
223
224
225
226 /* fixfloor :
227 * Fixed point version of floor().
228 * Note that it returns an integer result (not a fixed one)
229 */
fixfloor(fixed x)230 INLINE _AL_DLL int fixfloor(fixed x)
231 {
232 _asm {
233 mov eax, x
234 sar eax, 0x10
235 }
236 }
237
238 END_OF_INLINE(fixfloor);
239
240
241
242 /* fixceil:
243 * Fixed point version of ceil().
244 * Note that it returns an integer result (not a fixed one)
245 */
fixceil(fixed x)246 INLINE _AL_DLL int fixceil(fixed x)
247 {
248 _asm {
249 mov eax, x
250 add eax, 0xFFFF
251 jns Out1
252 jo Out2
253 Out1:
254 sar eax, 0x10
255 jmp Out3
256 Out2:
257 call _set_errno_erange
258 mov eax, 0x7FFF
259 Out3:
260 }
261 }
262
263 END_OF_INLINE(fixceil);
264
265 #endif /* ALLEGRO_IMPORT_MATH_ASM */
266
267
268 #pragma warning (default: 4035)
269
270