* Prompt.Asm * * Written 1/4/87 by C.Heath * * Copyright (c) 1986 by C.Heath of Microsmiths Inc. * * This program may be freely copied for individual use. It may * also be freely distributed with the following restrictions: * * 1) No modifications to the source code are made. If an executable * version of the program is distributed, use assem and blink 6.7, which * should result in an executable of 340 bytes. * 2) Please verify that the most current version is distributed. * This can be verified by contacting "cheath" on BIX, or 74216,2117 on CIS, * or write to Microsmiths, Inc., PO Box 561, Cambridge, MA 02140. * 3) The ARP series may be distributed with commercial software * except as noted in (4) provided it's origin is stated. Please contact * me to insure you have the latest version. * 4) This module may NOT be distributed with any commercial software * which encourages the BCPL program interface without express written * permission. This restriction includes the Metacomco Shell. * This module replaces the ADOS "Prompt" command. It matches the * ADOS prompt syntax, but also allows imbedded spaces in the prompt command. * In addition, it allows a simple path substitution to be made. This * must work in tandem with the ARP "CD" command. To use this, the key * %p is used on the command line. Anything following the %p will be * ignored. * This command is smaller than the ADOS equivalent so runs a bit faster. * This is installment three of the "ARP" series. Three down, 39 to go. ****** Equates and publics *************************************** INCLUDE "exec/types.i" INCLUDE "libraries/dos.i" INCLUDE "libraries/dosextens.i" MIN_LIB set $1f ; Library minimum rev level! ; ADOS "stack" command * NOTE: PLENGTH is less than ADOS's so we can use the last two * bytes as a flag in conjunction with the PATH option PLENGTH set 60 ; Maximum length of prompt CD_FLAG set $80 ; Store this flag value in string. * NOTE, it is assumed no other programs use $80 which is ignored by * the console.device. * This is here for assembler compatability stl_len equ 44 ; Length of stl_too_long *** WITH MANX, SUBSTITUTE public FOR xref xlib macro xref _LVO\1 endm *** BEGIN MANX code. Uncomment the next few lines to assemble with MANX * * entry .begin * public .begin *.begin *** END MANX CODE xlib OpenLibrary xlib CloseLibrary xlib FindTask xlib Output xlib Write ****** The Program *************************************** Start: move.l 4,a6 ; ExecBase in A6 unless DOSBase later move.l A0,A2 ; Register A2 is cmdline henceforth cmp #PLENGTH,D0 ble.s length_ok ************************************************************************ * * Input string too long, PLENGTH character limit. * Print error and exit. * ************************************************************************ too_long: lea DOSName(pc),A1 ; Open DOS.library moveq.l #MIN_LIB,d0 jsr _LVOOpenLibrary(A6) or.l D0,D0 beq.s BadExit ; Can't!! Return error value... move.l D0,A6 ; DOSBase in A6 henceforth move.l #str_too_long,D2 ; Set string to Write in D2,D3 move.l #stl_len,D3 jsr _LVOOutput(A6) ; Get Output handle move.l D0,D1 ; It's a calling arg jsr _LVOWrite(A6) ; Echo "String" move.l A6,A1 move.l 4,A6 ; AbsExecBase jsr _LVOCloseLibrary(A6) moveq #5,D0 ; Return a minimal error rts ************************************************************************ * * BadExit is where to go if there is an error opening the DOS library * This should only happen if things are really sick * ************************************************************************ BadExit: moveq #20,D0 rts ************************************************************************ * * Proceed with normal code * Find Process Base, we need the CLIStruct to store the prompt * ************************************************************************ length_ok: suba.l A1,A1 jsr _LVOFindTask(A6) move.l D0,A3 ; Process base move.l pr_CLI(A3),D0 beq.s BadExit ; Not a CLI process. Punt asl.l #2,D0 move.l D0,A3 ; A3 points at CLIStruct henceforth * * Process the input command string * skpspc: move.b (A2)+,D0 ; Skip spaces cmp.b #$20,D0 beq.s skpspc subq #1,A2 cmp.b #$0A,D0 ; check for a NULL string ? bne.s ok_string lea default(pc),A2 ; Null input, set to default string! * * OK, string (A2) can be copied into the DOS Prompt BSTR * * MCC needs an upper-case N for it's %N test. * MCC also translates all other chars, but I didn't. * ok_string: move.l cli_Prompt(A3),D0 ; Get BSTR pointing to prompt asl.l #2,D0 move.l D0,A0 ; A0 = where to store length lea 1(A0),A1 ; A1 = where to store string * Register A1 is where string is stored * Register D0 is the length tally * Register A0 is where to store the length when finished * Register D2 is last-char flag for %P test moveq #0,D2 ; Last char for % test moveq #-1,D0 ; Char count in D0 ll1: addq #1,D0 ; Copy the string move.b (A2)+,D1 beq.s ll2 cmp.b #$0A,D1 beq.s ll2 ; End of string cmp.b #'%',D2 ; Check if last char was '%' bne.s ll3 ; Nope, just copy it cmp.b #'p',D1 beq.s DoKluge ; DO THE PATH KLUGE cmp.b #'P',D1 ; PATH SPECIFIED WITH %P beq.s DoKluge cmp.b #'n',D1 bne.s ll3 move.b #'N',D1 ; Substitute N for n, for ADOS ll3: move.b D1,(A1)+ ; Save a char in the BSTR move.b D1,D2 ; Save for % test on next char! bra.s ll1 * * Finished copying the prompt. Now set the length and exit. * ll2: move.b D0,(A0) ; Save the length moveq.l #0,D0 ; Program sucess return rts ; Exit(0) * * DoKluge * Here, concatenate the current pathname onto the prompt * string and set the flag, offset bytes. * * NOTE: If the resulting string would be too long, just fall back * and do the same old stupid ADOS stuff. Sorry... DoKluge: move.l cli_SetName(A3),D5 asl.l #2,D5 move.l D5,A4 ; Get the BSTR for path name move.b (A4),D5 ; Length of path name add.b D0,D5 ; combined length cmp.b #PLENGTH-1,D5 bgt.s ll3 ; Safety punt if the CD string ; will make the command line too long. Just leave the %P in the prompt! subq #1,A1 ; Offset to start of %P addq #1,A4 ; Advance past BSTR length... ICK!!! move.b #CD_FLAG,(A1)+ * Loop Here concatenating the Path to the Prompt kl1: cmp.b D0,D5 ble.s kl2 ; exit loop move.b (A4)+,(A1)+ addq #1,D0 bra.s kl1 kl2: move.b #'>',(A1)+ ; Tack on "> " * The length is in D0, with a bit of hand waving. addq #1,D0 move.b D0,(A0) moveq #0,D0 ; Clean exit rts *************************************************************************** * * Following is just constant data used by the program * *************************************************************************** DOSName: dc.b 'dos.library',0 str_too_long: dc.b 'String too long, prompt limited to 58 chars',$0a default: dc.b '> ',$0a END