TITLE 'SYNONYM Vers 3.0 Oct81' ;*------------------------------------------------------* ;* * ;* SYNONYM vers 1.0 by Bill allen - Feb81 * ;* * ;* Version 1.1 Jun81 by Bill Allen * ;* Version 1.2 Aug81 by Roy Lipscomb * ;* Version 2.0 Sep81 by Bill Allen * ;* Version 2.1 Oct81 by Roy Lipscomb * ;* Version 2.2 Oct81 by Roy Lipscomb * ;* Version 3.0 Oct81 by Roy Lipscomb * ;* * ;* This program will create a synonym for any * ;* CP/M command. A fixed paramater string may be * ;* entered as a part of the synonym and any paramaters * ;* given on the command line that invokes the synonym * ;* will be appended to the fixed string. * ;* * ;* The program is self-modifying. It will create * ;* a .COM file with the "newname" given in the synonym * ;* command. This newname.COM when invoked will modify * ;* the CCP buffer using the "oldname" (see HELP) and * ;* then jump to the CCP to invoke the comand.. * ;* * ;* Help with the format of the synonym command * ;* may be obtained by typing: * ;* "SYNONYM " or "SYNONYM ?" * ;* * ;* MODIFICATIONS: * ;* * ;* 10/26/81 - Version 3.0 (RJL) * ;* 1) Allows imbedded as well as appended parms. * ;* 2) Allows assembly-time option of having * ;* synonyms visible in directory. (For CPM 2.X) * ;* 3) Aborts if proposed "newname" already * ;* present on directory--this safeguards the old * ;* command file from being overlaid if you inad- * ;* vertently omit the "newname" parameter. (This * ;* check is not performed if "newname" begins * ;* with "X", for "experimental.") * ;* 4) Set for cleaner viewing of newname file * ;* contents with ccp command: TYPE newname.COM * ;* 5) Null endmark not counted in command length. * ;* 6) Computes (vs. assumes) CCP buffptr location.* ;* (To facilitate use with non-standard CCP's. * ;* Note: this version bypasses version 2.3, * ;* which had a different way of setting buffptr.) * ;* * ;* 10/20/81 - Version 2.2 - Made version 2.1 * ;* compatible with CPM1.x. (RJL) * ;* * ;* 10/17/81 - Version 2.2 - Changed CCP-locator * ;* method to work even when CCP is protected, * ;* instead of hanging the system. New method * ;* uses address at 0h instead of 5h. (RJL) * ;* * ;* 09/01/81 - Version 2.0 - Simplified syntax so * ;* command may always have a variable paramater * ;* string and the fixed paramater does not have * ;* to use underlines to represent blanks. The * ;* combined fixed and variable data can now be * ;* up to 128 bytes. (WEA) * ;* * ;* 08/12/81 - fixed bug that caused program to * ;* abort if command line was moderately long. * ;* (RJL) * ;* * ;* 06/01/81 - Added the ability to have both a * ;* fixed and variable paramater string. The fix- * ;* ed string is entered by typing the underline * ;* (_) following the oldname. they will be re- * ;* placed by blanks in the command. (WEA) * ;* * ;* 06/01/81 - Modify to set $SYS indicator only * ;* when running under CP/M 2.X. (WEA) * ;* * ;*------------------------------------------------------* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;change these characters if desired BASE EQU 0 BLNKSUB EQU '_' ;says "replace this char with blank" TRAPCHR EQU '#' ;says "replace this char with rparm" HIDE EQU 0 ;1 = hide filename as $SYS file, ;0 = leave visible on directory ;(Used only by CPM 2.x and later versions) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ORG 100H+BASE BEGADR JMP CONFIG ;altered to JMP BEGIN by CONFIG ;command as built by CONFIG ;(set here for easy viewing with ccp command: TYPE newname.COM) DB CR NEWBUF DS 127 DB 0 ;insert parms into command BEGIN LXI H,NEWBUF ;point to stored command LXI D,NEWCOM ;point to temporary build-area PUSH D ;save now (for XCTL) CALL BLDCOM ;create new command XRA A STAX D ;insure null at end ;execute command (fall through to subroutine XCTL) PAGE ;*------------------------------------------------------* ;* * ;* This routine will setup the CCP with a * ;* command passed by the calling program. * ;* * ;* ENTRY CONDITIONS: * ;* * ;* (SP)->A variable area containing * ;* the command to be placed in * ;* the CCP. The area MUST be * ;* terminated by a one-byte 00H. * ;* * ;*------------------------------------------------------* ; CCPCMD EQU 08H ;offset to CCP command buffer CCPLTH EQU 07H ;offset to CCP command length CCPBMAX EQU CCPLTH-1 ;offset to CCP max bufflen (code ;as it stands requires this) CURDRV EQU 0004H+BASE ;current drive in pg zero CPMEP EQU 0001H+BASE ;CP/M wboot entry point addr ; ;address ccp XCTL LHLD CPMEP ;get addr of CP/M BIOS+3 MVI L,0 ;point to BIOS DISPLC LXI D,-0800H-0D00H ;lgth of CCP plus CPM1.x BDOS ;(will be changed if CPM2.x) DAD D ;compute CBASE XCHG ;move CBASE to DE ;move command to ccp LXI H,CCPCMD ;offset of CCP command buffer... DAD D ;...+ CBASE XCHG ;DE=>CCP command buffer, HL=> CBASE XTHL ;HL=> pointer to new command, ;SP=> CBASE MVI B,0 ;init byte ctr CALL VARMOV ;move command to CCP ;set ccp command length POP D ;restore CBASE LXI H,CCPLTH ;offset of CCP bufr lgth DAD D MOV M,B ;put lgth in CCP ;set ccp buffer pointer DCX H ;point to maxbuff value (CCPBMAX) MOV A,M ;add adjustment to find buffend+1 ADI CCPCMD+1 ;(result is assumed <256) MOV L,A ;find actual address MVI M,CCPCMD ;reset to point to start of buff ;set ccp drive select, and execute ccp LDA CURDRV MOV C,A ;select current drive XCHG ;HL=>CBASE PCHL ;go exec command ; PAGE ;*------------------------------------------------------* ;* * ;* Parsing subroutines * ;* * ;*------------------------------------------------------* ; ; Build command using stored command and runtime parms. ; TBSAV DW CPMBUF+2 ;point to first runtime parm ;trapchar found: move parm instead (stop at true blank) MOVPARM PUSH H LHLD TBSAV ;point to next parm in tbuff CALL IFRPARM ;insert runtime parm, if any SHLD TBSAV ;save pointer to next parm POP H ;restore new-command pointer ;get char, test if trapchar BLDCOM MOV A,M INX H CPI TRAPCHR ;if not trapchar, repeat JZ MOVPARM ;if trapchr, move parm instead ;move character to ccp command buffer BLDCOM1 STAX D INX D ORA A ;repeat until null moved JNZ BLDCOM ;main command done: now append any leftover runtime parms to command DCX D ;point to end null MVI A,NOP ;set to move everything, even blanks STA BLNKTST LHLD TBSAV ;point to what's left of parms ;if runtime parms were passed, move one (if end, move all) IFRPARM LDA FCB1+1 ;if default fcb1 is not blank, CPI BLANK RZ ;no parms, so return ;else fall through to WRDMOV ;*------------------------------------------------------* ; ; Move from (HL) to (DE) until (HL)=(ZERO or BLANK) ; WRDMOV EQU $ MOV A,M ORA A RZ ;if end, don't incr hl INX H CPI BLANK BLNKTST RZ ;NOP if moving leftovers CPI BLNKSUB ;blank substitute? JNZ WMOV2 MVI A,BLANK ;yes, substitute a blank WMOV2 STAX D INX D JMP WRDMOV ;*------------------------------------------------------* ; ; Move from (HL) to (DE) until ZERO has been moved. ; VARMOV EQU $ MOV A,M STAX D INX H INX D ORA A RZ INR B ;increment length count JMP VARMOV ;*------------------------------------------------------* ;* * ;* NOTE: All code above this address must * ;* assemble at 01FFH or lower. * ;* * ;*------------------------------------------------------* ; ; Incr HL to point to next non-BLANK. ; NONBLK EQU $ MOV A,M CPI BLANK RNZ INX H JMP NONBLK ;*------------------------------------------------------* ; ; Incr HL to point to next BLANK or ZERO. ; FNDBLK EQU $ MOV A,M ORA A RZ CPI BLANK RZ INX H JMP FNDBLK PAGE ; ; ;*------------------------------------------------------* ;* * ;* Save old command name [and parm string] * ;* Save as a .COM file. * ;* * ;*------------------------------------------------------* CONFIG EQU $ MVI C,PRTSTR LXI D,SGNMSG CALL SYSTEM ;print sign msg ;goto help if no parms or if "?" LDA FCB1+1 CPI BLANK ;nothing entered? JZ HELP ;yes-> CPI '?' ;asking for help? JZ HELP ;yes-> ;if CPM2.x or higher, reset variables MVI C,GETVER CALL SYSTEM ;get CP/M verson MOV A,L ORA A ;CP/M 2.x ? JZ CONFI1 ;no-> MVI A,'O'+(HIDE SHL 7) ;set $DIR or $SYS indicator STA TYPSYS LXI H,-800H-0E00H ;BDOS LENGTH FOR CPM2.2 IS 0E00H SHLD DISPLC+1 ;CHANGE DEFAULT VALUE ;turn off entry to CONFIG CONFI1 EQU $ LXI H,BEGIN SHLD BEGADR+1 ;modify program EP ;get name of command LXI H,CPMBUF+1 CALL NONBLK ;HL==>newname LXI D,SAVNAM CALL WRDMOV ;move newname to SAVE command CALL NONBLK ;HL==>oldname PUSH H LXI H,TYPCOM ;HL==>".COM" CALL VARMOV ;move typ to SAVE command POP H ;HL==>oldname and parm string if any ;store command in page that will be saved to disk LXI D,NEWBUF ;buffer to build cmd for XCTL CALL VARMOV ;move real command and parms MVI A,1AH ;append ctl-z (will end TYPE command, STAX D ;when used to view newname.com file) ;don't allow reusing old name (unless starts with "X") as synonym: ; it's too easy to type (eg) SYNONYM PIP CON:= , and wipe out PIP! LDA FCB1+1 ;get initial of proposed synonym CPI 'X' ;"experimental" synonym? JZ CONFEND ;it's ok to overlay this file: skip LXI H,'C?' SHLD FCB1+9 MVI A,'M' ;find even if hidden STA FCB1+11 LXI D,FCB1 ;do only after everything else, since MVI C,SEARCHF ;search wipes out tbuff (80h-ffh) CALL SYSTEM ;see if name already in use INR A JNZ NAMEUSD ;if found, abort ;save command to disk CONFEND CALL XCTL ;issue SAVE command DB 'SAVE 1 ' ;one page 0100H -- 01FFH SAVNAM DW 0,0,0,0,0,0,0,0 ;synonym name TYPCOM DB '.C' TYPSYS DB 'OM',0 ;*------------------------------------------------------* NAMEUSD EQU $ LXI D,ERR1MSG JMP PRINT DASHES MVI B,63 MVI C,CHAROUT DASH2 MVI E,'-' PUSH B CALL SYSTEM POP B DCR B JNZ DASH2 RET HELP EQU $ LXI D,HLPMSG1 CALL PRINT CALL DASHES LXI D,HLPMSG2 CALL PRINT CALL DASHES LXI D,HLPMSG3 PRINT MVI C,PRTSTR CALL SYSTEM RET ERR1MSG DB CR,LF,LF,'Abort: name already in use.' DB CR,LF,EOM SGNMSG DB CR,LF DB 'SYNONYM 3.0 Oct81' DB EOM HLPMSG1 DB ' (To view newname.COM: TYPE newname.COM)' DB CR,LF,EOM HLPMSG2 DB CR,LF DB 'SYNONYM format: SYNONYM newname oldname [parm string]' DB CR,LF,LF DB ' newname proposed synonym for command.' DB CR,LF,LF DB ' oldname standard name of command. (May ' DB 'give drive.)' DB CR,LF,LF DB ' parm string optional string, appended ' DB 'when newname is run.' DB CR,LF,LF,EOM HLPMSG3 DB CR,LF DB 'To execute newname: newname [rparm1 rparm2 ...]' DB CR,LF,LF DB ' rparmx ... optional runtime parameters' DB CR,LF,LF DB ' Any ' DB '"',TRAPCHR,'"s' DB ' in "parm string" ' DB 'will be replaced by an rparm.' DB CR,LF DB ' Any leftover rparms will be appended to ' DB '"parm string".' DB CR,LF,LF DB ' Rparms are separated by a SINGLE blank; ' DB 'two consecutive' DB CR,LF DB ' blanks indicate a null parm. ' DB '(To pass an rparm with an' DB CR,LF DB ' imbedded ' DB 'blank, use a "',BLNKSUB,'" instead of a blank.)' DB EOM ; BLANK EQU 20H FCB1 EQU 005CH+BASE CPMBUF EQU 0080H+BASE CHAROUT EQU 2 PRTSTR EQU 9 GETVER EQU 12 SEARCHF EQU 17 CR EQU 13 LF EQU 10 EOM EQU '$' SYSTEM EQU 0005H+BASE NEWCOM EQU $ ;128-byte buffer in uninitialized ram END