.TITLE VTLIO - VTL I/O Routines .IDENT /1.4/ .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: VTLIO.MAC ; Author: Robin Miller ; Date: June 30, 1983 ; ; Description: ; ; This module contains the routines for the terminal I/O. ; ; Modification History: ; ; June 14, 1984 by Robin Miller. Edit (02), Version 1.3 ; Added routine WABIT to wait for a little while after an invalid ; or partial escape sequence error is detected before clearing ; the typeahead buffer. This is needed for VT102 terminals. ; ; June 12, 1984 by Robin Miller. Version 1.2 ; Use read with termination table (IO.RTT) function to simulate ; the control keys used by EDT. Rewrote GETCMD routine for this. ; ; June 2, 1984 by Robin Miller. Edit (01), Version 1.1 ; Add GETM routine to get and mark the next record. ; ;- .ENABL AMA .NLIST BEX .MCALL DIR$, QIOW$S, GET$ ; Local messages: DELSEQ: .BYTE BS,SPACE,BS,0 ; Delete character from screen. ; ; The Read-with-termination table function (IO.RTT) allows control ; characters to terminate the read. ; TTABLE: .WORD -1 ; Terminate on all (00-15) .WORD -1 ; control characters (16-31) .WORD 0 ; (32-47) .WORD 0 ; (48-63) .WORD 0 ; (64-79) .WORD 0 ; (80-95) .WORD 0 ; (96-111) .WORD 100000 ; and the delete key. (112-127) .BLKW 8. ; Remaining table zero. BUFCNT: .WORD 0 ; Accumulated buffer byte count. BUFSAV: .WORD 0 ; Saved starting buffer address. BUFSIZ: .WORD 0 ; Original input buffer size. .SBTTL GETCMD - Get a command from the user. ;+ ; ; GETCMD - Gets a command from the user. ; ; This routine is used to read a command from the user. The string input ; is terminated by a null and if exact search string input is disabled, ; the string input is converted to upper case. If the first character ; input is a control character, then we call a routine to determine if the ; control key is defined. If not, the key acts as the terminator. If ; we're prompting for a search string, the control characters are inserted ; as part of the search string (except for ^C, ^U, and ^Z). ; ; Inputs: ; R0 = The buffer address. ; R1 = The buffer size. ; ; Outputs: ; C bit clear/set = success/failure (error or exit). ; ; R0 = The buffer address (string terminated by NULL). ; R1 = The input byte count. ; ; All other registers are preserved. ; ;- GETCMD::JSR R5,$SAVRG ; Save R3 - R5. MOV R0,BUFSAV ; Save starting buffer address. MOV R1,BUFSIZ ; Save the original buffer size. CLR BUFCNT ; Initialize the input count. 10$: TSTB VAXFLG ; Running on VAX/VMS ? BNE 12$ ; If NE, yes QIOW$S #IO.RLB,#TOLUN,#TOEFN,,#TIOSB,, BR 14$ ; Use common code ... 12$: QIOW$S #IO.RTT,#TOLUN,#TOEFN,,#TIOSB,, 14$: CALL CHKDIR ; Check/report directive errors. BCS 120$ ; If CS, we had an error. MOV BUFSAV,R0 ; Set the starting buffer address. ADD TIOSB+2,BUFCNT ; Accumulate the byte count. MOV BUFCNT,R1 ; Copy the current byte count. MOV TIOSB,R3 ; Copy the I/O status code. TSTB R3 ; Did we have any I/O errors ? BMI 100$ ; If MI, yes (process error). BIT #B.CTRC,STATUS ; Was CTRL/C typed during read ? BEQ 20$ ; If EQ, no. MOVB #CTRLU,TIOSB+1 ; Yes, treat like CTRL/U typed. ; ; On VAX/VMS, the escape sequence is NOT counted as part of the ; characters input, on RSX-11M they are. The returned byte count ; is adjusted to include the size of the escape sequence. ; 20$: MOV R0,R5 ; Copy the buffer address. MOV R1,R4 ; Copy the input byte count. CMP R3,#IS.ESQ ; Terminated by escape sequence ? BNE 40$ ; If NE, no (leave the count alone). TSTB VAXFLG ; Are we running on VAX/VMS ? BEQ 30$ ; If EQ, no (running on RSX-11M). ADD #3,R1 ; Include escape sequence in count. MOV R1,BUFCNT ; Adjust the saved byte count also. BR 60$ ; And continue ... 30$: SUB #3,R4 ; RSX-11M, point to the escape. BR 60$ ; And continue ... ; Check for the various control keys. 40$: CMP R1,BUFSIZ ; Terminated by buffer full ? BEQ 60$ ; If EQ, yes. MOVB TIOSB+1,R3 ; Copy the termination byte. CMPB #CTRLU,R3 ; Aborting the command line ? BEQ 120$ ; If EQ, yes. CMPB #DEL,R3 ; Are we deleting a character ? BNE 45$ ; If NE, no. CALL DELCHR ; Yes, delete character on screen. BR 55$ ; And continue ... 45$: BIT #B.SRCH,STATUS ; Prompting for a search string ? BNE 50$ ; If NE, yes (insert into string). CMPB #CR,R3 ; Carriage return the terminator ? BEQ 60$ ; If EQ, yes. CALL CTRKEY ; Check the control key. BCC 65$ ; If CC, the key is defined. 50$: CALL TYPCHR ; Display the control character. INC R1 ; Include control key in byte count. 55$: MOV R1,BUFCNT ; Set the new buffer byte count. ADD R1,R0 ; Set the next input buffer address. BR 10$ ; And get some more input. ; ; Terminate the input string with a NULL. If an escape sequence ; was entered, the ESCAPE character is overwritten thus preventing ; CUPPER from converting escape sequence bytes to upper case. ; 60$: ADD R4,R5 ; Point to end of the input. CLRB (R5) ; Terminate string with a NULL. 65$: BIT #B.SRCH,STATUS ; Prompting for a search string ? BEQ 70$ ; If EQ, no. BIT #B.XACT,SWMASK ; Are we doing an exact search ? BNE 80$ ; If NE, yes (don't do conversion). 70$: CALL CUPPER ; Convert string to upper case. 80$: CLC ; Show successful completion. BR 130$ ; And use common return ... 90$: BIS #B.EXIT,STATUS ; Show it's time to exit. BR 120$ ; And continue ... 100$: CMPB R3,#IE.EOF ; Was CTRL/Z typed to exit ? BEQ 90$ ; If EQ, yes. CMPB R3,#IE.IES ; Is error "Invalid escape seq" ? BEQ 110$ ; If EQ, yes. CMPB R3,#IE.PES ; Is error "Partial escape seq" ? BEQ 110$ ; If EQ, yes. CLC ; Show no directive error. CALL CHKERR ; Report the I/O status error. ; ; For invalid or partial escape sequences, flush the typehaead ; buffer and continue. These errors occur if the user has typed ; the escape key or a keypad key to a one character read. ; 110$: CALL WABIT ; Wait for a little while first. (02) CALL CTYPAH ; Clear the typeahead buffer. 120$: CLRB (R0) ; Terminate buffer with null. CLR R1 ; Show nothing was input. SEC ; Show command is being aborted. 130$: RETURN .SBTTL DELCHR - Delete character from the screen. ;+ ; ; DELCHR - Delete a character from the screen. ; ; Inputs: ; R0 = The starting buffer address. ; R1 = The total byte count. ; ; Outputs: ; R1 = The adjusted byte count. ; ;- DELCHR: JSR R5,$SAVRG ; Save R3 - R5. TST R1 ; Anymore characters to delete ? BEQ 100$ ; If EQ, no. MOV #DELSEQ,R4 ; Set delete sequence address. CALL WRITE ; Write the delete sequence. MOV R0,R3 ; Copy the buffer address. DEC R1 ; Adjust the byte count. ADD R1,R3 ; Point to last character. CMPB (R3),#SPACE ; Deleting a control character ? BHIS 100$ ; If HIS, no. CALL CHKGRA ; Character displayed in graphics ? BCC 100$ ; If CC, yes. CALL WRITE ; Yes, delete the up arrow. 100$: RETURN .SBTTL TYPCHR - Display a control character. ;+ ; ; TYPCHR - Display a control character. ; ; Inputs: ; R3 = The control character to display. ; ; Outputs: ; All registers are preserved. ; ;- TYPCHR::CALL $SAVAL ; Save all registers. MOV #FMTBUF,R0 ; Set the output buffer address. CALL DOCHAR ; Copy/format this character. JMP VTYPE ; And display at the terminal. .SBTTL WABIT - Wait for a little while. ;+ ; ; WABIT - Wait for a little while. ; ; This routine is called after an invalid or partial escape sequence is ; detected to wait for additional characters arriving from the escape ; sequence. If we don't wait for a short while on VT102 terminals, the ; clearing of the typeahead buffer doesn't discard the extra characters. ; It appears the VT102 terminals send the escape sequence at a slower ; rate than a normal VT100 terminal. ; ; Inputs: ; None. ; ; Outputs: ; All registers are preserved. ; ;- WABIT:: JSR R2,$SAVVR ; Save R0 - R2. MOV #10,R0 ; Wait for 10 MOV #TICKS,R1 ; clock ticks. CALL DELAY ; Go do the delay. RETURN .SBTTL WRITE - Write a message to the terminal. ;+ ; ; WRITE - Write a message to the terminal. ; ; This routine is used to write a message terminated by null to the ; terminal. It also makes sure that writes do not exceed 512 bytes ; in length. This is done becuase one of the VMS sysgen parameters ; prevents us from writing the entire message all at once. RSX-11M ; allows us to write up to 8128 bytes in length with one QIO. ; ; Inputs: ; R4 = Message address terminated by NULL. ; ; Outputs: ; All registers are preserved. ; ;- WRITE:: CALL $SAVAL ; Save all registers. MOV R4,R0 ; Copy the buffer address. CALL GETLEN ; Calculate the length --> R1. MOV #8128.,R3 ; Setup the maximum write size. TST VAXFLG ; Are we running on VAX/VMS ? BEQ 10$ ; If EQ, no (presume RSX-11M). MOV #512.,R3 ; Else, set smaller write size. 10$: CLR R2 ; Presume a single write. CMP R1,R3 ; Is the length too large ? BLE 20$ ; If LE, no (write it). ; The length is too big, adjust into 512 bytes length. MOV R1,R2 ; Save the message length. MOV R3,R1 ; Set the maximum message length. 20$: CALL WRITIT ; Write the message. BCS 100$ ; If CS, we had an error. TST R2 ; Is there any more to write ? BEQ 100$ ; If EQ, no (we're all done). ; Adjust the buffer address and the message length. ADD R1,R0 ; Yes, adjust the buffer address SUB R1,R2 ; and the message length. MOV R2,R1 ; Set the new message length. BR 10$ ; And continue ... 100$: RETURN .SBTTL WRITIT - Write a message to the terminal. ;+ ; ; WRITIT - Write a message to the terminal. ; ; Inputs: ; R0 = The buffer address. ; R1 = The buffer byte count. ; ; Outputs: ; Carry clear/set = success/failure. ; ; All registers are preserved. ; ;- WRITIT::QIOW$S #IO.WAL!TF.CCO,#TOLUN,#TOEFN,,#TIOSB,, CALL CHKERR ; Check/report any errors. RETURN .SBTTL GET - Get record from the input file. ;+ ; ; GET - Get next record from the input file. ; ; This routine gets the next record from the input file. If end of file ; is encountered, then the end of file flag is set in the status word. ; ; Inputs: ; R5 = The file entry address. ; ; Outputs: ; C bit clear/set = success/failure. ; ; All registers are preserved. ; ;- GET:: JSR R2,$SAVVR ; Save R0 - R2. MOV O.FDB(R5),R0 ; Copy the FDB address. GET$ R0 ; Get the next record. BCC 30$ ; If CC, success. CMPB F.ERR(R0),#IE.EOF ; Was the error end of file ? BNE 10$ ; If NE, no (report the error). BIS #S.EOF,(R5) ; Yes, show we're at end of file. BR 20$ ; And continue ... 10$: CALL FCSERR ; Report the error message. 20$: SEC ; Show failure ... 30$: RETURN .SBTTL GETM - Get/Mark the next input record. ;+ ; ; GETM - Get and mark the next input record. (01) ; ; This routine is used to mark and then get (read) the next input record. ; The record is marked first because the virtual block number and the byte ; displacement will be pointing to the next record instead of the current ; after we get the next record. ; ; Implicit Inputs: ; IENTRY = The active file entry address. ; ; Outputs: ; C bit clear/set = success/failure (from GET routine). ; ; All registers are preserved. ; ;- GETM:: JSR R5,$SAVRG ; Save R3 - R5. MOV IENTRY,R5 ; Copy the file entry address. CALL MARKER ; Mark the record position. CALL GET ; Get the next input record. BCC 100$ ; If CC, success ... BIT #S.EOF,(R5) ; Did we run into end of file ? BEQ 90$ ; If EQ, no. SUB #1,O.CREC+2(R5) ; Yes, backup the SBC O.CREC(R5) ; current record number. 90$: SEC ; Show failure ... 100$: RETURN .END