; TEL910 terminal driver - hand modified to remove function key code from
; TEL925.M68, which was built by FIXTRM V2.0a/L and then hand modified.
;
;                                 NOTICE
;
; All  rights  reserved.  This software is the property of Alpha Microsystems
; and the material contained herein is the  proprietary  property  and  trade
; secrets  of  Alpha Microsystems, embodying substantial creative efforts and
; confidential information, ideas and expressions, no part of  which  may  be
; reproduced  or  transmitted  in  any  form  or  by  any  means, electronic,
; mechanical,  or  otherwise,  including  photocopying  or  input  into   any
; information  storage  or  retrieval  system  without  the  express  written
; permission of Alpha Microsystems.
;
; CAUTION: Unauthorized distribution or reproduction  of  this  material  may
; subject you to legal action.
;
; Copyright (c) 1982 - Alpha Microsystems, Irvine  CA  92714
;
       MAYCREF

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       OBJNAM  0,0,[TDV]

       CREF

       PAGE

FIRST=0
SECOND=1
YES=1
NO=0
CRT=1
HARDCO=0

LIN.IN=100000
;;;CHR.IN=40000
;;;REVERS=20000
;;;DIM=   10000
;;;BLINK= 4000
;;;ULINE= 2000
EOSCRE=1000
EOLINE=400

NULLS=0+000.
FFNULLS=0+000.
KEYBOARD=0+YES
SHIFTED=0+NO
TDVTYPE=0+CRT
ROWS=0+024.
COLUMNS=0+080.
ROW=0+FIRST
OFFSET=0+031.
LEADIN=0+027.
SNOOZE=0+300.
SMART=0+LIN.IN+EOSCRE+EOLINE
FUNCTIONS=0+NO
FLEADIN=0+001.
DELAYCOUNT=0+2000.
FDISCARD=0+000.

IF EQ,TDVTYP
       WORD    0                       ; TDV flags.
IFF
       WORD    2000                    ; TDV flags, CRT specs included.
ENDC
IF NE,SHIFTE!FUNCTI
       BR      INPUT                   ; Handle INPUT routine.
IFF
       RTN                             ; No INPUT routine.
ENDC
IF NE,NULLS!FFNULL
       BR      OUTPUT                  ; Handle OUTPUT routine.
IFF
       RTN                             ; No OUTPUT routine.
ENDC
IF NE,KEYBOA
       BR      ECHO                    ; Handle keyboard ECHO.
IFF
       RTN                             ; No ECHO routine.
ENDC
IF NE,TDVTYP
       BR      TCRT                    ; Handle CRT.
       RTN                             ; No INIT routine.
IMPSIZ= 16.*TDVTYP
IF NE,FDISCA
       IMPSIZ  =IMPSIZ+2               ; Adjust for function key translation.
ENDC
       WORD    IMPSIZ                  ; IMPURE area.
       BYTE    ROWS,COLUMN             ; Terminal size.
       LWORD   SMART                   ; Terminal features.
IFF
       RTN                             ; No CRT routine.
       RTN                             ; No INIT routine.
       WORD    0                       ; No impure area.

ENDC
IF NE,SHIFTE!FUNCTI
       PAGE

;****************
;     INPUT     *
;****************
; Handle input character translation.
;
; Passed:
;
;       D1      := Input character.
;
INPUT:  SAVE    D6,A6                   ; Save registers.
IF NE,SHIFTE

; Reverse RUBOUT and UNDERLINE characters so RUBOUT is an unshifted character.
;
       AND     #177, D1                ; Make character legal.
       CMPB    D1, #137                ; Underline?
       BEQ     10$                     ;  Yes, convert it.
       CMPB    D1, #177                ; Rubout?
       BNE     20$                     ;  No, no conversion needed.
10$:    XORB    #40, D1                 ; Convert rubout/underline code.
20$:
ENDC
IF NE,FUNCTI

