;**************************************************************************;
;                                                                          ;
;                    ALPHA MICRO AM-62A TERMINAL DRIVER                    ;
;                                                                          ;
;**************************************************************************;
;                                                               ASL-     -00
;                                 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
;
;Edit History:
;[112] January 18, 1996 10:41 AM        Edited by Bob Rubendunst
;       Modified start-up string to initialize a modem to a reasonable
;       state. The assumption is that when the system boots, there is no
;       terminal attached to the port, only a modem, and that terminal
;       initialization strings have been known to make some modems not
;       work properly. This version of the AM62A driver, by sending
;       modem commands to turn off modem echoing, and turn on quiet mode,
;       will prevent problems. This driver also disables terminal
;       echoing until after the final AT sequence is sent to the modem.
;
;       Modified the routine that outputs strings to the terminal/modem
;       to be easier to change without introducing programming errors.
;
;[111] 24 October 1994          Edited by David Canfield
;       Speed up TRMDEF by replacing SLEEP call in INI routine with a TIMER
;       executed routine so we don't put the boot job to sleep.  Also only
;       allow INI routine to display "System booting" message when the system
;       actually IS booting-up.
;[110] September 15, 1994 03:09 PM      Edited by Bob Currier
;       Make sure that status line lengths returned by TRMCHR reflect current
;       80/132 column setting.
;[109] 12 June 1986
;       Fixed SPRs 3000 and 3001; TCRT 129 did not work. /VHS
;[108] 20 March 1986
;       Fixed problem with AlphaWRITE when going from text to menus in
;       wide mode. /VHS
;[107] 8 May 1985
;       Correct my boo-boo in edit 106. /RJH
;[106] 2 May 1985
;       Fixed problem with rubbing out control characters. /RJH
;[105] 7 Jan 1985
;       Fix 132 column problem. Use -32 instead. /RJH
;[104] 7 November 1984
;       Update to conform to new standard: update TRMCHR routine to support
;       new fields and bitmap. /RBC
;[103]  7 Sept 1984
;       Converted from AM6X code
;[102] 24 April 1984
;       Updated to include latest video attribute TCRT calls. /RBC
;[101] 3 January 1983
;       Updated to support revised AM-61.
;[100] 6 May 1983
;       Convert from AM-60.
;
;VEDIT = 111.
;

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       OBJNAM  .TDV

;Define capability flags
;

TDVFLG=TD$LID!TD$CID!TD$RVA!TD$DIM!TD$BLN!TD$UND!TD$EOS!TD$EOL!TD$MLT
TDVFLG=TDVFLG!TD$SPL!TD$STS!TD$AMS!TD$KID!TD$PRT!TD$132
TDVFLG=TDVFLG!TD$SMT!TD$BOX!TD$BLF

;********************
;*       AM62A      *
;********************
;Terminal driver communications area
AM62:   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:  MOVB    (A0)+,D1                ; get the first character
       DECB    D0                      ; no translation if single character
       BEQ     INMX
       CMPB    D1,#1                   ; function sequences start with SOH
       BEQ     INMF                    ;   function sequence -
;Escape sequences are translated directly by setting bit 7 on
;This will cause them to map to 240-377
       MOVB    (A0)+,D1                ; get the second character
INMG:   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

;Function codes require additional translation so that they become 200-237
INMF:   MOVB    (A0)+,D1                ; get the second character
       SUBB    #'@,D1                  ; offset so that F1 becomes 0
       BR      INMG                    ;   and go finish up

;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    314,3                   ; CANCEL = Control-C
       BYTE    302,3                   ; SHIFT + CANCEL = Control-C
       BYTE    274,15                  ; EXECUTE = Return
       BYTE    276,15                  ; SHIFT + EXECUTE = Return
       BYTE    313,'U-100              ; DEL LINE = Control-U
       BYTE    000,000

PAGE
;********************
;*      INI         *
;********************
;Handle initialization of the *MODEM*
INI:    MOV     T.IMP(A5),A6            ; index impure area
       MOVW    #80.,@A6                ; preset to 80 columns
       MOV     T.IDV(A5),A6            ; index the interface driver            [106]
       CMP     -(A6),#<[PSE]_16.>+[UDO]; is it the pseudo interface driver?    [106]
       BEQ     100$                    ;   yes - no modem initialization wanted        [106]
       CMP     QFREE,#12.              ; are there at least 12 queue blocks?   [106]
       BLO     100$                    ;   no - skip the initialization        [106]
       MOV     SYSTEM,D7               ;
       BTST    #SY%UP,D7               ; booting up ?
       BNE     100$                    ;  no - don't init modem
       ORW     #<T$ECS!T$DAT!T$IMI>,@A5; disable echoing, enable image mode
       QGET    A6                      ;
       CLR     (A6)                    ;
       MOV     #10000.,4(A6)           ; use a timer routine to finish
       PEA     TMRCOD                  ; terminal initialization
       POP     8.(A6)                  ;
       MOV     A5,12.(A6)              ; set TDV pointer for interrupt handler
       PEA     INISEQ
       POP     16.(A6)                 ; store address of start up structure
       TIMER   (A6)                    ; start up stuff executes later
                                       ; by timer routine until end of
                                       ; start up structure.
