2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
6 /*****************************************************************************
10 AROS_LH1(void, StackSwap,
13 AROS_LHA(struct StackSwapStruct *, newStack, A0),
16 struct ExecBase *, SysBase, 122, Exec)
19 This function switches to the new stack given by the parameters in the
20 stackswapstruct structure. The old stack parameters are returned in
21 the same structure so that the stack can be restored later
24 newStack - parameters for the new stack
40 ******************************************************************************/
42 #include "aros/m68k/asm.h"
46 .globl AROS_SLIB_ENTRY(StackSwap,Exec)
48 AROS_SLIB_ENTRY(StackSwap,Exec):
50 // Here's how the stack looks right now
51 // 0(%sp) : Return Address
52 #ifndef DoRegisterCalls
53 // 4(%sp) : pointer to StackSwap structure
56 /* Preserve returnaddress and fix sp */
57 move.l (%sp)+,%d1 // d1 contains return address
58 #ifndef DoRegisterCalls
59 move.l (%sp)+,%a0 // a0 holds param to this function
61 // now the stack is 'clean'
63 move.l %a6,-(%sp) // save contents of %a6
65 /* Get pointer to tc_SPLower in a1 (tc_SPUpper is next) */
66 move.l 0x4,%a6 // execbase to a6
67 bsr get_offsetof_ThisTask
69 bsr get_offsetof_tc_SPLower
72 move.l %d1,%d0 // d0 contains return address now
75 movem.l %d0/%a0/%a1,-(%sp) // d0: save return address on stack
76 // a0: param to this function onto stack
77 // a1: address of tc_SPLower to stack
78 move.l %a6,-(%sp) // a6: Execbase onto stack
80 /* Just to be sure interrupts always find a good stackframe */
81 jsr Disable(%a6) // disable interrupts
83 move.l (%sp)+,%a6 // a6: Execbase from stack
84 movem.l (%sp)+,%d0/%a0/%a1 // a1 holds address of tc_SPlower
85 // a0 holds param to this function
86 // d0 holds return address
88 move.l (%sp)+,%a6 // original a6 from stack
90 /* Swap Lower boundaries */
91 move.l (%a1),%d1 // d1 holds content of tc_SPLower
92 move.l (%a0),(%a1)+ // write the content of the first param in
93 // the structure to this function to tc_SPlower
94 move.l %d1,(%a0)+ // write d1 back to structure
96 /* Swap higher boundaries */
97 move.l (%a1),%d1 // d1 holds content of tc_SPHigher (???? check)
98 move.l (%a0),(%a1) // write the content of the 2nd param in
99 // the structure to this function to tc_SPHigher (??? check)
100 move.l %d1,(%a0)+ // write d1 back to structure
102 /* Swap stackpointers */
103 move.l %sp,%d1 // current stack pointer to d1
104 move.l (%a0),%sp // desired stack pointer to sp
105 move.l %d1,(%a0) // old stack pointer back into the structure
107 movem.l %d0/%a6,-(%sp) // save %d0 onto stack
108 // save %a6 onto stack
110 /* Reenable interrupts. */
111 move.l 0x4,%a6 // get ExecBase
112 move.l %a6,-(%sp) // ExecBase onto stack
113 jsr Enable(%a6) // Enable interrupts
114 move.l (%sp)+,%a6 // dummy
116 movem.l (%sp)+,%d0/%a6 // restore orig. content of %a6 register
117 // restore return address to d0
119 #ifndef DoRegisterCalls
120 move.l #0,-(%sp) // write fake parameter to this function
123 /* Restore returnaddress and return */
124 move.l %d0,-(%sp) // return address onto stack
126 // Here's how the stack looks right now
127 // 0(%sp) : Return Address
128 // 4(%sp) : fake pointer to StackSwap structure