mirror of
https://github.com/cahirwpz/libnix.git
synced 2025-12-08 14:58:56 +00:00
140 lines
3.5 KiB
C
Executable File
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);
|