.TITLE CATUTL - Catchall Utility Routines .IDENT /1.2/ .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: CATUTL.MAC ; Author: Robin Miller ; Date: September 22, 1982 ; ; Description: ; ; Catchall utility routines. ; ; Modification History: ; ; October 11, 1985 by Robin Miller. Version 1.2 ; Add routine GETUAB to check for a logged on user. ; ; January 14, 1985 by Robin Miller. Version 1.1 ; Add routine ASSLUN to assign LUN to a specific terminal. ; ;- .NLIST BEX .MCALL ALUN$S, CMKT$S, DIR$, MRKT$S, QIOW$, QIOW$S, QIO$S .MCALL WTLO$S, WTSE$S .MCALL GIN$, ACNDF$ ACNDF$ ; Define account block definitions. ; Local equates: SECNDS = 2 ; Time unit for seconds. ; Local data: GETTAH: QIOW$ SF.GMC,TOLUN,TOEFN,,IOSB,, ; Get typehead. TAHBUF: .BYTE TC.TBF,1 ; Store typeahead buffer count here. TAHSIZ = .-TAHBUF G.TNAM = 10 ; The terminal name. G.TNUM = 12 ; The terminal number. GINUAB: GIN$ GI.UAB,UABBUF,B.ULEN/2,, UABBUF::.BLKB B.ULEN ; Store accounting block here. UABFLG::.BYTE 0 ; Have accounting block flag. .EVEN .SBTTL ASSLUN - Assign LUN to Specified Terminal. ;+ ; ; ASSLUN - Assign LUN to specified terminal. ; ; Inputs: ; R0 = The input buffer address. ; ; Outputs: ; C bit clear/set = success/failure. ; ; R0 = The updated buffer address. ; ;- TTYNAM: .WORD 0 ; Store the terminal name here. ASSLUN::JSR R5,.SAVR1 ; Save R1 - R5. TSTB STATUS ; Did we get a terminal ? BPL 90$ ; If PL, no (return error). CALL SKIP ; Skip any leading spaces MOVB (R0)+,TTYNAM ; Save the first character BEQ 90$ ; If EQ, end of line (error). MOVB (R0)+,TTYNAM+1 ; Save the second character BEQ 90$ ; If EQ, end of line (error). CLR R1 ; Initialize the unit number. CALL $COTB ; Convert octal ASCII to binary. CMPB R2,#': ; Expected terminator found ? BNE 90$ ; If NE, no (syntax error). ; Assign a LUN to the specified terminal. ALUN$S #TOLUN,TTYNAM,R1 ; Finally assign the LUN CALL CHKDIR ; Check/report directive error. BCC 100$ ; If CC, success. 90$: SEC ; Show failure ... 100$: RETURN .SBTTL ATTERM - Attach The Terminal. ;+ ; ; ATTERM - Attach the terminal. ; ; This routine attempts to attach the terminal assigned to LUN ; TOLUN. This is done to prevent catchall from hanging during certain ; commands such as HANGUP. ; ; Inputs: ; None ; ; Outputs: ; C bit clear/set = success/failure. ; ;- ATTERM::JSR R2,$SAVVR ; Save R0 - R2. MOV #1,R2 ; Non-zero to report errors. BR DOATT ; Now do the attach. ATTALT::JSR R2,$SAVVR ; Save R0 - R2. CLR R2 ; Zero to suppress errors. DOATT: QIO$S #IO.ATT,#TOLUN,#TOEFN,,#IOSB,, ; Try to attach the terminal. CALL CHKDIR ; Check/report directive error. BCS 100$ ; If CS, we had an error. MRKT$S #MRKEFN,#10.,#1 ; Wait for 10 ticks to complete. CALL CHKDIR ; Check/report directive error. BCS 10$ ; If CS, failure (kill I/O). WTLO$S 0,#WTMASK ; Wait for mark time or attach. MOVB IOSB,R0 ; Copy the I/O status return. BNE 5$ ; If NE, there is a status. MOVB #IE.DUN,R0 ; Else, set "Device not attachable". 5$: CMPB R0,#IS.SUC ; Was the attach successful ? BEQ 20$ ; If EQ, yes. TST R2 ; Should we report the error ? BEQ 10$ ; If EQ, no (just the status). BIC #^C377,R0 ; Clear possible sign extend. CALL WRTERR ; Report the error message. 10$: QIOW$S #IO.KIL,#TOLUN,#TOEFN,,#IOSB,, ; No, kill the attach QIO. BR 90$ ; And return failure ... 20$: CMKT$S #MRKEFN ; Cancel the mark timer. BCC 100$ ; If CC, success. 90$: SEC ; Show failure ... 100$: RETURN .SBTTL CUPPER - Convert Characters To Uppercase. ;+ ; ; CUPPER - Convert characters to uppercase. ; ; This routine is used to convert a string to uppercase. Text ; contained within double quotes ("text") is not converted. ; ; Inputs: ; R0 = Address of string to convert (termminated by NULL). ; ; Outputs: ; R0 = The updated buffer address. ; ; All other registers are preserved. ; ;- CUPPER::JSR R5,.SAVR1 ; Save R0 - R5. CLR R1 ; Double quote detected flag. 10$: TSTB (R0) ; End of ASCII string ? BEQ 100$ ; If EQ, yes. CMPB (R0),#"" ; Is this a double quote ? BNE 20$ ; If NE, no. COM R1 ; Toggle the double quote flag. 20$: TST R1 ; Is text within double quote ? BNE 30$ ; If NE, yes (don't convert). CMPB (R0),#'a ; Possible lowercase ? BLO 30$ ; If LO, no. CMPB (R0),#'z ; Really lowercase ? BHI 30$ ; If HI, no. BICB #40,(R0) ; Convert it to uppercase. 30$: INC R0 ; Adjust the buffer pointer. BR 10$ ; And check for another ... 100$: RETURN .SBTTL DELAY - Wait Specified Number of Seconds. ;+ ; ; DELAY - Wait specified number of seconds. ; ; Inputs: ; R1 = The number of seconds to delay. ; ; Outputs: ; Carry clear/set = success/failure. ; ; All registers are preserved. ; ;- DELAY:: MRKT$S #MRKEFN,R1,#SECNDS ; ISSUE THE MARK TIME CALL CHKDIR ; Check fir directive status. BCS 100$ ; If CS, the directive failed. WTSE$S #MRKEFN ; ELSE WAIT FOR MARKTIME 100$: RETURN .SBTTL FNDSUB - Find A Specified Substring. ;+ ; ; FNDSUB - Find a specified substring. ; ; This routine searchs a buffer for a specified substring. ; ; Inputs: ; R0 = The search buffer address (terminated by NULL). ; R1 = The substring to search for (terminated by NULL). ; ; Outputs: ; C bit clear/set = string found/not found. ; ;- FNDSUB::JSR R2,$SAVVR ; Save R0 - R2. MOV R1,R2 ; Save the substring buffer address. ; Search for the specified pattern. 10$: TSTB (R1) ; At end of the search string ? BEQ 100$ ; If EQ, yes (string was found). TSTB (R0) ; At end of search buffer ? BEQ 90$ ; If EQ, yes (string not found). CMPB (R0)+,(R1)+ ; Does this character match ? BEQ 10$ ; If EQ, yes (check the next byte). MOV R2,R1 ; No, restore the starting address. CMPB -1(R0),(R1)+ ; Start of the substring match ? BEQ 10$ ; If EQ, yes (start at 2nd byte). DEC R1 ; No, start at the first character. BR 10$ ; And start the search again ... 90$: SEC ; Show string was not found. 100$: RETURN .SBTTL GETLEN - Get the length of a string. ;+ ; ; GETLEN - Get the length of a string. ; ; This routine is used to calculate the length of a string which is ; terminated by a NULL byte. ; ; Inputs: ; R0 = The string address (terminated by NULL). ; ; Outputs: ; R0 = The string address. ; R1 = The string length. ; ; All other registers are preserved. ; ;- GETLEN::MOV R0,R1 ; Copy the string address. 10$: TSTB (R1)+ ; Is this the NULL byte ? BNE 10$ ; If NE, no (loop). DEC R1 ; Adjust for the NULL byte. SUB R0,R1 ; Now calculate the length. RETURN .SBTTL GETUAB - Get User Account Block ;+ ; ; GETUAB - Get the user's accounting block. ; ; Inputs: ; R1 = The terminal name. ; R2 = The terminal number. ; ; Outputs: ; C bit clear/set = success/failure. ; ;- GETUAB::CALL $SAVAL ; Save all registers. MOV R1,GINUAB+G.TNAM ; Save the terminal name. MOV R2,GINUAB+G.TNUM ; Save the terminal number. DIR$ #GINUAB ; Get the user account block. ; ; The error is not checked since a terminal not logged in ; returns a "invalid device and/or unit number" error. ; ; CALL CHKDIR ; Check/report directive errors. RETURN .SBTTL GTYPAH - Get the typeahead buffer count. ;+ ; ; GTYPAH - Get the typeahead buffer count. ; ; Inputs: ; None. ; ; Outputs: ; R1 = The typeahead buffer count. ; ;- GTYPAH::CLR R1 ; Presume no typeahead count. DIR$ #GETTAH ; Get the typeahead buffer count. CALL CHKERR ; Check/report any errors. BCS 10$ ; If CS, we had an error. MOVB TAHBUF+1,R1 ; Else, copy the typeahead count. BIC #^C377,R1 ; Clear possible sign extend. 10$: RETURN .SBTTL MOVE -- Move An ASCIZ String ;+ ; ; MOVE - Move an ASCIZ string to Spawn buffer (SPNBUF). ; MOVEC - Alternate entry (R1 contains output address). ; ; INPUTS: ; R0 = Address of ASCIZ string to move. ; R1 = Address of output buffer. ; ; OUTPUTS: ; R1 = Updated (ready for next character). ;- MOVE:: MOV #SPNBUF,R1 ; SET UP OUTPUT BUFFER MOVEC:: MOVB (R0)+,(R1)+ ; START COPY BNE MOVEC ; IF NE, MORE TO GO DEC R1 ; POINT TO NULL RETURN .SBTTL SKIP - Skip Any Leading Spaces ;+ ; ; SKIP - Skip any leading spaces. ; ; This routine skips leading spaces before a string. ; ; Inputs: ; R0 = The string address (terminated by NULL). ; ; Outputs: ; R0 = The updated string address. ; ;- SKIP:: TSTB (R0) ; End of the command line ? BEQ 100$ ; If EQ, yes. CMPB (R0)+,#SPACE ; Is this a space byte ? BEQ SKIP ; If EQ, yes (check next). DEC R0 ; Nope, point to previous byte. 100$: RETURN .SBTTL WRITE -- Write A Message To The Terminal ;+ ; ; WRITE - Write a message to the terminal. ; ; This routine is used to write a message to the terminal. ; ; Inputs: ; R0 = address of message to write. ; R1 = the message byte count. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- VFC:: .WORD SPACE ; VERTICAL FORMAT CHARACTER WRITE:: QIOW$S #IO.WAL,#TILUN,#TIEFN,,#IOSB,, CALL CHKERR ; Check/report any errors. MOV #SPACE,VFC ; Reset to single spacing. RETURN .END