2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
11 #include "dos_intern.h"
14 * On m68k exiting a program can be performed by setting SP
15 * to (FindTask(NULL)->pr_ReturnAddr - 4), and performing an rts.
17 * For the complete code, see arch/m68k-amiga/dos/exit.c and
18 * arch/m68k-amiga/dos/bcpl.S, "BCPL Exit"
20 * pr_ReturnAddr points to the actual stack size.
22 * Similar construction should work on all CPUs. I guess this is what
23 * is used by Exit() routine.
25 * For other CPUs we don't keep exact stack layout and consider it
26 * private. Only Exit() knows what to do with it. However we keep stack
27 * size value where it was, some code relies on it.
38 /*****************************************************************************
41 #include <proto/dos.h>
46 AROS_LHA(LONG
, returnCode
, D1
),
49 struct DosLibrary
*, DOSBase
, 24, Dos
)
52 Instantly terminate the program.
55 returnCode - Process' return code.
61 Calling this function bypasses normal termination sequence of your program.
62 Automatically opened libraries will not be closed, destructors will not be
63 called, etc. Do this only if you really know what are you doing. It's not
64 adviced to use this function at all.
74 *****************************************************************************/
78 struct Process
*me
= (struct Process
*)FindTask(NULL
);
79 struct StackState
*ss
= me
->pr_ReturnAddr
;
81 /* Return code can be zero, so we can't pass it via longjmp() */
82 ss
->retval
= returnCode
;
84 /* Close dos.library because the program has opened it in order to obtain DOSBase */
85 CloseLibrary(&DOSBase
->dl_lib
);
87 /* Disable() because we may have to swap stack limits */
89 longjmp(ss
->state
, 1);
95 * CallEntry() is also defined here because it is closely associated with
96 * Exit() implementation.
97 * For different CPUs we may have optimized versions of these two functions in asm.
99 ULONG
CallEntry(STRPTR argptr
, ULONG argsize
, LONG_FUNC entry
, struct Process
*me
)
101 struct StackState ss
;
103 /* Set the first IPTR to something like on AmigaOS(tm) */
104 ss
.stackSize
= (APTR
)&ss
- me
->pr_Task
.tc_SPLower
;
105 /* Remember stack limits for Exit() */
106 ss
.stackLower
= me
->pr_Task
.tc_SPLower
;
107 ss
.stackUpper
= me
->pr_Task
.tc_SPUpper
;
108 me
->pr_ReturnAddr
= &ss
;
110 if (setjmp(ss
.state
))
113 * We came here from Exit().
114 * Restore stack limits because the program might have swapped stack.
115 * We are clever enough to recover from this.
117 me
->pr_Task
.tc_SPLower
= ss
.stackLower
;
118 me
->pr_Task
.tc_SPUpper
= ss
.stackUpper
;
120 Enable(); /* We Disable()d in Exit() */
125 return AROS_UFC3(ULONG
, entry
,
126 AROS_UFCA(STRPTR
, argptr
, A0
),
127 AROS_UFCA(ULONG
, argsize
, D0
),
128 AROS_UFCA(struct ExecBase
*, SysBase
, A6
));