2 * Copyright Robert J. Amstadt, 1993
7 #if defined(__NetBSD__) || defined(__FreeBSD__)
13 #define A(addr) _##addr
20 /**********************************************************************
21 * Places to keep info about the current 32-bit stack frame.
23 .globl A( IF1632_Saved32_esp), A(IF1632_Saved32_ebp), A(IF1632_Saved32_ss)
24 A(IF1632_Saved32_esp:)
26 A(IF1632_Saved32_ebp:)
31 /**********************************************************************
32 * Places to keep info about the current 16-bit stack frame.
34 .globl A(IF1632_Saved16_esp),A(IF1632_Saved16_ebp),A(IF1632_Saved16_ss)
35 A(IF1632_Saved16_esp:)
37 A(IF1632_Saved16_ebp:)
51 /**********************************************************************
52 * int CallToInit16(unsigned long csip, unsigned long sssp,
64 .globl A(CallToInit16)
73 pushl A(IF1632_Saved32_esp)
74 pushl A(IF1632_Saved32_ebp)
75 pushw A(IF1632_Saved32_ss)
85 * Put stack registers where we can get them after stack switch.
87 movw %ss,A(IF1632_Saved32_ss)
88 movl %esp,A(IF1632_Saved32_esp)
89 movl %ebp,A(IF1632_Saved32_ebp)
92 * Load initial registers
94 movw A(WIN_StackSize),%bx
95 movw A(WIN_HeapSize),%cx
98 movw A(PSPSelector),%ax
122 * Restore old stack and segment registers.
125 * 1. Trust that fs or gs hasn't changed.
126 * 2. Rely on knowledge of Linux use of segments.
128 * I'll opt for choice 2 because who knows what programs we
129 * going to run. Linux should be fairly stable in terms of
139 movw A(IF1632_Saved32_ss),%ss
140 movl A(IF1632_Saved32_esp),%esp
141 movl A(IF1632_Saved32_ebp),%ebp
144 * Restore registers, but do not destroy return value.
146 popw A(IF1632_Saved32_ss)
147 popl A(IF1632_Saved32_ebp)
148 popl A(IF1632_Saved32_esp)
149 movl %eax,return_value
151 movl return_value,%eax
156 /**********************************************************************
157 * int CallTo16 (unsigned long csip, unsigned short ds)
158 * int CallTo16cx(unsigned long csip, unsigned long dscx);
165 * 14 target cx (only CallTo16cx)
168 .globl A(CallTo16), A(CallTo16cx)
175 * Get target address and new ds
178 movl %eax,jump_target
184 * Switch to 16-bit stack
186 pushl A(IF1632_Saved32_esp)
187 pushl A(IF1632_Saved32_ebp)
188 pushw A(IF1632_Saved32_ss)
190 movw %ss,A(IF1632_Saved32_ss)
191 movl %esp,A(IF1632_Saved32_esp)
192 movl %ebp,A(IF1632_Saved32_ebp)
194 movw A(IF1632_Saved16_ss),%ss
195 movl A(IF1632_Saved16_esp),%esp
196 movl A(IF1632_Saved16_ebp),%ebp
207 * Restore old stack and segment registers.
210 * 1. Trust that fs or gs hasn't changed.
211 * 2. Rely on knowledge of Linux use of segments.
213 * I'll opt for choice 2 because who knows what programs we
214 * going to run. Linux should be fairly stable in terms of
225 movw %ss,A(IF1632_Saved16_ss)
226 movl %esp,A(IF1632_Saved16_esp)
227 movl %ebp,A(IF1632_Saved16_ebp)
229 movw A(IF1632_Saved32_ss),%ss
230 movl A(IF1632_Saved32_esp),%esp
231 movl A(IF1632_Saved32_ebp),%ebp
233 popw A(IF1632_Saved32_ss)
234 popl A(IF1632_Saved32_ebp)
235 popl A(IF1632_Saved32_esp)
237 movl %eax,return_value
238 movw return_value+2,%dx
243 /**********************************************************************
246 * This function is called as a relay point to the built function
247 * handler. KERNEL, USER and GDI calls are dealt with by this
248 * handler. Calls to these DLLs will be mapped to a call handler
249 * which will set EAX to a number indicating which DLL and which
250 * function within that DLL.
252 * This function will pass to the function handler two arguments.
253 * The first argument will be the contents of EAX, the second
254 * argument will be a segment:offset pair that points to the
264 * Save registers. 286 mode does not have fs or gs.
270 * Restore segment registers.
279 * Save old stack save variables, save stack registers, reload
282 pushl A(IF1632_Saved16_esp)
283 pushl A(IF1632_Saved16_ebp)
284 pushw A(IF1632_Saved16_ss)
286 movw %ss,A(IF1632_Saved16_ss)
287 movl %esp,A(IF1632_Saved16_esp)
288 movl %ebp,A(IF1632_Saved16_ebp)
290 movw A(IF1632_Saved32_ss),%ss
291 movl A(IF1632_Saved32_esp),%esp
292 movl A(IF1632_Saved32_ebp),%ebp
298 pushw A(IF1632_Saved16_ss)
299 pushw A(IF1632_Saved16_esp)
308 * Restore registers, but do not destroy return value.
310 movw A(IF1632_Saved16_ss),%ss
311 movl A(IF1632_Saved16_esp),%esp
312 movl A(IF1632_Saved16_ebp),%ebp
314 popw A(IF1632_Saved16_ss)
315 popl A(IF1632_Saved16_ebp)
316 popl A(IF1632_Saved16_esp)
324 * Now we need to ditch the parameter bytes that were left on the
325 * stack. We do this by effectively popping the number of bytes,
326 * and the return address, removing the parameters and then putting
327 * the return address back on the stack.
328 * Normally this field is filled in by the relevant function in
329 * the emulation library, since it should know how many bytes to
343 * Last, but not least we need to move the high word from eax to dx
353 /**********************************************************************
356 * This function is same one as CallTo32() except that the high
357 * word of EAX won't be moved to DX.
360 .globl A(CallTo32_16)
366 * Save registers. 286 mode does not have fs or gs.
372 * Restore segment registers.
381 * Save old stack save variables, save stack registers, reload
384 pushl A(IF1632_Saved16_esp)
385 pushl A(IF1632_Saved16_ebp)
386 pushw A(IF1632_Saved16_ss)
388 movw %ss,A(IF1632_Saved16_ss)
389 movl %esp,A(IF1632_Saved16_esp)
390 movl %ebp,A(IF1632_Saved16_ebp)
392 movw A(IF1632_Saved32_ss),%ss
393 movl A(IF1632_Saved32_esp),%esp
394 movl A(IF1632_Saved32_ebp),%ebp
400 pushw A(IF1632_Saved16_ss)
401 pushw A(IF1632_Saved16_esp)
410 * Restore registers, but do not destroy return value.
412 movw A(IF1632_Saved16_ss),%ss
413 movl A(IF1632_Saved16_esp),%esp
414 movl A(IF1632_Saved16_ebp),%ebp
416 popw A(IF1632_Saved16_ss)
417 popl A(IF1632_Saved16_ebp)
418 popl A(IF1632_Saved16_esp)
426 * Now we need to ditch the parameter bytes that were left on the
427 * stack. We do this by effectively popping the number of bytes,
428 * and the return address, removing the parameters and then putting
429 * the return address back on the stack.
430 * Normally this field is filled in by the relevant function in
431 * the emulation library, since it should know how many bytes to
446 /**********************************************************************
447 * ReturnFromRegisterFunc()
449 .globl A(ReturnFromRegisterFunc)
450 A(ReturnFromRegisterFunc:)
452 * Restore 16-bit stack
454 movw A(IF1632_Saved16_ss),%ss
455 movl A(IF1632_Saved16_esp),%esp
456 movl A(IF1632_Saved16_ebp),%ebp
458 popw A(IF1632_Saved16_ss)
459 popl A(IF1632_Saved16_ebp)
460 popl A(IF1632_Saved16_esp)
468 * This leaves us with a stack that has number of arguments,
469 * the return address, the saved registers, and the return
472 add $6,%esp /* argument count, return address */
473 #include "pop.h" /* restore context */
476 * Return to original caller.