Bringing ChocolateCaste-0.7 into the main branch.
[AROS-Contrib.git] / bgui / stkext.asm
blob275e3225162d7c6836d405776967aa10e7073598
2 ; @(#) $Header$
4 ; BGUI library
5 ; stkext.asm
6 ; Generic stack extension routines.
8 ; (C) Janne Jalkanen 1998
9 ; (C) Copyright 1998 Manuel Lemos.
10 ; (C) Copyright 1996-1997 Ian J. Einman.
11 ; (C) Copyright 1993-1996 Jaba Development.
12 ; (C) Copyright 1993-1996 Jan van den Baard.
13 ; All Rights Reserved.
15 ; $Log$
16 ; Revision 42.0 2000/05/09 22:10:18 mlemos
17 ; Bumped to revision 42.0 before handing BGUI to AROS team
19 ; Revision 41.11 2000/05/09 20:21:53 mlemos
20 ; Bumped to revision 41.11
22 ; Revision 41.1 2000/05/09 19:55:11 mlemos
23 ; Merged with the branch Manuel_Lemos_fixes.
25 ; Revision 1.1.2.5 1998/10/12 01:31:17 mlemos
26 ; Fixed a remaining make-proto word in the previous log.
27 ; Changed the make-proto declaration for EnsureStack function.
29 ; Revision 1.1.2.4 1998/10/11 15:39:35 mlemos
30 ; Split make-proto words in the log comment to not confuse make-proto program.
31 ; Added make-proto declarations for EnsureStack and RevertStack to let them
32 ; be called from C code.
34 ; Revision 1.1.2.3 1998/10/01 23:03:12 mlemos
35 ; Replaced a C like comment that was confusing make-proto by a semi-colon.
36 ; Defined functions exported to C by make-proto as regargs.
38 ; Revision 1.1.2.2 1998/10/01 04:37:01 mlemos
39 ; Made the calls to exec.library be done by fetching the library base pointer
40 ; from _SysBase(a4).
41 ; Increased the stack margin size to 2048 bytes.
42 ; Added code to pre-allocate and free the stack space for use by the
43 ; input.device task.
44 ; Removed the stack space copying code.
45 ; Fixed the bug of post incrementing the register a5 after restoring pushed
46 ; register from the previous stack space.
48 ; Revision 1.1.2.1 1998/09/12 02:21:22 mlemos
49 ; Initial revision.
52 INCLUDE 'exec/exec_lib.i'
53 INCLUDE 'exec/tasks.i'
54 INCLUDE 'exec/memory.i'
56 XDEF _EnsureStack,_RevertStack
57 XREF _SysBase
59 STKMARGIN EQU 2048 ; When should we start worrying about the stack?
60 STKSIZE EQU 16384 ; Allocate this much stack space
61 CTLBLOCK EQU 4*4 ; The control block, currently sizeof(StackSwapStruct)
63 callsys MACRO
64 move.l _SysBase(a4),a6
65 jsr _LVO\1(a6)
66 ENDM
68 call MACRO
69 jsr _LVO\1(a6)
70 ENDM
72 SECTION text,CODE
74 *******************************************************************************
76 * EnsureStack allocates a handle, which must be returned back to RevertStack
78 * Registers preserved: all, except d0 and sp
80 XREF _InputDevice
81 XREF _InputStack
83 ;makeproto ASM APTR EnsureStack(VOID);
85 _EnsureStack:
86 movem.l d1-d7/a0-a6,-(sp) ; total of 14 regs = 56 bytes
88 ; Figure out our address
90 suba.l a1,a1
91 callsys FindTask ; a2=FindTask(NULL)
92 move.l d0,a2
94 ; Calculate current stack left and check if it is within
95 ; allowed limits
97 move.l TC_SPLOWER(a2),d2 ; d2 = oldlower
98 move.l sp,d3
99 sub.l d2,d3 ; d3 = stkptr-oldlower
101 moveq #0,d0 ; d0 = NULL ; THis is the default return value
102 cmp.l #STKMARGIN,d3
103 bhi .stackok
105 ; Check if this is input.device
107 cmpa.l _InputDevice(a4),a2
108 bne .allocmore
110 ; if current stack space is already the pre-allocated stack, allocate a stack extension
112 move.l _InputStack(a4),d0
113 moveq.l #CTLBLOCK,d1
114 add.l d0,d1
115 cmp.l d1,d2
116 bne .dontalloc
118 ; Allocate the new stack and the control block (20 bytes extra)
120 .allocmore
121 move.l #STKSIZE+CTLBLOCK,d0
122 move.l #MEMF_CLEAR+MEMF_PUBLIC,d1
123 call AllocVec
124 tst.l d0
125 beq .memfailed
127 ; Allocation was successfull, so we'll fill out the necessary data
128 ; in the control block.
130 .dontalloc
131 move.l d0,a3 ; a3 = control block address
132 add.l #CTLBLOCK,d0
133 move.l d0,stk_Lower(a3) ; start of real stack (ctrl block not included)
135 add.l #STKSIZE,d0
136 move.l d0,stk_Upper(a3) ; end of stack
138 move.l TC_SPUPPER(a2),d1
139 sub.l sp,d1 ; d1 = stacksize = tc_SPUpper - stkptr
141 sub.l d1,d0 ; d0 = stk_Upper - stackoffset
142 move.l d0,stk_Pointer(a3)
144 ; Copy the return address.
146 move.l d0,a1
147 move.l 56(a7),(a1) ; Copy return address to new stack
149 ; Finally, do StackSwap()
150 move.l sp,a5 ; Old stack pointer so that we can easily
151 ; restore registers on exit
152 move.l a3,a0
153 call StackSwap
155 move.l a3,d0 ; d0 = return value
157 movem.l (a5),d1-d7/a0-a6 ; Restore registers and return
160 .memfailed
162 .stackok
164 ; return
165 movem.l (sp)+,d1-d7/a0-a6
168 *******************************************************************************
170 * This function returns the stack back to free memory pool.
171 * Safe to call with NULL args
173 * Registers destroyed: d0/a0/a1/a7
175 ;makeproto ASM VOID RevertStack( REG(a0) APTR);
177 _RevertStack
178 move.l a0,d0
179 tst.l d0
180 beq .noalloc
182 movem.l d1-d7/a2-a6,-(sp) ; 12 registers = 48 bytes
184 ; Revert to original stack
185 move.l d0,a3 ; a3 = control block
186 move.l a3,a0
188 callsys StackSwap
190 move.l stk_Pointer(a3),a5 ; a5 = our allocated stack pointer (now old)
191 move.l 48(a5),a0 ; a0 = return address
193 lea 48+12(sp),sp ; forget all previous stuff
194 move.l a0,-(sp) ; push real return address
196 move.l a3,a1 ; a1 = memory block area
198 cmp.l _InputStack(a4),a1
199 beq .nofree
201 callsys FreeVec ; free memory in a1
202 .nofree
203 movem.l (a5),d1-d7/a2-a6 ; Return real registers
204 .noalloc
207 ********************************************************************************
209 * This function allocates memory for the input.device stack extension,
210 * which is allocated only during library initialization.
212 ;makeproto VOID InitInputStack(VOID);
214 XDEF @InitInputStack
215 XDEF @FreeInputStack
217 @InitInputStack
218 movem.l a6,-(sp)
220 ; Find input.device address
222 lea InputName(pc),a1
223 callsys FindTask
224 move.l d0,_InputDevice(a4) ; Save to globals.
226 ; Allocate stack
227 move.l #STKSIZE+CTLBLOCK,d0
228 move.l #MEMF_CLEAR+MEMF_PUBLIC,d1
229 call AllocVec
230 tst.l d0
231 move.l d0,_InputStack(a4)
233 movem.l (sp)+,a6
236 ;makeproto VOID FreeInputStack(VOID);
238 @FreeInputStack
239 movem.l a6,-(sp)
241 move.l _InputStack(a4),a1
242 callsys FreeVec ; NULL is safe, says autodoc
244 movem.l (sp)+,a6
247 InputName
248 dc.b "input.device",0