home *** CD-ROM | disk | FTP | other *** search
- *vi:ts=8
- ****************************************************************************
- * *
- * TINY.A (C) Copyright Eddy Carroll 1992 *
- * ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
- * *
- * Replacement startup code for Lattice C V5.10a. Use instead of c.o. *
- * This has many features stripped out to allow small utilities to *
- * have as small a filesize as possible. If you use this, don't call *
- * any stdio functions. *
- * *
- ****************************************************************************
-
- 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"
- INCLUDE "exec/funcdef.i"
- INCLUDE "exec/exec_lib.i"
- INCLUDE "libraries/dos_lib.i"
-
- MAXARGS EQU 100 ; Maximum number of command line arguments from CLI
- AbsExecBase EQU 4 ; Welcome to the only fixed point in the universe
-
- * A useful macro to let us call library routines
- callsys macro
- CALLLIB _LVO\1
- endm
-
- xdef XCEXIT
- xdef exit
- xref LinkerDB
- xref _BSSBAS
- xref _BSSLEN
-
- csect text,0,0,1,2 * xref's after this are 16-bit reloc
- xref main * Name of C program to start with.
-
- start:
- movem.l d1-d6/a0-a6,-(a7)
- REGSIZE EQU (6+7)*4
- lea REGSIZE(a7),A5 * Determine old stack pointer
- move.l a0,a2 * Save command pointer
- move.l d0,d2 * and command length
- lea LinkerDB,a4 * Load base register
-
- move.l AbsExecBase.W,a6
- move.l a6,SysBase(A4)
- move.l a7,_StackPtr(A4) * Save stack ptr
-
- suba.l a1,a1
- callsys FindTask * Find out our task ID
- move.l d0,a3
-
- move.l a5,D0 * get top of stack
- sub.l 4(a5),D0 * compute bottom
- add.l #128,D0 * allow for parms overflow
- move.l D0,_base(A4) * save for stack checking
-
- lea DOSName(A4),A1
- moveq.l #0,D0
- callsys OpenLibrary
- move.l D0,DOSBase(A4)
- bne getcom
- noDOS:
- moveq.l #100,d0
- bra exitToDOS
-
- *------ find command name:
- getcom:
- move.l pr_CLI(a3),a0
- add.l a0,a0
- add.l a0,a0
- move.l cli_CommandName(a0),a1
- add.l a1,a1
- add.l a1,a1
-
- *------ collect parameters:
- move.l d2,d0 * get command line length
- moveq.l #0,d1
- move.b (a1)+,d1
- move.l a1,_ProgramName(A4)
- 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 d2,d0 * get command line length
- subq.l #1,d0
- add.l d1,d2
-
- copy_line:
- move.b 0(A2,D0.W),0(A7,D2.W) * copy command line to stack
- subq.l #1,d2
- dbf d0,copy_line
- move.l d2,d0 * save offset to argv[1] - 1
- clr.b 0(a7,d2.w) * Insert command name terminator
- 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
- lea 1(a7,d0.w),a1 * get pointer to start of arguments
- move.l a7,a2 * get pointer for argv[0]
-
- sub.l #(MAXARGS*4),a7 * Reserve space for argv[]
- move.l a7,a3 * Save ptr to base of argv (&argv[0])
- move.l a2,(a7) * Setup argv[0] to point to cmd line
- lea 4(a7),a2 * Init base into array at argv[1]
- moveq #1,d2 * Initialise argc
-
- *
- * From here on down, A1 is pointer into command line
- *
- build_argv:
- bsr.s getnext * Read next character from line
- bcs.s doquote * If quote, handle
- beq.s build_argv * If white space, skip over it
-
- lea -1(a1),a0 * Get address of this parameter
- bsr.s bumpargv * Store it to argv[] array
- build_2:
- bsr.s getnext * Get next character
- bne.s build_2 * If not white space, keep looking
- clr.b -1(a1) * Zero-terminate current argument
- bra.s build_argv * And go back to get next argument
-
- doquote:
- move.l a1,a0 * Get pointer to this argument
- bsr.s bumpargv * Output it to argv[]
- quote_2:
- bsr.s getnext * Get next character
- bcc.s quote_2 * If not quote, keep looking
- clr.b -1(a1) * Zero-terminate current argument
- quote_3:
- bsr.s getnext * Get next character
- bne.s quote_3 * Skip until space reached
- beq.s build_argv * Go back and read next argument
-
- bumpargv:
- move.l a0,(a2)+ * Output ptr to current argument
- addq #1,d2 * Increment argc
- cmpi #MAXARGS,d2 * Used up all our arguments yet?
- bls.s qrts * If not, then return
- moveq #110,d0 * Else set return code
- bra.s exit2 * And exit
-
- *
- * Reads next character from command line. If zero, never returns, but
- * drops into call to main. Else, returns, with C=1 if character is quote,
- * Z=1 if character is white space.
- *
- getnext:
- move.b (a1)+,d0 * Get character from command line
- beq.s get_2 * Exit if end of line
- cmp.b #34,d0 * Check if quote
- beq.s isquote *
- cmp.b #32,d0 * Check if space
- beq.s isspace *
- cmp.b #9,d0 * Or tab
- beq.s isspace *
- cmp.b #10,d0 * Or end of line
- isspace:
- andi #$1E,ccr * Clear carry flag, retaining Z
- qrts rts
-
- isquote:
- ori #1,ccr * Set carry flag
- andi #$FB,ccr * Clear zero flag
- rts * And return
-
- get_2:
- move.l a3,-(a7) * Push argv onto stack
- move.l d2,-(a7) * Push argc onto stack
-
- lea _BSSBAS,a3 * get base of BSS
- moveq #0,d1
- move.l #_BSSLEN,d0 * get length of BSS in longwords
- bra.s clr_lp * and clear for length given
- clr_bss move.l d1,(a3)+
- clr_lp dbf d0,clr_bss
-
- domain:
- jsr main(PC) * Call main(argc,argv)
- moveq.l #0,d0 * Set successful status
- bra.s exit2
-
- exit:
- _exit:
- XCEXIT:
- move.l 4(SP),d0 * Extract return code
- exit2:
- move.l d0,-(a7)
- move.l AbsExecBase.W,a6
- move.l DOSBase(A4),a1
- callsys CloseLibrary * Close Dos library
-
- *------ this rts sends us back to DOS:
- MOVE.L (A7)+,D0
- exitToDOS:
- movea.l _StackPtr(a4),SP * Restore stack ptr
- movem.l (a7)+,d1-d6/a0-a6
- rts
-
- *-----------------------------------------------------------------------
- * Global definitions
- *
- csect __MERGED,1,,2,2
-
- xdef NULL,SysBase,LoadAddress,DOSBase
- xdef _oserr,_OSERR,_ONBREAK
- xdef _ProgramName,_StackPtr,_base
-
- NULL dc.l 0
- _base dc.l 0
- _oserr equ *
- _OSERR dc.l 0
- _ONBREAK dc.l 0
- SysBase dc.l 0
- LoadAddress dc.l 0
- _StackPtr dc.l 0
- DOSBase dc.l 0
- _ProgramName dc.l 0
- DOSName dc.b 'dos.library',0
-
- END
-