.TITLE CHKCMD - CHECK AND PROCESS VALID LIST COMMAND .IDENT /01/ .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: CHKCMD ; Author: Robin Miller ; Date: October 27, 1981 ; ; Description: ; ; This module is used to check the valid LIST command. 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. ; ; ; Modification History: ; ;- .ENABL AMA .MCALL DIR$, QIOW$S ; ; Local equates. ; BELL = 7 ; ASCII FOR BELL HT = 11 ; ASCII FOR HORIZONTAL TAB LF = 12 ; ASCII FOR LINE FEED CR = 15 ; ASCII FOR CARRIAGE RETURN SPACE = 40 ; ASCII FOR SPACE DEFCNT = 8. ; DEFAULT COUNT FOR LEFT/RIGHT TXTBIT = 1 ; INCLUDE TEXT OF MESSAGE MIDBIT = 2 ; INCLUDE MESSAGE ID SEVBIT = 4 ; INCLUDE SEVERITY LEVEL FACBIT = 10 ; INCLUDE FACILITY NAME ; ; Local storage. ; NEGFLG: .BYTE 0 ; NEGATION FLAG RULFLG: .BYTE 0 ; RULER ON SCREEN FLAG RULADR: .WORD 0 ; LAST RULER DISPLAYED TEMP: .BLKB 10. ; TEMPORARY BUFFER SPACE ; Argument block for error messages. ERRBLK: .BYTE 5,0 ; ARG BLOCK FOR GETMSG .WORD ERRCOD ; ADDRESS OF ERROR CODE .WORD TYOBUF ; ADDRESS OF OUTPUT BUFFER .WORD MSGFLG ; ADDRESS OF FLAG WORD .WORD -1 ; NO FACILITY NAME WANTED .WORD STACOD ; ADDRESS FOR STATUS RETURN ERRCOD: .WORD 0 ; ERROR MESSAGE CODE MSGFLG: .WORD TXTBIT ; TEXT OF MESSAGE ONLY STACOD: .WORD 0 ; STATUS CODE RETURN .EVEN ; ; Local messages. ; .NLIST BEX DELMSG: .ASCIZ %Really DELETE this file ? % HLPMSG: .BYTE ,,, .ASCII %The following commands may be used in LIST:% .BYTE ,,, .ASCII % B(ottom) - Positions at bottom of file.% .ASCII % D(elete) - Deletes the current file.% .ASCII % E(xit) - Exits from listing.% .ASCII % H(elp) or ? - Displays this help frame.% .ASCII % L(eft) - Moves window left 'n' positions.% .ASCII % N(ext) - Starts listing of the next file.% .ASCII % NA(rrow) - Lists file on narrow screen.% .ASCII % R(ight) - Moves window right 'n' positions.% .ASCII % RU(ler) - Displays ruler on top of screen.% .ASCII % S(eeall) - Displays non-printable characters.% .ASCII % T(op) - Positions at top of file.% .ASCII % W(ide) - Lists file on wide screen.% .ASCII % record n - Starts listing at record # 'n'.% .ASCII % .+n - Starts listing 'n' records forward.% .ASCII % .-n - Starts listing 'n' records back.% .BYTE , .ASCIZ %Press the RETURN key to continue: % ; Two different rulers for ruler command. RULTWO: .ASCII %1 5 10 15 20 25 30 35 40 45 5% .ASCII %0 55 60 65 70 75 80 85 90 95 1% .ASCII %00 105 110 115 120 125 130 135 140 145 1% .ASCII %50 155 160 165 170 175 180 185 190 195 2% .ASCII %00 205 210 215 220 225 230 235 240 245 2% .ASCIZ %50 255 260 265 270 275 280 285 290 295 300% RULONE: .ASCII %123456789 123456789 123456789 123456789 123456789 % .ASCII %123456789 123456789 123456789 123456789 123456789 % .ASCII %123456789 123456789 123456789 123456789 123456789 % .ASCII %123456789 123456789 123456789 123456789 123456789 % .ASCII %123456789 123456789 123456789 123456789 123456789 % .ASCIZ %123456789 123456789 123456789 123456789 123456789 % .EVEN ;+ ; ; CHKCMD - Check for a valid list control command. ; ; This routine is called to check for various list control commands. ; ; Inputs: ; R0 = Command buffer. ; R1 = The byte count. ; ;- CHKCMD:: CALL $SAVAL ; SAVE R0 - R5 MOV R0,R2 ; COPY THE BUFFER ADDR MOV R1,R3 ; AND THE BYTE COUNT BNE 10$ ; IF NE, GOT ONE JMP RET ; ELSE RETURN ... 10$: CALL CUPPER ; CONVERT TO UPPER CASE TSTB (R2)+ ; POINT TO NEXT BYTE SOB R3,10$ ; DO ENTIRE STRING CLRB (R2) ; SET TERMINATOR ; Check for negate flag. CLRB NEGFLG ; PRESUME NO NEGATE CMPB (R0),#'- ; NEGATE WANTED ? BNE SLASH ; IF NE, NO INC R0 ; PRESUME COMMAND NEXT INCB NEGFLG ; SHOW NEGATION ; If slash specified for switch, skip it so command still works. SLASH: CMPB (R0),#'/ ; SLASH FOR SWITCH ? BNE BOTTOM ; IF NE, NO INC R0 ; POINT PAST SLASH ; B(ottom) command. Position at bottom of file. BOTTOM: CMPB (R0),#'B ; BOTTOM COMMAND ? BNE DELETE ; IF NE, NO MOV #-1,WTGREC ; SET HIGHEST MOV #-1,WTGREC+2 ; RECORD NUMBER JMP DOIT ; AND POINT TO IT ; D(elete) command. Delete the current file. DELETE: CMPB (R0),#'D ; DELETE COMMAND ? BNE EXIT ; IF EQ, NO CALL WRTMSG ; PREPARE FOR MESSAGE MOV #DELMSG,R4 ; SET MESSAGE ADDRESS CALL WRITE ; AND WRITE IT CALL REMATR ; REMOVE ATTRIBUTES CALL GETRES ; GET RESPONSE CALL CUPPER ; CONVERT TO UPPERCASE CMPB (R2),#'Y ; REALLY DELETE FILE ? BNE 50$ ; IF NE, NO MOV #FDB,R0 ; SET FDB ADDRESS CALL .DLFNB ; DELETE THE FILE BCS 10$ ; IF CS, FAILED BIS #B.KILL!B.NEXT,STATUS ; SHOW FILE DELETED RETURN ; AND RETURN ... 10$: CALL WRTMSG ; PREPARE FOR MESSAGE CALL REMATR ; REMOVE VT100 ATTRIBUTES CALL ADDBLI ; ADD BOLD/BLINK TO VT100 MOV FDB+F.ERR,ERRCOD ; COPY THE ERROR CODE MOV #ERRBLK,R5 ; SET ERROR ARGUMENT BLOCK CALL GETMSG ; AND GET THE ERROR MESSAGE MOV #TYOBUF,R4 ; SET BUFFER ADDRESS MOV R4,R3 ; COPY THE BUFFER ADDRESS ADD STACOD,R3 ; POINT TO END OF MESSAGE MOVB #BELL,(R3)+ ; RING BELL ON ERROR CLRB (R3) ; SET TERMINATOR CALL WRITE ; WRITE IT TO TERMINAL CALL REMATR ; REMOVE ATTRIBUTES CALL GETRES ; WAIT FOR RESPONSE BIS #B.NEXT,STATUS ; GO ON TO NEXT FILE RETURN ; AND RETURN ... 50$: INCB RAGAIN ; READ AGAIN THEN RETURN ; E(xit) command. Exit from LISTing. EXIT: CMPB (R0),#'E ; EXIT COMMAND ? BNE FIND ; IF NE, NO BIS #B.EXIT,STATUS ; SHOW TIME TO EXIT RETURN ; F(ind) command. Find specified search string. FIND: BR HELP ; H(elp) command. Display the Help frame. HELP: CMPB (R0),#'? ; HELP REQUESTED ? BEQ 10$ ; IF EQ, YES CMPB (R0),#'H ; HELP REQUESTED ? BNE LEFT ; IF NE, NO 10$: CALL CLRSCR ; CLEAR THE SCREEN CALL SETNAR ; RESET VT100 TO NARROW MOV #HLPMSG,R4 ; SET HELP MESSAGE CALL WRITE ; AND DO IT CALL GETRES ; GET RESPONSE 20$: CALL WRTHDR ; WRITE FILE HEADER CALL CHKRUL ; CHECK THE RULER CALL PNTDOT ; SET TO REDISPLAY PAGE 30$: RETURN ; L(eft) command. Move the margin left. LEFT: CMPB (R0),#'L ; LEFT MARGIN COMMAND ? BNE NEXT ; IF NE, NO CALL SKIP ; SKIP PAST COMMAND BCS 20$ ; IF CS, END OF LINE CALL CONVRT ; CONVERT TO DECIMAL BCS 40$ ; IS CS, BAD NUMBER TST R1 ; SPECIFY ZERO ? BNE 30$ ; IF NE, NO 10$: CLR MARGIN ; SET FOR NO MARGIN BR 40$ ; AND CONTINUE ... 20$: MOV #DEFCNT,R1 ; SETUP DEFAULT COUNT 30$: SUB R1,MARGIN ; MOVE MARGIN LEFT BLT 10$ ; IF LT, TOO FAR 40$: CALL PNTDOT ; SET TO REDISPLAY PAGE CALL CHKRUL ; CHECK FOR RULER JMP CLEAR ; GO CLEAR THE PAGE ; N(ext) command. Display the next file. NEXT: CMPB (R0),#'N ; NEXT FILE COMMAND ? BNE PAGE ; IF NE, NO CMPB 1(R0),#'A ; NARROW COMMAND ? BEQ NARROW ; IF EQ, YES BIS #B.NEXT,STATUS ; SHOW DO NEXT FILE RETURN ; NA(rrow) command. List file in narrow format. NARROW: TSTB NEGFLG ; NEGATION SPECIFIED ? BEQ NAROW1 ; IF EQ, NO JMP WIDE1 ; -NA MEANS WIDE NAROW1: BIC #WISW,SWMASK ; CLEAR THE WIDE SWITCH BIS #NASW,SWMASK ; SET THE NARROW SWITCH CALL SETNAR ; SET TERMINAL NARROW CALL SETUP ; DO SETUP (WRITES FILENAME) CALL CHKRUL ; CHECK THE RULER CALL PNTDOT ; SET TO REDISPLAY PAGE RETURN ; P(age) command. Start displaying at next formfeed. PAGE: BR RIGHT ; R(ight) command. Move the margin right. RIGHT: CMPB (R0),#'R ; MARGIN RIGHT COMMAND ? BNE SEEALL ; IF NE, NO CMPB 1(R0),#'U ; DISPLAY RULER COMMAND ? BNE 5$ ; IF NE, NO (RIGHT) CALL RULER ; WRITE THE RULER RETURN ; AND RETURN 5$: CALL SKIP ; SKIP PAST COMMAND BCC 10$ ; IF CS, END OF LINE MOV #DEFCNT,R1 ; SETUP DEFAULT COUNT BR 20$ ; AND CONTINUE ... 10$: CALL CONVRT ; CONVERT TO DECIMAL BCS 30$ ; IS CS, BAD NUMBER 20$: BIC #177000,R1 ; NOT TOO BIG NOW ... ADD R1,MARGIN ; INDENT THE MARGIN 30$: CALL PNTDOT ; SET TO REDISPLAY PAGE CALL CHKRUL ; CHECK FOR RULER JMP CLEAR ; GO CLEAR THE PAGE ; RU(ler) command. Display a ruler on top of the screen. RULER: CALL SETTOP ; POSITION TO TOP OF SCREEN TSTB NEGFLG ; NEGATION SPECIFIED ? BEQ 2$ ; IF EQ, NO CLRB RULFLG ; SHOW RULER REMOVED BR 50$ ; AND CONTINUE ... 2$: MOV #TYOBUF,R4 ; TERMINAL OUTPUT BUFFER CMPB (R0),#'R ; WAS THIS A RULER COMMAND ? BEQ 3$ ; IF EQ, YES MOV RULADR,R5 ; USE PREVIOUS RULER BR 5$ ; AND CONTINUE ... 3$: MOVB #1,RULFLG ; SHOW RULER ON SCREEN MOV #RULONE,R5 ; SET DEFAULT RULER CALL SKIP ; SKIP PAST COMMAND CALL CONVRT ; CONVERT NUMBER BCS 5$ ; IS CS, USE DEFAULT TST R1 ; SPECIFY ZERO ? BNE 4$ ; IF NE, NO BISB #377,RULFLG ; SET FLAG NEGATIVE MOV RULADR,R5 ; USE CURRENT RULER BNE 4$ ; IF NE, THERE WAS ONE MOV #RULONE,R5 ; OTHERWISE, USE DEFAULT BR 5$ ; AND CONTINUE ... 4$: CMP R1,#2 ; WANT RULER 2 ? BNE 5$ ; IF NE, NO MOV #RULTWO,R5 ; SET TO RULER 2 5$: MOV R5,RULADR ; SAVE RULER ADDRESS TSTB RULFLG ; DISABLE INDENT ? BMI 20$ ; IF MI, YES MOV MARGIN,R2 ; GET MARGIN COUNT BEQ 20$ ; IF EQ, NONE 10$: TSTB (R5)+ ; ADJUST THE RULER SOB R2,10$ ; LOOP TILL DONE 20$: MOV LINWID,R2 ; SIZE OF RULER 30$: MOVB (R5)+,(R4)+ ; MOVE IN THE RULER BEQ 40$ ; IF EQ, TOO MANY SOB R2,30$ ; LOOP TILL DONE 40$: MOVB #CR,(R4)+ ; GET TO LEFT MARGIN CLRB (R4) ; SHOW END OF MESSAGE CALL ADDREV ; ADD REVERSE VIDEO MOV #TYOBUF,R4 ; SET THE BUFFER ADDR CALL WRITE ; AND GO DO IT CALL REMATR ; REMOVE ATTRIBUTES CMPB #O.TEK,TERM ; IS THIS A TEKTRONIX ? BNE 50$ ; IF NE, NO CALL PNTDOT ; YES, REDISPLAY PAGE BR 60$ ; AND CONTINUE ... 50$: INCB RAGAIN ; DO READ AGAIN 60$: RETURN ; S(eeall) command. Enable see-all mode. SEEALL: CMPB (R0),#'S ; ENABLE SEE-ALL MODE ? BNE TOP ; IF NE, NO TSTB NEGFLG ; NEGATION SPEICIFIED ? BEQ 10$ ; IF EQ, NO BIC #SESW,SWMASK ; CLEAR SEE-ALL MODE BR 20$ ; AND CONTINUE ... 10$: BIS #SESW,SWMASK ; SET SET-ALL BIT 20$: CALL PNTDOT ; SET TO REDISPLAY PAGE JMP CLEAR ; GO CLEAR PAGE ; T(op) command. Postion at top of file. TOP: CMPB (R0),#'T ; TOP OF FILE COMMAND ? BNE WIDE ; IF NE, NO CLR WTGREC ; SET TO GO CLR WTGREC+2 ; TO RECORD 1. BR DOIT ; AND DO IT ; W(ide) command. Set terminal to wide mode. WIDE: CMPB (R0),#'W ; WIDE COMMAND ? BNE DOT ; IF NE, NO TSTB NEGFLG ; NEGATION SPECIFIED ? BEQ WIDE1 ; IF EQ, NO JMP NAROW1 ; -WI MEANS NARROW WIDE1: BIC #NASW,SWMASK ; CLEAR NARROW SWITCH BIS #WISW,SWMASK ; SET WIDE SWITCH CALL SETUP ; DO SETUP (WRITES FILENAME) CALL CHKRUL ; CHECK THE RULER CALL PNTDOT ; SET TO REDISPLAY PAGE RETURN ; . (dot) command. Starts listing + or - records from current record. DOT: CMPB (R0),#'. ; DOT COMMAND ? BNE NUMBER ; IF NE, NO MOV CURREC,WTGREC ; COPY CURRENT RECORD MOV CURREC+2,WTGREC+2 ; TO WTG RECORD # ; Dot (.) plus negative number. CMPB 1(R0),#'- ; IS IT MINUS SIGN ? BNE 50$ ; IF NE, NO (PRESUME +) CALL SKIP ; SKIP TO NUMBER (OVER -) CALL CONVRT ; CONVERT THE NUMBER BCC 5$ ; IF CC, OK MOV #1,R1 ; DEFAULT TO 1 5$: CMP R1,LINCNT ; BACK MORE THAN PAGE ? BGT 10$ ; IF GT, YES DEC R1 ; BIASED IN DOIT BY -1 ADD MAXLIN,R1 ; DISPLAY -n LINES 10$: TST WTGREC ; WILL WE UNDERFLOW ? BNE 15$ ; IF NE, NO CMP R1,WTGREC+2 ; GOING BACK TOO FAR ? BLOS 15$ ; IF LOS, NO MOV WTGREC+2,R1 ; TO TOP OF FILE THEN 15$: SUB R1,WTGREC+2 ; SUBTRACT FROM CURRENT SBC WTGREC ; AND CARRY 20$: JMP DOIT ; POSITION TO IT ; dot (.) plus positive number. 50$: CALL SKIP ; SKIP TO NUMBER (OVER +) CALL CONVRT ; CONVERT THE NUMBER BCC 55$ ; IF CC, OK MOV #1,R1 ; DEFAULT TO 1 55$: CMP R1,LINCNT ; LINCNT SHOULD = MAXLIN BGT 80$ ; IF GT, NO CMPB #T.V100,TTYPE ; IS THIS A VT100 ? BNE 60$ ; IF NE, NO SUB R1,LINCNT ; VT100 WILL SCROLL UP INCB CLRCNT ; DON'T CLEAR COUNT JMP RET ; PROCESS LIKE NEXT PAGE 60$: SUB LINCNT,WTGREC+2 ; ADJUST WHERE TO GO SBC WTGREC ; AND THE CARRY INC R1 ; BIASED IN DOIT BY -1 80$: ADD R1,WTGREC+2 ; ADD TO CURRENT RECORD ADC WTGREC ; AND THE CARRY JMP DOIT ; POSITION TO IT ; Numeric input. Position at specified record number. NUMBER: CMPB (R0),#'0 ; POSSIBLE NUMBER ? BLT RET ; IF LT, NO CMPB (R0),#'9 ; REALLY A NUMBER ? BGT RET ; IF GT, NO MOV #WTGREC,R3 ; SETUP OUTPUT ADDRESS MOV TIOSB+2,R4 ; SETUP THE BYTE COUNT MOV #INCMD,R5 ; ADDR OF STRING TO CONVERT CALL .DD2CT ; CONVERT IT TO BINARY BCS RET ; IF CS, BAD NUMBER DOIT: TST WTGREC ; GOT A VALID RECORD # ? BNE 10$ ; IF NE, YES TST WTGREC+2 ; REALLY VALID ? BEQ 20$ ; IF EQ, MUST BE '0' 10$: SUB #1,WTGREC+2 ; BY -1 TO GET ACTUAL RECORD SBC WTGREC ; SUBTRACT OUT BORROW (IF ANY) 20$: CALL POINTR ; AND POINT TO THE RECORD CMPB FDB+F.ERR,#IE.EOF ; END OF FILE DETECTED ? BNE CLEAR ; IF NE, NO TST CURREC ; LARGER THAN MAX LINES ? BNE 30$ ; IF NE, YES CMP CURREC+2,MAXLIN ; LESS THAN MAX LINES ? BLOS CLEAR ; IF LOS, YES (DON'T POINT) 30$: MOV CURREC,WTGREC ; COPY LAST RECORD # MOV CURREC+2,WTGREC+2 ; AND THE SECOND WORD MOV MAXLIN,R0 ; COPY MAX # OF LINES DEC R0 ; BY -1 TO GET TO EOF SUB R0,WTGREC+2 ; SET TO DISPLAY FULL PAGE SBC WTGREC ; SUBTRACT CARRY (IF ANY) CALL POINTR ; GO POINT TO IT CLEAR: CALL CLRPAG ; CLEAR THE CURRENT PAGE RETURN RET: CMPB FDB+F.ERR,#IE.EOF ; ARE WE AT END OF FILE ? BEQ 10$ ; IF EQ, YES CALL NXTPAG ; DO NEXT PAGE PROCESSING 10$: RETURN CHKRUL: TSTB RULFLG ; RULER ON THE SCREEN ? BEQ 10$ ; IF EQ, NO CALL RULER ; YES, WRITE NEW ONE CLRB RAGAIN ; DON'T DO READ AGAIN 10$: RETURN .SBTTL CUPPER - CONVERT CHARACTER TO UPPER CASE ;+ ; ; CUPPER - Convert character to upper case. ; ; Inputs: ; (R2) = Character to convert. ; ;- CUPPER:: CMPB (R2),#'a ; POSSIBLE LOWERCASE ? BLO 10$ ; IF LO, NO CMPB (R2),#'z ; REALLY LOWERCASE ? BHI 10$ ; IF HI, NO BICB #40,(R2) ; CONVERT TO UPPERCASE 10$: RETURN .SBTTL CONVRT - CONVERT ASCII DECIMAL TO BINARY ;+ ; ; CONVRT - Convert ASCII decimal number to binary. ; ; Inputs: ; R0 = Address of first byte to be converted. ; ; Outputs: ; R0 = Address of next byte in the buffer. ; R1 = The converted number. ; R2 = The terminating character. ; ;- CONVRT: TSTB (R0) ; AT END OF LINE ? BEQ 10$ ; IF EQ, YES CALL $CDTB ; CONVERT DECIMAL TO BINARY TST R1 ; NEGATIVE NUMBER ? BMI 10$ ; IF MI, YES CLC ; SHOW GOOD NUMBER BR 20$ ; AND RETURN ... 10$: SEC ; SHOW BAD NUMBER 20$: RETURN .SBTTL SKIP - SKIP PAST COMMAND ;+ ; ; SKIP - Skip past the command and any tabs/spaces. ; ; Inputs: ; R0 = Buffer address (pointing to 1st byte of command). ; ; Outputs: ; R0 = Points to number, next keyword of command ; or end of line (NULL). ; C set if end of line encountered, else clear. ; ;- SKIP: ; Skip past rest of command (if any). 10$: INC R0 ; POINT TO NEXT BYTE TSTB (R0) ; END OF STRING ? BEQ 90$ ; IF EQ, YES CMPB (R0),#SPACE ; IS THIS A SPACE ? BEQ 30$ ; IF EQ, YES CMPB (R0),#HT ; HORIZONTAL TAB ? BEQ 30$ ; IF EQ, YES CMPB (R0),#'0 ; POSSIBLE NUMBER ? BLT 10$ ; IF LT, NO (SKIP) CMPB (R0),#'9 ; REALLY A NUMBER ? BGT 10$ ; IF GT, NO (SKIP) BR 40$ ; YES, RETURN ; Found space or tab, now skip all of those. 30$: INC R0 ; UPDATE POINTER TSTB (R0) ; END OF LINE ? BEQ 90$ ; IF EQ, YES CMPB (R0),#SPACE ; IS THIS A SPACE ? BEQ 30$ ; IF EQ, YES (SKIP) CMPB (R0),#HT ; HORIZONTAL TAB ? BEQ 30$ ; IF EQ, YES (SKIP) 40$: CLC ; SHOW SUCCESS BR 100$ ; AND RETURN... 90$: SEC ; END OF LINE SEEN 100$: RETURN .SBTTL GETRES - GET RESPONSE FROM THE USER ;+ ; ; GETRES - Gets a response from the user. ; ;- GETRES: QIOW$S #IO.RVB,#INLUN,#INEFN,,#TIOSB,,<#TEMP,#10.,#0> CMPB TIOSB,#IE.EOF ; CNTL/Z TYPED ? BNE 10$ ; IF NE, NO BIS #B.EXIT,STATUS ; SHOW TIME TO EXIT TST (SP)+ ; POP RETURN ADDRESS 10$: MOV #TEMP,R2 ; INPUT BUFFER RETURN .END