.TITLE AUXCMD - Check and Process Commands .IDENT /1.0/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: AUXCMD.MAC ; Author: Robin Miller ; Date: July 23, 1985 ; ; Description: ; ; This module is used to check the valid AUX commands. ; ; edit history ; ; May 2, 86 F. Borger ; edited to not save command if same as previous command ;- .ENABL AMA .NLIST BEX ; ; Action routines for TPARS. ; Registers R0, R1, and R2 may be used by the action routines. ; All other registers must be preserved. ; ;****************************************************************************** ; ADVANCE - Set the direction to forward. ADVCMD::BIS #B.ADV,SWMASK ; Set advance direction. RETURN ; BACKUP - Set the direction to backward. BCKCMD::BIC #B.ADV,SWMASK ; Set backup direction. RETURN ;****************************************************************************** ; Move the cursor to beginning of command line. BOLCMD::MOV CMDPTR,R1 ; At beginning of command line ? BEQ 100$ ; If EQ, yes (no action). CLR CMDPTR ; Set pointer to beginning of line. MOV #FMTBUF,R0 ; Set the output buffer address. CALL CLEFT ; Position cursor after prompt. JMP VTYPE ; Go update the screen. 100$: RETURN ;****************************************************************************** ; CLEAR - Clear the terminal screen. CLRCMD::CALL CLRTTY ; Clear the terminal screen. JMP REFCMD ; Refresh the command line. ;****************************************************************************** ; EOL - Move the cursor to end of command line. EOLCMD::MOV CMDEND,R1 ; Copy end of the command line. CMP CMDPTR,R1 ; Already at end of command line ? BEQ 100$ ; If EQ, yes (no action). SUB CMDPTR,R1 ; Calculate positions to move. MOV CMDEND,CMDPTR ; Set pointer to end of line. MOV #FMTBUF,R0 ; Set the output buffer address. CALL CRIGHT ; Move the cursor to the right. JMP VTYPE ; Go update the screen. 100$: RETURN ;****************************************************************************** ; Display an exit message. EXICMD::MOV #FMTBUF,R0 ; Set the output buffer address. MOV CMDPTR,R1 ; Copy the command line pointer. BEQ 10$ ; If EQ, at start of line. CALL CLEFT ; Else, position after prompt. 10$: CALL REVERSE ; Turn on the reverse video. MVS ; Show user we are exiting. CALL ATTOFF ; Turn off the attributes. CALL CEOL ; Clear to end of command line. CLR CMDPTR ; Clear the command line pointer. CLR CMDEND ; Clear end of the command line. JMP VTYPE ; Display the message and return. ;****************************************************************************** ; Move the cursor left. LEFCMD::TST CMDPTR ; At beginning of command line ? BEQ 100$ ; If EQ, yes (no action). DEC CMDPTR ; Point to previous character. MOV #FMTBUF,R0 ; Set the output buffer address. ;* MOV #1,R1 ; Set number of positions to move. ;* CALL CLEFT ; Move the screen cursor left. MOVB #BS,(R0)+ ; Move the screen cursor left. JMP VTYPE ; Update the screen. 100$: RETURN ;****************************************************************************** ; Refresh the command line. REFCMD::JSR R2,$SAVVR ; Save R0 - R2. MOV #FMTBUF,R0 ; Set the output buffer address. CALL COPYPR ; Copy the prompt line sequence. TST CMDEND ; Is there a command line ? BEQ 10$ ; If EQ, no (don't copy). MOV #CMDBUF,R1 ; Set address of command line. CALL MOVEF ; Copy the command line. 10$: CALL CEOL ; Clear to end of command line. MOV CMDEND,R1 ; Copy end of the command line. MOV CMDPTR,R2 ; Copy the command pointer. CMP R1,R2 ; Are we at end of command ? BEQ 20$ ; If EQ, yes. SUB R2,R1 ; Calculate positions to move. CALL CLEFT ; Point cursor in command line. 20$: JMP VTYPE ; Update the screen and return. ;****************************************************************************** ; Move the cursor right. RIGCMD::CMP CMDPTR,CMDEND ; Are we at end of the command ? BEQ 100$ ; If EQ, yes. INC CMDPTR ; No, Point to the next character. MOV #FMTBUF,R0 ; Set the output buffer address. MOV #1,R1 ; Set number of positions to move. CALL CRIGHT ; Move the screen cursor right. JMP VTYPE ; Update the screen. 100$: RETURN ;****************************************************************************** ; Get the next command line (if any). NXTCMD::MOV CMDCUR,R0 ; Copy the current command entry. BEQ 100$ ; If EQ, there is none. MOV C.FORW(R0),R0 ; Get pointer to the next entry. TST C.BUFF(R0) ; Is this command entry empty ? BEQ 100$ ; If EQ, no. MOV R0,CMDCUR ; Set address of current entry. JMP CPYCMD ; Copy this command line entry. 100$: JMP WRTBEL ; Ring bell to show no more cmds. ;****************************************************************************** ; Get the previous command line (if any). PRVCMD::MOV CMDCUR,R0 ; Copy the current command entry. MOV C.BACK(R0),R0 ; Get pointer to previous entry. TST C.BUFF(R0) ; Is this command entry empty ? BEQ 100$ ; If EQ, yes. MOV R0,CMDCUR ; Set address of current entry. JMP CPYCMD ; Copy this command line entry. 100$: JMP WRTBEL ; Ring bell to show no more cmds. .SBTTL SKBCMD - Skip backward to character. ;+ ; ; SKBCMD - Skip backward to a character. ; ; This routine is used to skip to the character specified by the user. ; After entering this routine, the user is expected to type a character ; to search backwards for in the command line. If found, the cursor ; and the command pointer is updated appropriatly. If not found, the ; terminal bell is rung. ; ; Inputs: ; None. ; ; Outputs: ; Registers R3 - R5 are preserved. ; ;- SKBCMD::JSR R5,$SAVRG ; Save R3 - R5. MOV CMDPTR,R1 ; Copy the command pointer. BEQ 90$ ; If EQ, at start of line. MOV #TMPBUF,R0 ; Set the input buffer address. CALL GETONE ; Go read a character. MOVB (R0),R2 ; Copy character to search for. MOV #CMDBUF,R0 ; Set starting buffer address. ADD R1,R0 ; Index to current pointer. MOV R1,R3 ; Copy the command pointer. 10$: CMPB -(R0),R2 ; Does this character match ? BEQ 100$ ; If EQ, yes. SOB R3,10$ ; Loop until we're done. 90$: CALL WRTBEL ; Ring the terminal bell. RETURN 100$: DEC R3 ; Adjust for character searched. SUB R3,R1 ; Calculate characters searched. SUB R1,CMDPTR ; Adjust the command pointer. MOV #FMTBUF,R0 ; Set the output buffer address. CALL CLEFT ; Set to move the cursor left. JMP VTYPE ; Update the terminal and return. .SBTTL SKFCMD - Skip forward to character. ;+ ; ; SKFCMD - Skip forward to a character. ; ; This routine is used to skip to the character specified by the user. ; After entering this routine, the user is expected to type a character ; to search forwards for in the command line. If found, the cursor ; and the command pointer is updated appropriatly. If not found, the ; terminal bell is rung. ; ; Inputs: ; None. ; ; Outputs: ; Registers R3 - R5 are preserved. ; ;- SKFCMD::JSR R5,$SAVRG ; Save R3 - R5. CMP CMDPTR,CMDEND ; Already at end of line ? BEQ 90$ ; If EQ, yes (no action). MOV #TMPBUF,R0 ; Set the input buffer address. CALL GETONE ; Go read a character. MOVB (R0),R2 ; Copy character to search for. MOV CMDPTR,R0 ; Copy the command pointer. MOV CMDEND,R1 ; Copy end of command line. INC R0 ; Start search at next character. SUB R0,R1 ; Calculate characters to search. BEQ 90$ ; If EQ, we're at end of line. ADD #CMDBUF,R0 ; Set the command buffer address. MOV R1,R3 ; Copy the command pointer. 10$: CMPB (R0)+,R2 ; Does this character match ? BEQ 100$ ; If EQ, yes. SOB R3,10$ ; Loop until we're done. 90$: CALL WRTBEL ; Ring the terminal bell. RETURN 100$: DEC R3 ; Adjust for character searched. SUB R3,R1 ; Calculate characters searched. ADD R1,CMDPTR ; Adjust the command pointer. MOV #FMTBUF,R0 ; Set the output buffer address. CALL CRIGHT ; Set to move the cursor right. JMP VTYPE ; Update the terminal and return. .SBTTL SKPWRD - Skip word forward/backward. ;+ ; ; SKPWRD - Skip word forward/backward. ; ; This routine is used to skip words in the command line. ; ; Implicit Inputs: ; CMDPTR = The command line pointer. ; CMDEND = End of the command line. ; ; Implicit Outputs: ; CMDPTR = The adjusted command line pointer. ; ;- SKPWRD::JSR R5,$SAVRG ; Save R3 - R5. BIT #B.ADV,SWMASK ; Is the direction advance ? BEQ 10$ ; If EQ, no (backup). ; Advance over the next word. CALL ADVWRD ; Advance over next word. BCS 100$ ; If CS, no word skipped. ADD R3,CMDPTR ; Adjust the command pointer. MOV #FMTBUF,R0 ; Set the output buffer address. MOV R3,R1 ; Copy # of characters skipped. CALL CRIGHT ; Position cursor after word. JMP VTYPE ; Update screen and return. ; Backup over the previous word. 10$: CALL BCKWRD ; Backup over previous word. BCS 100$ ; If CS, no word skipped. SUB R3,CMDPTR ; Adjust the command pointer. MOV #FMTBUF,R0 ; Set the output buffer address. MOV R3,R1 ; Copy # of characters skipped. CALL CLEFT ; Position cursor before word. JMP VTYPE ; Update screen and return. 100$: RETURN .SBTTL ADVWRD - Advance over word. ;+ ; ; ADVWRD - Advance over word. ; ; This routine is used to advance over words in the command line. ; ; Implicit Inputs: ; CMDPTR = The command line pointer. ; CMDEND = End of the command line. ; ; Outputs: ; C bit clear/set = word skipped/not skipped. ; ; R0 = The starting address of the word. ; R1 = The ending address of the word. ; R2 = The ending command line address. ; R3 = The number of characters skipped. ; ;- ADVWRD::CMP CMDPTR,CMDEND ; Are we at end of command ? BEQ 90$ ; If EQ, yes (no action). MOV #CMDBUF,R0 ; Set the command line address. MOV R0,R2 ; Save the command line address. ADD CMDEND,R2 ; Point to end of command line. ADD CMDPTR,R0 ; Index into the command line. MOV R0,R1 ; Save the starting position. CMPB (R1),#SPACE ; Starting character a space ? BNE 20$ ; If NE, no. ; Skip over all spaces, stop at first non-space. 10$: CMP R1,R2 ; At end of the command line ? BEQ 30$ ; If EQ, yes. CMPB (R1)+,#SPACE ; Is this a space character ? BEQ 10$ ; If EQ, yes (check next). DEC R1 ; Don't delete last character. BR 30$ ; Delete all leading spaces. ; Now find the next space or horizontal tab. 20$: CMP R1,R2 ; At end of the command line ? BEQ 30$ ; If EQ, yes. CMPB (R1)+,#HT ; Is this a horizontal tab ? BEQ 30$ ; If EQ, yes. CMPB -1(R1),#SPACE ; Previous a space character ? BNE 20$ ; If NE, no (check next). ; Now, skip all spaces at end of this word. 25$: CMP R1,R2 ; At end of the command line ? BEQ 30$ ; If EQ, yes. CMPB (R1),#HT ; Is this a horizontal tab ? BEQ 30$ ; If EQ, yes. CMPB (R1)+,#SPACE ; Is this a space character ? BEQ 25$ ; If EQ, yes. DEC R1 ; Don't delete this character. 30$: MOV R1,R3 ; Copy the ending address. SUB R0,R3 ; Calculate characters skipped. BR 100$ ; Use common return ... 90$: SEC ; Show no word was skipped. 100$: RETURN .SBTTL BCKCMD - Backup over word. ;+ ; ; BCKWRD - Backup over word. ; ; This routine is used to backup words in the command line. ; ; Implicit Inputs: ; CMDPTR = The command line pointer. ; CMDEND = End of the command line. ; ; Outputs: ; C bit clear/set = word skipped/not skipped. ; ; R0 = The start address of the word. ; R1 = The ending address of the word. ; R2 = The starting command line address. ; R3 = The number of characters skipped. ; ;- BCKWRD::TST CMDPTR ; Already at start of line ? BEQ 90$ ; If EQ, yes (no action). MOV #CMDBUF,R0 ; Set the command line address. MOV R0,R2 ; Save the command line address. ADD CMDPTR,R0 ; Index into the command line. MOV R0,R1 ; Save the starting position. ; Backup over all previous spaces, stop at first non-space. 10$: CMP R0,R2 ; Are we at start of line ? BEQ 30$ ; If EQ, yes. CMPB -(R0),#HT ; Is this a horizontal tab ? BEQ 30$ ; Yes, delete a single tab. CMPB (R0),#SPACE ; Is this a space character ? BEQ 10$ ; If EQ, yes (check next). ; Now find the previous space or horizontal tab. 20$: CMP R0,R2 ; Are we at start of line ? BEQ 30$ ; If EQ, yes. CMPB -(R0),#HT ; Is this a horizontal tab ? BEQ 25$ ; If EQ, yes. CMPB (R0),#SPACE ; Is this a space character ? BNE 20$ ; If NE, no (check next). 25$: INC R0 ; Don't delete this space. 30$: MOV R1,R3 ; Copy the starting address. SUB R0,R3 ; Calculate characters skipped. BR 100$ ; Use common return ... 90$: SEC ; Show no word was skipped. 100$: RETURN .SBTTL CPYCMD - Copy the current command entry. ;+ ; ; CPYCMD - Copy the current command entry. ; ; This routine is called to copy the current command entry buffer to the ; normal command buffer used for input. ; ; Inputs: ; R0 = The command entry address. ; ; Outputs: ; R0 and R1 are destroyed. ; ;- CPYCMD::ADD #C.BUFF,R0 ; Point to the save command area. CALL GETLEN ; Calculate the command length. MOV R1,CMDEND ; Set the ending command address. MOV R1,CMDPTR ; Show we're pointing to a command. MOV #CMDBUF,R1 ; Set the command buffer address. 10$: MOVB (R0)+,(R1)+ ; Copy the last command line. BNE 10$ ; If NE, loop until we're done. CALL REFCMD ; Display command on the screen. RETURN ;****************************************************************************** ; RCLCMD - Recall a particular command. RCLCMD::TST .PNUMH ; Is number specified too big ? BNE 90$ ; If NE, yes. MOV .PNUMB,R2 ; Copy the number specified ? CMP R2,#CMDMAX ; Is the number too large ? BHI 90$ ; If HI, yes. MOV #CMDTBL,R1 ; Point to top of command table. ; Find the command entry specified. DEC R2 ; Adjust the command number. BEQ 20$ ; If EQ, first entry. 10$: MOV C.FORW(R1),R1 ; Get address of the next entry. SOB R2,10$ ; Loop till entry is found. ; Setup the new command line if a command exists. 20$: ADD #C.BUFF,R1 ; Point to the data area. MOV #CMDBUF,R0 ; Set command buffer address. CALL MOVEC ; Copy the command line. MOV R1,CMDPTR ; Setup the command pointer. MOV R1,CMDEND ; Setup end of command line. BIS #B.MORE,STATUS ; Set to get more input. JMP REFCMD ; Refresh the command line. 90$: ERRMSG TOOBIG, RETURN ;****************************************************************************** ; RECALL - Display all saved command lines. .ENABL LSB RECALL::CALL $SAVAL ; Save all registers. MOV #FMTBUF,R0 ; Set the output buffer address. MOV IENTRY,R5 ; Set the file entry address. CALL SAVEC ; Save the cursor position. CALL CPYMSG ; Position/clear message line. CALL CBOS ; Clear to top of the scrren. CALL CPYTOP ; Set to top of current window. CALL VTYPE ; And go do it. ;*** CALL CLRWIN ; Clear the current window. MOV #CMDTBL,R2 ; Point to top of command table. TST C.BUFF(R2) ; Are there any commands saved ? BNE 10$ ; If NE, yes. MVS BR 100$ ; Use common code ... ; Format and display each command in the table. 10$: MOV #CMDMAX,R3 ; Set the maximum command entrys. CLR R4 ; Initialize the command number. 20$: INC R4 ; Adjust the command count. CMP R2,CMDCUR ; Is this the current entry ? BNE 30$ ; If NE, no. MOVB #'>,(R0)+ ; Flag this as active command. MVS < > ; Move in two more spaces. BR 40$ ; And join common code ... 30$: MVS < > ; Start of with three spaces. 40$: MOV R4,R1 ; Copy the command number. CMP R1,#10. ; Is it only a single digit ? BLT 50$ ; If LT, yes. DEC R0 ; Else, discard one space. 50$: CALL CVTDEC ; Convert # to decimal ASCII. MVS <. > ; Follow this with two spaces. MOV R2,R1 ; Copy the command line entry. ADD #C.BUFF,R1 ; Point to the buffer area. CALL MOVEF ; Copy & format command line. CALL CPYBLA ; Add some carriage control. CALL VTYPE ; Display this command entry. MOV C.FORW(R2),R2 ; Get address of the next entry. TST C.BUFF(R2) ; Is this command entry empty ? BEQ 100$ ; If EQ, yes (we're all done). SOB R3,20$ ; Loop until all entrys done. 100$: CALL RESTC ; Restore the cursor position. ; JMP VTYPE ; Update the screen and return. jmp refcmd ; Update the screen this way .DSABL LSB .SBTTL SAVCMD - Save the last command line. ;+ ; ; SAVCMD - Save the last command line. ; ; This routine is used to copy the last command line for recall at a later ; time, unless the previous command is the same. ; ; Inputs: ; R0 = The command line address. ; R1 = The command byte count. ; ; Implicit Inputs: ; CMDENT = Address to save next command line. ; ; Outputs: ; All registers are preserved. ; ;- SAVCMD::call $SAVAL ;FRB01 Save all registers mov cmdent,r2 ;FRB01 Copy the current entry address mov c.back(r2),r2 ;FRB01 Back up to last one saved add #c.buff,r2 ;FRB01 bump to buffer area mov r0,r3 ;FRB01 point to current command mov r1,r4 ;FRB01 count to r4 1$: cmpb (r2)+,(r3)+ ;FRB01 compare commands bne 9$ ;FRB01 branch if not same sob r4,1$ ;FRB01 loop till done mov cmdent,cmdcur ;FRB01 Update command entry anyway br 99$ ;FRB01 fell thru, don't save 9$: MOV CMDENT,R2 ; Copy the current entry address. MOV C.FORW(R2),CMDENT ; Set address of next command entry. MOV CMDENT,CMDCUR ; Set the current command entry. ADD #C.BUFF,R2 ; Point to the buffer area. 10$: MOVB (R0)+,(R2)+ ; Copy the current command line. SOB R1,10$ ; And loop until we're done. CLRB (R2) ; Mark end of this command line. 99$: RETURN .END