; VT102 terminal driver that supports 80 & 132 columns
; Added compatibility for alpha function keys & VT cursor keys
; changes 233's to 33 to make it work with TELIX's VT102 driver
; changed xy =1 to use CUB to move to column 1 for 2.2 compatibility
; updated graphics characters support, only added to feature bitmap when 100%
; compatible.
; added concurrent printing support TCRTs 173,174 8/4/93 rpr
SEARCH SYS
SEARCH SYSSYM
SEARCH TRM
OBJNAM .TDV
TD$VRC=400000000 ; has variable row count [152]
TD$PRO=200000000 ; has proportional spacing [152]
TD$GRY=100000000 ; has grayscale capability [152]
TD$GRA=40000000 ; has true graphics capability
TD$NSP=20000000 ; has "no space" attributes [137]
TD$PHR=10000000 ; has Phineas T. Phart color mode [137]
TD$MOD=4000000 ; has "mode" attributes [137]
;Define capability flags
; VT102 does not have:
;TD$SPL - split screen
;TD$AMS - not an Alpha Micro terminal
;TD$KID - column insert/delete
;TD$SMT,TD$BOX!TD$BLF - smooth scroll,box commands, block fill
;TD$STS no status line
;
TDVFLG=TD$LID!TD$CID!TD$RVA!TD$DIM!TD$BLN!TD$UND!TD$EOS!TD$EOL!TD$MLT
TDVFLG=TDVFLG!TD$PRT!TD$132!TD$MOD!TD$NSP
DEFINE ANSI A,B,C,D,E,F,G,H,I ;
BYTE 33,'[ ; do ANSI CSI
IF NB,A,BYTE A
IF NB,B,BYTE B
IF NB,C,BYTE C
IF NB,D,BYTE D
IF NB,E,BYTE E
IF NB,F,BYTE F
IF NB,G,BYTE G
IF NB,H,BYTE H
IF NB,I,BYTE I
BYTE 0
ENDM
DEFINE SANSI A,B,C,D,E,F,G,H,I ;
BYTE 40,33,'[ ; do space, then ANSI CSI
IF NB,A,BYTE A
IF NB,B,BYTE B
IF NB,C,BYTE C
IF NB,D,BYTE D
IF NB,E,BYTE E
IF NB,F,BYTE F
IF NB,G,BYTE G
IF NB,H,BYTE H
IF NB,I,BYTE I
BYTE 0
ENDM
DEFINE ANSIS A,B,C,D,E,F,G,H,I ;
BYTE 33,'[ ; do ANSI CSI
IF NB,A,BYTE A
IF NB,B,BYTE B
IF NB,C,BYTE C
IF NB,D,BYTE D
IF NB,E,BYTE E
IF NB,F,BYTE F
IF NB,G,BYTE G
IF NB,H,BYTE H
IF NB,I,BYTE I
BYTE 40,0
ENDM
DEFINE ANSINT A,B,C,D,E,F,G,H,I ; no termination
BYTE 33,'[ ; do ANSI CSI
IF NB,A,BYTE A
IF NB,B,BYTE B
IF NB,C,BYTE C
IF NB,D,BYTE D
IF NB,E,BYTE E
IF NB,F,BYTE F
IF NB,G,BYTE G
IF NB,H,BYTE H
IF NB,I,BYTE I
ENDM
;********************
;* VT102 *
;********************
;Terminal driver communications area
VT102: WORD TD$NEW!TD$TCH ; terminal attributes
BR JMPINP ; input routine
RTN ; output routine
BR ECHO ; echo routine
BR JMPCRT ; crt control
BR JMPINI ; INIT routine
WORD 2. ; impure area of one word (2 bytes)
ROWCNT: BYTE 24. ; number of rows
BYTE 80. ; number of columns
LWORD TDVFLG ; terminal flags
BR JMPTCH ; entry for TRMCHR
JMPINP: JMP INP ; go handle input characters
JMPCRT: JMP CRT ; go handle TCRT codes
JMPINI: JMP INI ; go handle initialization
JMPTCH: JMP TCH ; go handle TRMCHR call
PAGE
;********************
;* ECHO *
;********************
;Special echo processing is performed here
;Rubouts will backspace and erase the previous character
;Control-U will erase the entire line by backspacing and erasing
ECHO: CMPB D1,#25 ; control-U
BEQ CTRLU
CMPB D1,#177 ; rubout
BNE ECHX
;Rubouts are handled by the old backspace-and-erase game
;Special handling must be performed if we are rubbing out a tab
;D6 contains the character being rubbed out
RUBOUT: CMPB D6,#11 ; was it a tab?
BEQ RBTB ; yes -
CMPB D6,#40 ; no, was it a control char. ? [106]
BLO RBX ; yes - [106][107]
;Rubout was of a printable character - queue up the backspace sequence
KRTG: MOV #3,D3 ; set character count
LEA A6,ERUB ; set buffer address
MOV A6,D1 ; into D1
TRMBFQ ; queue the backspace sequence
RBX: RTN ; [106]
ERUB: BYTE 10,40,10,0
;Rubout was of a tab - we must calculate how big the tab was and backup over it
RBTB: CLR D3 ; preclear D3
MOVW T.POB(A5),D3 ; set beginning position count
MOV T.ICC(A5),D2 ; set input character count
MOV T.IBF(A5),A6 ; set input buffer base
KRTS: DEC D2 ; done with scan?
BMI KRTQ ; yes -
MOVB (A6)+,D1 ; scan forward calculating position
CMPB D1,#11 ; tab -
BEQ KRTT
CMPB D1,#15 ; carriage return -
BEQ KRTC
CMPB D1,#33 ; escape -
BEQ KRTI
CMPB D1,#40 ; control-char -
BLO KRTS
CMPB D1,#172
BHI KRTS
KRTI: INC D3 ; increment position for one character
BR KRTS
KRTT: ADD #10,D3 ; adjust position for tab
AND #^C7,D3
BR KRTS
KRTC: CLR D3 ; clear position for cr
BR KRTS
KRTQ: COM D3 ; calculate necessary backspaces
AND #7,D3
INC D3
MOV #10,D1 ; set immediate backspace character
TRMBFQ ; queue the backspaces
ECHX: RTN
;Echo a control-U by erasing the entire line
CTRLU: TST D6 ; no action if nothing to erase
BEQ CTUX
CLR D3 ; preclear D3
MOVW T.POO(A5),D3 ; calculate backspace number to erase line
SUBW T.POB(A5),D3
BEQ ECHX
CMP D3,T.ILS(A5) ; insure not greater than terminal width
BLOS CLUA
MOV T.ILS(A5),D3
CLUA: MOV #10,D1 ; queue up backspaces
TRMBFQ
ASL D1,#2 ; queue up spaces
TRMBFQ
MOV #10,D1 ; queue up backspaces
TRMBFQ
CTUX: RTN
PAGE
;********************
;* INP *
;********************
;Input character processing subroutine
;Return a negative flag to indicate possible multi-byte key codes
;Detect a negative flag which indicates the multi-byte processing return
INP: BMI INMLT ; skip if multi-byte processing
CMPB D1,#1 ; function code?
BEQ INPM ; yes - could be multi-byte sequence
CMPB D1,#33 ; escape?
BEQ INPM ; yes - could be multi-byte sequence
LCC #0 ; no - normal processing
RTN
INPM: LCC #PS.N ; possible multi-byte - return N flag
RTN
;Multi-byte processing is done here
;This occurs when TRMSER has accumulated all bytes of a multi-byte keystroke
;D0 contains the character count and A0 indexes the data string
;A5 indexes the terminal definition block and must be preserved
;The translated character must be returned in D1 for storage
;This routine may destroy only A0,A3,A6,D0,D6,D7
INMLT:
; determine if sequnce is alpha-type function key (total of 2 bytes), or
; VT-style CSI sequnce (3 characters)
CMPB D0,#3 ; 3 characters means VT-type
BLO 30$ ; process VT-type command
; could process VT220 keys here, maybe later!
;; BEQ 10$
;; CMPB D0,#5
;; MOVB 2(A0),D1
;; CMPB D1,#'1
; Handle 3 byte CSI sequences here
10$: MOVB 2(A0),D1 ; pick up last character of sequence
ANDB #^B01111111,D1 ; strip to ASCII
BR INMNOT ; and translate to single character.
; handle single keypresses
30$: MOVB (A0)+,D1 ; get the first character
DECB D0 ; count down remaining
BEQ INMX ; none remain - done.
MOVB D1,D7 ; store 1st character in D7
ANDB #^B01111111,D7 ; strip to ASCII
MOVB (A0)+,D1 ; get the second character
ANDB #^B01111111,D1 ; strip to ASCII
CMPB D7,#1 ; started with SOH?
BNE 50$ ; no, must of started with ESCAPE
SUBB #'@,D1 ; yes, SOH, so xlate F1 to "0"
50$: ORB #200,D1 ; set bit 7 on to flag it's a function
BIT #T$XLT,@A5 ; are we doing translation?
BEQ INMNOT ; no - check for another translation
INMX: LCC #0 ; reset the flags
INMX2: RTN
;Come here if program is not doing translation and we must do our own
INMNOT: LEA A6,XLTTBL ; index the translation table
10$: MOVB (A6)+,D7 ; get character
BEQ INMX2 ; end of table - ignore the character
CMPB D1,D7 ; is it in the table?
BEQ 20$ ; yes -
INC A6 ; no - bypass translation
BR 10$ ; loop for more -
;Come here to translate the character
20$: MOVB @A6,D1 ; translate the character
BR INMX
;Translation table
XLTTBL: BYTE 'A,'K&37 ; up arrow
BYTE 'B,'J&37 ; down arrow
BYTE 'C,'L&37 ; right arrow
BYTE 'D,'H&37 ; left arrow
BYTE 'H,^O36 ; home
BYTE 'P,181. ; PF1 => F1
BYTE 'Q,180. ; PF2 => F2
BYTE 'R,211. ; PF3 => F3
BYTE 'S,192. ; PF4 => F4
BYTE 000,000
PAGE
;********************
;* INI *
;********************
;Handle initialization of the terminal
INI: MOV T.IDV(A5),A6 ; index the interface driver [106]
MOV T.IMP(A5),A6 ; index impure area
MOVW #80.,@A6 ; preset to 80 columns
; do some free advertising
MOV T.IDV(A5),A6
CMP -4(A6),#[PSE]_16.![UDO]
BEQ 100$ ; don't use with pseudo IDVs
CMP QFREE,#20. ; we have queue blocks?
BLO 100$
SAVE D1,D3
PEA INISTR
POP D1
MOV #INISZ,D3
TRMBFQ
SLEEP #2500.
PEA INIST2
POP D1
MOV #INIS2,D3
TRMBFQ
REST D1,D3
100$: RTN
INISTR:
ANSINT '4,'i ; Printer controller off
ANSINT 'H ; home cursor (shorthand)
ANSINT 'J ; clear screen
ANSINT '0,'m ; normal intensity
BYTE 33,'(,'B ; end line drawing mode (disable alternate character set)
ANSINT '?,'3,'l ; set 80 column mode
INISZ=.-INISTR
INIST2:
BYTE 33,'#,'3 ; double high top
ASCII "Soft Machines VT-102 driver"
BYTE 15,12
BYTE 33,'#,'4 ; double high bottom
ASCII "Soft Machines VT-102 driver"
BYTE 15,12
BYTE 33,'#,'5 ; single width
INIS2=.-INIST2
EVEN
PAGE
;********************
;* TCH *
;********************
;Handle TRMCHR call
;A1 points to argument block, A2 indexes this TDV, D2 contains flags
;Can only use A1,A2,A6,D1,D2,D6,D7
TCH: MOV TD.FLG(A2),TC.FLG(A1) ; transfer flags
MOV JOBCUR,A6 ; index job
MOV JOBTRM(A6),A6 ; index terminal control area
MOV T.IMP(A6),A6 ; index impure area
CLR D6 ; preclear register
MOVB ROWCNT(A2),D6 ; get row count
MOVW D6,TC.ROW(A1) ; transfer row count
MOVW @A6,TC.COL(A1) ; transfer column count
CLRW TC.CLR(A1) ; no colors
MOVW #00.,TC.TSL(A1) ; set length of top status line [104]
MOVW #00.,TC.SSL(A1) ; set length of shifted status line [104]
MOVW #00.,TC.USL(A1) ; set length of unshifted status line [104]
MOV D2,D7 ; get TRMCHR argument flags [104]
AND #TC$BMP,D7 ; does user want bitmap? [104]
BEQ 20$ ; no - skip bitmap transfer code [104]
;User has requested bitmap -- return it to him [104]
PUSH A1 ; save argument block index [104]
ADDW #TC.BMP,A1 ; index bitmap return area [104]
LEA A6,TCHBMP ; index our bitmap [104]
MOV #<256./16.>-1,D7 ; get amount to transfer [104]
10$: MOVW (A6)+,(A1)+ ; transfer to user [104]
DBF D7,10$ ; loop until done [104]
POP A1 ; restore register [104]
20$: RTN ; return to TRMCHR monitor routine [104]
PAGE
;********************
;* CRT *
;********************
;Special CRT control processing
;D1 contains the control code for x,y positioning or special commands
;If D1 is positive we have screen positioning (row in hi byte, col in lo byte)
;If D1 is negative we have the special command in the low byte
CRT: TSTW D1 ; is it cursor position?
BMI CRTS ; no -
TTYI ; Send cursor position command.
BYTE 33,'[,0 ; do ANSI CSI
EVEN
PUSHW D1 ; save value
CLR D1 ; pre-clear D1
MOVB 1(SP),D1 ; get row
DCVT 0,OT$TRM ; output the row
TYPE <;> ; seperator
MOVB @SP,D1 ; get column
DCVT 0,OT$TRM ; output the column
TYPE <H> ; finish with 'H
POPW D1
RTN ; Return to caller.
;Special commands - D1 contains the command code in the low byte
CRTS: CMPB D1,#80. ; set to wide format?
BEQ CRTWID ; yes - special handling
CMPB D1,#81. ; set to normal format?
BEQ CRTNOR ; yes - special handling
;[103]
; Special handling of the printer port calls...
;
CMPB D1,#82. ; Turn on the printer port ?
BEQ PRTON ; Yes.
CMPB D1,#83. ; No. Turn port off ?
BEQ PRTOFF ; Yes.
;
;
AND #377,D1 ; strip the high byte
BNE CRTU ; and branch unless clear screen
TTYI ; special case for clear screen
BYTE 33,'[ ; do ANSI CSI
BYTE 'H ; home cursor (shorthand)
ANSI 'J ; clear entire display (shorthand)
EVEN
CRTZ: RTN
;Set terminal to wide format
CRTWID: TTYI
ANSI '?,'3,'h ; set 132 column mode
EVEN
MOV #132.,D1 ; get new width
WIDSET: MOV T.IMP(A5),A6 ; index impure area
MOVW D1,@A6 ; store the new width
SLEEP #5000. ; pause while command completes [108]
RTN
;Set terminal to normal format
CRTNOR: TTYI
ANSI '?,'3,'l ; set 80 column mode
EVEN
MOV #80.,D1 ; get the new width
BR WIDSET ; go store it
;[103]
;
; Code to handle the printer port on/off feature.
; We must sleep after we either turn it on or off.
;
PRTON: TTYI
ANSI '5,'i ; Printer controller on
EVEN
PRTDUN: SLEEP #5000. ; pause while command completes. [103]
RTN
; Turn printer port off and wait the same as when turning it on.
;
PRTOFF: TTYI
ANSI '4,'i ; Printer controller off
EVEN ;
BR PRTDUN ; go store it [103]
;Command processing per director tables
CRTU: PUSH A2
ASL D1 ; times 2 (word offset)
CMP D1,#CRCB-CRCA ; check for valid code
BHI CRTX ; and bypass if bad
LEA A2,CRCA-2 ; index the table
ADD D1,A2 ; add command code
MOVW @A2,D1 ; pick up data field offset
ADD D1,A2 ; make absolute data address
TTYL @A2 ; print the data field
CRTX: POP A2 ; restore A2
RTN
DEFINE OFFTAB A1,A2,A3,A4,A5,A6,A7,A8,A9,A10
IF NB, A1, WORD A1-.
IF NB, A2, WORD A2-.
IF NB, A3, WORD A3-.
IF NB, A4, WORD A4-.
IF NB, A5, WORD A5-.
IF NB, A6, WORD A6-.
IF NB, A7, WORD A7-.
IF NB, A8, WORD A8-.
IF NB, A9, WORD A9-.
IF NB, A10, WORD A10-.
ENDM