; If function key translation, do not translate if not in image mode.
;
       MOVW    T.STS(A5), D6           ; Get terminal status flags.
       ANDW    #T$IMI, D6              ; Image mode?
       BEQ     INPUTX                  ;  No - no translation.
IF NE,FDISCA

; Check for function key terminator
;
       MOV     T.IMP(A5), A6           ; Index impure area.
       TSTW    @A6                     ; Terminator send in progress?
       BNE     INPC3                   ;  Yes - discard terminator.
ENDC
       AND     #177, D1                ; Ignore parity.
       CMPB    D1, #FLEADI             ; Function key leadin?
       BEQ     DELAY                   ;  Yes - pause to let in code.

; Discard commands go here
;
       CMPB    T.LCH(A5), #FLEADI      ; Last input function key leadin?
       BNE     INPUTX                  ;  No - no translation.
       TST     T.ICC(A5)               ; Input waiting?
       BEQ     INPUTX                  ;  No - lost function key.
       LEA     A6, XLAT                ; Get translation table.
INPC1:  TSTB    @A6                     ; End of table?
       BEQ     INPUTX                  ;  Yes - nonsupported function.
       CMPB    D1,(A6)+                ; This function?
       BEQ     INPC2                   ;  Yes - translate it.
       ADD     #1, A6                  ;  No - move to next one.
       BR      INPC1
INPC2:  MOVB    @A6, D1                 ; Set the proper code.
       SUB     #1, T.ICC(A5)           ; Fool system into discarding leadin.
IF NE,FDISCA
       MOV     T.IMP(A5), A6           ; Index impure area.
       MOVW    #FDISCA, @A6            ; Set terminator character count.
ENDC
IF EQ,FLEADI-33
       SUB     #1, T.BCC(A5)           ; If escape, bump break char count.
ENDC
       BR      INPUTX                  ;  All done.

IF NE,FDISCA
INPC3:  MOV     T.IMP(A5), A6           ; Index impure area.
       SUBW    #1, @A6                 ; Decrement terminator char count.
ENDC
DISCAR: CLRB    D1                      ; Discard char.
DELAY:  MOV     #DELAYC, D6
DLY:    SOB     D6, DLY                 ; Stall until code comes in.
ENDC

; All done. Restore registers and return.
;
INPUTX: REST    D6,A6                   ; Restore registers.
       RTN                             ; Return to caller.

ENDC
IF NE,NULLS!FFNULL
       PAGE

;********************
;*      OUTPUT      *
;********************
; Check for required delays and append nulls if so.
;
; Passed:
;
;       D1      := Output character.
;
OUTPUT: SAVE    A3                      ; Save registers.
IF NE,NULLS

; Output nulls after line feed?
;
       CMPB    D1, #12                 ; Output nulls after LF?
       BNE     10$                     ;  No.
       LEA     A3, T.OQX(A5)           ; Index output queue.
       QINS    A3                      ;  Insert queue block.
       MOV     #NULLS, 4(A3)           ; Set null count.
10$:    LCC     #PS.N                   ; Signal to handle normally.
ENDC
IF NE,FFNULL

; Output nulls after form feed?
;
       CMPB    D1, #14                 ; Output nulls after FF?
       BNE     20$                     ;  No.
       LEA     A3, T.OQX(A5)           ; Index output queue.
       QINS    A3                      ;  Insert queue block.
       MOV     #NULLS, 4(A3)           ; Set null count.
20$:    LCC     #PS.N                   ; Signal we did something.
ENDC

; All done. Restore registers and return. Pass condition codes back to
;  caller to indicate whether or not anything happened.
;
OUTPTX: REST    A3                      ; Restore registers.
       RTN                             ; Return to caller.

ENDC

       PAGE

TCRT:   JMP     POSCUR                  ; Reach CRT and cursor positioning routines.
ECHO:   JMP     ECH                     ; Reach Rubout/Ctrl-U echo routines.

