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
197 * Restore old stack and segment registers.
200 * 1. Trust that fs or gs hasn't changed.
201 * 2. Rely on knowledge of Linux use of segments.
203 * I'll opt for choice 2 because who knows what programs we
204 * going to run. Linux should be fairly stable in terms of
215 movw %ss,_IF1632_Saved16_ss
216 movl %esp,_IF1632_Saved16_esp
217 movl %ebp,_IF1632_Saved16_ebp
219 movw _IF1632_Saved32_ss,%ss
220 movl _IF1632_Saved32_esp,%esp
221 movl _IF1632_Saved32_ebp,%ebp
223 popw _IF1632_Saved32_ss
224 popl _IF1632_Saved32_ebp
225 popl _IF1632_Saved32_esp
227 movl %eax,return_value
228 movw return_value+2,%dx
233 /**********************************************************************
236 * This function is called as a relay point to the built function
237 * handler. KERNEL, USER and GDI calls are dealt with by this
238 * handler. Calls to these DLLs will be mapped to a call handler
239 * which will set EAX to a number indicating which DLL and which
240 * function within that DLL.
242 * This function will pass to the function handler two arguments.
243 * The first argument will be the contents of EAX, the second
244 * argument will be a segment:offset pair that points to the
254 * Save registers. 286 mode does not have fs or gs.
260 * Restore segment registers.
269 * Save old stack save variables, save stack registers, reload
272 pushl _IF1632_Saved16_esp
273 pushl _IF1632_Saved16_ebp
274 pushw _IF1632_Saved16_ss
276 movw %ss,_IF1632_Saved16_ss
277 movl %esp,_IF1632_Saved16_esp
278 movl %ebp,_IF1632_Saved16_ebp
280 movw _IF1632_Saved32_ss,%ss
281 movl _IF1632_Saved32_esp,%esp
282 movl _IF1632_Saved32_ebp,%ebp
287 pushw _IF1632_Saved16_ss
288 pushw _IF1632_Saved16_esp
293 * Restore registers, but do not destroy return value.
295 movw _IF1632_Saved16_ss,%ss
296 movl _IF1632_Saved16_esp,%esp
297 movl _IF1632_Saved16_ebp,%ebp
299 popw _IF1632_Saved16_ss
300 popl _IF1632_Saved16_ebp
301 popl _IF1632_Saved16_esp
309 * Now we need to ditch the parameter bytes that were left on the
310 * stack. We do this by effectively popping the number of bytes,
311 * and the return address, removing the parameters and then putting
312 * the return address back on the stack.
313 * Normally this field is filled in by the relevant function in
314 * the emulation library, since it should know how many bytes to
328 * Last, but not least we need to move the high word from eax to dx
337 /**********************************************************************
338 * ReturnFromRegisterFunc()
340 .globl _ReturnFromRegisterFunc
341 _ReturnFromRegisterFunc:
343 * Restore 16-bit stack
345 movw _IF1632_Saved16_ss,%ss
346 movl _IF1632_Saved16_esp,%esp
347 movl _IF1632_Saved16_ebp,%ebp
349 popw _IF1632_Saved16_ss
350 popl _IF1632_Saved16_ebp
351 popl _IF1632_Saved16_esp
359 * This leaves us with a stack that has number of arguments,
360 * the return address, the saved registers, and the return
363 add $6,%esp /* argument count, return address */
364 #include "pop.h" /* restore context */
367 * Return to original caller.