Files
amiga-libnix2/libnix/sources/stack/stkext.c
T
jshepher f8848586fd Added large baserel and resident startup code.
Added implementations of truncate, readlink, putenv, setenv.
2004-09-09 23:29:14 +00:00

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