;**************************************************************************;
;                                                                          ;
;                       TELEVIDEO 912 TERMINAL DRIVER                      ;
;                                                                          ;
; This driver was written by Tom Dahlquist for the National Farmer's Union ;
; Insurance Co.  It is compatible with AMOS/L 1.3 and with AlphaBase 4.8.  ;
; Since combinations of attributes are not supported by the 912, I have    ;
; substituted single attributes for them; e.g., if the program attempts to ;
; set reverse/blink I do blink, and so forth.  Occasional screen weirdnesses
; with 4.8 are due to the fact that they still have some ESCape sequences  ;
; hard-coded into it, not due to errors in the driver.                     ;
;                                                                          ;
;**************************************************************************;
;                                                               ASL-02012-00

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       OBJNAM  0,0,[TDV]

DEFINE  CNTRL   CHTER                   ; Control Character Macro
       BYTE    CHTER-^H40,0
       ENDM

DEFINE  LDIN    CHTER                   ; Escape Macro
       BYTE    233,CHTER,0
       ENDM

;Define capability flags
;

TDVFLG=TD$LID!TD$CID!TD$RVA!TD$DIM!TD$BLN!TD$UND!TD$EOS!TD$EOL!TD$MLT

;********************
;*       TVI912     *
;********************
;Terminal driver communications area
TVI912: WORD    TD$NEW!TD$TCH           ; terminal attributes
       BR      JMPINP                  ; input routine                         [102]
       RTN                             ; output routine
       BR      ECHO                    ; echo routine
       BR      JMPCRT                  ; crt control
       RTN                             ; INIT routine
       WORD    4                       ; impure area of one longword.
ROWCNT:
       BYTE    24.                     ; number of rows
COLCNT:
       BYTE    80.                     ; number of columns
       LWORD   TDVFLG                  ; terminal has:
                                       ;   insert/delete line
                                       ;   insert/delete character
                                       ;   reverse video attribute
                                       ;   dim video attribute
                                       ;   blinking video attribute
                                       ;   underlined video attribute
                                       ;   erase to end of screen
                                       ;   erase to end of line
                                       ;   split screen
                                       ;   status line
                                       ;   is an AlphaTERMINAL
                                       ;   line graphics
       BR      JMPTCH                  ; entry for TRMCHR routine
JMPINP: JMP     INP                     ; go handle input                       [102]
JMPCRT: JMP     CRT                     ; go handle TCRT codes
JMPTCH: JMP     TCH                     ; go handle TRMCHR call

;********************
;*       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.?          [103]
       BLO     RBX                     ;   yes -                               [103][104]
;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                             ;                                       [103]

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          ;  CR
       BEQ     KRTC
       CMPB    D1,#33          ;  ALTMODE
       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 THE 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

;********************
;*       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
       MOVB    COLCNT(A2),D6           ; Get column count                      [103]
       MOVW    D6,TC.COL(A1)           ; transfer column count.                [103]
;       MOVW    @A6,TC.COL(A1)          ; transfer column count                 [103]
       CLRW    TC.CLR(A1)              ; no colors
       MOVW    #0,TC.TSL(A1)           ; set length of top status line         [101]
       MOVW    #0,TC.SSL(A1)           ; set length of shifted status line     [101]
       MOVW    #0,TC.USL(A1)           ; set length of unshifted status line   [101]
       MOV     D2,D7                   ; get TRMCHR argument flags             [101]
       AND     #TC$BMP,D7              ; does user want bitmap                 [101]
       BEQ     20$                     ; no - skip transfer code               [101]
; user has requested bitmap -- return to him
       PUSH    A1                      ; save argument block index                     [101]
       ADDW    #TC.BMP,A1              ; index bitmap return area                      [101]
       LEA     A6,TCHBMP               ; index our bitmap                      [101]
       MOV     #<256./16.>-1,D7        ; get amount to transfer                [101]
10$:    MOVW    (A6)+,(A1)+             ; transfer to user
       DBF     D7,10$                  ; loop until done
       POP     A1                      ; restore register
20$:    RTN                             ; return to TRMCHR monitor routine

