2 * Copyright Robert J. Amstadt, 1993
7 #if defined(__NetBSD__) || defined(__FreeBSD__)
15 /**********************************************************************
16 * Places to keep info about the current 32-bit stack frame.
18 .globl _IF1632_Saved32_esp,_IF1632_Saved32_ebp,_IF1632_Saved32_ss
26 /**********************************************************************
27 * Places to keep info about the current 16-bit stack frame.
29 .globl _IF1632_Saved16_esp,_IF1632_Saved16_ebp,_IF1632_Saved16_ss
46 /**********************************************************************
47 * int CallToInit16(unsigned long csip, unsigned long sssp,
68 pushl _IF1632_Saved32_esp
69 pushl _IF1632_Saved32_ebp
70 pushw _IF1632_Saved32_ss
80 * Put stack registers where we can get them after stack switch.
82 movw %ss,_IF1632_Saved32_ss
83 movl %esp,_IF1632_Saved32_esp
84 movl %ebp,_IF1632_Saved32_ebp
87 * Load initial registers
89 movw _WIN_StackSize,%bx
90 movw _WIN_HeapSize,%cx
117 * Restore old stack and segment registers.
120 * 1. Trust that fs or gs hasn't changed.
121 * 2. Rely on knowledge of Linux use of segments.
123 * I'll opt for choice 2 because who knows what programs we
124 * going to run. Linux should be fairly stable in terms of
134 movw _IF1632_Saved32_ss,%ss
135 movl _IF1632_Saved32_esp,%esp
136 movl _IF1632_Saved32_ebp,%ebp
139 * Restore registers, but do not destroy return value.
141 popw _IF1632_Saved32_ss
142 popl _IF1632_Saved32_ebp
143 popl _IF1632_Saved32_esp
144 movl %eax,return_value
146 movl return_value,%eax
151 /**********************************************************************
152 * int CallTo16(unsigned long csip, unsigned short ds)
167 * Get target address and new ds
170 movl %eax,jump_target
175 * Switch to 16-bit stack
177 pushl _IF1632_Saved32_esp
178 pushl _IF1632_Saved32_ebp
179 pushw _IF1632_Saved32_ss
181 movw %ss,_IF1632_Saved32_ss
182 movl %esp,_IF1632_Saved32_esp
183 movl %ebp,_IF1632_Saved32_ebp
185 movw _IF1632_Saved16_ss,%ss
186 movl _IF1632_Saved16_esp,%esp
187 movl _IF1632_Saved16_ebp,%ebp
198 * Restore old stack and segment registers.
201 * 1. Trust that fs or gs hasn't changed.
202 * 2. Rely on knowledge of Linux use of segments.
204 * I'll opt for choice 2 because who knows what programs we
205 * going to run. Linux should be fairly stable in terms of
216 movw %ss,_IF1632_Saved16_ss
217 movl %esp,_IF1632_Saved16_esp
218 movl %ebp,_IF1632_Saved16_ebp
220 movw _IF1632_Saved32_ss,%ss
221 movl _IF1632_Saved32_esp,%esp
222 movl _IF1632_Saved32_ebp,%ebp
224 popw _IF1632_Saved32_ss
225 popl _IF1632_Saved32_ebp
226 popl _IF1632_Saved32_esp
228 movl %eax,return_value
229 movw return_value+2,%dx
234 /**********************************************************************
237 * This function is called as a relay point to the built function
238 * handler. KERNEL, USER and GDI calls are dealt with by this
239 * handler. Calls to these DLLs will be mapped to a call handler
240 * which will set EAX to a number indicating which DLL and which
241 * function within that DLL.
243 * This function will pass to the function handler two arguments.
244 * The first argument will be the contents of EAX, the second
245 * argument will be a segment:offset pair that points to the
255 * Save registers. 286 mode does not have fs or gs.
261 * Restore segment registers.
270 * Save old stack save variables, save stack registers, reload
273 pushl _IF1632_Saved16_esp
274 pushl _IF1632_Saved16_ebp
275 pushw _IF1632_Saved16_ss
277 movw %ss,_IF1632_Saved16_ss
278 movl %esp,_IF1632_Saved16_esp
279 movl %ebp,_IF1632_Saved16_ebp
281 movw _IF1632_Saved32_ss,%ss
282 movl _IF1632_Saved32_esp,%esp
283 movl _IF1632_Saved32_ebp,%ebp
289 pushw _IF1632_Saved16_ss
290 pushw _IF1632_Saved16_esp
299 * Restore registers, but do not destroy return value.
301 movw _IF1632_Saved16_ss,%ss
302 movl _IF1632_Saved16_esp,%esp
303 movl _IF1632_Saved16_ebp,%ebp
305 popw _IF1632_Saved16_ss
306 popl _IF1632_Saved16_ebp
307 popl _IF1632_Saved16_esp
315 * Now we need to ditch the parameter bytes that were left on the
316 * stack. We do this by effectively popping the number of bytes,
317 * and the return address, removing the parameters and then putting
318 * the return address back on the stack.
319 * Normally this field is filled in by the relevant function in
320 * the emulation library, since it should know how many bytes to
334 * Last, but not least we need to move the high word from eax to dx
344 /**********************************************************************
347 * This function is same one as CallTo32() except that the high
348 * word of EAX won't be moved to DX.
357 * Save registers. 286 mode does not have fs or gs.
363 * Restore segment registers.
372 * Save old stack save variables, save stack registers, reload
375 pushl _IF1632_Saved16_esp
376 pushl _IF1632_Saved16_ebp
377 pushw _IF1632_Saved16_ss
379 movw %ss,_IF1632_Saved16_ss
380 movl %esp,_IF1632_Saved16_esp
381 movl %ebp,_IF1632_Saved16_ebp
383 movw _IF1632_Saved32_ss,%ss
384 movl _IF1632_Saved32_esp,%esp
385 movl _IF1632_Saved32_ebp,%ebp
391 pushw _IF1632_Saved16_ss
392 pushw _IF1632_Saved16_esp
401 * Restore registers, but do not destroy return value.
403 movw _IF1632_Saved16_ss,%ss
404 movl _IF1632_Saved16_esp,%esp
405 movl _IF1632_Saved16_ebp,%ebp
407 popw _IF1632_Saved16_ss
408 popl _IF1632_Saved16_ebp
409 popl _IF1632_Saved16_esp
417 * Now we need to ditch the parameter bytes that were left on the
418 * stack. We do this by effectively popping the number of bytes,
419 * and the return address, removing the parameters and then putting
420 * the return address back on the stack.
421 * Normally this field is filled in by the relevant function in
422 * the emulation library, since it should know how many bytes to
437 /**********************************************************************
438 * ReturnFromRegisterFunc()
440 .globl _ReturnFromRegisterFunc
441 _ReturnFromRegisterFunc:
443 * Restore 16-bit stack
445 movw _IF1632_Saved16_ss,%ss
446 movl _IF1632_Saved16_esp,%esp
447 movl _IF1632_Saved16_ebp,%ebp
449 popw _IF1632_Saved16_ss
450 popl _IF1632_Saved16_ebp
451 popl _IF1632_Saved16_esp
459 * This leaves us with a stack that has number of arguments,
460 * the return address, the saved registers, and the return
463 add $6,%esp /* argument count, return address */
464 #include "pop.h" /* restore context */
467 * Return to original caller.