; HAZEL terminal driver - built by FIXTRM V2.0a/L
;
;                                 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+001.
FFNULLS=0+002.
KEYBOARD=0+YES
SHIFTED=0+YES
TDVTYPE=0+CRT
ROWS=0+024.
COLUMNS=0+080.
ROW=0+SECOND
OFFSET=0+255.
LEADIN=0+126.
SNOOZE=0+003.
SMART=0+LIN.IN+EOSCRE+EOLINE
FUNCTIONS=0+YES
FLEADIN=0+126.
DELAYCOUNT=0+400.
FDISCARD=0

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

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


       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


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:

; Special functions.
C0:     BYTE    126.,156.,0     ; clear screen
C1:     BYTE    126.,018.,0     ; cursor home
C2:     BYTE    <'M-100>!200,0          ; Cursor return
C3:     BYTE    126.,012.,0     ; cursor up
C4:     BYTE    126.,011.,0     ; cursor down
C5:     BYTE    008.,0  ; cursor left
C6:     BYTE    016.,0  ; cursor right
C7:     BYTE    126.,021.,0     ; lock keyboard
C8:     BYTE    126.,006.,0     ; unlock keyboard
C9:     BYTE    126.,015.,0     ; erase to end of line
C10:    BYTE    126.,152.,0     ; erase to end of screen
C11:    BYTE    126.,025.,0     ; protect field (dim mode)
C12:    BYTE    126.,031.,0     ; unprotect field (normal mode)
C13:    BYTE            0               ; enable protection of fields
C14:    BYTE            0               ; disable protection of fields
C15:    BYTE    126.,019.,0     ; delete line
C16:    BYTE    126.,026.,0     ; insert line
C17:    BYTE            0               ; delete char
C18:    BYTE            0               ; insert char
C19:    BYTE    126.,133.,0     ; read cursor address
C20:    BYTE            0               ; read char at cursor address
C21:    BYTE            0               ; start blinking field
C22:    BYTE            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            0               ; turn cursor on
C29:    BYTE            0               ; turn cursor off
; End of Alpha Micro supported functions.

CURPOS: BYTE    126.,145.,0     ; cursor positioning
       BYTE    0                       ; In case driver is built without CURPOS.

; Function key translation table
;
XLAT:
       BYTE    018.,030.
       BYTE    0               ; End of table.
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.
       SUB     #401,D1
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.
       CMP     D1, #CRCB-CRCA          ; Check for valid code
       BHI     TCRTX                   ;  and bypass if bad.
       LEA     A2, CRCA                ; Index the table.
       ADD     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
       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