; Define feature bitmap
TCHBMP: BYTE    ^B11111111              ; 0 - 7
       BYTE    ^B11111111              ; 8 - 15
       BYTE    ^B11110110              ; 16 - 23
       BYTE    ^B00000011              ; 24 - 31       (no horiz or vertical pos)
       BYTE    ^B11110011              ; 32 - 39
       BYTE    ^B11111111              ; 40 - 47
       BYTE    ^B10011100              ; 48 - 55
       BYTE    ^B00000000              ; 56 - 63
       BYTE    ^B11111100              ; 64 - 71
       BYTE    ^B10000000              ; 72 - 79
       BYTE    ^B00000000              ; 80 - 87       (no alternate page )
       BYTE    ^B00000000              ; 88 - 95       (no smooth scroll)
       BYTE    ^B00001111              ; 96 - 103
       BYTE    ^B11000000              ; 104 - 111     (no non-space attributes)
       BYTE    ^B00000000              ; 112 - 119     (no non-space attributes)
       BYTE    ^B00000000              ; 120 - 127     (no cursor blink & steady)
       BYTE    ^B10000000              ; 128 - 135     (no top status line )
       BYTE    ^B00000111              ; 136 - 143     (no AM-70 style color)
       BYTE    ^B11100000              ; 144 - 151
       BYTE    ^B00000000              ; 152 - 159
       BYTE    ^B00000000              ; 160 - 167
       BYTE    ^B00000000              ; 168 - 175
       BYTE    ^B00000000              ; 176 - 183
       BYTE    ^B00000000              ; 184 - 191
       BYTE    ^B00000000              ; 192 - 199
       BYTE    ^B00000000              ; 200 - 207
       BYTE    ^B00000000              ; 208 - 215
       BYTE    ^B00000000              ; 216 - 223
       BYTE    ^B00000000              ; 224 - 231
       BYTE    ^B00000000              ; 232 - 239
       BYTE    ^B00000000              ; 240 - 247
       BYTE    ^B00000000              ; 248 - 255
PAGE

;********************
;       INP         *
;********************
;
;
INP:    BMI     INMLT                   ; skip if multi-byte processing
       ANDB    #177,D1                 ; strip hi byte...
       CMPB    D1,#1                   ; function code?
       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:  MOVB    (A0)+,D1                ; get the first character
       DECB    D0                      ; no translation if single character
       BEQ     INMX
;Function codes require additional translation so that they become 200-237
       MOVB    (A0)+,D1                ; get the second character
       CMPB    D1,#'1                  ; see if in range 1 and above...
       BLO     INMX                    ; if lower, no trans...
       SUBB    #'1,D1                  ; offset so that Func 1 becomes 0
       ORB     #200,D1                 ; set bit 7 on
       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    0,0


PAGE

;********************
;*       CRT        *
;********************
;SPECIAL CRT CONTROL PROCESSING
;D1 CONTAINS THE CONTROL CODE FOR X,T 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
;CURSOR POSITIONING - D1 CONTAINS X,Y COORDINATES
       TTYI                    ;SEND POSITION COMMAND
       BYTE    233,75,0,0
       ADD     #17437,D1       ;ADD POSITION OFFSETS
       ROR     D1,#8.          ;SEND ROW FIRST
       TTY
       ROL     D1,#8.          ;SEND COLUMN SECOND
       TTY
       RTN
;SPECIAL COMMANDS - D1 CONTAINS THE COMMAND CODE IN THE LOW BYTE
CRTS:   AND     #377,D1         ;STRIP THE HIGH BYTE
       BNE     CRTU            ;  AND BRANCH UNLESS CLEAR SCREEN
       TTYI                    ;SPECIAL CASE FOR CLEAR SCREEN
       BYTE    233,52,0
       EVEN
CRTZ:   TTYL    CRTNUL          ; OUTPUT SOME NULLS
       RTN

;COMMAND PROCESSING PER DIRECTOR TABLES
CRTU:   PUSH    A2              ;SAVE A2
       CMP     D1,#CRCB-CRCA   ;CHECK FOR VALID CODE
       BHI     CRTX            ;  AND BYPASS IF BAD
       LEA     A2,CRCA-1       ;INDEX THE TABLE
       ADD     D1,A2           ;ADD COMMAND CODE
       MOVB    @A2,D1          ;PICK UP DATA FIELD OFFSET
       ADD     D1,A2           ;MAKE ABSOLUTE DATA ADDRESS
       TTYL    @A2             ;PRINT THE DATA FIELD
       CMPB    @A2,#36         ;SLEEP IF HOME COMMAND
       BEQ     CRTXZ
       CMPB    1(A2),#100      ;SLEEP IF ERASE COMMAND
       BHI     CRTXZ
CRTX:   POP     A2              ;RESTORE A2
       RTN

CRTXZ:  POP     A2              ;RESTORE A2
       BR      CRTZ            ;  AND GO OUTPUT NULLS

;Null characters for long commands
CRTNUL: BYTE 200,200,200,200,200,200,200,200,200,200,200,0
       EVEN