CRCA:   ; Byte offset and data tables follow for all commands
       BYTE    C0-.,C1-.,C2-.,C3-.,C4-.,C5-.,C6-.,C7-.
       BYTE    C8-.,C9-.,C10-.,C11-.,C12-.,C13-.,C14-.,C15-.
       BYTE    C16-.,C17-.,C18-.,C19-.,C20-.,C21-.,C22-.,C23-.
       BYTE    C24-.,C25-.,C26-.,C27-.,C28-.,C29-.
CRCB:
; Additional Non-AM supported commands
       BYTE    C64-.,C65-.,C66-.,C67-.,C68-.,C69-.,C70-.,C71-.,C72-.
       BYTE    C73-.,C74-.,C75-.,C76-.,C77-.,C78-.,C79-.,C80-.,C81-.
       BYTE    C82-.,C83-.,C84-.,C85-.,C86-.,C87-.,C88-.,C89-.,C90-.
       BYTE    C91-.,C92-.,C93-.,C94-.,C95-.,C96-.,C97-.,C98-.,C99-.
       BYTE    C100-.,C101-.,C102-.,C103-.,C104-.,C105-.,C106-.,C107-.
       BYTE    C108-.,C109-.,C110-.
CRCC:

; Special functions.
;C0:    BYTE    027.,042.,0     ; clear screen to nulls, reset protect & intensity
C0:     BYTE    027.,042.,026.,0,200
C1:     BYTE    030.,0          ; cursor home
C2:     BYTE    <'M-100>!200,0  ; cursor return
C3:     BYTE    013,0           ; cursor up
C4:     BYTE    026,0           ; cursor down
C5:     BYTE    010,0           ; cursor left
C6:     BYTE    014,0           ; cursor right
C7:     BYTE    027.,035.,0     ; lock keyboard
C8:     BYTE    027.,034.,0     ; unlock keyboard
;C9:    BYTE    027.,116.,0     ; erase to end of line with nulls
C9:     BYTE    027.,'T,0,200   ; erase to end of line with fill char (spaces)
;C10:   BYTE    027.,121.,0     ; erase to end of screen with nulls
C10:    BYTE    027.,'Y,0,200   ; erase to end of screen with fill characters
C11:    BYTE    027.,041.,0     ; protect field (dim mode)
C12:    BYTE    027.,040.,0     ; unprotect field (normal mode)
C13:    BYTE    027.,038.,0     ; enable protection of fields
C14:    BYTE    027.,039.,0     ; disable protection of fields
C15:    BYTE    027.,082.,0,200 ; delete line
C16:    BYTE    027.,069.,0,200 ; insert line
C17:    BYTE    027.,087.,0     ; delete char
C18:    BYTE    027.,081.,0     ; insert char
C19:    BYTE    027.,063.,0     ; read cursor address
C20:    BYTE            0               ; read char at cursor address
C21:    BYTE    027.,071.,050.,0        ; start blinking field
C22:    BYTE    027.,071.,048.,0        ; end blinking field
C23:    BYTE            0               ; start line draw or alt char set
C24:    BYTE            0               ; end line draw or alt char set
C25:    BYTE            0               ; set horizontal position
C26:    BYTE            0               ; set vertical position
C27:    BYTE            0               ; set terminal attributes
C28:    BYTE    027.,046.,051.,0                ; turn cursor on
C29:    BYTE    027.,046.,048.,0                ; turn cursor off
; End of Alpha Micro supported functions.
C64:    BYTE    027.,'I,0       ; back tab
C65:    BYTE    027.,'1,0       ; set column tab
C66:    BYTE    027.,'2,0       ; clear column tab
C67:    BYTE    027.,'3,0       ; clear all tabs
C68:    BYTE    027.,44.,0      ; clear all to half intensity
C69:    BYTE    027.,62.,0      ; keyclick on
C70:    BYTE    027.,60.,0      ; keyclick off
C71:    BYTE    027.,'G,'4,0    ; start reverse video
C72:    BYTE    027.,'G,'0,0    ; end reverse video
C73:    BYTE    027.,'G,'8,0    ; start underline
C74:    BYTE    027.,'G,'0,0    ; end underline
C75:    BYTE    027.,'b,0       ; black on white
C76:    BYTE    027.,'d,0       ; white on black
C77:    BYTE    027.,'B,0       ; block mode on
C78:    BYTE    027.,'C,0       ; conversation mode on
C79:    BYTE    027.,'O,0       ; blank screen
C80:    BYTE    027.,'N,0       ; normal screen
C81:    BYTE    027.,'4,0,200   ; send line unprotect only
C82:    BYTE    027.,'5,0,200   ; send page unprotect only
C83:    BYTE    027.,'6,0,200   ; send line all
C84:    BYTE    027.,'7,0,200   ; send page all
C85:    BYTE    027.,'S,0,200   ; send message unprotect only
C86:    BYTE    027.,'s,0,200   ; send message all
C87:    BYTE    027.,'U,0       ; monitor mode on
C88:    BYTE    027.,'u,0       ; monitor mode off
C89:    BYTE    18.,0           ; enable bidirectional printer mode
C90:    BYTE    20.,0           ; disable bidirectional printer mode
C91:    BYTE    15.,0           ; enable X on/off
C92:    BYTE    14.,0           ; disable X on/off
C93:    BYTE    027.,'@,0       ; extension mode on
C94:    BYTE    027.,'A,0       ; extension mode off
C95:    BYTE    027.,'P,0,200   ; print page
C96:    BYTE    027.,96.,0      ; transparent print on
C97:    BYTE    027.,'a,0       ; transparent print off
C98:    BYTE    027.,'g,0,200   ; display user line
C99:    BYTE    027.,'h,0,200   ; turn off 25th line
C100:   BYTE    027.,'f,0       ; start loading user line
C101:   BYTE    027.,'j,0       ; reverse linefeed
C102:   BYTE    027.,'k,0       ; set local edit mode
C103:   BYTE    027.,'l,0       ; set duplex edit mode
C104:   BYTE    027.,'.,'1,0    ; blinking block cursor
C105:   BYTE    027.,'.,'2,0    ; steady block cursor
C106:   BYTE    027.,'.,'4,0    ; steady underline cursor
C107:   BYTE    027.,'.,'3,0    ; blinking underline cursor
C108:   BYTE    027.,'p,0       ; Next char will be printer termination char
C109:   BYTE    027.,032.,'1,0  ; Next 5 characters set terminal time
C110:   BYTE    027.,032.,'2,0  ; Read terminal time
;
CURPOS: BYTE    027.,061.,0     ; cursor positioning
       BYTE    0               ; In case driver is built without CURPOS.

