|
@@ -1,4 +1,4 @@
|
|
|
-/*
|
|
|
+/*
|
|
|
This file is part of the Free Pascal run time library.
|
|
|
Copyright (c) 2016 by Marcus Sackrow
|
|
|
|
|
@@ -10,57 +10,190 @@
|
|
|
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
|
|
|
+
|
|
|
+ .text
|
|
|
+ .globl _start
|
|
|
+ .type _start,#function
|
|
|
_start:
|
|
|
- push {r0-r12,r14}
|
|
|
- ldr ip,=_Backjump
|
|
|
- str lr,[ip]
|
|
|
- /* ExecBase */
|
|
|
- ldr ip,=_ExecBase
|
|
|
- str r5, [ip] /* Execbase seems to be in r5 ;-)*/
|
|
|
-
|
|
|
- /* Save initial stackpointer*/
|
|
|
- ldr ip,=__stkptr
|
|
|
- str sp,[ip]
|
|
|
-
|
|
|
- bl PASCALMAIN
|
|
|
-
|
|
|
- /*mov r0,#71
|
|
|
- bl _RawCharS
|
|
|
- mov r0,#10
|
|
|
- bl _RawCharS*/
|
|
|
-
|
|
|
- .globl _haltproc
|
|
|
- .type _haltproc,#function
|
|
|
+ # 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:
|
|
|
-
|
|
|
- ldr ip,=__stkptr
|
|
|
- ldr sp,[ip]
|
|
|
+ # 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]
|
|
|
|
|
|
- pop {r0-r12,r14}
|
|
|
+ # restore registers
|
|
|
+ pop {r0-r12,r14}
|
|
|
|
|
|
- /* exitcode should be r0*/
|
|
|
- ldr ip,=operatingsystem_result
|
|
|
- ldr r0,[ip]
|
|
|
+ # exitcode should be r0
|
|
|
+ ldr ip,=operatingsystem_result
|
|
|
+ ldr r0,[ip]
|
|
|
|
|
|
- ldr ip,=_Backjump
|
|
|
- ldr lr,[ip]
|
|
|
- bx lr
|
|
|
-
|
|
|
+ # 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
|
|
|
+ /* 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
|
|
|
+ .long 0
|
|
|
+ .weak data_start
|
|
|
+ data_start = __data_start
|
|
|
|
|
|
.bss
|
|
|
.comm __stkptr,4
|
|
|
- .comm _ExecBase,4
|
|
|
- .comm _Backjump,4
|
|
|
+ .comm __stkptr1,4
|
|
|
+ .comm _ExecBase,4
|
|
|
+ .comm _Backjump,4
|
|
|
+ .comm StackAreaPtr,4
|
|
|
+ .comm StackSwapStruct, 12
|
|
|
+ .comm StackSwapArgs, 32
|