PAGE    60,132  ; 60 lines, 132 columns
TITLE   MSTEKTRM - TEKTRONIX 4010 terminal emulation module
; 29-Nov-84     Joe Smith, CSM Computing Center, Golden CO 80401 (303)273-3448

        public  TERMEMU                     ; Terminal emulation routine
        extrn   INMODEM:near,OUTMODEM:near  ; Read and write to the modem port
        extrn   INKEYB:near,OUTSCRN:near    ; Read and write to the console
        extrn   CLS:near,TEKDRAW:near       ; Erase and draw routines
        extrn   CROSHAIR:near               ; Trigger the cross-hairs
        extrn   IDSEQ:word                  ; Pointer to string for ESC-Z
        extrn   CTLTAB:word                 ; Pointer to control table

NUL     equ     00h             ; ^@
BEL     equ     07h             ; ^G Bell
BS      equ     08h             ; ^H Backspace
HT      equ     09h             ; ^I Horizontal TAB
LF      equ     0Ah             ; ^J Linefeed
VT      equ     0Bh             ; ^K Vertical tab
FF      equ     0Ch             ; ^L formfeed to clear the screen
CR      equ     0Dh             ; ^M Carriage Return
CAN     equ     18h             ; ^X to return to ANSI mode
EM      equ     19h             ; ^Y not used
SUB     equ     1Ah             ; ESC-^Z triggers crosshairs
ESC     equ     1Bh             ; ESC-^Z and ESC-FF does special things
FS      equ     1Ch             ; ^\ not used
GS      equ     1Dh             ; ^] goes to graphics (1st move invisible)
RS      equ     1Eh             ; ^^ for point plot mode
US      equ     1Fh             ; ^_ returns tor returns to text mode
DEL     equ     7Fh             ; DELETE or RUBOUT

datas   segment public 'datas'

escflag db      0               ; Flag for ESCape sequences
visible db      0               ; 0 to move, 1 to draw a line
tek_hiy dw      0               ; Y coordinate in Tektronix mode
tek_loy db      0
tek_hix dw      0
tek_lox db      0
tek_lsb db      0               ; Low-order 2 bits of X + low Y (4014 mode)

datas   ends

code    segment public
        assume  cs:code,ds:datas


SENDID  PROC NEAR               ; Pretend VT100 with graphics option only
        mov bx,IDSEQ            ; Get addr of string
sndid1: mov al,DS:[bx]          ; Get char from sequence
        cmp al,0                ; End of sequence?
        jz sndid0               ; Yes, return
        call OUTMODEM           ; Send it out the port
        inc bx
        jmp sndid1
sndid0: ret
SENDID  ENDP


;Terminal emulation - check for ESC-Z and for TEKTRONIX graphics commands

TERMEMU PROC NEAR               ; Send 7-bit character to the screen
        and al,7Fh              ;  mask off parity for terminal
        cmp al,NUL              ; NULL character?
        je terme9               ; Yes, skip it
        cmp al,GS               ; Group Separator (^]) ?
        je go2graf              ; Yes, set graphics mode, pen up
        cmp al,ESC              ; Escape?
        je go2esc               ; Yes, remember that
        mov bl,escflag          ; Get the state flag
        xor bh,bh
        jmp CS:tekjump[bx]      ; Go to routine

tekjump label   word
        dw      TEKTXT          ; 0 = Normal text mode
        dw      TEKESC          ; 2 = ESCape seen (forces text mode)
        dw      TEKHIY          ; 4 = Graphics, get HI-Y
        dw      TEKHIX          ; 6 = Graphics, get HI-X

go2graf:mov visible,0           ; Next move is invisible
        mov escflag,4           ; Go to TEKGHIY next
terme9: ret

go2esc: mov escflag,2           ; ESCape in text mode, goto TEKESC next
        ret

;ESCFLAG=0 - Normal text mode

TEKTXT: cmp al,DEL              ; RUBOUT?
        je tektxt1              ; Yes, skip it in text mode
        cmp al,FF               ; Formfeed?
        je tektxt2              ; Yes, clear graphics
        call OUTSCRN            ; No, output character to the screen
tektxt1:ret

tektxt2:mov al,1                ; Clear only graphics (not text)
        call CLS
        ret

;ESCFLAG=2 - Previous character was an ESCape

TEKESC: cmp al,'Z'              ; ESC-Z?
        jne tekesc1
        call SENDID             ; Send terminal identification
        jmp go2text

tekesc1:cmp al,FF               ; ESC-FF?
        jne tekesc2
        mov al,0                ; CLS 0 to erase both text and graphics
        call cls                ; Clear screen
        jmp go2text             ; Return to text mode after ESC-FF

tekesc2:cmp al,SUB              ; ESC-^Z ?
        jne tekesc3
        call CROSHAIR           ; Activate the cross-hairs
        jmp go2text

tekesc3:push ax                 ; Pass ESCape sequence to DOS
        mov al,esc
        call OUTSCRN
        pop ax                  ; Character after the ESCape
        call OUTSCRN
go2text:mov escflag,0           ; Go to TEKTXT next time
        ret

;ESCFLAG=4 - Expecting HIY because LOX was seen
;ESCFLAG=6 - Expecting HIX because LOY was seen
TEKHIY:
TEKHIX: cmp al,CR               ; Exit graphics mode on CR,LF,US
        je go2text
        cmp al,LF
        je go2text
        cmp al,US
        je go2text
        cmp al,CAN
        je go2text
        cmp al,20h              ; Control char?
        jl tekgh1               ; Ignore it
        cmp al,40h
        jl tekgh2               ; 20-3F are HIX or HIY
        cmp al,60h              ; 40-5F are LOX (causes beam movement)
        jl tekgh4               ; 60-7F are LOY

;Extract low-order 5 bits of Y coordinate, set ESCFLAG=6

        mov ah,tek_loy          ; Copy previous LOY to MSB (in case 4014)
        mov tek_lsb,ah
        and al,1Fh              ; LOY is 5 bits
        mov tek_loy,al
        cmp escflag,6           ; 2nd LOY in a row?
        je tekgh1               ; Yes, then LSB is valid
        mov tek_lsb,0           ; 1st one, clear LSB
        mov escflag,6           ; LOY seen, expect HIX (instead of HIY)
tekgh1: ret

;Extract high-order 5 bits (X or Y, depending on ESCFLAG)

tekgh2: and ax,1Fh              ; Just 5 bits
        mov cl,5
        shl ax,cl               ; Shift over 5 bits
        cmp escflag,4           ; Looking for HIY?
        jne tekgh3              ; No, HIX
        mov tek_hiy,ax          ; Yes, this byte has HIY
        ret                     ; Keep ESCFLAG=4

tekgh3: mov tek_hix,ax          ; This byte has HIX (because ESCFLAG=6)
        mov escflag,4           ; Reset to look for HIY next time
        ret

;Extract low-order X, do beam movement

tekgh4: and al,1Fh              ; Just 5 bits
        mov tek_lox,al

        mov ax,tek_hix          ; Combine HIX*32
        or  al,tek_lox          ;  with LOX
        mov bx,tek_hiy          ; Same for Y
        or  bl,tek_loy
        mov cl,visible          ; 0=move, 1=draw
        call TEKDRAW

go2visi:mov visible,1           ; Next movement is with a visible trace
        mov escflag,4           ; Reset to look for HIY next time
        ret
TERMEMU ENDP

code    ends
        end