IF NE,FUNCTI
; Function key translation table
;
XLAT:
       BYTE    064.,023.       ; F1 = ^W
       BYTE    065.,001.       ; F2 = ^A
       BYTE    066.,014.       ; F3 = ^N
       BYTE    067.,021.       ; F4 = ^U
       BYTE    068.,024.       ; F5 = ^X
       BYTE    069.,018.       ; F6 = ^R
       BYTE    070.,020.       ; F7 = ^T
       BYTE    071.,005.       ; F8 = ^E
       BYTE    072.,019.       ; F9 = ^S
       BYTE    073.,002.       ; F10= ^B
       BYTE    096.,026.       ;SF1 = ^Z
       BYTE    097.,015.       ;SF2 = ^O
       BYTE    098.,006.       ;SF3 = ^F
       BYTE    099.,004.       ;SF4 = ^D
       BYTE    100.,025.       ;SF5 = ^Y
       BYTE    101.,022.       ;SF6 = ^V
       BYTE    102.,017.       ;SF7 = ^Q
       BYTE    103.,028.       ;SF8 = ^\
       BYTE    104.,016.       ;SF9 = ^P
       BYTE    0               ; End of table.
ENDC
ERUB:   BYTE    10,40,10        ; Rubout sequence for ECHO.
       EVEN

       PAGE