;BYTE OFFSET AND DATA TABLES FOLLOW FOR ALL COMMANDS
CRCA:   BYTE    C1-.,C2-.,C3-.,C4-.,C5-.,C6-.,C7-.,C8-.
       BYTE    C9-.,C10-.,C11-.,C12-.,C13-.,C14-.
       BYTE    C15-.,C16-.,C17-.,C18-.,C19-.,C20-.
       BYTE    C21-.,C22-.,C23-.,C24-.,C25-.,C26-.,C27-.,C28-.,C29-.,C30-.
       BYTE    C31-.,C32-.,C33-.,C34-.,C35-.
       BYTE    C36-.,C37-.,C38-.,C39-.,C40-.
       BYTE    C41-.,C42-.,C43-.,C44-.,C45-.
       BYTE    C46-.,C47-.,C48-.,C49-.,C50-.
       BYTE    C51-.,C52-.,C53-.,C54-.,C55-.,C56-.,C57-.,C58-.,C59-.,C60-.
       BYTE    C61-.,C62-.,C63-.,C64-.,C65-.,C66-.,C67-.,C68-.,C69-.,C70-.
       BYTE    C71-.,C72-.,C73-.,C74-.,C75-.,C76-.,C77-.,C78-.,C79-.,C80-.
       BYTE    C81-.,C82-.,C83-.,C84-.,C85-.,C86-.,C87-.,C88-.,C89-.,C90-.
       BYTE    C91-.,C92-.,C93-.,C94-.,C95-.,C96-.,C97-.,C98-.,C99-.,C100-.
       BYTE    C101-.,C102-.,C103-.,C104-.,C105-.,C106-.,C107-.,C108-.,C109-.,C110-.
       BYTE    C111-.,C112-.,C113-.,C114-.,C115-.,C116-.,C117-.,C118-.,C119-.,C120-.
       BYTE    C121-.,C122-.,C123-.,C124-.,C125-.,C126-.,C127-.,C128-.,C129-.,C130-.
       BYTE    C131-.,C132-.,C133-.,C134-.,C135-.,C136-.,C137-.,C138-.,C139-.,C140-.
       BYTE    C141-.,C142-.,C143-.,C144-.,C145-.,C146-.,C147-.
CRCB:

