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