;****************
;     POSCUR    *
;****************
; Special CRT control processing.
; If D1 is positive we have screen position (row in high, column in low byte)
;  else we have the special command in the low byte.
;
; Passed:
;
;       D1      := Cursor position.
;
POSCUR: SAVE    D1,D3,A0,A2             ; Save regies.
       TSTW    D1                      ; Is it cursor position?
       BMI     TCRTS                   ;  No - special command.
       LEA     A0, CURPOS              ; Index cursor positioning command.
       CLR     D3                      ; Clear character count.
       MOV     T.IMP(A5), A2           ; Index the impure area.
IF NE,FDISCA
       ADD     #2, A2                  ; Bypass function key translation flag.
ENDC
10$:    ADD     #1, D3                  ; Bump counter.
       MOVB    (A0)+, (A2)+            ; Move bytes.
       TSTB    @A0                     ; All done?
       BNE     10$                     ;  No.
IF NE,OFFSET
       ADD     #<OFFSET_8.>+<OFFSET&377>, D1   ; Adjust positional offsets.
ENDC
       OR      #100200, D1             ; Prevent control code conversions.
IF EQ,ROW
       RORW    D1, #8.                 ; Send row first.
ENDC
       MOVB    D1, (A2)+               ; Set first position.
       RORW    D1, #8.                 ;  Index high byte.
       MOVB    D1, (A2)+               ; Set second position.
       ADD     #2, D3                  ; Bump count.
       MOV     T.IMP(A5), A2           ; Set character index.
IF NE,FDISCA
       ADD     #2, A2                  ; Bypass function key translation flag.
ENDC
       TBUF                            ; Send position sequence.
IF NE,SNOOZE
       MOVB    CURPOS+1, D6            ; Get cursor position code.
       CMPB    D6, #200                ; Nulls after cursor position?
       BHIS    TCRTZ                   ;  Yes, go sleepy-bye.
ENDC
       BR      TCRTX                   ; All done.

; Special commands - D1 contains the command code in the low byte
;
TCRTS:  AND     #377, D1                ; Strip the high byte.
       LEA     A2,CRCA                 ; Index AM table
       CMP     D1, #CRCB-CRCA          ; Check for valid code
       BLOS    1$                      ; Valid code in AM range (<64.)
       LEA     A2,CRCB                 ; Index user code section
       SUBB    #100, D1                ; See if user code (>=64.)
       CMP     D1, #CRCC-CRCB          ; Within user range?
       BHI     TCRTX                   ; Bypass if bad.
1$:     ADDW    D1, A2                  ; Add command code.
       CLR     D1                      ; Preclear D1.
       MOVB    @A2, D1                 ; Pick up data field offset.
       ADD     D1, A2                  ; Make absolute data address.
       TTYL    @A2                     ; Print the data field.
