Files
amiga-libnix2/libnix/sources/stack/stkext.c
T
2004-09-09 22:52:26 +00:00

140 lines
3.2 KiB
C
Executable File

#include "bases.h"
#include "stabs.h"
asm("
.text
.even
.globl ___stkext_f
.globl ___stkext
.globl ___exit_stk
.globl ___stk_free
___stkext_f:
movel a0,sp@-
movel sp,a0 | memorize sp
moveml #0xc062,sp@- | preserves all registers
movel sp,a2 | memorize sp
addl #28:W,d1 | Used by this function itself
movel "A4(___stackborders)",a1| get upper border of stack in a1
movel a1@(4:W),a1
tstl "A4(___used_stack)"
bne l0
movel "A4(___SaveSP)",a1
l0: jbsr ___stkext | change to a stackframe with d0 bytes
movel "A4(___used_stack)",a6 | fix stored sp
addl d1,a6@(12:W)
movel a2,d0 | calculate number of bytes to copy
addl "A4(___stk_argbytes)",d0| to new stackframe in d0
addl d1,d0
cmpl a1,d0 | never copy over the bottom of the stack
jls l1
movel a1,d0
l1: subl a0,d0 | copy
subl d0,sp
movel sp,a1
movel "A4(_SysBase)",a6
jsr a6@(-0x270) | CopyMem(src:a0,dst:a1,siz:d0)
movel a2,a0
moveml a0@+,#0x4603
movel sp,a0 | Prepare cleanup
addl d1,a0
movel #___stkrst_f,a0@(8:W)
movel sp@+,a0
rts
___stkext:
movel a0,sp@-
moveml #0xf072,sp@- | preserves all registers
movel "A4(___stk_safezone)",d3
lea "A4(___stk_limit)",a2
lea "A4(___used_stack)",a3
addql #4,a3
movel "A4(_SysBase)",a6
movel d0,d2
addl d3,d2
addl "A4(___stk_argbytes)",d2| required stack
movel a3@,d0 | Look for a spare stackframe
jeq l4
l3: movel d0,a0
movel a0@,a3@ | Remove spare stackframe from list
movel a0@(8:W),d0 | Test spare stackframe
subl a0@(4:W),d0
cmpl d0,d2
jls l7
moveq #20,d1 | Not big enough
addl d1,d0
movel a0,a1
jsr a6@(-0xd2) | FreeMem(mem:a1,siz:d0)
movel a3@,d0
jne l3
l4: moveq #20,d0
addl d0,d2 | no more stackframes - allocate a new one
movel "A4(___stk_minframe)",d0
cmpl d0,d2
jge l5
movel d0,d2
l5: movel d2,d0
moveql #1,d1 | MEMF_PUBLIC
jsr a6@(-0xc6) | AllocMem(siz:d0,typ:d1)
movel d0,a0
movel a0,d0
jne l6
jbsr ___stkovf | allocation failed
l6: moveq #20,d0
addl a0,d0
movel d0,a0@(4:W)
addl a0,d2 | prepare new frame for use
movel d2,a0@(8:W)
l7: movel a3@-,a0@ | Add it to the used list
movel a0,a3@
addql #4,a0
movel a2@,a0@(12:W)
movel a0@,a2@ | Prepare ___top_of_stackframe variable
addl d3,a2@
lea a0@(4:W),a2
movel a2@+,a2@ | Prepare target sp
jsr a6@(-0x2dc) | StackSwap(sss:a0)
moveq #40,d0
movel a2@,a0
addl d0,a2@ | Fix stored sp
moveml a0@+,#0x4e0f
movel a0@(4:W),sp@- | prepare returnaddress
movel a0@,a0
rts
___exit_stk:
tstl "A4(___used_stack)"
jeq ___stk_free
lea sp@(12:W),a0
movel "A4(___SaveSP)",d0 | Go back to first stackframe
jbsr ___stkrst
movel a0@,sp@- | restore argument of exit()
movel a0@-,sp@- | returnaddress for exit()
movel a0@-,sp@- | returnaddress for callfuncs()
movel a0@-,sp@- | our returnaddress
| jbsr ___stk_free
| rts
___stk_free:
movel a2,sp@-
movel a6,sp@- | Free all unused stackframes
movel "A4(_SysBase)",a6
lea "A4(___used_stack)",a2
addql #4,a2
movel a2@,d0 | Remove spare stackframe from list
jeq l9
l8: movel d0,a1
movel a1@,a2@
moveq #20,d0
addl a1@(8:W),d0 | Calculate size
subl a1@(4:W),d0
jsr a6@(-0xd2) | FreeMem(mem:a1,siz:d0)
movel a2@,d0
jne l8
l9: movel sp@+,a6
movel sp@+,a2
rts
");
ADD2EXIT(__exit_stk,-50);