* BothStartup.obj * * A drop in replacement for Astartup.obj * For Workbench programs, or CLI programs with or without command * line parameters. * Modified from Astartup.asm by Bryce Nesbitt. Release V1.0 * ******* Included Files ************************************************* NOLIST INCLUDE "exec/types.i" IFND EXEC_ABLES_I INCLUDE "exec/ables.i" ENDC IFND EXEC_EXECBASE_I INCLUDE "exec/execbase.i" ENDC IFND LIBRARIES_DOS_I INCLUDE "libraries/dos.i" ENDC IFND LIBRARIES_DOESEXTENS_I INCLUDE "libraries/dosextens.i" ENDC IFND WORKBENCH_STARTUP_I INCLUDE "workbench/startup.i" ENDC LIST ******* Imported ******************************************************* xref _Input xref _Output xref _main ; C code entry point callsys macro xref _LVO\1 jsr _LVO\1(a6) endm blink macro bchg.b #1,$bfe001 endm ******* Exported ******************************************************* xdef _SysBase xdef _DOSBase xdef _errno xdef _stdin xdef _stdout xdef _stderr xdef _exit ; standard C exit function ************************************************************************ * * Standard Program Entry Point * * main (argc, argv) * int argc; ;Passed as 32 bits. 0=from Workbench * char *argv[]; ;Passed as 32 bits. If from workbench, * ;then this is the WB message pointer. * ; ;a3 - frame pointer ;a4 - ThisTask ;a5- DOSBase dosCmdLen equr d6 dosCmdBuf equr d5 ; startup: move.l d0,dosCmdLen move.l a0,dosCmdBuf lea.l ss,a3 ; set up "frame pointer" clr.l (a3)+ ; _errno move.l sp,(a3)+ ; initailSP ;------ get Exec's library base pointer: move.l 4,a6 ; get _AbsExecBase move.l a6,(a3)+ ; _SysBase ;------ Open the DOS library: lea.l DOSName(pc),A1 callsys OldOpenLibrary ; Look ma, no error check! move.l d0,(a3)+ ; _DOSBase move.l d0,a5 ;------ get the address of our task move.l ThisTask(a6),a4 ;------ are we running as a son of Workbench? tst.l pr_CLI(A4) beq fromWorkbench clr.l (a3)+ ; returnMsg ;======================================================================= ;====== CLI Startup Code =============================================== ;======================================================================= ;------ find command name: fromCLI move.l pr_CLI(a4),a0 add.l a0,a0 ; bcpl pointer conversion add.l a0,a0 move.l cli_CommandName(a0),a0 add.l a0,a0 ; bcpl pointer conversion add.l a0,a0 ;------ create buffer and array: lea.l argvBuffer-_stdin(a3),a2 lea.l argvArray-_stdin(a3),a1 moveq.l #1,d2 ; param counter ;------ fetch command name: moveq.l #0,d0 move.b (a0)+,d0 ; size of command name move.l a2,(a1)+ ; ptr to command name bra.s 1$ 2$ move.b (a0)+,(a2)+ 1$ dbf d0,2$ clr.b (a2)+ ;------ collect parameters: move.l dosCmdLen,d0 move.l dosCmdBuf,a0 ;------ skip control characters and space: parmloopa: move.b (a0)+,d1 subq.l #1,d0 ble.s parmExit cmp.b #' ',d1 ble.s parmloopa ;------ copy parameter: addq.l #1,d2 cmp.w #32,d2 beq parmExit ;!!Too many parms!! move.l a2,(a1)+ bra.s 5$ 4$ move.b (a0)+,d1 subq.l #1,d0 cmp.b #' ',d1 ble.s endofarg 5$ move.b d1,(a2)+ bra.s 4$ endofarg clr.b (a2)+ ;Null terminate bra.s parmloopa ;------ Clear out ends, and go away parmExit: clr.b (a2)+ clr.l (a1)+ move.l d2,d0 ; Arg count pea argvArray ; Arg array pointer move.l d0,-(sp) ;------ get standard input handle: move.l a5,a6 ; Get DOSBase callsys Input move.l d0,(a3)+ ; _stdin ;------ get standard output handle: callsys Output move.l d0,(a3)+ ; _stdout move.l d0,(a3)+ ; _stderr ;------ call C main entry point bra domain ;======================================================================= ;====== Workbench Startup Code ========================================= ;======================================================================= ;------ we are now set up. wait for a message from our starter fromWorkbench: ;[a4=ThisTask] ;[a5=DOSBase] lea.l pr_MsgPort(A4),a0 ; our process base callsys WaitPort lea.l pr_MsgPort(A4),a0 ; our process base callsys GetMsg ;------ save the message so we can return it later move.l d0,(a3)+ ; set returnMsg. NOTE: no ReplyMsg yet! ;------ push argc and argv. if argc = 0 program came from ;------ Workbench, and argv will have the WB message. move.l d0,-(SP) ; set argv to the WB message clr.l -(SP) ; set argc to 0 ;------ get the first argument ;[d0=WBMessage] move.l a5,a6 ;Get DOSBase move.l d0,a2 move.l sm_ArgList(a2),d0 beq.s docons ;------ and set the current directory to the same directory move.l d0,a0 move.l wa_Lock(a0),d1 callsys CurrentDir docons: ;------ ignore the toolwindow argument domain: jsr _main moveq.l #0,d0 ; Successful return code bra.s exit2 ************************************************************************ * * C Program exit(returncode) Function * * Warning: no resources are deallocated. If you took it, you must * have already given it back!! * * _exit: move.l 4(SP),d0 ; extract return code exit2: lea.l ss,a3 ; set "frame pointer" back up move.l initialSP-ss(a3),SP ; restore stack pointer move.l d0,-(SP) ; save return code ;------ close DOS library: move.l 4,a6 move.l _DOSBase-ss(a3),a1 callsys CloseLibrary ;------ if we ran from CLI, skip workbench cleanup: move.l returnMsg-ss(a3),d0 beq.s exitToDOS ;------ return the startup message to our parent ;------ we forbid so workbench can't UnLoadSeg() us ;------ before we are done: FORBID ;[d0=returnMsg] move.l d0,a1 callsys ReplyMsg ;------ this rts sends us back to DOS: exitToDOS: move.l (SP)+,d0 rts DOSName: dc.b 'dos.library',0 cnop 0,2 ******* DATA *********************************************************** BSS ss ; placemarker _errno ds.l 1 ; error number from OS routines initialSP ds.l 1 ; initial stack pointer _SysBase ds.l 1 ; exec library base pointer _DOSBase ds.l 1 ; dos library base pointer returnMsg ds.l 1 ; Workbench message, or zero for CLI startup _stdin ds.l 1 _stdout ds.l 1 _stderr ds.l 1 argvArray ds.l 32 ;maximum 32 args argvBuffer ds.b 256 ;and 256 characters END