100$:   RTN                             ;

; define INISTR macro to allow any normal M68 expressions to be used to
; define a terminal/modem init string. The TMRCOD routine queues up output
; and then delays for DELAY timer ticks before executing the next term/modem
; init string. When TMRCOD sees that the delay is 0, it dequeues its
; timer block and that concludes the extended init sequence.
DEFINE  INISTR  DELAY,A,B,C
       LWORD   20$$-10$$       ; output count
       LWORD   30$$-10$$       ; offset to next entry
       LWORD   DELAY           ; ticks to next timer
10$$:   A
       B
       C
20$$:   EVEN
30$$:
       ENDM

INISEQ: INISTR  20000.,<BYTE 'X&037,15>,,
       INISTR  20000.,<ASCII /ATZ/>,BYTE 15,
       INISTR  3000.,<ASCII /ATE0Q1/>,BYTE 15,
       INISTR  0,<ASCII /ATE0Q1/>,BYTE 15,


;routine executed each time timer expires until all strings and delays
;complete.
TMRCOD: SAVE    A1,A3,A5,D0,D1
       MOV     (A0)+,A5                ; get port's TCB pointer
       MOV     @A0,A1                  ; get pointer to ini sequence
       SUB     #16.,A0                 ; get queue block base address
       CMP     QFREE,#12.              ; are there at least 12 queue blocks?   [106]
       BLO     20$                     ;   no - abort entire sequence.
       LEA     A3, T.OQX(A5)           ; Index the output queue.
       QINS    A3                      ; Insert a queue block.
       MOV     (A1)+,4(A3)             ; Set output count.                     [103]
       MOV     (A1)+,D0                ; get offset to next entry
       MOV     (A1)+,D1                ; get next timer count
       MOV     A1,10(A3)               ; Set address of output string
       TINIT   @A5                     ; kickstart the transmitter
       TST     D1                      ; do we have another entry?
       BEQ     20$                     ;  no next timer, reclaim timer block
       ADD     D0,A1                   ; update seq ptr to next entry
       CLR     (A0)                    ;
       MOV     D1,4(A0)                ; ticks till next output
       PEA     TMRCOD                  ; terminal initialization
       POP     8.(A0)                  ;
       MOV     A5,12.(A0)              ; set TDV pointer for interrupt handler
       MOV     A1,16.(A0)              ; store address of start up structure
       TIMER   (A0)                    ; start up stuff executes later
       BR      100$

20$:    CLR     T.ICC(A5)
       CLR     T.ECC(A5)
       CLR     T.BCC(A5)               ; flush the input buffers
       ANDW    #^C<T$ECS!T$DAT!T$IMI>,@A5; re-enable normal echoing & line mode
       QRET    A0                      ; and give it back to system
100$:   REST    A1,A3,A5,D0,D1  ; restore regs we used
       RTN                             ; return to the shadows (timer service)
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    @A6,D6                  ; get current width                     [110]
       MOVW    D6,TC.SSL(A1)           ; set length of shifted status line     [104][110]
       MOVW    D6,TC.USL(A1)           ; set length of unshifted status line   [104][110]
       SUBW    #7.,D6                  ; adjust for CAPS/LOCK indicator        [110]
       MOVW    D6,TC.TSL(A1)           ; set length of top status line         [104][110]
       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]

