mirror of
https://github.com/cahirwpz/libnix.git
synced 2026-09-11 19:26:17 +00:00
140 lines
3.6 KiB
C
Executable File
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);
|