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