section text,CODE * C initial startup procedure under AmigaDOS * * Requirements: INCLUDE "exec/types.i" INCLUDE "exec/alerts.i" INCLUDE "exec/nodes.i" INCLUDE "exec/lists.i" INCLUDE "exec/ports.i" INCLUDE "exec/libraries.i" INCLUDE "exec/tasks.i" INCLUDE "libraries/dos.i" INCLUDE "libraries/dosextens.i" INCLUDE "workbench/startup.i" ; some usefull macros: xlib macro xref _LVO\1 endm callsys macro CALLLIB _LVO\1 endm xdef _XCEXIT * exit(code) is standard way to leave C. xref _Debug xref __main * Name of C program to start with. xref _MemCleanup xref _AbsExecBase xref _FindTask xref _main * added by robp per EA instructions xlib Alert xlib FindTask xlib Forbid xlib GetMsg xlib OpenLibrary xlib ReplyMsg xlib Wait xlib WaitPort xlib Open xlib Close xlib CurrentDir start: move.l d0,dosCmdLen move.l a0,dosCmdBuf move.l a7,d0 ; save old stack ptr movem.l d1-d6/a0-a6,-(a7) move.l d0,a5 move.l _AbsExecBase,a6 move.l a6,_SysBase move.l a7,__StackPtr * Save stack ptr clr.l _WBenchMsg ;------ get the address of our task suba.l a1,a1 callsys FindTask move.l d0,a4 ;------ are we running as a son of Workbench? move.l pr_CurrentDir(A4),_curdir tst.l pr_CLI(A4) beq fromWorkbench ;======================================================================= ;====== CLI Startup Code =============================================== ;======================================================================= fromCLI: move.l a5,D0 ; get top of stack sub.l 4(a5),D0 ; compute bottom move.l D0,__base ; save for stack checking ;------ attempt to open DOS library: bsr openDOS ;------ find command name: move.l #start,a0 ; jsr _Debug clr.l -(sp) jsr _FindTask addq.l #4,sp move.l d0,a0 move.l pr_CLI(a0),a0 add.l a0,a0 ; bcpl pointer conversion add.l a0,a0 move.l cli_CommandName(a0),a1 add.l a1,a1 ; bcpl pointer conversion add.l a1,a1 ;------ collect parameters: move.l dosCmdLen,d0 ; get command line length moveq.l #0,d1 move.b (a1)+,d1 move.l a1,__ProgramName add.l d1,d0 ; add length of command name addq.l #1,d0 ; allow for space after command clr.w -(A7) ; set null terminator for command line addq.l #1,D0 ; force to even number of bytes andi.w #$fffe,D0 ;(round up) sub.l D0,A7 ; make room on stack for command line subq.l #2,D0 clr.w 0(A7,D0) ;------ copy command line onto stack move.l dosCmdLen,d0 ; get command line length move.l dosCmdBuf,a0 move.l d0,d2 subq.l #1,d0 add.l d1,d2 copy_line: move.b 0(A0,D0.W),0(A7,D2.W) ; copy command line to stack subq.l #1,d2 dbf d0,copy_line move.b #' ',0(a7,d2.w) ; add space between command and parms subq.l #1,d2 copy_cmd: move.b 0(a1,d2.w),0(a7,d2.w) ; copy command name to stack dbf d2,copy_cmd move.l A7,A1 move.l A1,-(A7) ; push command line address jsr __main * call C entrypoint moveq.l #0,d0 ; set successful status bra.s exit2 ;======================================================================= ;====== Workbench Startup Code ========================================= ;======================================================================= fromWorkbench: move.l TC_SPLOWER(a4),__base ; set base of stack ;------ open the DOS library: bsr openDOS ;------ we are now set up. wait for a message from our starter bsr waitmsg move.l d0,_WBenchMsg move.l d0,-(SP) ; move.l d0,a2 ; get first argument move.l sm_ArgList(a2),d0 beq.s do_cons move.l _DOSBase,a6 move.l d0,a0 move.l wa_Lock(a0),d1 callsys CurrentDir do_cons: move.l sm_ToolWindow(a2),d1 ; get the window argument beq.s do_main move.l #MODE_OLDFILE,d2 callsys Open move.l d0,stdin beq.s do_main lsl.l #2,d0 move.l d0,a0 move.l fh_Type(a0),pr_ConsoleTask(A4) do_main: clr.l -(sp) *was pea _NULL jsr _main * call C entrypoint (was jsr __main) moveq.l #0,d0 ; set successful status bra.s exit2 ; _XCEXIT: move.l 4(SP),d0 ; extract return code exit2: move.l d0,-(a7) jsr _MemCleanup ; cleanup leftover memory alloc. ;------ if we ran from CLI, skip workbench cleanup: tst.l _WBenchMsg beq.s exitToDOS move.l _console_dev,d1 beq.s done_2 callsys Close done_2: move.l stdin,d1 beq.s done_4 callsys Close done_4: ;------ return the startup message to our parent ; we forbid so workbench can't UnLoadSeg() us ; before we are done: move.l _AbsExecBase,A6 callsys Forbid move.l _WBenchMsg,a1 callsys ReplyMsg ;------ this rts sends us back to DOS: exitToDOS: MOVE.L (A7)+,D0 movea.l __StackPtr,SP * restore stack ptr movem.l (a7)+,d1-d6/a0-a6 rts * and exit ;----------------------------------------------------------------------- noDOS: ALERT (AG_OpenLib!AO_DOSLib) moveq.l #100,d0 bra.s exit2 ;----------------------------------------------------------------------- ; This routine gets the message that workbench will send to us ; called with task id in A4 waitmsg: lea pr_MsgPort(A4),a0 * our process base callsys WaitPort lea pr_MsgPort(A4),a0 * our process base callsys GetMsg rts ;----------------------------------------------------------------------- ; Open the DOS library: openDOS lea DOSName,A1 moveq.l #0,D0 callsys OpenLibrary move.l D0,_DOSBase beq noDOS rts section data,DATA ; XDEF _NULL,_DOSBase,_SysBase,_LoadAddress,_console_dev,_WBenchMsg XDEF __mbase,__mnext,__msize,__tsize,__oserr,__fperr,__mstep XDEF __ProgramName,__StackPtr,__base ; _NULL DC.L 0 ; __base DC.L 0 ; base of stack __mbase DC.L 0 ; base of memory pool __mnext DC.L 0 ; next available memory location __msize DC.L 0 ; size of memory pool __mstep DC.L 1024 ; memory pool step size __tsize DC.L 0 ; total size? __oserr DC.L 0 __fperr DC.L 0 _curdir DC.L 0 _console_dev DC.L 0 _SysBase DC.L 0 _DOSBase DC.L 0 _LoadAddress DC.L 0 ; program load address _WBenchMsg dc.l 0 __StackPtr dc.l 0 dosCmdLen dc.l 0 dosCmdBuf dc.l 0 stdin dc.l 0 __ProgramName dc.l 0 DOSName DOSNAME