Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 50 additions & 22 deletions platform/amiga/startup.S
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,78 @@
.globl _start
.globl _entrypoint

/* The NDK ships its asm headers (exec/tasks.i, lvo/exec_lib.i) in
* Amiga assembler syntax (IFND, EQU, ...), which GNU as does not
* understand. We define the few constants we need here.
*/

/* Exec library vector offsets (from NDK lvo/exec_lib.i) */
#define _LVOFindTask -294
#define _LVOAllocMem -198
#define _LVOFreeMem -210
#define _LVOStackSwap -732

/* struct Task offsets (from NDK exec/tasks.i) */
#define TC_SPLOWER 58
#define TC_SPUPPER 62

/* struct StackSwapStruct offsets (from NDK exec/tasks.i) */
#define STK_LOWER 0
#define STK_UPPER 4
#define STK_POINTER 8
#define STK_SIZEOF 12

/* AllocMem flags (from NDK exec/memory.i) */
#define MEMF_PUBLIC 0x00000001
#define MEMF_CLEAR 0x00010000

#define MIN_STACK 4096
#define SWAP_STACK 8192

_start:
_entrypoint:
move.l 4.w,a6 /* SysBase */
sub.l a1,a1
jsr -0x126(a6) /* FindTask(NULL) */
jsr _LVOFindTask(a6) /* FindTask(NULL) */
move.l d0,a4 /* a4 = our task */

/* Check stack — we need at least 4096 bytes */
move.l 62(a4),d0 /* tc_SPUpper */
sub.l 58(a4),d0 /* tc_SPLower */
cmp.l #4096,d0
/* Check stack — swap to a larger one if too small */
move.l TC_SPUPPER(a4),d0
sub.l TC_SPLOWER(a4),d0
cmp.l #MIN_STACK,d0
bge.s .stack_ok

/* Stack too small — allocate a new one */
move.l #8192,d0
move.l #0x10001,d1 /* MEMF_PUBLIC|MEMF_CLEAR */
jsr -0xc6(a6) /* AllocMem */
move.l #SWAP_STACK,d0
move.l #MEMF_PUBLIC+MEMF_CLEAR,d1
jsr _LVOAllocMem(a6)
tst.l d0
beq.s .fail
move.l d0,a5 /* a5 = stack base */

/* Set up StackSwap structure on current stack */
sub.l #12,sp
move.l a5,(sp) /* stk_Lower */
lea 8192(a5),a0
move.l a0,4(sp) /* stk_Upper */
move.l a0,8(sp) /* stk_Pointer (top of stack) */
move.l sp,a2 /* save StackSwap struct addr */
sub.l #STK_SIZEOF,sp
move.l a5,STK_LOWER(sp)
lea SWAP_STACK(a5),a0
move.l a0,STK_UPPER(sp)
move.l a0,STK_POINTER(sp) /* initial SP = top of new stack */
move.l sp,a2 /* save struct addr (callee-saved) */
move.l a2,a0
jsr -0x2dc(a6) /* StackSwap */
jsr _LVOStackSwap(a6)

jsr _handler_main /* C entry point */

/* Swap stack back to original */
/* Swap back to original stack (struct still on old stack via a2) */
move.l 4.w,a6
move.l a2,a0 /* StackSwap struct on old stack */
jsr -0x2dc(a6) /* StackSwap — restore original stack */
move.l a2,a0
jsr _LVOStackSwap(a6)

/* Free the allocated stack */
move.l a5,a1 /* stack memory base */
move.l #8192,d0
jsr -0xd2(a6) /* FreeMem */
move.l a5,a1
move.l #SWAP_STACK,d0
jsr _LVOFreeMem(a6)

lea 12(sp),sp /* remove StackSwap struct */
lea STK_SIZEOF(sp),sp /* pop StackSwap struct */
bra.s .done

.stack_ok:
Expand Down
Loading