;Define feature bitmap                                                          [104]
TCHBMP: BYTE    ^B11111111              ; 0 - 7
       BYTE    ^B11111111              ; 8 - 15
       BYTE    ^B11111111              ; 16 - 23
       BYTE    ^B11111001              ; 24 - 31    (no horiz or vert pos)
       BYTE    ^B11111111              ; 32 - 39
       BYTE    ^B11111111              ; 40 - 47
       BYTE    ^B11111111              ; 48 - 55
       BYTE    ^B11100011              ; 56 - 63    (no vertical split)
       BYTE    ^B11111111              ; 64 - 71
       BYTE    ^B11111111              ; 72 - 79
       BYTE    ^B00001111              ; 80 - 87    (no alternate page)
       BYTE    ^B11111111              ; 88 - 95
       BYTE    ^B11111111              ; 96 - 103
       BYTE    ^B00000011              ; 104 - 111  (no non-space attributes)
       BYTE    ^B00000000              ; 112 - 119  (no non-space attributes)
       BYTE    ^B00001111              ; 120 - 127  (spare)
       BYTE    ^B00001111              ; 128 - 135  (no AM-70 style color)
       BYTE    ^B00000000              ; 136 - 143
       BYTE    ^B00000000              ; 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
;********************
;*       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 position command
       BYTE    33,'=,0
       EVEN
       PUSH    D2                      ; save off the register.
       MOVB    D1,D2                   ; save the value in D2
       CMPB    D2,#96.                 ; is it beyond column 96?
       BLOS    10$                     ; no...send as is.
       SUBB    #96.-32.,D2             ; yes..get offset past column 96.       [105]
       CLRB    D1                      ; and clear the low byte.
10$:    ADDW    #^H1F1F,D1              ; convert to coded format
       RORW    D1,#8.                  ; send row first
       TTY
       ROLW    D1,#8.                  ; send column second
       TTY
       CMPB    D1,#^H1F                ; is there a third byte to send?
       BNE     20$                     ; no..all done.
       MOVB    D2,D1                   ; yes.. send it then.
       TTY
20$:    POP     D2                      ; restore the register.
       RTN

;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,';,0
       EVEN
CRTZ:   RTN

;Set terminal to wide format
CRTWID: TTYI
       BYTE    33,'`,';,0
       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
       BYTE    33,'`,':,0
       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 sl
eep after we either turn it on or off.
;
PRTON:  TTYI
       BYTE    24,0                    ; Printer port on command.              [103]
       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
       BYTE    30,0                    ; Printer port off command.             [103]
       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

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

PAGE
;CRT code tables
;

