Files
amiga-libnix2/libnix/sources/stack/stkext.c
T
2004-09-12 01:16:36 +00:00

140 lines
3.6 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);