.title PLTRTN -- VT-52 Screen control routines .ident "V1.5" .nlist me,bex,cnd .enabl lc ; Author: Henry R. Tumblin ; Date: 8-Dec-78 ; Version: 1.5 ; For: Systems/Utilities ; Module Name: PLTRTN -- VT-52 plotting(?) routines ; Residence: DB1:[1,20]PLTRTN.MAC ; Machine/System: PDP-11/70 - IAS V2.0 ; Type/Language: Subroutine/Assembler(MACRO) ; Module Size: Impure - 96. bytes ; Pure - 572. bytes ; Total - 668. bytes, 334. words ; Abstract: This collection of subroutines is provided ; to perform VT-52 functions from any higher ; level or assembler languages that follow the ; FORTRAN R5 conventions. I will leave the ; description of each module to the internal ; blurb at the beginning of each. ; Edits: ; ; Date By Reason ; ---------- ------ ------------------------------------------------- ;01 08-Dec-78 HRT Cleaned up and documented these modules. ;02 31-Jan-79 HRT Added single subroutine to perform I/O. ;02 31-Jan-79 HRT Modified erase commands so if no arguments ; are specified, erasure will be performed ; from the current cursor position. ;03 02-Feb-79 HRT Added Read-with-timeout feature. ;03 02-Feb-79 HRT Added ESC support. ;04 07-Mar-79 HRT Added SET TER ESC, and SET TER NOESC. ;05 12-Mar-79 HRT Added SET TER NOCARRIAGE to enable input and output ; of long escape sequences. .sbttl Tell the assembler which libmacs to use .MCALL QIOW$,EXIT$S,C$C,PUSH,POP,DIR$,ALUN$S,TTSYM$ C$C ; Define carriage control chars. .MACRO PRINT,ARG1,ARG2 .MCALL PUSH,POP ; This macro will generate output using a common DPB. ; The inputs are : ; ; ARG1 - The starting address of the output string ; ARG2 - The length in bytes of the output string ; ; Outputs: ; None, The stack is cleaned up by the subroutine. ; PUSH ; Set up stack for call CALL $OUT ; Go to output routine .ENDM PRINT .MACRO PINPUT A1,L1,P1,L2 ; This macro will perform a read-with-prompt Q-I/O ; The inputs are: ; ; A1 -- The starting address of the input buffer. ; L1 -- The maximum nunber of characters to read. ; P1 -- The starting address of the prompt string. ; L2 -- The length of the prompt string. MOV A1,READP+Q.IOPL ; Set input buffer address MOV L1,READP+Q.IOPL+2 ; Set length of read MOV P1,READP+Q.IOPL+6 ; Point to prompt string MOV L2,READP+Q.IOPL+10 ; Set prompt string length DIR$ #READP ; Perform the QIO .ENDM PINPUT .sbttl Set up common data areas and any DPB's .psect .PLTD,D,RW,REL TTSYM$ ; Define the TT symbols READP: QIOW$ IO.RPR,5,13.,50.,.IOSB.,,<0,0,0,0,0> ; Terminal read w/prompt WRITE: QIOW$ IO.WVB!TF.WAL!TF.SYN,5,14.,50.,.IOSB.,,<0,0,0> ; TT out DPB SETCHA: QIOW$ SF.SSC,5,4,50.,,,<0,0> ; +04 Set characteristics DPB .IOSB.: .BLKW 1 ; I/O Status Block .LENG.: .BLKW 1 ; Actual read or write length .sbttl Set up the different escape sequences .CRHOM: .BYTE 33,110 ; Cursor home .EREOS: .BYTE 33,112 ; Erase to end of screen .DIRAD: .BYTE 33,131 ; Direct cursor addressing .ROW.: .BYTE 0 ; Row # .COL.: .BYTE 0 ; Column # .CRDN: .BYTE 33,102 ; Cursor down .CRUP: .BYTE 33,101 ; Cursor up .RVLF: .BYTE 33,111 ; Reverse line feed .NMLF: .BYTE 12,0 ; Normal line feed .CRRT: .BYTE 33,103 ; Cursor right .CRLT: .BYTE 33,104 ; Cursor left .EREOL: .BYTE 33,113 ; Erase to end of line .BELL: .BYTE 7,0 ; Bell .ENHLD: .BYTE 33,133 ; Enter hold screen mode .EXHLD: .BYTE 33,134 ; Exit hold screen mode .ENALT: .BYTE 33,75 ; Enter alternate keypad .EXALT: .BYTE 33,76 ; Exit alternate keypad .ENGRP: .BYTE 33,106 ; Enter graphics mode .EXGRP: .BYTE 33,107 ; Exit graphics mode .sbttl 1) SETLUN -- Set terminal lun .psect .pltc,i,rw,rel .enabl lsb ; This module changes the default lun. Initially ; the lun that is used by the plot routines is 5, ; since the task builder assigns that lun to our ; TI0:. There may be a need to have this lun ; changed, so rather than having to re-assemble ; this module time and time again, merely do it ; dynamically. ; Note, once the lun is changed, that ; change will remain in effect until this ; routine is called again with a different lun. ; FORTRAN Call is : ; CALL SETLUN(LUN[,DEV,DEVNO]) ; Where ; LUN - is the lun to use. ; Optional arguments are the device to assign to the lun and ; the unit number. ; Where ; DEV - is the device name, (i.e. DATA IDEV/'TT'/) ; DEVNO - is the device number (i.e. DATA IDEVNO/O40/) ; Remember, the device number must be OCTAL!!! ; All arguments specified must be I*2 SETLUN:: ; Define global entry point CMP #1,(R5) ; Only one argument? BEQ 10$ ; EQ - YES CMP #3,(R5) ; 3 arguments ? BNE 20$ ; NE - then bad arguments, return CMP #255.,@2(R5) ; Is the lun within range? BMI 20$ ; MI - then bad lun ALUN$S @2(R5),@4(R5),@6(R5) ; Assign the LUN 10$: MOV @2(R5),READP+Q.IOLU ; Set TT prompt lun MOV @2(R5),WRITE+Q.IOLU ; Set TT write lun MOV @2(R5),SETCHA+Q.IOLU ; +04 Set TT characteristics lun 20$: RETURN ; Return to calling proc. .dsabl lsb .sbttl 2) CLRSCN -- Clear screen .enabl lsb ; This module will perform a cursor home then an ; erase to end of screen function. If there is an ; argument specified, then the cursor will be positioned ; to the specified line number, then the screen will be ; erased from there down. ; FORTRAN Call is : ; CALL CLRSCN [(IROW[,ICOL])] ! Clears the entire screen ; Where : ; IROW - Is the row to clear from. If not specified, ; then the whole screen will be cleared. ; ICOL - Is the col to clear from. If used, must be in ; conjunction with IROW. If not used, then ; the starting column number will be 1. CLRSCN:: ; Define global entry point CALL $SAVAL ; Use syslib register save routine TST (R5) ; Any arguments specified ? BEQ 30$ ; +01 No arguments, erase from here on 10$: MOV @2(R5),R0 ; Get line number into R0 MOV #1,R1 ; Set def. col number CMP #2,(R5) ; Were both arguments spec. BHI 20$ ; NE - then do for 2 MOV @4(R5),R1 ; Else setup column # spec. 20$: CALL INT01 ; Verfiy row,col pair BCS 100$ ; CS - then error PRINT #.DIRAD,#4 ; Position cursor 30$: PRINT #.EREOS,#2 ; Clear Screen 100$: RETURN ; Return to calling proc. .dsabl lsb .sbttl 3) CLRLN -- Clear line .enabl lsb ; This module will clear the line specified, ; or starting with the column specified, clear the ; remainder of the line to the right ; FORTRAN call is: ;+01 CALL CLRLN ! Clear from current cursor position ; CALL CLRLN( ILIN ) ! Clear the line specified ; or ; CALL CLRLN( ILIN,ICOL ) ! Clear line starting in col ICOL ; Where : ; ILIN - Is the line(row) to clear, in the range of 1-24 ; ICOL - is the column to clear from, in the range of 1-80 ; If ILIN or ICOL exceeds the ranges, then no I/O is performed, and ; for now, a normal return is performed. CLRLN:: ; Define the global entry point CALL $SAVAL ; Use syslib routine to save regs TST (R5) ; +01 Any arguments ? BEQ 20$ ; +01 erase from current position MOV @2(R5),R0 ; Set row # MOV #1,R1 ; Set col # CMP #2,(R5) ; More than one arg.? BHI 10$ ; HI - then only single arg. MOV @4(R5),R1 ; Get col # 10$: CALL INT01 ; Verify row,col pair BCS 100$ ; CS - then error PRINT #.DIRAD,#4 ; Position cursor 20$: PRINT #.EREOL,#2 ; Erase to end of line 100$: RETURN ; Return to calling proc. .dsabl LSB .sbttl 4) POSCUR -- Position cursor .enabl lsb ; This module will position the cursor to any position ; on the screen. Note that the screen size is 24 lines X 80 Columns ; FORTRAN call is : ; CALL POSCUR(ILIN,ICOL) ; Where : ; ILIN - Is the line(row) number in the range 1-24 ; ICOL - is the column number in the range 1-80 ; If the arguments specified exceed the ranges, then a normal ; return will be done, and no I/O performed. POSCUR:: ; Define global entry point CALL $SAVAL ; Use syslib routine to save registers CMP #2,(R5) ; Do we have enough arguments?? BHI 100$ ; HI - then return MOV @2(R5),R0 ; Get row # MOV @4(R5),R1 ; Get the column # CALL INT01 ; Verify row,col pair BCS 100$ ; CS - then error PRINT #.DIRAD,#4 ; Position cursor 100$: RETURN ; Return to calling proc. .dsabl lsb .sbttl 5) PSREAD -- Position cursor, then read .enabl lsb ; This module will first position the cursor, then ; read from the screen for up to the length ; specified. This module performs no checking ; for where it may be overwriting in memory, so ; take care in specifying the read length. ; FORTRAN call is : ;+03 CALL PSREAD(IBUF,ILEN,ILIN,ICOL[,ISTAT][,ITMO]) ; Where : ; IBUF - is the buffer that the input line ; is to be read into. ; ILEN - Is the number of characters to read. ; ILIN - Is the line number to position the cursor to. ; ICOL - Is the column number to position the cursor to. ;+03 ISTAT- If specified, will contain the the following ;+03 Status. If an is typed, then the escape ;+03 sequence will be placed directly into the ;+03 first word. If it is greater than a 1-word ;+03 escape sequence, then the second word will ;+03 contain the remainder of the sequence. ;+03 Note: For escape sequence processing, only the ;+03 high byte is returned in the I/O status word. ;+03 If this value is a minus 1(-1), then check the ;+03 length word to be sure that it wasn't a ;+03 non-translatable escape sequence. If the length ;+03 word is zero, then we can assume that a CTRL-Z or ;+03 other error condition has occured. ;+03 ITMO - The timeout value in seconds. This number should ;+03 be in units of ten seconds.(That's how the TT ;+03 handler does it. Why be different?). ; If ILIN and ICOL aren't within range, then a return ; will be immediately performed with no I/O done. PSREAD:: ; Define the global entry point CMP #4,(R5) ; Do we have enough arguments? BHI 100$ ; HI - then quit now MOV @6(R5),R0 ; Get the line(row) # MOV @10(R5),R1 ; Get column # CALL INT01 ; Verify row,col pair BCS 200$ ; CS -then error MOV #IO.RPR,READP+Q.IOFN ; +03 Set read function code CLR READP+Q.IOPL+4 ; +03 Clear timeout value. CMP #6,(R5) ; +03 Did they want a timeout? BNE 10$ ; +03 NE - then go ahead and read BIS #TF.TMO,READP+Q.IOFN ; +03 Set the subfunction code MOV @14(R5),READP+Q.IOPL+4 ; +03 Set the timeout 10$: PINPUT 2(R5),@4(R5),#.DIRAD,#4 ; Position cursor and read 100$: CMP #5,(R5) ; +03 Did they want status back? BHI 200$ ; +03 NE - no, return MOV 12(R5),R0 ; +03 Else return the ESC code BEQ 200$ ; +03 EQ - then null argument TSTB .IOSB.+1 ; +03 Was it an sequence? BLE 210$ ; +03 LE - then return code as is MOVB .IOSB.+1,R1 ; +03 Expand into a register MOV R1,.IOSB. ; +03 Store status 210$: MOV .IOSB.,(R0)+ ; +03 Move status into place MOV .LENG.,(R0)+ ; +03 Return the length here 200$: RETURN ; Return to calling proc. .dsabl lsb .sbttl 6) PSWRIT - Position cursor, then write .enabl lsb ; This module allows a user string to be placed ; anywhere on a VT-52 screen. ; The FORTRAN call is : ; CALL PSWRIT(IBUF,ILEN,ILIN,ICOL) ; Where : ; IBUF - Is the user buffer to be output. ; ILEN - is the number of characters to output. ; ILIN - Is the line number to position the cursor to. ; ICOL - Is the column number to position the cursor to. PSWRIT:: ; Define the global entry point CALL $SAVAL ; Use syslib routine to save regs CMP #4,(R5) ; Do we have enough arguments ? BHI 100$ ; HI - then bad arguments MOV @6(R5),R0 ; Get row # MOV @10(R5),R1 ; Get column # CALL INT01 ; Verify row,col pair BCS 100$ ; CS - then error PRINT #.DIRAD,#4 ; Position cursor PRINT 2(R5),@4(R5) ; Output string 100$: RETURN ; Return to calling proc. .DSABL LSB .sbttl 7) HOLD - Routine to perform HOLD/NOHOLD function .enabl lsb ; This routine has two entry points. The first ; entry point will set the terminal in hold-screen ; mode. The other entry point will set the terminal ; in no-hold screen mode. For further information ; about hold-screen mode, see the VT-52 users manual, ; page 24. ; FORTRAN call : ; CALL HOLD ! Sets the terminal into hold-screen ; or ; CALL NOHOLD ! Sets the terminal to no-hold screen HOLD:: ; Define the global entry point PUSH <#.ENHLD> ; Set function pointer on stack BR 10$ ; Go set the terminal into HS mode NOHOLD:: ; Define the global entry point PUSH <#.EXHLD> ; Set function pointer on stack BR 10$ ; Go restore terminal .sbttl 8) GRPH - Set terminal in graphics mode ; This routine has two entry points. The first ; entry point will set the terminal in graphics ; mode. The other entry point will set the terminal ; in normal screen mode. For further information ; about graphics mode, see the VT-52 users manual, ; page 25. ; FORTRAN call : ; CALL GRPH ! Sets the terminal into graphics mode ; or ; CALL NOGRPH ! Sets the terminal to normal mode GRPH:: ; Define the global entry point PUSH <#.ENGRP> ; Set function pointer on stack BR 10$ ; Go set the terminal into Graphics NOGRPH:: ; Define the global entry point PUSH <#.EXGRP> ; Set function pointer on stack BR 10$ ; Go restore terminal .sbttl 9) ALTK - Set terminal in alternate keypad mode ; This routine has two entry points. The first ; entry point will set the terminal in alternate keypad ; mode. The other entry point will set the terminal ; in normal keypad mode. For further information ; about alternate keypad mode, see the VT-52 users manual, ; page 24. ; FORTRAN call : ; CALL ALTK ! Sets the terminal into graphics mode ; or ; CALL NOALTK ! Sets the terminal to normal mode ALTK:: ; Define the global entry point PUSH <#.ENALT> ; Set function pointer on stack BR 10$ ; Go set the terminal into ALT KPD NOALTK:: ; Define the global entry point PUSH <#.EXALT> ; Set function pointer on stack BR 10$ ; Go restore the terminal .sbttl 10) Cursor movement commands ; This module has multiple entry points due to the nature ; of the commands. Each of the commands supported here ; are used to move the cursor in different directions. ; FORTRAN call is: ; CALL CRSUP ! Moves the cursor up one space ; CALL CRSDN ! Moves the cursor down one space ; CALL CRSRT ! Moves the cursor one space to the right ; CALL CRSLT ! Moves the cursor one space to the left ; Note: For a further description of each of these functions, ; refer to the VT-52 users manual, pg 19-20. CRSUP:: ; Define the global entry point PUSH <#.CRUP> ; Set function pointer on stack BR 10$ ; Go output it. CRSDN:: ; Define the global entry point PUSH <#.CRDN> ; Set function pointer on stack BR 10$ ; Go output it. CRSRT:: ; Define the global entry point PUSH <#.CRRT> ; Set function pointer on stack BR 10$ ; Go output it. CRSLT:: ; Define the global entry point PUSH <#.CRLT> ; Set function pointer on stack BR 10$ ; Go output it. .sbttl 11) BELL - Ring the bell ; This module will send the appropriate sequence to ; ring the bell on the terminal. ; FORTRAN call is: ; CALL BELL BELL:: ; Define the global entry point PUSH <#.BELL> ; Point to output string BR 10$ .sbttl 12) Line positioning routines ; This module contains multiple entry points to perform the ; following functions. Reverse line feed, normal line feed ; For more information, see the VT-52 users manual, pg 19. ; FORTRAN call is: ; CALL RVLF ! Perform a reverse line feed ; CALL NMLF ! Perform a normal line feed RVLF:: ; Define the global entry point PUSH <#.RVLF> ; Set function pointer on stack BR 10$ ; Go output sequence NMLF:: ; Define the global entry point PUSH <#.NMLF> ; Set function pointer on stack 10$: POP R0 ; Place pointer in R0 PRINT R0,#2 ; Output the sequence RETURN ; Return to calling proc. .dsabl lsb .sbttl 13) Set terminal in escape mode .enabl lsb ;+04 This module will allow the user to either set or ;+04 unset their terminal to recognize the VT-52 ;+04 escape sequences and perform the proper translation. ;+04 The FORTRAN call is: ;+04 CALL ESCSET(N) ;+04 Where : ;+04 N -- Is 0 to not recognize escape sequences ;+04 1 to recognize escape sequences. ESCSET:: ; +04 Define global entry point MOV #TC.ESQ,SETCHA+Q.IOPL ; +04 Set characteristic in DPB SETC: TST @2(R5) ; +04 Is it a 0? BEQ 10$ ; +04 EQ - then go clear CMP #1,@2(R5) ; +04 Was it a 1? BNE 20$ ; +04 NE - then return 10$: MOV @2(R5),SETCHA+Q.IOPL+2 ; +04 Set parameter DIR$ #SETCHA ; +04 Send it off to the TT handler 20$: RETURN ; +04 And return .dsabl lsb .sbttl 13) AUTOCR -- Set terminal for no AUTO- ;+05 The IAS/RSX-11D terminal handler keeps track of how many ;+05 characters have been output to the terminal, then when the ;+05 terminal width is exceeded, a - sequence is output ;+05 to allow lines longer than the terminal width to be displayed. ;+05 This ,unfortunately, poses a problem to the proper handling of ;+05 the VT-52 using these subroutines. To alleviate this problem, ;+05 the terminal can be set in no-auto-carriage-return mode. ;+05 ;+05 The FORTRAN call is : ;+05 CALL AUTOCR(n) ;+05 Where: ;+05 n - = 1 if the AUTO-CR facility is to be enabled. ;+05 = 0 if the AUTO-CR facility is to be disabled. AUTOCR:: MOV #TC.ACR,SETCHA+Q.IOPL ; +05 Set characteristic in DPB BR SETC ; +05 Go set the characteristic .sbttl Support subroutines .enabl lsb ; These modules are subroutines common to the ; plot routines only, therefore are not made ; global. .sbttl 1) INT01 - Setup direct address buffer ; Register conventions ; Entry: ; R0 - contains the row # ; R1 - Contains the column # ; Exit: ; R0, R1 contain VT-52 adjusted values. ; C-bit is set if values are not within range ; of VT-52 screen. INT01: TST R0 ; Is the value 0 or less ? BLE 90$ ; LE - then set carry and leave CMP #24.,R0 ; Is it within the upper range ? BLT 90$ ; LT - then bad value ADD #31.,R0 ; Adjust for VT-52 MOVB R0,.ROW. ; Store in output buffer TST R1 ; Is the value 0 or less? BLE 90$ ; LE - then bad value CMP #80.,R1 ; Check upper limit BLT 90$ ; LT - then bad value ADD #31.,R1 ; Adjust for VT-52 MOVB R1,.COL. ; Store in output buffer CLC ; Indicate success BR 100$ ; Go return 90$: SEC ; Indicate error 100$: RETURN ; Return to calling proc. .sbttl 2) $OUT - Output escape sequence $OUT:: MOV (SP)+,R0 ;+02 Save return @ POP ;+02 Set up the DPB DIR$ #WRITE ;+02 Output it MOV R0,-(SP) ;+02 Restore return address RETURN .end