.TITLE VTLCMD - Check and Process Commands .IDENT /1.7/ .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: VTLCMD.MAC ; Author: Robin Miller ; Date: June 30, 1983 ; ; Description: ; ; This module is used to check the valid VTL commands. If the ; command is valid, then it is executed before returned to list any ; further lines in the file. If it is invalid, it is simply ignored. ; ;- .ENABL AMA .NLIST BEX ;+ ; ; Modification History: ; ; June 13, 1984 by Robin Miller. Edit (05), Version 1.7 ; When moving forward more records than the current page size, ; use the top of page record number for the calculation instead ; of the current record number. ; ; June 12, 1984 by Robin Miller. Edit (04), Version 1.6 ; Added check for CTRL/U typed after getting a command to force ; a reprompt of the user. ; ; June 7, 1984 by Robin Miller. Edit (03), Version 1.5 ; Add calls to timer routines to display working message in the ; BOTCMD and the NUMCMD routines. ; ; June 4, 1984 by Robin Miller. Edit (02), Version 1.4 ; Don't clear search string active flag on TOP of file command. ; ; May 29, 1984 by Robin Miller. Edit (01), Version 1.3 ; Don't automatically change directions at top of file or end of ; file. We'll display a message instead. ;- .SBTTL CHKCMD - Get/check/execute a command. ;+ ; ; CHKCMD - Get/check/execute a command. ; ; Inputs: ; R5 = The active file entry address. ; ; Implicit Inputs: ; O.LCNT = The current page line count. ; O.TOPR = The top of page record number. ; O.CREC = The current record number. ; ; Outputs: ; All registers are destroyed. ; ;- CHKCMD::CALL $SAVAL ; Save all registers, MOV O.CREC(R5),WTGREC ; Copy the current record MOV O.CREC+2(R5),WTGREC+2 ; to the WTG record number. .ENABL LSB PRLOOP::BIC #B.BACK!B.CTRC,STATUS ; Reset partial backup & CTRL/C. MOV IENTRY,R5 ; Copy the file entry address. BIC #B.DOPR,STATUS ; Clear the do prompt bit. CALL WRITPR ; Prepare and write the prompt. MOV #CMDBUF,R0 ; Set address of the input buffer. MOV #CMDSIZ,R1 ; Set the maximum input byte count. CALL GETCMD ; Read a command from the user. ;*** BCS 20$ ; If CS, error or time to exit. (04) CMPB TIOSB+1,#CTRLU ; Control/U typed to reprompt ? (04) BEQ PRLOOP ; If EQ, yes. (04) MOV TIOSB,R2 ; Copy the terminator status code. CALL CLRMSG ; Clear the message line. ; ; Check for an escape sequence. If an escape sequence was used to ; terminate a normal VTL command (the size is greater than 3), then ; the count is adjusted before parsing the command line. Otherwise, ; the escape sequence is converted into a normal VTL command. ; 10$: CMP R2,#IS.ESQ ; Was this an escape sequence ? BNE 20$ ; If NE, no (parse the command). CMP R1,#3 ; Was command terminated by escape ? BGT 15$ ; If GT, yes (adjust the count). ; Check for a valid keypad command. CALL KEYPAD ; Check for a valid keypad command. BCC 20$ ; If CC, the key is defined. ERRMSG NOKEY, BR PRLOOP ; Prompt user for another command. 15$: SUB #3,R1 ; Adjust for the escape sequence size. ; Parse the command line. 20$: BIT #B.EXIT,STATUS ; Does the user want to exit now ? BNE 25$ ; If NE, yes. TST R1 ; Was anything entered or just ? BEQ 30$ ; If EQ, nothing was entered. MOV #VTLCMD,R5 ; Set the starting state table address. CALL DOPARS ; Parse the command line. BCS PRLOOP ; If CS, we had an error. BIT #B.EXIT!B.NEXT,STATUS ; Time to exit of display next file ? BNE 25$ ; If NE, yes. CALL CHCTRC ; If CTRL/C typed, report the message. 22$: BIT #B.DOPR,STATUS ; Should we issue the prompt again ? BNE PRLOOP ; If NE, yes. 25$: RETURN 30$: MOV IENTRY,R2 ; Copy the file entry address. (01) CALL CHKTB ; Check for top/bottom of file. (01) BCS 22$ ; If CS, reprompt the user. (01) JMP DONEXT ; Do the next page processing. .DSABL LSB ; Action routines for TPARS. ; Registers R0, R1, and R2 may be used by the action routines. ; All other registers must be preserved. ;****************************************************************************** ; Advance forward through the file (sets the direction only). ADVCMD::MOV IENTRY,R2 ; Copy the file entry address. BIS #S.FORW,(R2) ; Show we're listing forward. RETURN ;****************************************************************************** ; Position to the bottom of the file. BOTCMD::MOV IENTRY,R2 ; Set the file entry address. MOV #-1,WTGREC ; Set highest MOV #-1,WTGREC+2 ; record number. CALL STIMER ; Start working message timer. (03) CALL POINTR ; Position to the end of file. (03) CALL CTIMER ; Cancel working message timer. (03) JMP DOPOS1 ; Dispatch to refresh routine. (03) ;****************************************************************************** ; List backwards through the file (sets the direction only). BCKCMD::MOV IENTRY,R2 ; Copy the file entry address. ;*** BIC #S.FORW!S.EOF,(R2) ; Show we're listing backwards. BIC #S.FORW,(R2) ; Show we're listing backwards. RETURN ;****************************************************************************** ; Display help on a command. HLPCMD::ERRMSG NOHELP, BIS #B.DOPR,STATUS ; Show we should prompt again. RETURN ;****************************************************************************** ; Move the margin left. .ENABL LSB LEFCMD::MOV IENTRY,R2 ; Copy the file entry address. MOV .PNUMB,R1 ; Copy the count to adjust. BNE 20$ ; If NE, we got a number. 10$: CLR O.MARG(R2) ; Zero means all the way left. BR 30$ ; And continue ... LEFDEF::MOV TABSIZ,R1 ; Setup the default count. 20$: MOV IENTRY,R2 ; Copy the file entry address. MOV O.MARG(R2),R0 ; Copy the margin indent count. BEQ 40$ ; If EQ, already at left margin. SUB R1,R0 ; Calculate the new margin count. BMI 10$ ; If MI, too far (reset to zero). MOV R0,O.MARG(R2) ; Else, save the new margin count. 30$: CALL CHKRUL ; Rewrite the ruler (if active). JMP REPAGE ; Get ready to redisplay the page. 40$: BIS #B.DOPR,STATUS ; Show we should reprompt the user. RETURN .DSABL LSB ;****************************************************************************** ; Move the margin right. .ENABL LSB RIGCMD::MOV .PNUMB,R1 ; Copy the count to indent. BR 10$ ; And continue ... RIGDEF::MOV TABSIZ,R1 ; Setup the default count. 10$: MOV IENTRY,R2 ; Copy the file entry address. MOV O.MARG(R2),R0 ; Copy the current margin count. ADD R1,R0 ; Calculate the new margin count. CMP R0,#RECSIZ ; Is the indent count too big ? BHI 20$ ; If HI, exceeding record size. MOV R0,O.MARG(R2) ; Save the new margin indent count. CALL CHKRUL ; Rewrite the ruler (if active). JMP REPAGE ; Get ready to redisplay the page. 20$: BIS #B.DOPR,STATUS ; Show we should reprompt the user. RETURN .DSABL LSB ;****************************************************************************** ; Refresh the current page (including the filename). .ENABL LSB REFCMD::BIT #B.EXIT!B.NEXT,STATUS ; Time to exit or next file ? BNE 100$ ; If NE, yes (don't refresh). ; ; If doing two file display, we redisplay the active file first ; so the line width propagates to the non-active file. ; BIT #B.2FIL,STATUS ; Are we displaying two files ? BEQ REFSCR ; If EQ, no (refresh current). ; ; If terminal has no AVO, force into a narrow screen. ; BIT #B.AVO,SWMASK ; Does terminal have the AVO ? BNE 10$ ; If NE, yes. BIC #B.WIDE,SWMASK ; Disable the wide screen flag ? BIS #B.NAR,SWMASK ; Force into a narrow screen ? 10$: BIC #B.2FIL,STATUS ; Disable two file display mode. CALL SETWID ; Setup the screen width. CALL WRTWID ; Now, write the screen width. BIS #B.2FIL,STATUS ; Restore the two file flag. CALL SWAPEM ; Swap the file table entrys. CALL DOREF ; Redisplay the other file. CALL SWAPEM ; Swap back to the active file. REFSCR::CALL DOREF ; Refresh only the active file. CALL WRTACT ; Show that this file is active. 100$: RETURN .DSABL LSB ; Routine to redisplay a page for a file entry. DOREF: CALL SETUP ; Setup the display parameters. CALL WRTHDR ; Write the file name, etc. BR DODIS ; Now do the page redisplay. REPAGE:: ; Entry to redisplay the page. CALL CLRWIN ; Clear the active display window. DODIS: BIS #B.DOPR,STATUS ; Show we should reprompt the user. CALL PNTTOP ; Point to the top of page record. CALL DISPAG ; Display the last page again. RETURN ;****************************************************************************** ; Advance or backup a section on the screen. SECCMD::MOV IENTRY,R2 ; Set the file entry address. MOV O.SSIZ(R2),R1 ; Copy the section line count. BIT #S.FORW,(R2) ; Are we listing forward ? BNE PLUS ; If NE, yes. BR MINUS ; No, we're listing backward. ;****************************************************************************** ; Postion to the top of file. TOPCMD::MOV IENTRY,R2 ; Set the file entry address. ;(02) BIC #S.SRCH,(R2) ; Show no search string active. BIS #S.FORW,(R2) ; Set to forward direction. (01) CLR WTGREC ; Set to go to CLR WTGREC+2 ; the first record. JMP DOPOS ; Do the record positioning. .SBTTL LINCMD - Backup/forward specified number of lines. ;+ ; ; LINCMD - Backup/forward a specified number of lines. ; ; This routine backs up or goes forward a specified number of lines before ; displaying the next screen. If a "+" or "-" sign is specified, then the ; direction is either "forward" or "backward" respectivly. If a direction ; is not specified, then the current direction is used. ; ; *** These routines are very messy and need rewritten. *** ;- LINCMD::MOV IENTRY,R2 ; Copy the file entry address. MOV #1,R1 ; Set the default number to move. TST NEGFLG ; Backup specified number of lines ? BMI MINUS ; If MI, yes. TST PLUFLG ; Forward specified number of lines ? BMI PLUS ; If MI, yes BIT #S.FORW,(R2) ; Are we listing in forward direction ? BNE PLUS ; If NE, yes. ; Backup a specified number of lines. R1 = The number of records. MINUS:: CALL CHKTOP ; Backing up past top of file ? (01) BCS 90$ ; If CS, yes (can't backup) (01) BIC #B.BACK,STATUS ; Presume not a partial backup. MOV R1,BCKCNT ; No, save count for scroll down. BIT #S.EOF,(R2) ; Are we backing up from EOF ? BNE 20$ ; If NE, yes (refesh entire page). BIT #S.SEE,(R2) ; Are we in see-all mode ? BNE 10$ ; If NE, yes (allow partial backup). CMP R1,O.RCNT(R2) ; Backing up more than a page ? BGE 20$ ; If GE, yes (refresh entire page). ; ; Backing up a partial page only works if the file has implied or ; Fortran carriage control since each record is usually displayed ; on one line. If this is not true, writing the records to fill ; up the screen overwrites what is already on the screen. ; MOV O.FDB(R2),R0 ; Copy the FDB address. BITB #FD.CR!FD.FTN,F.RATT(R0) ; Implied/fortran carriage control ? BEQ 20$ ; If EQ, no (repaint the entire page). 10$: BIS #B.BACK,STATUS ; Yes, show backing up a partial page. 20$: ADD O.RCNT(R2),R1 ; Add the last page record count. DEC R1 ; Adjust to get desired record. JMP BACKUP ; Backup to the appropriate record. 90$: RETURN ; (01) ; Forward a specified number of lines. R1 = The number of records. PLUS:: CALL CHKBOT ; Advance past bottom of file ? (01) BCS 5$ ; If CS, yes (can't advance) (01) ;(01) BIT #S.EOF,(R2) ; Are we at the end of file ? ;(01) BNE 20$ ; If NE, yes (can't go forward). CMP R1,O.LSAV(R2) ; Forward more than a page ? BGT 10$ ; If GT, yes (position to record). MOV O.LSAV(R2),O.LCNT(R2) ; Set the last page line count. SUB R1,O.LCNT(R2) ; Calculate the lines to display. ADD R1,O.TOPR+2(R2) ; Adjust the top of ADC O.TOPR(R2) ; page record number. BIC #S.STOP,(R2) ; Show top of page record is setup. ;*** ;*** The following only works if the entire page is full. ;*** CALL NXTPAG ; Do the next page processing. 5$: RETURN 10$: MOV O.TOPR(R2),WTGREC ; Else, copy the top of (05) MOV O.TOPR+2(R2),WTGREC+2 ; page record number. (05) ADD R1,WTGREC+2 ; Calculate the record ADC WTGREC ; number to position to. JMP DOPOS ; And position to it. ;20$: JMP DONEXT ; Do the next page processing. (01) ; Numeric input. Position at a specified record number. NUMCMD::MOV IENTRY,R2 ; Copy the file entry address. MOV .PNUMH,WTGREC ; Copy the record (high bits) MOV .PNUMB,WTGREC+2 ; number specified (low bits). CALL STIMER ; Start working message timer. (03) CALL POINTR ; Position to the end of file. (03) CALL CTIMER ; Cancel working message timer. (03) JMP DOPOS1 ; Dispatch to refresh routine. (03) .SBTTL DOPOS - Position to a record number. ;+ ; ; DOPOS - Position to a record number. ; DOPOS1 - Entry to dispatch to refresh routine. ; ; This routine is used to position to a particular record number. If we're ; we're going to the top of file, the forward direction is set. ; ; Inputs: ; R2 = The active file entry address. ; ; Implicit inputs: ; WTGREC = The record number to position to. ; ; Outputs: ; All registers are preserved. ; ;- DOPOS: ;(01) TST WTGREC ; Are we going to the top of file ? ;(01) BNE 10$ ; If NE, no. ;(01) CMP WTGREC+2,#1 ; Really TOF, to record 0 or 1 ? ;(01) BHI 10$ ; If HI, no. ;(01) BIS #S.FORW,(R2) ; Yes, set forward direction. 10$: CALL POINTR ; Now point to the specified record. DOPOS1: BIT #S.EOF,(R2) ; Did we run into the end of file ? BNE DOEOF ; Yes, do the end of file processing. CALL CLRPAG ; Else, clear the display window. RETURN .SBTTL DOEOF - Do the end of file processing. ;+ ; ; DOEOF - Do the end of file processing. ; ; This routine is called when we've detected end of file. The purpose of ; this routine is to calculate the number of record to backup to display ; the last records of the file on the screen. ; ; Inputs: ; O.CREC = The end of file record number. ; ; Outputs: ; All registers are preserved. ; ;- DOEOF:: CALL $SAVAL ; Save all registers. MOV IENTRY,R2 ; Copy the file entry address. TST O.CREC(R2) ; Is there enough records to backup ? BNE 10$ ; If NE, yes (high record bits). CMP O.CREC+2(R2),O.LMAX(R2) ; Is there less than a page ? BLOS 100$ ; If LOS, yes (don't point). 10$: MOV O.CREC(R2),WTGREC ; COPY LAST RECORD # MOV O.CREC+2(R2),WTGREC+2 ; AND THE SECOND WORD MOV O.LMAX(R2),R0 ; COPY MAX # OF LINES MOV O.FDB(R2),R1 ; Copy the FDB address. MOV #2,R2 ; DEFAULT # TO ADJUST ;*** BITB #FD.CR!FD.FTN,F.RATT(R1); NORMAL OR FORTRAN CONTROL ? BNE 40$ ; IF NE, YES (USE DEFAULT) CLR R2 ; CLEAR THE HIGH BITS MOV R0,R3 ; COPY MAXIMUM # OF LINES DIV #3,R2 ; GET 1/3 OF SCREEN SIZE ;*** 40$: SUB R2,R0 ; DISPLAY ONLY 2/3 OF SCREEN SUB R0,WTGREC+2 ; SET TO DISPLAY FULL PAGE SBC WTGREC ; SUBTRACT CARRY (IF ANY) CALL POINTR ; GO POINT TO IT CALL CLRPAG ; Clear the entire display window. 100$: RETURN .SBTTL CLRPAG - Clear the active display window. ;+ ; ; CLRPAG - Clear the active display window. ; ; This routine is used to clear all lines within the current display ; window after the record position has been changed. Since the record ; position has changed, we start displaying the next record at the top ; of the display window. ; ; Implicit inputs: ; If a partial page backup is being done (B.BACK in STATUS), then ; the display window is not cleared. ; ; Outputs: ; All registers are preserved. ; ;- CLRPAG::BIT #B.BACK,STATUS ; Are we backing up a partial page ? BNE 10$ ; If NE, yes (don't clear the page). CALL CLRWIN ; Clear the entire display window. 10$: RETURN .SBTTL DONEXT - Do the next page processing. ;+ ; ; DONEXT - Do the next page processing. ; ; This routine is used to prepare for the next display page. If at end of ; file and force exit is disabled, we simply return. Otherwise, we position ; to the next record to be displayed based upon the current direction. ; ; Inputs: ; None. ; ; Outputs: ; Register 1 is destroyed. ; ;- DONEXT::MOV IENTRY,R2 ; Copy the file entry address. ;(01) BIT #S.EOF,(R2) ; Are we at the end of file ? ;(01) BEQ 10$ ; If EQ, no (normal processing). ;(01) BIT #B.FE,SWMASK ; Did the user specify force exit ? ;(01) BEQ 10$ ; If EQ, no (check for backwards). ;(01) BIC #S.FORW,(R2) ; Yes, force into listing backwards. 10$: MOV O.RCNT(R2),R1 ; Copy the last page record count. ; When listing backwards, we must backup records. BIT #S.FORW,(R2) ; Are we listing forward ? BNE 30$ ; If NE, yes (normal mode). JMP MINUS ; Process like -n records. ; Prepare to display the next page. 30$: BIT #S.EOF,(R2) ; Are we at the end of file ? BNE 100$ ; If NE, yes (no next page). CALL NXTPAG ; Do the next page processing. 100$: RETURN .SBTTL BACKUP - Calculate the record for backing up. ;+ ; ; BACKUP - Calculate the record for backing up. ; ; This routine calculates the record number to backup to from the current ; record number. ; ; Inputs: ; R2 = The active file entry address. ; R1 = The number of lines to backup. ; ; Outputs: ; All registers are preserved. ; ;- BACKUP::MOV O.CREC(R2),WTGREC ; Copy the current record MOV O.CREC+2(R2),WTGREC+2 ; to the WTG record number. TST WTGREC ; Will we underflow ? BNE 10$ ; If NE, no (continue ...) CMP R1,WTGREC+2 ; Are we going back too far ? BLO 10$ ; If LOS, no. MOV WTGREC+2,R1 ; Yes, go to the top of file. BIC #B.BACK,STATUS ; Reset the partial backup flag. ; to force redisplay of page. 10$: SUB R1,WTGREC+2 ; Calculate the record SBC WTGREC ; number to position to. 20$: CALL DOPOS ; Now do the record positioning. ; When backing up a partial page, scroll the screen down. BIT #B.BACK,STATUS ; Are we backing up a partial page ? BEQ 100$ ; If EQ, no (we're all done). MOV BCKCNT,R1 ; Yes, copy the # of lines to scroll. CALL SCRDWN ; Now, scroll the screen down. 100$: RETURN .SBTTL CHKTB - Check for top or bottom of file. ;+ ; ; CHKTB - Check for both top and bottom of file. ; CHKBOT - Check for advance past bottom of file. ; CHKTOP - Check for backup past top of file. ; ; This routine checks for the top of file if backing up through the file, ; or checks for end of file if advancing through the file. If we're ; advancing/backing up past the bottom/top of file a message is displayed. ; ; Inputs: ; R2 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; ;- .ENABL LSB ; This routine added for edit # (01) CHKTB:: BIT #S.FORW,(R2) ; Listing in forward direction ? BNE CHKBOT ; If NE, yes (check for bottom). ; Check for backup past top of file. CHKTOP::JSR R2,$SAVVR ; Save R0 - R2. TST O.TOPR(R2) ; Possibly at top of file ? BNE 100$ ; If NE, no. CMP O.TOPR+2(R2),#1 ; Really at top of file ? BNE 100$ ; If NE, no (return success). ERRMSG BTOPM, BR 90$ ; Use the error return ... ; Check for advance past bottom of file. CHKBOT::JSR R2,$SAVVR ; Save R0 - R2. BIT #S.EOF,(R2) ; Are we currently at end of file ? BEQ 100$ ; If EQ, no (return success). BIT #B.FE,SWMASK ; Did the user specify force exit ? BEQ 95$ ; If EQ, no (don't display message). ERRMSG ABOTM, 90$: BIS #B.DOPR,STATUS ; Set to reprompt the user. 95$: SEC ; Show we had a error. RETURN 100$: CLC ; Show success. RETURN .DSABL LSB .END