C1:     CNTRL   '^                      ; Cursor Home (move to column 1,1)
C2:     CNTRL   'M+200                  ; Cursor Return (move to column 1)
C3:     CNTRL   'K                      ; Cursor Up
C4:     CNTRL   'J                      ; Cursor Down
C5:     CNTRL   'H                      ; Cursor Left
C6:     CNTRL   'L                      ; Cursor Right
C7:     LDIN    '#                      ; Lock Keyboard
C8:     LDIN    '"                      ; Unlock Keyboard
C9:     LDIN    'T                      ; Erase to End of Line
C10:    LDIN    'Y                      ; Erase to End of Screen
C11:    LDIN    ')                      ; Enter Background Display Mode (reduced intensity)
C12:    LDIN    '(                      ; Enter Foreground Display mode (normal intensity)
C13:    LDIN    '&                      ; Enable Protected  fields
C14:    LDIN    ''                      ; Disable Protected Fields
C15:    LDIN    'R                      ; Delete Line
C16:    LDIN    'E                      ; Insert Line
C17:    LDIN    'W                      ; Delete Character
C18:    LDIN    'Q                      ; Insert Character
C19:    LDIN    '?                      ; Read Cursor Address
C20:    BYTE    0                       ; Read Character at Current Cursor Position
C21:    LDIN    '^                      ; Start Blinking Field
C22:    LDIN    'q                      ; End Blinking Field
C23:                                    ; start line drawing mode (enable alternate character set)
C24:                                    ; end line drawing mode (disable alternate character set)
C25:                                    ; set horizontal position
C26:                                    ; set vertical position
C27:                                    ; set terminal attributes
C28:                                    ; cursor on
C29:    BYTE    0                       ; cursor off
C30:    LDIN    'l                      ; start underscore
C31:    LDIN    'm                      ; end underscore
C32:    LDIN    'j                      ; start reverse video
C33:    LDIN    'k                      ; end reverse video
C34:    LDIN    'j                      ; start reverse blink
C35:    LDIN    'k                      ; end reverse blink
C36:                                    ; turn off screen display
C37:    BYTE    0                       ; turn on screen display
C38:    BYTE    '+,0                    ; top left corner
C39:    BYTE    '+,0                    ; top right corner
C40:    BYTE    '+,0                    ; bottom left corner
C41:    BYTE    '+,0                    ; bottom right corner
C42:    BYTE    '-,0                    ; top intersect
C43:    BYTE    '|,0                    ; right intersect
C44:    BYTE    '|,0                    ; left intersect
C45:    BYTE    '-,0                    ; bottom intersect
C46:    BYTE    '-,0                    ; horizontal line
C47:    BYTE    '|,0                    ; vertical line
C48:    BYTE    '+,0                    ; intersection
C49:                                    ; solid block
C50:    BYTE    0                       ; slant block
C51:    BYTE    '#,0                    ; cross-hatch block
C52:    BYTE    '=,0                    ; double line horizontal
C53:    BYTE    '|,0                    ; double line vertical
C54:                                    ; send message to function key line
C55:                                    ; send message to shifted function key line
C56:                                    ; set normal display format
C57:                                    ; set horizontal split (follow with row code)
C58:                                    ; set vertical split (39 char columns)
C59:                                    ; set vertical split (40 char columns)
C60:                                    ; set vertical split column to next char
C61:                                    ; activate split segment 0
C62:                                    ; activate split segment 1
C63:    BYTE    0                       ; send message to host message field
C64:    BYTE    '^,0                    ; up-arrow
C65:    BYTE    '!,0                    ; down-arrow
C66:    BYTE    ' ,0                    ; raised dot
C67:    BYTE    '~,0                    ; end of line marker
C68:    BYTE    '\,0                    ; horizontal tab symbol
C69:    BYTE    '&,0                    ; paragraph
C70:                                    ; dagger
C71:    BYTE    ' ,0                    ; section
C72:    BYTE    'c,0                    ; cent sign
C73:                                    ; one-quarter
C74:                                    ; one-half
C75:                                    ; degree
C76:                                    ; trademark
C77:                                    ; copyright
C78:    BYTE    ' ,0                    ; registered
C79:                                    ; print screen
C80:                                    ; reserved for set to wide mode
C81:                                    ; reserved for set to normal mode
C82:                                    ; enter transparent print mode
C83:                                    ; exit transparent print mode
C84:                                    ; begin writing to alternate page
C85:                                    ; end writing to alternate page
C86:                                    ; toggle page
C87:                                    ; copy to alternate page
C88:                                    ; insert column
C89:                                    ; delete column
C90:                                    ; block fill with attribute
C91:                                    ; block fill with character
C92:                                    ; draw a box
C93:                                    ; scroll box up one line
C94:                                    ; scroll box down one line
C95:                                    ; select jump scroll
C96:                                    ; select fast smooth scroll
C97:                                    ; select med-fast smooth scroll
C98:                                    ; select med-slow smooth scroll
C99:    BYTE    0                       ; select slow smooth scroll
C100:   LDIN    'l                      ; start underscore/blink
C101:   LDIN    'm                      ; end underscore/blink
C102:   LDIN    'j                      ; start underscore/reverse
C103:   LDIN    'k                      ; end underscore/reverse
C104:   LDIN    'j                      ; start underscore/reverse/blink
C105:   LDIN    'k                      ; end underscore/reverse/blink
C106:                                   ; start underscore w/o space
C107:                                   ; end underscore w/o space
C108:                                   ; start reverse w/o space
C109:                                   ; end reverse w/o space
C110:                                   ; start reverse/blinking w/o space
C111:                                   ; end reverse/blinking w/o space
C112:                                   ; start underscore/blinking w/o space
C113:                                   ; end underscore/blinking w/o space
C114:                                   ; start underscore/reverse w/o space
C115:                                   ; end underscore/reverse w/o space
C116:                                   ; start underscore/reverse/blinking w/o space
C117:                                   ; end underscore/reverse/blinking w/o space
C118:                                   ; start blink w/o space
C119:                                   ; end blink w/o space
C120:                                   ; set cursor to blinking block
C121:                                   ; set cursor to steady block
C122:                                   ; set cursor to blinking underline
C123:                                   ; set cursor to steady underline
C124:                                   ; spare
C125:                                   ; spare
C126:                                   ; spare
C127:   BYTE    0                       ; spare
C128:   BYTE    33,'=,'7,'              ; select top status line
C129:                                   ; end of all status line
C130:                                   ; select unshifted status line
C131:                                   ; select shifted status line
C132:                                   ; select black text
C133:                                   ; select white text
C134:                                   ; select blue text
C135:                                   ; select mag
neta text
C136:                                   ; select red text
C137:                                   ; select yellow text
C138:                                   ; select green text
C139:                                   ; select cyan text
C140:   BYTE    0                       ; select black reverse text
; AlphaBase uses the following CRT calls (as of 4.8) instead of the ones
; which are defined as standard.
C141:   LDIN    'j                      ; select white reverse text
C142:   LDIN    'k                      ; select blue reverse text
C143:   LDIN    'j                      ; select magneta reverse text
C144:   LDIN    'k                      ; select red reverse text
C145:   LDIN    'l                      ; select yellow reverse text
C146:   LDIN    'm                      ; select green reverse text
C147:   BYTE    0                       ; select cyan reverse text
       EVEN
       WORD    0
       END