IF NE,SNOOZE
2$:     CMPB    (A2)+,#0                ; Fix AM bug - TTYL doesn't update
       BNE     2$                      ;  A2 to point to null (inferential
       CMPB    (A2),#200               ;  evidence only)
;       CMPB    1(A2), #200             ; Sleep if long command.
       BLO     TCRTX
TCRTZ:  SLEEP   #SNOOZE                 ; Sleep long enough for command to finish.
ENDC

; All done, restore registers and return.
;
TCRTX:  REST    D1,D3,A0,A2             ; Restore registers.
       RTN                             ; Return to caller.

       PAGE

;****************
;      ECH      *
;****************
; Special echo processing
; Rubouts will backspace and erase the previous character
; Control-U will erase the entire line by backspacing and erasing
;
; Passed:
;
;       D1      := Character to echo.
;       D6      := Previous input character.
;
ECH:    SAVE    D1-D4,D6,D7,A2,A6       ; Save registers.

; Check for rubout or control-U.
;
       CMPB    D1, #177                ; RUBOUT?
       BEQ     DELCHR                  ;  Yes, delete previous character.
       CMPB    D1, #25                 ; Control-U?
       BEQ     CTRLU                   ;  Yes, delete entire line.
       JMP     ECHX                    ; All done.

; Rubouts are handled by the old backspace-and-erase game
; D3 contains the character being rubbed out
;
DELCHR: CMPB    D6, #11                 ; Was it a TAB?
       BEQ     RBTB                    ;  Yes - rub it out.

; Rubout was of a printable character - queue up the backspace sequence
;
KRTG:   MOV     #3, D3                  ; Set char count.
       LEA     A6, ERUB                ; Get buffer address.
       MOV     A6, D1                  ;  Set index.
       TRMBFQ                          ; Queue the backspace sequence.
       JMP     ECHX                    ; All done.

; Rubout was of a tab - we must calculate how big the tab was and backup over it
;
RBTB:   CLR     D4                      ; Preclear.
       MOVW    T.POB(A5), D4           ; Set beginning position count.
       MOV     T.ICC(A5), D2           ; Set input char count.
       MOV     T.IBF(A5), A3           ; Set input buffer base.
KRTS:   SUB     #1, D2                  ; Done with scan?
       BMI     KRTQ                    ;  Yes - output backspaces.
       MOVB    (A3)+, D1               ; Scan forward calculating position.
       CMPB    D1, #11                 ; TAB?
       BEQ     KRTT                    ;  Yes.
       CMPB    D1, #15                 ; CR?
       BEQ     KRTC                    ;  Yes.
       CMPB    D1, #33                 ; ALTMODE (ESCAPE)?
       BEQ     KRTI                    ;  Yes.
       CMPB    D1, #40                 ; CONTROL-CHAR?
       BLO     KRTS                    ;  Yes.
       CMPB    D1, #176                ; Check high end...
       BHI     KRTS                    ;  Yes, unprintable character.
KRTI:   ADD     #1, D4                  ; Increment position for one char.
       BR      KRTS
KRTT:   ADD     #10, D4                 ; Adjust position for TAB.
       AND     #^C<7>, D4
       BR      KRTS
KRTC:   CLR     D4                      ; Clear position for CR.
       BR      KRTS
KRTQ:   COM     D4                      ; Calculate necessary backspaces.
       AND     #7, D4
       ADD     #1, D4
       MOV     D4, D3                  ; Set char count.
       MOV     #10, D1                 ; Set immediate backspace char.
       TRMBFQ                          ; Queue the backspaces.
       BR      ECHX                    ; All done.

; Handle control-U.
;
CTRLU:  TST     D6                      ; No action if nothing to erase.
       BEQ     ECHX
       CLR     D3                      ; Preclear.
       MOVW    T.POO(A5), D3           ;  Get current output position.
       CLR     D4                      ; Preclear.
       MOVW    T.POB(A5), D4           ;  Get beginning output position.
       SUB     D4, D3                  ; Calculate spaces/backspaces needed.
       BEQ     ECHX                    ;  None.
       CMP     D3, T.ILS(A5)           ; Insure not greater than terminal width.
       BLOS    10$
       MOV     T.ILS(A5), D3
10$:    MOV     #10, D1                 ; Queue up backspaces.
       TRMBFQ                          ;  Do it.
       MOV     #32., D1                ; Queue up spaces.
       TRMBFQ                          ;  Do it.
       MOV     #10, D1                 ; Queue up backspaces.
       TRMBFQ                          ;  Do it.

; All done. Restore registers and return.
;
ECHX:   REST    D1-D4,D6,D7,A2,A6       ; Restore registers.
       RTN                             ; Return to caller.

       END