C1:     BYTE    30.,0                   ; cursor home (move to column 1,1)
C2:     BYTE    200+13.,0               ; cursor return (move to column 1)
C3:     BYTE    11.,0                   ; cursor up
C4:     BYTE    10.,0                   ; cursor down
C5:     BYTE    8.,0                    ; cursor left
C6:     BYTE    12.,0                   ; cursor right
C7:     BYTE    33,43,0                 ; lock keyboard
C8:     BYTE    33,42,0                 ; unlock keyboard
C9:     BYTE    33,'T,0                 ; erase to end of line
C10:    BYTE    33,'Y,0                 ; erase to end of screen
C11:    BYTE    33,'),0                 ; reduced intensity
C12:    BYTE    33,'(,0                 ; normal intensity
C13:    BYTE    33,'&,33,'N,0           ; enable protected  fields
C14:    BYTE    33,'',33,'O,0           ; disable protected fields
C15:    BYTE    33,'R,0                 ; delete line
C16:    BYTE    33,'E,0                 ; insert line
C17:    BYTE    33,'W,0                 ; delete character
C18:    BYTE    33,'Q,0                 ; insert character
C19:    BYTE    33,'?,0                 ; read cursor address
C20:    BYTE    33,'M,0                 ; read character at current cursor position
C21:    BYTE    33,'G,'2,0              ; start blink field
C22:    BYTE    33,'G,'0,0              ; end blink field
C23:    BYTE    33,'H,176,0             ; start line drawing mode (enable alternate character set)
C24:    BYTE    33,'H,175,0             ; end line drawing mode (disable alternate character set)
C25:                                    ; set horizontal position
C26:    BYTE    0                       ; set vertical position
C27:    BYTE    33,'A,0                 ; set terminal attributes
C28:    BYTE    33,'`,'1,0              ; cursor on
C29:    BYTE    33,'`,'0,0              ; cursor off
C30:    BYTE    33,'G,'8,0              ; start underscore
C31:    BYTE    33,'G,'0,0              ; end underscore
C32:    BYTE    33,'G,'4,0              ; start reverse video
C33:    BYTE    33,'G,'0,0              ; end reverse video
C34:    BYTE    33,'G,'6,0              ; start reverse blink
C35:    BYTE    33,'G,'0,0              ; end reverse blink
C36:    BYTE    33,'b,0                 ; turn off screen display
C37:    BYTE    33,'a,0                 ; turn on screen display
C38:    BYTE    '2,0                    ; top left corner
C39:    BYTE    '3,0                    ; top right corner
C40:    BYTE    '1,0                    ; bottom left corner
C41:    BYTE    '5,0                    ; bottom right corner
C42:    BYTE    '0,0                    ; top intersect
C43:    BYTE    '9,0                    ; right intersect
C44:    BYTE    '4,0                    ; left intersect
C45:    BYTE    '=,0                    ; bottom intersect
C46:    BYTE    ':,0                    ; horizontal line
C47:    BYTE    '6,0                    ; vertical line
C48:    BYTE    '8,0                    ; intersection
C49:    BYTE    '7,0                    ; 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:    BYTE    33,'z,0                 ; send message to function key line
C55:    BYTE    33,'Z,0                 ; send message to shifted function key line
C56:    BYTE    33,'x,'0,0              ; set normal display format
C57:    BYTE    33,'x,'1,0              ; set horizontal split (follow with row code)
C58:                                    ; set vertical split (39 char columns)
C59:                                    ; set vertical split (40 char columns)
C60:    BYTE    0                       ; set vertical split column to next char
C61:    BYTE    33,'],0                 ; activate split segment 0
C62:    BYTE    33,'},0                 ; activate split segment 1
C63:    BYTE    33,'F,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:    BYTE    '',0                    ; dagger
C71:    BYTE    '(,0                    ; section
C72:    BYTE    '),0                    ; cent sign
C73:    BYTE    '*,0                    ; one-quarter
C74:    BYTE    '+,0                    ; one-half
C75:    BYTE    ',,0                    ; degree
C76:    BYTE    '-,0                    ; trademark
C77:    BYTE    '.,0                    ; copyright
C78:    BYTE    '/,0                    ; registered
C79:    BYTE    33,'P,0                 ; 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:    BYTE    0                       ; copy to alternate page
C88:    BYTE    33,'k,0                 ; insert column
C89:    BYTE    33,'j,0                 ; delete column
C90:    BYTE    33,'m,0                 ; block fill with attribute
C91:    BYTE    33,'l,0                 ; block fill with character
C92:    BYTE    33,'^,0                 ; draw a box
C93:    BYTE    33,'_,'U,0              ; scroll box up one line
C94:    BYTE    33,'_,'D,0              ; scroll box down one line
C95:    BYTE    33,'`,'@,0              ; select jump scroll
C96:    BYTE    33,'`,'?,0              ; select fast smooth scroll
C97:    BYTE    33,'`,'>,0              ; select med-fast smooth scroll
C98:    BYTE    33,'`,'=,0              ; select med-slow smooth scroll
C99:    BYTE    33,'`,'<,0              ; select slow smooth scroll
C100:   BYTE    33,'G,':,0              ; start underscore/blink
C101:   BYTE    33,'G,'0,0              ; end underscore/blink
C102:   BYTE    33,'G,'<,0              ; start underscore/reverse
C103:   BYTE    33,'G,'0,0              ; end underscore/reverse
C104:   BYTE    33,'G,'>,0              ; start underscore/reverse/blink
C105:   BYTE    33,'G,'0,0              ; 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/blink w/o space
C117:                                   ; end underscore/reverse/blink w/o space
C118:                                   ; start blink w/o space
C119:   BYTE    0                       ; end blink w/o space
C120:   BYTE    33,'`,'5,0              ; set cursor to blinking block
C121:   BYTE    33,'`,'2,0              ; set cursor to steady block
C122:   BYTE    33,'`,'3,0              ; set cursor to blinking underline
C123:   BYTE    33,'`,'4,0              ; set cursor to steady underline
C124:                                   ;   SPARE
C125:                                   ;   SPARE
C126:                                   ;   SPARE
C127:   BYTE    0                       ;   SPARE
C128:   BYTE    33,'F,'!,0              ; select top status line w/o address
C129:   BYTE    177,0                   ; end status line                       [109]
C130:   BYTE    33,'z,40,0              ; select unshifted status line w/o addr
C131:   BYTE    33,'Z,40,0              ; select shifted status line w/o addr
C132:                                   ; select black text
C133:                                   ; select white text
C134:                                   ; select blue text
C135:                                   ; select magenta text
C136:                                   ; select red text
C137:                                   ; select yellow text
C138:                                   ; select green text
C139:                                   ; select cyan text
C140:                                   ; select black reverse text
C141:                                   ; select white reverse text
C142:                                   ; select blue reverse text
C143:                                   ; select magenta reverse text
C144:                                   ; select red reverse text
C145:                                   ; select yellow reverse text
C146:                                   ; select green reverse text
C147:   BYTE    0                       ; select cyan reverse text

       EVEN

       END