mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 06:08:55 +02:00
200 lines
4.1 KiB
ActionScript
200 lines
4.1 KiB
ActionScript
/*
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 2016 by Marcus Sackrow
|
|
|
|
Startup code for AROS/ARM RTL
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY;without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
r0 = argc
|
|
r1 = argv
|
|
r2 = ExecBase
|
|
*/
|
|
|
|
.text
|
|
.globl _start
|
|
.type _start,#function
|
|
_start:
|
|
# save registers
|
|
push {r0-r12,r14}
|
|
# save the back jump into OS
|
|
ldr ip,=_Backjump
|
|
str lr,[ip]
|
|
|
|
/* ExecBase */
|
|
ldr ip,=_ExecBase
|
|
str r2, [ip] /* ExecBase seems to be in r2 ;-)*/
|
|
|
|
/* Save initial stackpointer*/
|
|
ldr ip,=__stkptr
|
|
str sp,[ip]
|
|
|
|
# jump back -> exit
|
|
ldr ip,=_exit
|
|
ldr lr,[ip]
|
|
|
|
/* check for stack extent */
|
|
/* FindTask(nil) */
|
|
# execbase to r1
|
|
ldr r1,=_ExecBase
|
|
ldr r1,[r1]
|
|
# nil to r0
|
|
mov r0,#0
|
|
# caluclate offset
|
|
ldr r12,[r1, #-196]
|
|
# do it
|
|
blx r12
|
|
|
|
/* get data from PTask splower r0, spupper r1 */
|
|
mov r1, r0
|
|
ldr r0, [r0, #60]
|
|
ldr r1, [r1, #64]
|
|
/* sub spUpper- spLower */
|
|
sub r0,r1,r0
|
|
/* compre with stacklen */
|
|
ldr r1,=__stklen
|
|
ldr r1,[r1]
|
|
/* if OS stack bigger jump to nostack -> no stackswap needed */
|
|
cmp r0, r1
|
|
bge _nostack
|
|
|
|
/* alloc a new stack and swap to it */
|
|
_withstack:
|
|
/* AllocVec(__stklen, MEMF_ANY) */
|
|
# execbase to r2
|
|
ldr r2,=_ExecBase
|
|
ldr r2,[r2]
|
|
# MEMF_ANY (0) to r1
|
|
mov r1,#0
|
|
# stacksize to r0
|
|
ldr r0,=__stklen
|
|
ldr r0,[r0]
|
|
# do the call
|
|
ldr r12,[r2, #-456]
|
|
blx r12
|
|
|
|
# save the Pointer to StackAreaPtr
|
|
ldr ip,=StackAreaPtr
|
|
str r0,[ip]
|
|
# check if we got some Memory -> else byebye
|
|
cmp r0, #0
|
|
beq _exit
|
|
|
|
/* Prepare StackSwapStruct */
|
|
ldr ip,=StackSwapStruct
|
|
str r0,[ip] /* stk_Lower */
|
|
# get stacklen
|
|
ldr r1,=__stklen
|
|
ldr r1,[r1]
|
|
# add StackLen to Lower Stack
|
|
add r0,r1,r0
|
|
# put upper stack swap
|
|
str r0,[ip, #4] /* stk_Upper */
|
|
# start pointer
|
|
str r0,[ip, #8] /* stk_Pointer */
|
|
|
|
/* NewStackSwap(StackSwapStruct, _runpascal, StackSwapArgs) */
|
|
# 4. ExecBase
|
|
ldr r3,=_ExecBase
|
|
ldr r3,[r3]
|
|
# 3. StackSwapArgs
|
|
ldr r2,=StackSwapArgs
|
|
# 2. funcptr
|
|
ldr r1,=_runpascal
|
|
# 1. StackSwapStruct
|
|
ldr r0,=StackSwapStruct
|
|
# do the call
|
|
ldr r12,[r3, #-536]
|
|
blx r12
|
|
|
|
# after Stackswap we just to _afterstackswap to leave the program
|
|
bl _afterstackswap
|
|
|
|
/* NewStackswap will jump here */
|
|
_runpascal:
|
|
# save registers on the new stack
|
|
push {r0-r12,lr}
|
|
# save the stackswapped stackptr to
|
|
ldr ip,=__stkptr1
|
|
str sp,[ip]
|
|
|
|
/* Main Program for both cases */
|
|
_nostack:
|
|
# call the Pascal Main
|
|
bl PASCALMAIN
|
|
# seems never reach this point
|
|
|
|
/* haltproc is called by Pascal */
|
|
.globl _haltproc
|
|
.type _haltproc,#function
|
|
_haltproc:
|
|
# Check if StackAreaPtr not set -> no need to free, can directly exit
|
|
ldr ip,=StackAreaPtr
|
|
ldr r0,[ip]
|
|
cmp r0, #0
|
|
beq _exit
|
|
|
|
# StackAreaPtr is assigned, so we did the Stack Swap and must
|
|
# swap back and free the memory
|
|
|
|
# get back the stackswaped stack and get back all registers and jump back
|
|
# to stackswap -> leave the Stack
|
|
ldr ip,=__stkptr1
|
|
ldr sp,[ip]
|
|
pop {r0-r12,lr}
|
|
bx lr
|
|
|
|
/* jumps here after Stackswap leaving -> with original stack again*/
|
|
_afterstackswap:
|
|
# get StackAreaPtr
|
|
ldr ip,=StackAreaPtr
|
|
ldr r0,[ip]
|
|
|
|
# freeVec(StackAreaPtr)
|
|
#execbase to r1
|
|
ldr r1,=_ExecBase
|
|
ldr r1,[r1]
|
|
#calc FreeVec offset
|
|
ldr r12,[r1, #-460]
|
|
blx r12
|
|
|
|
/* jumps here on error or if no stackswap was done */
|
|
_exit:
|
|
# get back the original OS Stack
|
|
ldr ip,=__stkptr
|
|
ldr sp,[ip]
|
|
|
|
# restore registers
|
|
pop {r0-r12,r14}
|
|
|
|
# exitcode should be r0
|
|
ldr ip,=operatingsystem_result
|
|
ldr r0,[ip]
|
|
|
|
# jump back to OS
|
|
ldr ip,=_Backjump
|
|
ldr lr,[ip]
|
|
bx lr
|
|
|
|
/* Define a symbol for the first piece of initialized data. */
|
|
.data
|
|
.globl __data_start
|
|
__data_start:
|
|
.long 0
|
|
.weak data_start
|
|
data_start = __data_start
|
|
|
|
.bss
|
|
.comm __stkptr,4
|
|
.comm __stkptr1,4
|
|
.comm _ExecBase,4
|
|
.comm _Backjump,4
|
|
.comm StackAreaPtr,4
|
|
.comm StackSwapStruct, 12
|
|
.comm StackSwapArgs, 32
|