home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / mszibm.asm < prev    next >
Assembly Source File  |  2020-01-01  |  375KB  |  11,805 lines

  1.     NAME    mszibm
  2. ; File MSZIBM.ASM
  3.     include mssdef.h
  4. ;    Copyright (C) 1982, 1997, Trustees of Columbia University in the 
  5. ;    City of New York.  The MS-DOS Kermit software may not be, in whole 
  6. ;    or in part, licensed or sold for profit as a software product itself,
  7. ;    nor may it be included in or distributed with commercial products
  8. ;    or otherwise distributed by commercial concerns to their clients 
  9. ;    or customers without written permission of the Office of Kermit 
  10. ;    Development and Distribution, Columbia University.  This copyright 
  11. ;    notice must not be removed, altered, or obscured.
  12. ;
  13. ; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
  14. ; VT52, VT102, and VT320, Honeywell VIP7809, Prime PT200, DG D463 and D470,
  15. ; and Wyse-50. 
  16. ; Original version for VT100 done by James Harvey, Indiana Purdue Univ, for 
  17. ; MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ for 
  18. ; MS Kermit 2.29 et seq.
  19. ; Edit history
  20. ; 12 Jan 1995 version 3.14
  21. ; Last edit
  22. ; 12 Jan 1995
  23.  
  24.     public    anstty, ansini, ansrei, ansdsl, anskbi ; Entry points
  25.     public    ans52t, vsinit, tabset, tabclr, tekflg
  26.     public    mar_top, mar_bot, anspflg, scroll, cursor, curattr
  27.     public    dnparam, dparam, dlparam, dninter, dinter, emubufc, emubuf
  28.     public    emubufl, dcsstrf, upss, att_normal
  29.     public    GRptr, G0set, G1set, G2set, G3set
  30.     public    savezlen, savezoff, blinkdis, protectena, dghscrdis
  31.     public    linescroll, xltkey, dgkbl, dgwindcomp, atctype, dgcross
  32.     public    dgnctoggle, apcstring, dgd470mode, chrdef
  33.  
  34. public modeset, setptr, atrsm10, mkascii, mkaltrom, chrsetup
  35. ;
  36. ; DEC and VT are trademarks of Digital Equipment Corporation.
  37. ;
  38. ; Description of the global entry points and calls on external routines
  39. ; needed by this emulator.
  40. ;
  41. ; vsinit - start up routine called as Kermit initializes. Takes no arguments.
  42. ;       Sets up address pointers to tabs, reads default terminal parameters
  43. ;       reads current screen coloring. Examines and updates structure
  44. ;       "vtemu." which is how mssset communicates changed information
  45. ;       about many Set Term parameters; "flags." is a Kermit structure
  46. ;       carrying the other Set Term parameters.
  47. ; anstty - starting point for displaying a character, delivered in AL.
  48. ;       Returns when the display operation is completed and that may
  49. ;       take many many instructions. All normal "characters received by
  50. ;       the terminal" are provided by calling anstty with the char in AL.
  51. ; ansini - entry point to initialize the emulator. It requires information
  52. ;       from msy in four registers: the Kermit terminal routine flags
  53. ;       "yflags" (used mainly to sense debug mode and the mode line toggle)
  54. ;       "low_rgt" (bh = row, bl = column of the lower right display corner)
  55. ;       "lbaudtab" (index into baud rate table, for status reporting)
  56. ;       "lpartab" (index into parity table, for status reporting)
  57. ;       Ansini causes a full reset of the emulator, including screen 
  58. ;       clearing and a beep. Ansini is also called by msy in response to
  59. ;       sensing the Alt = key combination to fully reset the emulator.
  60. ; ansrei - entry point to reinitialize the emulator. Nearly the same as
  61. ;       ansini except operating flags, tabs, etc are retained from the
  62. ;       previous emulator session. Items which can be changed by Set Term
  63. ;       are examined and updated. The msy flags "yflags" are needed.
  64. ;       This is the warm-restart entry point used when connect mode
  65. ;       is reentered gracefully. The screen is cleared only if the coloring
  66. ;       has changed. The starting cursor location is whereever msy puts it.
  67. ; ansdsl - display "led" (status line) information. Invoked by msy when
  68. ;       the mode line is constructed so the emulator can write the 
  69. ;       terminal type and the VT100 led status lights when Connect mode
  70. ;       is started. Requires "yflags" from msy to sense whether the mode
  71. ;       line is to be shown.
  72. ; anskbi - a routine called by msy to notify the emulator that a character
  73. ;       is available from the keyboard. No character is read, just flag
  74. ;       ttkbi is set. This is actually used only to beep when the cursor
  75. ;       goes beyond column 72 and the margin bell flag is on.
  76. ; ans52t - called by msy to change terminal types "on the fly" without
  77. ;       fully updating all operating parameters and without losing setup
  78. ;       information. Msy senses the Alt minus key and calls ans52t with
  79. ;       no arguments. Ans52t cycles among terminal types.
  80. ; other modules in msy are called by this file to handle screen scrolling
  81. ;       mode line on/off, output to the serial port (reports), screen
  82. ;       particulars (location, cursor shape, blanking). The list is
  83. ;       the set of code extrn procedures below; all are in file msy.
  84. ;
  85. ; data exchange is directly with msy to assist in scrolling (varaibles
  86. ;       "mar_top", "mar_bot") and in sensing the non-connect
  87. ;       mode screen coloring ("scbattr"). Screen coloring controlled by
  88. ;       the emulator is not permitted to influence the non-connect mode
  89. ;       screens whereas the emulator attempts to use the regular Kermit
  90. ;       screen colors as defaults. The kind of terminal to emulate is
  91. ;       held in word "flags.vtflg" which is set by Set Term and by this
  92. ;       module for global information within Kermit.
  93. ;
  94. ; Many things have been added or modified since James Harvey donated this
  95. ;       code to Columbia University for use in Kermit.              [jrd]
  96. ; Character sets in VT320 and VT102 modes:
  97. ;  ASCII ("B"/94)
  98. ;  ISO Latin-1 ("A"/96)
  99. ;  DEC UK-ASCII ("A"/94, available only in VT102 mode)
  100. ;  DEC Supplemental Graphics ("%5"/94),
  101. ;  DEC Technical Graphics (">"/94), an extension taken from the VT340,
  102. ;  DEC Special Graphics ("0"/94 and "2"/94)
  103. ;  ALT-ROM (Kermit specific, "1"/94/96)
  104. ;  DEC National Replacement Chars (all 12 sets)
  105. ;  Startup:
  106. ;   GL = G0 = G1 = ASCII (or ALT-ROM if selected by SET TERM CHAR ALT-ROM),
  107. ;   GR = G2 = G3 = ISO Latin-1.
  108. ;   When an NRC is selected by SET TERM CHAR <country> and enabled by
  109. ;   CSI ? 42 h the NRC table replaces G0..G3 at the time of selection. When
  110. ;   thus designated and selected incoming characters are forced to 7 bits and
  111. ;   8-bit Controls (outgoing) is turned off. No designation means no selection.
  112. ;  Selecting a character set with the wrong sized designator yields no action.
  113. ;
  114. ;  Startup in D463/D470 mode:
  115. ;   GL = G0 = ASCII
  116. ;   GR = G1 = Data General International if using 8-bit characters, else
  117. ;   GR = G1 = Data General Word Processing.
  118. ;
  119. ; References:
  120. ;  "PT200 Programmers Reference Guide", 1984, Prime Computer # DOC 8621-001P
  121. ;  "Video Terminal Model H19, Operation", 1979, Heath Company # 595-2284-05
  122. ;  "VT100 User's Guide", 2nd ed., Jan 1979, DEC # EK-VT100-UG
  123. ;  "Rainbow 100+/100B Terminal Emulation Manual", June 1984, DEC # QV069-GZ
  124. ;  "Installing and Using The VT320 Video Terminal", June 1987,
  125. ;    DEC # EK-VT320-UU-001
  126. ;  "VT320 Programmer Reference Manual", July 1987, DEC # EK-VT320-RM-001
  127. ;  "VT330/340 Programmer Ref Manual", 2nd ed, May 1988,
  128. ;    Vol 1: Text programming DEC # EK-VT3XX-TP-002
  129. ;    Vol 2: Graphics programming DEC # EK-VT3XX-GP-002
  130. ;  "Programming the Display Terminal: Models D217, D413, and D463", Data
  131. ;    General Corp, 014-00211-00, 1991.
  132. ;  "Installing and Operating Your D216E+, D217, D413, and D463 Display
  133. ;    Terminals", Data General Corp, 014-002057-01, 1991.
  134. ;  "Dasher D470C Color Display Terminal, Programmer's Reference Manual",
  135. ;    Data General Corp, 014-001015, 1984.
  136. ;  "WY-50 Display Terminal Quick-Reference Guide", Wyse Technology,
  137. ;    Wyse No. 88-021-01, 1983.
  138. ; ---------------------------------------------------------------------------
  139.  
  140. vswidth    equ    207            ; cross correlate with msyibm
  141. swidth  equ     207            ; assumed max screen width
  142. slen    equ    60            ; assumed max screen length 
  143. maxparam equ    10            ; number of ESC and DCS Parameters
  144. maxinter equ    10            ; number of ESC and DCS Intermediates
  145. gsize    equ    128            ; character set storage size
  146.                     ; anspflg bit field definitions:
  147. ; prtscr equ    1            ; used in msyibm print screen toggle
  148. vtautop    equ    1            ; autoprint enabled (1)
  149. vtcntp    equ    2            ; controller print enabled (1)
  150. vtextp    equ    4            ; printer extent set (1)
  151. vtffp    equ    10h            ; form feed wanted at end of print (1)
  152.  
  153. h19l25    equ    1            ; h19stat, line 25 enabled
  154. h19alf    equ    2            ; h19stat, auto cr/lf when cr seen
  155.                     ; display save-info for dspstate
  156. dsptype    equ    1            ; main (0) or status line (1) flag
  157. dspdecom equ    2            ; remembered origin mode (1=on)
  158.  
  159. att_bold    equ    08h        ; bold        in main video word
  160. att_blink    equ    80h        ; blinking    in main video word
  161. att_protect    equ    01h        ; protected    in vsatt
  162. att_uline    equ    02h        ; underscored    in vsatt
  163. att_rev        equ    04h        ; reversed video  in vsatt
  164. ;softfonts    are    top 5 bits of extended attributes
  165.  
  166. braceop    equ    7bh            ; opening curly brace
  167. bracecl    equ    7dh            ; closing curly brace
  168.  
  169. ; DEC emulator status flags (bits in words vtemu.vtflgst and vtemu.vtflgop)
  170. ;anslnm  equ    1H            ; ANSI line feed/new line mode
  171. ;decawm  equ    2H            ; DEC autowrap mode
  172. ;decscnm equ    80H            ; DEC screen mode
  173. ;decckm  equ    200H            ; DEC cursor keys mode
  174. ;deckpam equ    400H            ; DEC keypad application mode
  175. ;decom   equ    800H            ; DEC origin mode
  176. ;deccol     equ    1000H            ; DEC column mode (0=80 col)
  177. ;decanm  equ    2000H            ; ANSI mode
  178. ;;dececho equ    4000H            ; ANSI local echo on (1 = on)
  179.      
  180. ; Terminal SETUP mode flags (joint with bits above, some name dups)
  181. ;vsnewline    equ    1H        ; ANSI new line (0 = off)
  182. ;vswrap        equ    2H        ; Line wrap around (0 = no wrap)
  183. ;vsnrcm        equ    4H        ; National Rep Char set (0=none)
  184. ;vswdir        equ    8H        ; Writing direction (0=left, 1 right)
  185. ;vskeyclick    equ    10H        ; Keyclick (0 = off)
  186. ;vsmarginbell    equ    20H        ; Margin bell (0 = off)
  187. ;vscursor    equ    40H        ; Cursor (0 = block, 1 = underline)
  188. ;vsscreen    equ    80H        ; Screen (0 = normal, 1 = rev. video)
  189. ;vscntl        equ    100h        ; 8 or 7 bit controls (1 = 8-bit)
  190. ;vshscroll    equ    4000h        ; horiz scroll (0=auto, 1=manual)
  191. ;vscompress    equ    8000h        ; compressed text(0=graphics,1=132col)
  192.  
  193. ;vsdefaults    equ    0+vscursor
  194.  
  195. ; Kinds of terminals available
  196. ;ttgenrc    equ    0        ; no emulation done by Kermit
  197. ;ttheath    equ    1        ; Heath-19
  198. ;ttvt52        equ    2        ; VT52
  199. ;ttvt100    equ    4        ; VT100
  200. ;ttvt102    equ    8        ; VT102
  201. ;ttvt220    equ    10h        ; VT220
  202. ;ttvt320    equ    20h        ; VT320
  203. ;tttek        equ    40h        ; Tektronix 4010
  204. ;tthoney    equ    80h        ; Honeywell VIP7809
  205. ;ttpt200    equ    100h        ; Prime PT200
  206. ;ttd463        equ    200h        ; Data General D463
  207. ;ttd470        equ    400h        ; Data General D440
  208. ;ttwyse        equ    800h        ; Wyse-50
  209. ;ttd217        equ    1000h        ; Data General D217 (D463 w/217 ident)
  210. ;ttansi        equ    2000h        ; Ansi.sys flavor (VT100 base)
  211. ;TTTYPES    equ    15        ; Number of terminal types defined
  212. ;; tekflg bits in byte
  213. ;tek_active equ    1            ; actively in graphics mode
  214. ;tek_tek equ    2            ; Tek terminal
  215. ;tek_dec equ    4            ; Tek submode of DEC terminals
  216. ;tek_sg    equ    8            ; special graphics mode
  217.  
  218. ;emulst    struc        ; structure of vtemu.xxx for VTxxx emulator
  219. ;vtflgst dw    0    ; DEC setup flags (from SET)
  220. ;vtflgop dw    0    ; DEC runtime flags, like setup flags (here & STAT)
  221. ;vttbs    dw    0    ; pointer to default tab stops, for SET
  222. ;vttbst    dw    0    ; pointer to active tab stops, for STATUS
  223. ;vtchset db    1    ; value of default character set (1=US-ascii)
  224. ;att_ptr dw    0    ; pointer to normal & reverse video attributes
  225. ;emulst    ends
  226. ;;;;;;;;;;;;;;;;  end references ;;;;;;;;;;;;;;;;;;;;
  227.  
  228. data    segment
  229.     extrn    vtemu:byte, scbattr:byte, flags:byte, yflags:byte
  230.     extrn    crt_lins:byte, rxtable:byte, denyflg:word, low_rgt:word
  231.     extrn    vtclear:byte, dosnum:word, apcenable:byte, trans:byte
  232.     extrn    parstate:word, pardone:word, parfail:word, nparam:word
  233.     extrn    param:word, lparam:byte, ninter:word, inter:byte, ttyact:byte
  234.     extrn    L1cp437:byte, L1cp850:byte, L1cp860:byte, L1cp863:byte
  235.     extrn    L1cp865:byte, L5cp866:byte, modbuf:byte, extattr:byte
  236.     extrn    rdbuf:byte
  237.     extrn    vtenqenable:byte, vtcpage:word, prnhand:word,reset_color:byte
  238.     extrn    vtclrflg:byte, enqbuf:byte, crdisp_mode:byte
  239.     extrn    isps55:byte        ; [HF]940130 Japanese PS/55 mode
  240.     extrn    ps55mod:byte        ; [HF]940206 PS/55 modeline status
  241. ifndef    no_graphics
  242.     extern    softptr:word, chcontrol:byte
  243. endif    ; no_graphics
  244.  
  245.     even                    ; C0 7-bit control code table
  246. ansc0    dw    5 dup (atign)            ; NUL, SOH, STX, ETX, EOT
  247.     dw    atenq,atign,vtbell,atbs,atht     ; ENQ, ACK, BEL, BS,  HT
  248.     dw    atlf, atlf, atff, atcr,atls1    ; LF,  VT,  FF,  CR,  SO
  249.     dw    atls0, 4 dup (atign)        ; SI,  DLE, DC1, DC2, DC3
  250.     dw    4 dup (atign), atcan        ; DC4, NAK, SYN, ETB, CAN
  251.     dw    atign, atnrm, atesc,atign,atign    ; EM,  SUB, ESC, FS,  GS
  252.     dw    2 dup (atign)            ; RS,  US
  253.  
  254.                         ; C1 8-bit control code table
  255. ansc1    dw    4 dup (atign), atind        ; ignore 4, IND
  256.     dw    atnel,atign,atign,athts,atign    ; NEL, SSA, ESA, HTS, HTJ
  257.     dw    atign,atign,atign,atri, atss2    ; VTS, PLD, PLU, RI,  SS2
  258.     dw    atss3,atdcs,3 dup (atign)    ; SS3, DCS, PU1, PU2, STS
  259.     dw    atign,atign,protena,protdis,atign ; CCH, MW, SPA, EPA,ignore
  260.     dw    atign,atign,atcsi,atgotst,atdcsnul; ignore 2, CSI, ST, OSC
  261.     dw    atdcsnul, atapc            ; PM,  APC
  262.  
  263. ; Heath-19 mode escape follower table
  264. h19esc    db    36            ; number of entries
  265.     dw    h19ejt            ; address of action routines
  266.     db    '<=>@A','BCDEF','GHIJK','LMNOY','Z[bjk','lnopq','rvwxy','z'
  267.  
  268. ; Dispatch table for Heath-19 escape sequence table h19esc
  269.     even
  270. h19ejt    dw    h19sans, atkpam,  atkpnm,  entins,  atcuu    ; '<=>@A'
  271.     dw    atcud,   atcuf,   atcub,   h19clrs, v52sgm    ; 'BCDEF'
  272.     dw    chrdef,  atcup,   atri0,   ated,    atel    ; 'GHIJK'
  273.     dw    inslin,  dellin,  atdelc,  noins,   v52pos    ; 'LMNOY'
  274.     dw    decid,   h19csi,  h19esos, h19sc,   h19rc    ; 'Z[bjk'
  275.     dw    h19erl,  hrcup,   h19ero,  h19herv, h19hxrv    ; 'lnopq'
  276.     dw    atnorm,  h19wrap, h19nowrp,h19smod, h19cmod    ; 'rvwxy'
  277.     dw    atxreset                    ; 'z'
  278.  
  279. h19ans    db    21            ; Heath-19 ANSI style escape sequences
  280.     dw    h19jmp            ; address of action routine table
  281.     db    'ABCDH','JKLMP','fhlmn','pqrsu','z'
  282.  
  283. ; Heath-19 action table for h19ans
  284.     even
  285. h19jmp    dw    atcuu, atcud, atcuf,  atcub,  atcup        ; 'ABCDH'
  286.     dw    h19ed, atel,  inslin, dellin, atdelc        ; 'JKLMP'
  287.     dw    atcup, atsm,  atrm,   atsgr,  rpcup        ; 'fhlmn'
  288.     dw    atign, atign, atign,  h19sc,  h19rc        ; 'pqrsu'
  289.     dw    atxreset                    ; 'z'
  290.  
  291. ; VT52 compatibility mode escape follower table
  292. v52esc    db    23            ; number of entries
  293.     dw    v52ejt            ; address of action routines
  294.     db    '78<=>', 'ABCDF', 'GHIJK', 'VWXYZ'
  295.     db    ']',5eh,5fh        ; 5eh = caret, 5fh = underscore
  296.  
  297. ; Dispatch for v52esc table
  298.     even
  299. v52ejt    dw    atsc,   atrc,   v52ans, atkpam, atkpnm        ; '78<=>'
  300.     dw    atcuu,  atcud,  atcuf,  atcub,  v52sgm        ; 'ABCDF'
  301.     dw    chrdef, atcup,  atri0,  ated,   atel        ; 'GHIJK'
  302.     dw    v52pl,  v52pcb, v52pce, v52pos, decid        ; 'VWXYZ'
  303.     dw    v52ps,  v52pcb, v52pce                ; ']^_'
  304.  
  305. ; Prime PT200 escape follower table
  306. pt200esc db    38            ; number of entries
  307.     dw    p20ejt            ; address of action routines
  308.     db    '01234','5678<', '=>?AB', 'DEFGH', 'JMNOP'
  309.     db    'Z[\]',5eh        ; 5eh = caret
  310.     db    5fh,'cno',7bh        ; 5fh=underscore, 7bh=left curly brace
  311.     db    7ch,7dh,7eh   ; 7ch=vert bar, 7dh=right curly brace, 7eh=tilde
  312.  
  313. ; Dispatch for p20esc
  314.     even
  315. p20ejt    dw    atdgf0, atdgf1, atdgf0, atsdhl, atsdhl         ; '01234'
  316.     dw    4 dup (atsdhl), atdgfu                ; '5678<'
  317.     dw    atkpam, atnorm, p20ed, atdgfA, atdgfB         ; '=>?AB'
  318.     dw    atind,  atnel,  ats7c, ats8c,  athts        ; 'DEFGH'
  319.     dw    ated,   atri,   atss2, atss3,  atdcs        ; 'JMNOP'
  320.     dw    decid,  atcsi,  atgotst, 2 dup(atdcsnul)    ; 'Z[\]^'
  321.     dw    atdcsnul, atxreset,atls2, atls3, atpriv        ; '_cno{'
  322.     dw    atls3r, atls2r, atls1r                ; '|}~'
  323.  
  324. ; VT320/VT102/VT100/Honewell ANSI mode escape follower table
  325. ansesc    db    52            ; number of entries
  326.     dw    ansejt            ; address of action routines
  327.     db    '01234','56789','<=>?@'
  328.     db    'ABCDE','FGHIJ','KLMN','OPQRV'
  329.     db    'WYZ[\',']',5eh,5fh    ; 5eh = caret, 5fh=underscore
  330.     db    60h,'c','fgno',7bh    ; 7bh=left curly brace,  7ch=vert bar
  331.     db    7ch,7dh,7eh        ; 7dh=right curly brace, 7eh=tilde
  332.  
  333. ; Dispatch for ansesc table
  334.     even
  335. ansejt    dw    atdgf0, atdgf1, atdgf0, atsdhl, atsdhl         ; '01234'
  336.     dw    4 dup (atsdhl), atdgnrc                ; '56789'
  337.     dw    atdgfu,atkpam, atdgft, atdgfq, atdgfB        ; '<=>?@'
  338.     dw    atdgfA,atdgfB, atdgnrc, atind0, atnel0         ; 'ABCDE'
  339.     dw    ats7c, ats8c, athts0, atdgfI, atdgfJ        ; 'FGHIJ'
  340.     dw    atdgnrc,atdgnrc,atri0, atss2            ; 'KLMN'
  341.     dw    atss3, atdcs0, atdgnrc, atdgnrc, dgpton        ; 'OPQRV'
  342.     dw    dgptoff, decid, atdgnrc, atcsi0, atgotst0    ; 'WYZ[\'
  343.     dw    2 dup (atdcsnul0),atapc, athoncls, atxreset    ; ']^_`c'
  344.     dw    atdgnrc,atdgnrc,atls2,atls3, atpriv        ; 'fgno{'
  345.     dw    atls3r, atls2r, atls1r                ; '|}~'
  346.  
  347. ; Final char table for VT320/VT102/VT100/Honeywell ANSI control sequences
  348. anstab    db    40            ; number of entries
  349.     dw    ansjmp            ; address of action routines
  350.     db    '@ABCD','EFGHI','JKLMP', 'Xacde','fghil','mnpqr','uwxyz'
  351.     db    7ch,7dh,7eh        ; 7dh=right curly brace, 7eh=tilde
  352.     db    'su'
  353.  
  354. ; Dispatch for anstab table
  355.     even
  356. ansjmp    dw    ansich, atcuu,  atcud,  atcuf,  atcub        ; '@ABCD'
  357.     dw    atcnl,  atcpl,  atcha,  atcup,  atcht        ; 'EFGHI'
  358.     dw    ated,   atel,   inslin, dellin, atdelc        ; 'JKLMP'
  359.     dw    atech,  atcuf,  atda,   atcva,    atcud          ; 'Xacde'
  360.     dw    atcup,  attbc,  atsm,   ansprt, atrm        ; 'fghil'
  361.     dw    atsgr,  atdsr,  decscl, decsca, atstbm        ; 'mnpqr'
  362.     dw    atrqtsr,atrqpsr,atreqt, atctst, atxreset    ; 'uwxyz'
  363.     dw    atscpp, atsasd, atssdt                ; '|}~'
  364.     dw    atsc                        ; 's'
  365.  
  366. ; Final character table for Device Control Strings (DCS, ESC P)
  367. dcstab    db    5            ; number of entries
  368.     dw    dcsjmp            ; address of action routines
  369.     db    'pqu',7bh,7ch        ; 7bh = left curly brace
  370.  
  371. ; Dispatch for dcstab table
  372.     even
  373. dcsjmp    dw    atcrqq, atcrq, atupss, atdcsnul, atudk        ; 'pqu{|'
  374. ;;; DCS Ps $ p string ST   page 209 restore color palette
  375.  
  376. ; Data General D463/D470 terminal section
  377. dgescape equ    1eh                ; DG escape char (RS)
  378.  
  379.     even                ; DG C0 7-bit control code table
  380. dgc0    dw    atign,dgprtfm,dgrevidoff,dgblkena,dgblkdis;NUL,SOH,STX,ETX,EOT
  381.     dw    dgrwa,atign,vtbell,dgwinhome,atign  ; ENQ, ACK, BEL, BS,  HT
  382.     dw    dglf, dgeol, dgewin, dgcr,dgblkon   ; LF,  VT,  FF,  CR,  SO
  383.     dw    dgblkoff,dgwwa,dgprtwn,dgrollena,dgrolldis ;SI,DLE,DC1,DC2,DC3
  384.     dw    dguson,dgusoff,dgrevidon,dgcuu,dgcuf ; DC4, NAK, SYN, ETB, CAN
  385.     dw    dgcub, dgcud,atign,dgdimon,dgdimoff ; EM, SUB, ESC, FS, GS
  386.     dw    dgesc, atign                ; RS, US
  387.  
  388. ; DG D463/D470 DG-escape (RS) follower table
  389.  
  390. dgesctab db    17            ; number of entries
  391.     dw    dgejt            ; address of action routines
  392.     db    'ABCDE','FGHIJ','KLMNO','PR'
  393.  
  394. ; Dispatch for dgesctab table
  395.     even
  396. dgejt    dw    dgsfc, dgsbc, dgrmid, dgrevidon, dgrevidoff     ; 'ABCDE'
  397.     dw    dgFSERIES, dgGSERIES, dgscrup, dgscrdn, dginsc    ; 'FGHIJ'
  398.     dw    dgdelc, dggline, atign, atls1, atls0        ; 'KLMNO'
  399.     dw    dgunix, dgRSERIES                ; 'PR'
  400.  
  401. fltable    db    61                ; RS F letter dispatch table
  402.     dw    faction                ; table of action routines
  403.     db    '789;<', '>?ABC', 'DEFGH', 'IJKLM', 'NOPQR'
  404.     db    'STUVW', 'XYZ[\', ']^_`a', 'bcdef', 'hikmq'
  405.     db    'rstvw', 'xz{}~', '@'
  406.  
  407. ; Dispatch for fltable table
  408.     even
  409. faction    dw    dgign2n, atign, dggrid, atign, atign        ; '789;<'
  410.     dw    dgalign, dgprt, atreset, dgsetw, dgsleft    ; '>?ABC'
  411.     dw    dgsright, dgescn, dgeeos, dgshome, dginsl    ; 'DEFGH'
  412.     dw    dgdell, dgnarrow, dgwide, dgpton, dgptoff    ; 'IJKLM'
  413.     dw    dgchatr, dgrhso, dgwsa, dgsct, dgdefch        ; 'NOPQR'
  414.     dw    dgscs, dgign1n, dg78bit, protena, protdis    ; 'STUVW'
  415.     dw    dgsetmar, dgsetamar, dgrnmar, dgilbm, dgdlbm    ; 'XYZ[\'
  416.     dw    dghsdis, dghsena, dgshcol, dgprt3a, atign    ; ']^_`a'
  417.     dw    dgrsa, dgscmap, dgrchr, dgresch, dgskl        ; 'bcdef'
  418.     dw    atign, atign, atnorm, atnorm, dgdchs         ; 'hikmq'
  419.     dw    dgsclk, dgign1n, dgrss, dgrwc, dgrnmod        ; 'rstvw'
  420.     dw    dgppb, dgs25l, dgsmid, dgnscur, dgign2n        ; 'xz{}~'
  421.     dw    dgtoansi                    ; '@'
  422.  
  423. gltable    db    14                ; RS G letter dispatch table
  424.     dw    gaction                ; table of action routines
  425.     db    '018:>','?@ABC','HInp'
  426.  
  427. ; Dispatch for gltable table
  428.     even
  429. gaction    dw    dggarc, dggbar, dggline, dggpoly, dggcloc    ; '018:>'
  430.     dw    dggrcl, dggcatt, dggcrst, dggcon, dggcoff    ; '?@ABC'
  431.     dw    dggctrk, atnorm, atnorm, dggsetp        ; 'HInp'
  432.  
  433. rltable    db    6            ; Data General D463/D470 RS R series
  434.     dw    raction
  435.     db    '@ABCD','E'
  436.  
  437. ; Dispatch for rltable table
  438. raction    dw    dgign2n, dgsps, dgsfield, dgspage, dgsdo    ; '@ABCD'
  439.     dw    dgdhdw                        ; 'E'
  440.  
  441. dgescftab db    34            ; DG ESC.. Final escape follower tab
  442.     dw    dgescfjmp        ; address of action routines
  443.     db    '01234','56789',':;<=>','?ABHI','JKL'
  444.     db    'cDEMN','OPVW[','\'
  445.  
  446. dgescfjmp dw    23 dup (dgesc_ch)      ; '01234','56789',':;<=>','?ABHI','JKL'
  447.     dw    dgesc_c,dgesc_D,dgesc_E,dgesc_M,atss2    ; 'cDEMN'
  448.     dw    atss3,atdcs0,dgesc_V,dgesc_W,atcsi0    ; 'OPVW['
  449.     dw    atgotst0                ; '\'
  450.  
  451. dganstab db    28            ; DG CSI .. Final  char dsptch
  452.     dw    dgcjmp            ; address of action routines
  453.     db    '@ABCD','HJKLM','PSTfh','ilmnp','qrstu','vwx'
  454.  
  455.                     ; DG ANSI dispatch table
  456. dgcjmp    dw    dgcsi_@,dgcsi_A,dgcsi_B,dgcsi_C,dgcsi_D    ; '@ABCD'
  457.     dw    dgcsi_f,ated,  atel,   dgcsi_L,dgcsi_M    ; 'HJKLM'
  458.     dw    atdelc,dgcsi_S,dgcsi_T,dgcsi_f,dgcsi_h    ; 'PSTfh'
  459.     dw    dgcsi_i,dgcsi_sl,atsgr,dgcsi_n,dgcsi_sp    ; 'ilmnp'
  460.     dw    dgcsi_q,dgcsi_r,dgcsi_ss,dgcsi_st,dgcsi_u ; 'qrstu'
  461.     dw    dgcsi_v,dgcsi_w,dgcsi_x            ; 'uwx'
  462.  
  463. dgdcstab db    6            ; DG DCS dispatch table
  464.     dw    dgdcsjmp
  465.     db    'ABCDE','F'
  466.  
  467. dgdcsjmp dw    dgdefch,dggline,dggset2,dgsetw,dggpoly        ; 'ABCDE'
  468.     dw    dgdcs_F                        ; 'F'
  469.  
  470.                 ; Wyse-50 control codes
  471.     even                    ; C0 7-bit control code table
  472. wyc0    dw    5 dup (atign)            ; NUL, SOH, STX, ETX, EOT
  473.     dw    atenq,atign,vtbell,wycub,atht     ; ENQ, ACK, BEL, BS,  HT
  474.     dw    atlf, wycup, dgcuf, atcr,atign    ; LF,  VT,  FF,  CR,  SO
  475.     dw    atign, atign, atign, wyprton, atign ; SI,  DLE, DC1, DC2, DC3
  476.     dw    wyprtoff,3 dup (atign), wy_d2    ; DC4, NAK, SYN, ETB, CAN
  477.     dw    atign, wysub, wyesc,atign,atign    ; EM,  SUB, ESC, FS,  GS
  478.     dw    wyhome, atlf1            ; RS,  US
  479.  
  480.                 ; Wyse-50 escape dispatch table
  481. wyescf    db    50
  482.     dw    wyejt                ; table of action routines
  483.     db    ' !&',27h,'(',')*+,-','./012','89:;=','?ADEF'
  484.     db    'GHIMN','OQRTV','WY`ab','dijqr','txyz{'
  485.  
  486. wyejt    dw    wyenq,wy_bang,protena,protdis,clrprot    ; ' !&'('
  487.     dw    setprot,wy_star,wy_star,wy_comma,wy_minus ; ')*+,-'
  488.     dw    wy_dot,wy_slash,wytab0,athts,wytab2    ; './012'
  489.     dw    wy_8,wy_9,wysub,wysub,wy_equ        ; '89:;='
  490.     dw    wy_query,wy_A,atnorm,inslin,wy_F    ; '?ADEF'
  491.     dw    wy_G,wy_H,wy_I,wy_M,wy_N        ; 'GHIMN'
  492.     dw    wy_O,ansich,wy_R,atel0,wy_V        ; 'OQRTV'
  493.     dw    atdelc,ereos,wy_acc,wy_sa,wy_b        ; 'WY`ab'
  494.     dw    wy_d,atht,atri,wy_q,wy_sr        ; 'dijqr'
  495.     dw    atel0,wy_x,ereos,wy_z,wyhome        ; 'txyz{'
  496.  
  497. ;; Notes on char set idents
  498. ; Kermit ident         size    ident    comment            designator
  499. ;    0        94    'B',0    ASCII             "B"
  500. ;    1        94    'A',0    British NRC         "A"
  501. ;    2        94    '4',0    Dutch NRC         "4"
  502. ;    3        94    '5',0    Finnish    NRC (also "C")    "5"
  503. ;    4        94    'R',0    French NRC (also "f")    "R"
  504. ;    5        94    '9',0    French Canadian NRC     "9"
  505. ;    6        94    'K',0    German NRC        "K"
  506. ;    7        94    'Y',0    Italian    NRC        "Y"
  507. ;    8        94    '`',0    Norwegian/Danish NRC    "`"
  508. ;    9        94    '%','6'    Portugese NRC ("L","g") "%6"
  509. ;    10        94    'Z',0    Spanish    NRC        "Z"
  510. ;    11        94    '7',0    Swedish    NRC        "7"
  511. ;    12        94    '=',0    Swiss NRC        "="
  512. ;    13        94    '=','%' DEC Hebrew NRC        "=%'
  513. ;    14        94    '1',0    Alt-ROM            "1"
  514. ;    15        96    '?',0    Transparent        "?"
  515. ;    16        96    'A',0    Latin1            "A"
  516. ;    17        94    '%','5'    DEC Multinat (Sup Gr)     "%5"
  517. ;    18        94    '>',0    DEC Technical        ">"
  518. ;    19        94    '0',0    DEC-Special          "0","2"
  519. ;    20        94    'D','I' DG International    "DI"
  520. ;     21        94    'D','L'    DG Line Drawing        "DL"
  521. ;    22        94    'D','W' DG Word Processing    "DW"
  522. ;    23        96    'B',0   Latin2            "B"
  523. ;    24        96    'H',0   Hebrew-ISO        "H"
  524. ;    25        94    '"','4' DEC Hebrew        ""4"
  525. ;    26        94    'YW'    Wyse-50 graphics    "YW"
  526. ;    27        96    'H','P'    HP-Roman8        "HP"
  527. ;    28        96    'CI'  ISO 8859-5 Latin/Cyrillic "CI"
  528. ;    29        96    'CK'  KOI8-Cyrillic        "CK"
  529. ;    30        96    'CS'  Short-KOI Cyrillic    "CS"
  530. ;      100 - 131    94    'D','U' DG soft sets        "DU"
  531. ;      141 (128+13)    94    'I' JIS-Katanaka (JIS X 201)    "I"
  532. ;      142 (128+14)    94    'J' JIS-Roman (JIS X 201)    "J"
  533. ;      215 (128+87)    94    'B','$' JIS-Kanji (JIS X 208)    "B$"
  534. ;; End of notes
  535.  
  536. ; Heath-19 special graphics characters to CP437. Use as offsets from caret
  537. ; (94D)
  538. hgrtab    db    249, 17,179,196,197    ; caret,underscore,accent grave,a,b
  539.     db    191,217,192,218,241    ; c,d,e,f,g
  540.     db     26,177,219, 25,220    ; h,i,j,k,l
  541.     db    220,223,223,223,222    ; m,n,o,p,q
  542.     db     16,194,180,193,195    ; r,s,t,u,v
  543.     db    'X','/','\',223,220    ; w,x,y,z,left curly brace
  544.     db    221,222, 20        ; vertical bar,right curly brace,tilde
  545. hgrtabl    equ ($-hgrtab)
  546.  
  547. ; Data General Line Drawing Character Set, based on CP437, starting in 10/0
  548. dgldc    db    20h,0dah,0bfh,0c0h,0d9h,0c2h,0b4h,0c3h        ; 2/0
  549.     db    0c1h,0c5h,0b3h,0c4h,0c2h,0b4h,0c3h,0c1h
  550.     db    0b3h,0c9h,0bbh,0c8h,0bch,0cbh,0b9h,0cch        ; 3/0
  551.     db    0cah,0ceh,0bah,0cdh,0c4h,0f6h,9bh,3fh
  552.     db    3fh,3fh,3fh                    ; 4/0
  553. dgldclen equ    ($-dgldc)
  554.  
  555. ; VT320/VT102 "Special graphics" set translation table for characters 95..126d
  556. ; when the special graphics set is selected. Some characters (98, 99, 100,
  557. ; 101, 104, 105, 111, 112, 114, 115, and 116) do not have exact equivalents
  558. ; in the available set on the IBM, so a close substitution is made.
  559. ; Table is indexed by ASCII char value minus 95 for chars 95..126d.
  560. sgrtab    db     32,  4,177, 26, 23,  27, 25,248,241, 21
  561.     db     18,217,191,218,192, 197,196,196,196,196
  562.     db    196,195,180,193,194, 179,243,242,227,157
  563.     db    156,250
  564. sgrtabl    equ    $-sgrtab
  565.  
  566.  
  567.     ; DEC National Replacement Char sets, referenced to Latin1
  568. nrclat    db    23h,40h,5bh,5ch,5dh,5eh        ; 0, ASCII, "B", dispatch ref
  569.     db    5fh,60h,7bh,7ch,7dh,7eh
  570.     db    94,'B',0            ; 94 byte set, letter pair
  571.     db    0a3h,40h,5bh,5ch,5dh,5eh    ; 1, British, "A"
  572.     db    5fh,60h,7bh,7ch,7dh,7eh
  573.     db    94,'A',0
  574.     db    0a3h,0beh,0ffh,0bdh,7ch,5eh    ; 2, Dutch, "4"
  575.     db    5fh,60h,0a8h,66h,0bch,0b4h
  576.     db    94,'4',0
  577.     db    23h,40h,0c4h,0d6h,0c5h,0dch    ; 3, Finnish, "5"
  578.     db    5fh,0e9h,0e4h,0f6h,0e5h,0fch
  579.     db    94,'5',0
  580.     db    0a3h,0e0h,0b0h,0e7h,0a7h,5eh    ; 4, French, "R"
  581.     db    5fh,60h,0e9h,0f9h,0e8h,0fbh
  582.     db    94,'R',0
  583.     db    23h,0e0h,0e2h,0e7h,0eah,0eeh    ; 5, French Canadian, "9"
  584.     db    5fh,0f4h,0e9h,0f9h,0e8h,0f8h
  585.     db    94,'9',0
  586.     db    23h,0a7h,0c4h,0d6h,0dch,5eh    ; 6, German, "K"
  587.     db    5fh,60h,0e4h,0f6h,0fch,0dfh
  588.     db    94,'K',0
  589.     db    0a3h,0a7h,0b0h,0e7h,0e9h,5eh    ; 7, Italian, "Y"
  590.     db    5fh,97h,0e0h,0f2h,0e8h,0ech
  591.     db    94,'Y',0
  592.     db    23h,40h,0c6h,0d8h,0c5h,5eh    ; 8, Norwegian/Danish, "`"
  593.     db    5fh,60h,0e6h,0f8h,0e5h,7eh
  594.     db    94,60h,0
  595.     db    23h,40h,0c4h,0c7h,0d6h,5eh    ; 9, Portugese, "%6"
  596.     db    5fh,60h,0e4h,0e7h,0f6h,7eh
  597.     db    94,'%','6'
  598.     db    0a3h,0a7h,0a1h,0d1h,0bfh,5eh    ; 10, Spanish, "Z"
  599.     db    5fh,60h,0b0h,0f1h,0e7h,7eh
  600.     db    94,'Z',0
  601.     db    23h,0c9h,0c4h,0d6h,0c5h,0dch    ; 11, Swedish, "7"
  602.     db    5fh,0e9h,0e4h,0f6h,0e5h,0fch
  603.     db    94,'7',0
  604.     db    0f9h,0e0h,0e9h,0e7h,0eah,0eeh    ; 12, Swiss, "="
  605.     db    0e8h,0f4h,0e4h,0f6h,0fch,0fbh
  606.     db    94,'=',0
  607.  
  608. nrcfinal db    'A45CRf9QKY`E6Z7H=Lg'        ; NRC country letters
  609. nrcflen    equ    $-nrcfinal            ; "%6" "%=" done separately
  610. nrcnum    db    1,2,3,3,4,4,5,5,6,7,8,8,8,10,11,11,12,9,9 
  611.                         ; country numbers matching
  612.                         ; nrcfinal letters
  613.  
  614. ;NRC to DEC keyboard codes, North American (ASCII is nrckbd 1),+ALT-ROM+transp
  615. nrckbd    db    1,2,8,6,14,4,7,9,13,16,15,12,11,1, 1,1,1,1,1,1,1
  616. ;NRC to DG keyboard codes, North American + ALT-ROM+transparent
  617. nrcdgkbd db    19h,1ah,0,1dh,1bh,18h,1ch,17h,1fh,0,1eh,1dh,14h,19h, 19h,18h
  618.     db    19h,19h,19h,19h,19h
  619. ; DG char set idents to Kermit set idents
  620. ; DG set values 0 1 2 3 4  5  6    7     8   9  0a  0b  0c  0d 0e  0f  hex
  621. dgchtab    db    0,0,1,4,6,11,10,8,   12,100,100,100,100,100,20,100 ; decimal
  622. ;        10 11  12 13 14 15  16   17  18  19  1a  1b  1c 1d 1e 1f
  623.     db    22,21,100,15,17,19,100, 100,100,100,100,100,100, 0,15,16
  624. ;        20h and above map to soft set filler 100
  625.     db    100                        ; filler set
  626.  
  627. d470chr    db    '12345','6ABHK','L'        ; D470 ANSI char idents
  628. d470chrlen equ    ($-d470chr)
  629. mskchr    db    10,8,12,20,22, 21,1,0,3,6, 4    ; Kermit char idents
  630.  
  631. ; Device attributes response string. Make strings asciiz.
  632. v32str    db    escape,'[?63;1;2;4;6;8;9;15;22c',0 ; VT320, level 3, 132 col, 
  633. ;printer, selective chars, Sixel graphics, UDkeys, NRC, DEC Tech Chars, color
  634. v32sda    db    escape,'[>24;0;0c',0    ; VT320 secondary DA response
  635. v22str    db    escape,'[?62;1;2;4;6;8;9;15c',0; VT220, level 2, etc as above
  636. v102str    db    escape,'[?6;0c',0    ; VT102
  637. v100str db    escape,'[?1;0c',0    ; vanilla VT100
  638. v52str    db    escape,'/Z',0        ; VT100 in VT52 compatibility mode
  639. h19str    db    escape,'/K',0        ; Heath-19 (says plain VT52)
  640. VIPstr    db    escape,'[8p  OT',03h,escape,'[y7813  P GC  A ',03h,0
  641. VIPstrl    equ    $-VIPstr        ; Honeywell MOD400 3.1 id for ESC [ y
  642. ENQhstr    db    '7813  P GC  A',03h    ; Honeywell MOD400 4.0 id string
  643. ENQhstrl equ    $-ENQhstr
  644. pt20str    db    escape,'! ~0 ~..6~C~2 ~$',0 ; Prime PT200
  645. ENQstr    db    'MS-DOS-KERMIT'        ; generic enquiry response
  646. ENQstrl    equ    $-ENQstr
  647.                     ; parity code translation table
  648. partab    db    5,3,1,4,2        ; even, mark, none, odd, space
  649. lpartab equ    $-partab
  650. parcode db    0            ; parity code (0-4)
  651.                     ; baud rate code translation table
  652. ; 45.5 - no VT100 code (call it 50),50,75,110,134.5,150,300,600,1200,
  653. ; 1800,2000,2400,4800,9600,19200,38400,57600,115200  extended beyond DEC
  654. baudtab db    0,0,8,16,24,32,48,56,64,72,80,88,104,112,120,128,128,128,64,8
  655. lbaudtab equ    $-baudtab-1    ; last two are 1200/75 for split speeds
  656. baudidx db    0            ; index into baud rate table
  657. datbits db    7            ; number of databits (7 or 8)
  658. wyse_grch db    0c2h,0c0h,0dah,0bfh,0c3h,0d9h,0b3h,0b2h ; Wyse-50 graphics
  659.     db    0c5h,0b4h,0c4h,0b1h,0cdh,0c1h,0bah,0b0h    ; chars (0..15) CP437
  660.  
  661. issoft    db    0            ; 0=hard char set, else soft
  662. apcstring dw    0            ; segment of apcmacro memory
  663.  
  664. ;;;;;;;;;;;;;;; start session save area
  665.     even
  666. savezoff label    word
  667. ttstate dw    offset atnrm        ; terminal automata state
  668. ttstateST dw    offset atnorm        ; state for action after ST seen
  669. bracecount db    0            ; count of curly braces in APC string
  670. att_normal db    07H            ; default normal screen coloring
  671. oldterm    dw    0            ; terminal type from previous entry
  672. tekflg    db    0            ; Tek mode active flag
  673. old8bit    db    -1            ; flags.remflg setting for D463/D470
  674. iniflgs    dw    0            ; status flags at entry time
  675. modeset db    0            ; temp for atsm/atrm
  676. anspflg    db    0            ; printer flag bits and definitions
  677. h19stat    db    0            ; H-19 extra status bits
  678. h19ctyp    db    1            ; H-19 cursor type (1=ul, 2=bk, 4=off)
  679. h19cur    dw    0            ; H-19 saved cursor position
  680. insmod    db    0            ; insert mode on (1) or off (0)
  681. belcol    db    72            ; column at which to ring margin bell
  682. kbicsr    dw    0            ; cursor when keyboard input typed
  683. kbiflg    db    0            ; set/reset for keyboard input
  684. ttkbi    db    0            ; flag for keyboard input seen
  685. atescftab dw    ansesc            ; offset of esc follower table
  686. setptr    dw    0            ; hold offset of designated char set
  687. upss    db    96,'A',0,0        ; User Preferred Supplemental Set
  688.                     ; size, ident (Latin1)
  689. ; tab stops, stored here
  690. tabs    db    (swidth+7)/8 dup (0)    ; active tab stops, one column per bit
  691. deftabs    db    (swidth+7)/8 dup (0)    ; default (setup) tab stops
  692. ; byte per line, type of line: 0=normal, 1=double wide, 2=double high
  693. linetype db    slen dup (0)        ; single/double width chars for a line
  694. linescroll db    slen dup (0)        ; horizontal scroll for each line
  695. oldscrn    dw    0            ; old screen. hi=rows-1, low=cols-1
  696.  
  697. ; Scrolling region - do not separate or change order of mar_top & mar_bot
  698. mar_top db    0            ; scrolling region top margin
  699. mar_bot db    23            ; scrolling region bottom margin
  700. mar_left db    0            ; left margin
  701. mar_right db    vswidth-1        ; right margin
  702. savdgmar dw    0            ; DG saved right/left margins
  703. dspstate db    0            ; display state (mode)line work byte
  704. dspmsave dw    0            ; saved main dsp scrolling margins
  705. dspcstat dw    0            ; saved cursor pos for status line
  706. dspcmain dw    0            ; saved cursor pos for main display
  707. G0set    db    gsize+3+1 dup (0),0    ; G0..G3 char set space
  708. G1set    db    gsize+3+1 dup (0),1    ; last byte is permanent set index
  709. G2set    db    gsize+3+1 dup (0),2    ;  and should never be changed
  710. G3set    db    gsize+3+1 dup (0),3
  711. xltkeytable db    gsize dup (0)        ; keyboard translation table
  712. doublebyte db    0            ; [HF] 93/Nov/26 storage for dbl.char.
  713. double2nd db    0            ; [HF]
  714.                     ; Start of save cursor material
  715. savelist equ    this byte        ; top of list of things to save
  716. havesaved db    0            ; if have saved anything
  717. cursor    dw    0            ; cursor position
  718. savextattr db    0            ; extended display attributes
  719. curattr db    07h            ; cursor attribute
  720. svattr_index    equ $-savelist        ; offset of saved cursor attribute
  721. savscbattr db    1            ; normal background attributes
  722. atctype    db    1            ; VTxxx cursor type (1=ul,2=bk,0/4=off)
  723. savflgs dw    0            ; saved flags for atsc/atrc
  724. atwrap    db    0            ; autowrap flag
  725. atinvisible db    0            ; invisible char attribute flag
  726. decrlm    db    0            ; host controlled right-left writing
  727. GLptr    dw    0            ; pointer to char set for GL
  728. GRptr    dw    0            ; pointer to char set for GR
  729. SSptr    dw    0            ; pointer to char set for single shift
  730. Gsetid    db    4 dup (0)        ; set numbers 0..24 of char set
  731. lsavecu equ    $-savelist        ; length of stuff to save
  732. savecu    db    lsavecu dup (0)        ; saved cursor, attr., charset, etc
  733.                     ; End of save cursor material
  734.     even                ; Control sequence storage area
  735. ansifinptr dw    anstab            ; pointer to ANSI final char dispatch
  736. dcstabptr dw    dcstab            ; pointer to DCS dispatch table
  737. dnparam    dw    0            ; number of parameters for DCS
  738. dparam    dw    maxparam dup (0)    ; Parameters for DCS
  739. dlparam    db    0            ; a single letter Parameter for DCS
  740. dninter    dw    0            ; number of DCS intermediates
  741. dinter    db    maxinter dup (0)    ; Intermediates for DCS
  742. dcsstrf    db    0            ; Final char of DCS
  743. dnldcnt dw    0            ; autodownload, chars in emubuf
  744. emubufc    dw    0            ; count of chars in string buffer
  745. emubuf    db    66 dup (0)        ; emulator string storage buffer
  746.     db    0            ; safety for string overflow
  747. emubufl    dw    $-emubuf        ; length of emulator buffer
  748. pktbuf    db    66 dup (0)        ; Kermit packet recognizer buffer
  749.     db    0
  750. pktbufl    dw    $-pktbuf
  751. pktlen    db    0            ; autodownload, declared packet LEN
  752. pkttype db    0            ; autodownload, packet TYPE
  753. pktchk    db    0            ; autodownload, running pkt chksum
  754. dgparmread dw    0            ; DG count of parameters read
  755.                     ; DG windows structure
  756. dgwindcnt dw    1            ; DG count of active windows
  757. dgwindow dw    slen dup (0)        ; DG window [mar_top,mar_bot]
  758. dgwindcomp db    slen dup (0)        ; DG window compress (0=80,1=132 cols,
  759.                     ;  2 = line has soft font chars)
  760. dgcaller dw    atnorm            ; DG hex proc callback address
  761. numdigits db    0            ; DG hex digits remaining to be done
  762. dgnum    dw    0            ; DG numerical result
  763. protectena db    0            ; DG protected mode enabled (if != 0)
  764. blinkdis db    0            ; DG blink disabled
  765. dgroll    db    1            ; DG roll (0=disabled, 1=enabled)
  766. dghscrdis db    0            ; DG horz scroll disabled (if 1)
  767. dgcursave dw    16 dup (0)        ; DG cursor position named save area
  768. dgctypesave db    16 dup (0)        ; DG cursor type named save area
  769. dgcross    db    0            ; DG crosshair activity: 0=off, 1=on
  770.                     ;   2 = track keypad, 4= track mouse
  771. dg463fore db    0            ; DG D463 Polygon fill foregnd color
  772. dgaltid    dw    0            ; DG alt term id from host (0=none)
  773. dgkbl    db    0            ; DG keyboard language
  774. dgd470mode db    0            ; DG nonzero if D470 in ANSI mode
  775. dglinepat dw    0ffffh            ; DG line drawing pattern
  776. thisline db    0            ; linetype for current line
  777. scroll    db    1            ; lines to scroll, temp worker
  778. wyse_scroll db    0            ; Wyse-50 scroll/noscroll mode flag
  779. wyse_protattr dw 0            ; Wyse-50 protected char attributes
  780.                     ;  high byte=extattr, low=scbattr
  781. savezlen dw    ($-savezoff)        ; length of z save area
  782. ;;;;;;;;;;;;;;;;; end of session save area
  783.  
  784. ;note low_rgt    dw    0        ; text screen dimensions
  785.                     ; byte low_rgt = max column (79)
  786.                     ; byte low_rgt+1 = max row (23)
  787. led_col    equ    65            ; column position for "LEDs" display
  788. led_off equ    '.'            ; "Off" LED
  789. v320leds db    'VT320 ....'        ; VT320 mode (all 10 characters)
  790. v220leds db    'VT220 ....'        ; VT220 mode
  791. v102leds db    'VT102 ....'        ; VT102 mode
  792. v100leds db    'VT100 ....'        ; VT100 mode
  793. v52leds    db    'VT52      '        ; VT52 mode
  794. h19leds    db    'Heath-19  '        ; Heath-19 mode
  795. honeyleds db    'Honey ....'        ; Honeywell VIP 7809
  796. ansileds db    'ANSI  ....'        ; ANSI-BBS
  797. pt20leds db    'PT200 ....'        ; Prime PT200
  798. d470leds db    'D470      '        ; D470 series from Data General
  799. d470model db    'D470'            ; D470 response for Read New Model ID
  800. d463leds db    'D463      '        ; D463 series from Data General
  801. d463model db    'D463'            ; D463 response for Read New Model ID
  802. d217leds db    'D217      '        ; D217 series from Data General
  803. d217model db    'D217'            ; D217 response for Read New Model ID
  804. ;;d413model db    'D413'            ; D413 response for Read New Model ID
  805. wyseleds db    'Wyse-50   '        ; Wyse-50 mode
  806. data    ends
  807.  
  808. data1    segment
  809.     extrn lccp866r:byte, k8cp866r:byte, k7cp866r:byte
  810.     extrn cp866koi7:byte, cp866koi8:byte, cp866lci:byte
  811.  
  812. ; Translation tables for byte codes 0a0h..0ffh to map DEC Multinational
  813. ; Character Set (DEC Supplemental Graphic) to Code Pages.
  814. ; Codes 00h-1fh are 7-bit controls (C0), codes 20h..7eh are ASCII, 7fh DEL is
  815. ; considered to be a control code, 80h..9fh are 8-bit controls (C1).
  816. ; Each table is 128 translatable bytes followed by the table size (94) and the
  817. ; ISO announcer ident '%5'.
  818.  
  819. MNlatin    db    0a4h,0a6h,0ach,0adh,0aeh,0afh,0b4h    ; Latin1 code points
  820.     db    0beh,0d0h,0deh,0f0h,0feh,0ffh        ; to MNlatin spaces
  821.  
  822.  
  823.                ; Dec Technical set to CP437, CP860, CP863, CP865
  824.              ; Note: CP850 lacks the symbols so expect trash
  825. dectech    db    32 dup (0)                ; columns 8 and 9
  826.     db    0h,0fbh,0dah,0c4h, 0f4h,0f5h,0b3h,0dah    ; column 10
  827.     db    0c0h,0bfh,0d9h,28h,28h,29h,29h,0b4h
  828.     db    0c3h,3ch,3eh,5ch,  2fh,0bfh,0d9h,03eh    ; column 11
  829.     db    0a8h,20h,20h,20h,  0f3h,3dh,0f2h,3fh
  830.     db    1eh,0ech,0ech,0f6h,1eh,1fh,0e8h,0e2h    ; column 12
  831.     db    0f7h,0f7h,0e9h,58h,3fh,1dh,1ah,0f0h
  832.     db    0e3h,3fh,20h,0e4h, 20h,20h,0fbh,0eah    ; column 13
  833.     db    3fh,54h,3fh,3fh,   0efh,55h,5eh,76h
  834.     db    0aah,0e0h,0e1h,78h,0ebh,0eeh,0edh,3fh    ; column 14 
  835.     db    6eh,69h,0e9h,6bh,  3fh,20h,76h,3fh
  836.     db    0e3h,3fh,70h,0e5h, 0e7h,0a8h,9fh,77h    ; column 15
  837.     db    45h,76h,3fh,1bh,   18h,1ah,19h,7fh
  838.     db    94,3eh,0            ; 94 byte set, letter ident
  839.  
  840.                 ; Data General Word Processing to CP 437
  841. dgwpcp437 db    20h,0dah,0c0h,0bfh, 0d9h,9fh,'~',8h    ; column 10
  842.     db    0e4h,0e4h,0f4h,0f5h, 0fbh,8h,0ech,8h
  843.     db    '0','1',0fdh,'3', '4','5','6','7'    ; column 11
  844.     db    '8','9',8h,0c9h, 1bh,8h,1ah,0fah
  845.     db    13h,0e0h,0e1h,8h, 0ebh,8h,8h,0fch    ; column 12
  846.     db    0e9h,8h,8h,8h, 0e6h,8h,0eeh,8h
  847.     db    8h,8h,0e5h,0e7h, 8h,0edh,8h,8h        ; column 13
  848.     db    8h,0eah,1eh,14h, 4 dup (8h)
  849.     db    0c3h,04h,010h,010h, 011h,1eh,1fh,9 dup (8h) ; column 14
  850.     db    '0','1','2','3', '4','5','6','7'    ; column 15
  851.     db    '8','9',3fh,18h, 1ah,1bh,19h,20h
  852.     db    94,'D','W'            ; 94 byte set, letter idents
  853. dgwplen    equ    $-dgwpcp437            ; table size
  854.  
  855.             ; Convert Data General International to Latin1.
  856.             ; DGI chars at these code points translate to the
  857.             ; value used as a code point in the Latin1 table.
  858.             ; Thus the second byte, 0ach, DGI not sign, in its
  859.             ; row 2 col 10 translates to Latin1 not sign in row 12
  860.             ; col 10. Columns 8 and 9 are C1 controls.
  861. dgi2lat    db    0a0h,0ach,0bdh,0b5h, 0b2h,0b3h,0a4h,0a2h ; column 10
  862.     db    0a3h,0aah,0bah,0a1h, 0bfh,0a9h,0aeh,3fh
  863.     db    0bbh,0abh,0b6h,3fh,  3fh,0a5h,0b1h,3fh     ; column 11
  864.     db    3fh,0b7h,60h,0a7h,   0b0h,0a8h,0b4h,3fh
  865.     db    0c1h,0c0h,0c2h,0c4h, 0c3h,0c5h,0c6h,0c7h ; column 12
  866.     db    0c9h,0c8h,0cah,0cbh, 0cdh,0cch,0ceh,0cfh
  867.     db    0d1h,0d3h,0d2h,0d4h, 0d6h,0d5h,0d8h,3fh     ; column 13
  868.     db    0dah,0d9h,0dbh,0dch, 0a0h,59h,0a0h,0a0h
  869.     db    0e1h,0e0h,0e2h,0e4h, 0e3h,0e5h,0e6h,0e7h ; column 14
  870.     db    0e9h,0e8h,0eah,0ebh, 0edh,0ech,0eeh,0efh
  871.     db    0f1h,0f3h,0f2h,0f4h, 0f6h,0f5h,0f8h,3fh     ; column 15
  872.     db    0fah,0f9h,0fbh,0fch, 0dfh,0ffh,0a0h,0a0h
  873. dgi2len    equ    $-dgi2lat
  874.  
  875. ; yr8l1[]   /* Hewlett Packard Roman8 to Latin-1 */
  876. ;/* This is HP's official translation, straight from iconv */
  877. ;/* It is NOT invertible. */ omits columns 0..9
  878. hr8L1    db 160,192,194,200,202,203,206,207,180, 96, 94,168,126,217,219,163
  879.     db 175,221,253,176,199,231,209,241,161,191,164,163,165,167,102,162
  880.     db 226,234,244,251,225,233,243,250,224,232,242,249,228,235,246,252
  881.     db 197,238,216,198,229,237,248,230,196,236,214,220,201,239,223,212
  882.     db 193,195,227,208,240,205,204,211,210,213,245, 83,115,218, 89,255
  883.     db 222,254,183,181,182,190, 45,188,189,170,186,171, 42,187,177,160
  884. hr8L1len equ $-hr8L1
  885.  
  886. ; yr8l1[]   /* HP Roman8 to ISO Latin-1, Invertible */ omits cols 0..9
  887. ihr8L1    db 160,192,194,200,202,203,206,207,180,166,169,168,172,217,219,173
  888.     db 175,221,253,176,199,231,209,241,161,191,164,163,165,167,174,162
  889.     db 226,234,244,251,225,233,243,250,224,232,242,249,228,235,246,252
  890.     db 197,238,216,198,229,237,248,230,196,236,214,220,201,239,223,212
  891.     db 193,195,227,208,240,205,204,211,210,213,245,178,179,218,184,255
  892.     db 222,254,183,181,182,190,185,188,189,170,186,171,215,187,177,247
  893. ihr8L1len equ $-ihr8L1
  894.  
  895.  
  896. data1    ends
  897.  
  898. ifndef    no_graphics
  899. code2    segment
  900.     extrn    tekini:far, tekemu:far, tekend:far, teksetcursor:far
  901.     extrn    dgline:far, dgbar:far, dgcrosson:far, dgcrossoff:far
  902.     extrn    dgcrossrpt:far, dgsetcrloc:far, dgarc:far, dgpoly:far
  903.     extrn    mksoftspace:far, clearsoft:far
  904. code2    ends
  905. endif    ; no_graphics
  906.  
  907. code    segment
  908.     extrn    cptchr:near, pntchr:near, pntchk:near, pntflsh:near
  909.     extrn    modlin:near, latin1:near
  910.     extrn    clrmod:near, latininv:near, trnprs:near
  911.     extrn    dgsettek:far, vtksmac:near, vtkrmac:near, product:near
  912.     extrn    jpnftox:near, jpnxtof:near    ; [HF] 93/Nov/26
  913.  
  914.     assume    ds:data, es:nothing
  915.  
  916. fmodlin    proc    far
  917.     call    modlin
  918.     ret
  919. fmodlin    endp
  920.  
  921. fclrmod    proc    far
  922.     call    clrmod
  923.     ret
  924. fclrmod    endp
  925.  
  926. fcptchr    proc    far
  927.     call    cptchr
  928.     ret
  929. fcptchr    endp
  930.  
  931. fpntchr    proc    far
  932.     call    pntchr
  933.     ret
  934. fpntchr    endp
  935.  
  936. fpntchk    proc    far
  937.     call    pntchk
  938.     ret
  939. fpntchk    endp
  940.  
  941. fpntflsh proc    far
  942.     call    pntflsh
  943.     ret
  944. fpntflsh endp
  945.  
  946. ftrnprs    proc    far
  947.     call    trnprs
  948.     ret
  949. ftrnprs    endp
  950.  
  951. fvtksmac proc    far
  952.     call    vtksmac
  953.     ret
  954. fvtksmac endp
  955.  
  956. fvtkrmac proc    far
  957.     call    vtkrmac
  958.     ret
  959. fvtkrmac endp
  960.  
  961. fproduct proc    far
  962.     call    product
  963.     ret
  964. fproduct endp
  965.  
  966. flatin1    proc    far
  967.     push    ax
  968.     push    es
  969.     push    flags.chrset
  970.     push    ds
  971.     mov    ax,seg flags
  972.     mov    ds,ax
  973.     mov    ax,ds:vtcpage        ; get current terminal Code Page
  974.     mov    ds:flags.chrset,ax    ; tell file transfer part
  975.     pop    ds
  976.     call    latin1            ; sets DS:BX
  977.     call    latininv        ; adjusts BX
  978.     mov    ax,seg flags
  979.     mov    es,ax
  980.     pop    es:flags.chrset
  981.     pop    es
  982.     pop    ax
  983.     ret
  984. flatin1    endp
  985.  
  986. fjpnxtof proc    far            ; [HF] 93/Nov/26
  987.     call    jpnxtof            ; [HF] 93/Nov/26
  988.     ret                ; [HF] 93/Nov/26
  989. fjpnxtof endp                ; [HF] 93/Nov/26
  990. code    ends
  991.  
  992. code1    segment
  993.     extrn    prtbout:near, prtnout:near, csrtype:near, atsclr:near
  994.     extrn    vtscru:near, vtscrd:near, chgdsp:near
  995.     extrn    setpos:near, setudk:near, udkclear:near, vtbell:near
  996.     extrn    setatch:near, qsetatch:near, getatch:near
  997.     extrn    revideo:near, getbold:near, setbold:near, clrbold:near
  998.     extrn    getblink:near, setblink:near, clrblink:near, getunder:near
  999.     extrn    setunder:near, clrunder:near, revscn:near, setcolor:near
  1000.     extrn    setrev:near, clrrev:near, dec2di:far
  1001.     extrn    atparse:near, atpclr:near, atdispat:near, apcmacro:near
  1002.     extrn    setprot:near, clrprot:near, frepaint:far, touchup:near
  1003.     extrn    rcvmacro:near, srvmacro:near
  1004. ifndef    no_graphics
  1005.     extrn    tekinq:near, tekpal:near, tekrpal:near
  1006. endif    ; no_graphics
  1007.  
  1008.     assume    cs:code1, ds:data, es:nothing
  1009.  
  1010. ; Terminal display routine. Call with character incoming character in AL
  1011.  
  1012. anstty    proc    near
  1013.     mov    dx,cursor        ; some routines need cursor in dx
  1014.     mov    kbiflg,0        ; clear old flag value
  1015.     test    yflags,trnctl        ; Debug mode?
  1016.     jz    anstt1            ; z = no
  1017.     jmp    atdeb            ; yes, just translate control chars
  1018. anstt1:    cmp    ttkbi,0            ; new keyboard input?
  1019.     je    anstt2            ; e = no, just continue
  1020.     mov    kbiflg,1        ; yes, set flag
  1021.     mov    kbicsr,dx        ; save old cursor
  1022.     mov    ttkbi,0            ; clear this flag
  1023.  
  1024. anstt2:    test    anspflg,vtcntp        ; print controller on?
  1025.     jz    anstt4            ; z = no
  1026.     test    flags.capflg,logses    ; capturing output?
  1027.     jz    anstt3            ; z = no, forget this part
  1028.     push    ax            ; save char
  1029.     call    fcptchr            ; give it captured character
  1030.     pop    ax            ; restore character
  1031. anstt3:    jmp    ttstate            ; print transparently
  1032.  
  1033. anstt4:    test    yflags,capt        ; capturing output?
  1034.     jz    anstt4a            ; z = no, forget this part
  1035.     call    fcptchr            ; give it captured character
  1036. anstt4a:or    al,al            ; NUL char?
  1037.     jnz    anstt5            ; nz = no
  1038.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1039.     jnz    anstt5            ; nz = yes, must pass nulls
  1040.     test    flags.vtflg,ttwyse    ; Wyse?
  1041.     jz    atign            ; z = no, ignore it
  1042.  
  1043. anstt5:    cmp    vtemu.vtdnld,0        ; autodownload disabled?
  1044.     je    anstt8            ; e = yes
  1045.     cmp    al,trans.rsoh        ; start of packet char?
  1046.     jne    anstt5c            ; ne = no
  1047.     push    ax
  1048.     call    anstt5x            ; flush current buffer
  1049.     pop    ax
  1050.     mov    dnldcnt,1        ; say recording new packet
  1051.     mov    pktbuf,al        ; store char for replay
  1052.     mov    pktchk,0        ; initialize checksum
  1053.     ret
  1054. anstt5c:cmp    dnldcnt,0        ; parsing?
  1055.     je    anstt8            ; e = no
  1056.     mov    bx,dnldcnt
  1057.     mov    pktbuf[bx],al
  1058.     inc    dnldcnt            ; count incoming bytes
  1059.     inc    bx
  1060.     cmp    bx,pktbufl        ; packet too long?
  1061.     jae    anstt5x            ; ae = too much, fail
  1062.     add    pktchk,al        ; add to running checksum
  1063.     cmp    al,trans.reol        ; premature EOL?
  1064.     je    anstt5x            ; e = yes, fail
  1065.     cmp    dnldcnt,2        ; LEN byte?
  1066.     jne    anstt5d            ; ne = no
  1067.     cmp    al,' '+3        ; minimal length packet?
  1068.     jbe    anstt5x            ; be = no, fail
  1069.     push    ax
  1070.     sub    al,' '            ; remove length ASCII bias
  1071.     mov    pktlen,al        ; packet length
  1072.     pop    ax
  1073.     ret
  1074.  
  1075. anstt5d:cmp    dnldcnt,3        ; SEQ?
  1076.     ja    anstt5e            ; a = no
  1077.     cmp    al,' '            ; SEQ of zero?
  1078.     jne    anstt5x            ; ne = no, fail
  1079.     ret
  1080. anstt5e:cmp    dnldcnt,4        ; TYPE?
  1081.     ja    anstt5g            ; a = no
  1082.     mov    pkttype,al        ; remember TYPE for macro call
  1083.     cmp    al,'S'            ; TYPE of S?
  1084.     je    anstt5h            ; e = yes, succeed
  1085.     cmp    al,'I'            ; TYPE of I?
  1086.     jne    anstt5x            ; ne = no, fail
  1087.     ret
  1088.  
  1089. anstt5g:mov    bl,pktlen        ; reported packet length
  1090.     add    bl,2            ; add SOP and LEN
  1091.     xor    bh,bh
  1092.     cmp    dnldcnt,bx        ; count matches declared pkt length?
  1093.     jb    anstt5h            ; b = no, not yet, keep looking
  1094.     ja    anstt5x            ; a = went too far, fail
  1095.     mov    bl,pktchk        ; running checksum, type 1
  1096.     sub    bl,al            ; don't add checksum byte to ours
  1097.     xor    bh,bh
  1098.     shl    bx,1            ; get top two bits into bh
  1099.     shl    bx,1
  1100.     shr    bl,1            ; restore bl
  1101.     shr    bl,1
  1102.     add    bl,bh            ; add in top two bits
  1103.     and    bl,03fh            ; chop to lower six bits
  1104.     add    bl,' '            ; add ASCII bias
  1105.     cmp    al,bl            ; compare checksum bytes
  1106.     jne    anstt5x            ; ne = no match, fail
  1107.     mov    dnldcnt,0        ; declare replay buffer empty
  1108.     cmp    pkttype,'S'        ; S packet?
  1109.     jne    anstt5i            ; ne = no
  1110.     call    rcvmacro        ; do packet Receive macro
  1111. anstt5h:ret
  1112. anstt5i:call    srvmacro        ; do packet Server macro
  1113.     ret
  1114. anstt5x:mov    cx,dnldcnt        ; bytes in buffer
  1115.     jcxz    anstt5z            ; z = empty
  1116.     mov    bx,offset pktbuf    ; buffer
  1117. anstt5y:push    cx
  1118.     push    bx
  1119.     mov    al,[bx]            ; read old byte
  1120.     call    anstt8            ; replay old byte (near call)
  1121.     pop    bx
  1122.     pop    cx
  1123.     inc    bx            ; next buffer byte
  1124.     loop    anstt5y
  1125. anstt5z:mov    dnldcnt,0
  1126.     ret
  1127.  
  1128.                     ; Direct char to processor module
  1129. anstt8:    test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1130.     jnz    anstt10            ; nz = yes
  1131.     test    flags.vtflg,ttwyse    ; Wyse?
  1132.     jnz    anstt20            ; nz = yes
  1133.     cmp    vtemu.vtchset,13    ; ASCII (0) or NRC's (1-13) active?
  1134.     ja    anstt8b            ; a = no
  1135.     cmp    vtemu.vtchset,0        ; ASCII?
  1136.     je    anstt8b            ; e = yes
  1137.     and    al,7fh            ; yes, NRCs force chars to 7-bits
  1138. anstt8b:test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  1139.     jnz    anstt9            ; nz = no
  1140.     cmp    al,20h            ; C0 control code?
  1141.     jb    anstt8c            ; b = yes
  1142.     cmp    vtemu.vtchset,15    ; TRANSPARENT?
  1143.     je    anstt9            ; e = yes, pass all others
  1144. anstt8c:jmp    atctrl            ; dispatch on control code
  1145. anstt9:    jmp    ttstate            ; dispatch according to state
  1146.  
  1147.                     ; DG D463/D470 terminal
  1148. anstt10:test    flags.remflg,d8bit    ; use high bit?
  1149.     jnz    anstt11            ; nz = yes
  1150.     and    al,7fh            ; 7 bit terminal only
  1151. anstt11:test    anspflg,vtcntp        ; controller (transparent) printing?
  1152.     jnz    anstt12            ; nz = yes, go through filter routine
  1153.     cmp    dgd470mode,0        ; ansi mode?
  1154.     jne    anstt13            ; ne = yes
  1155.     test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  1156.     jnz    anstt12            ; nz = no, do according to state
  1157.     cmp    ttstate,offset atnrm    ; normal text processing?
  1158.     jne    anstt12            ; ne = no, pass controls to state
  1159.     jmp    dgctrl            ; do DG controls
  1160. anstt12:jmp    ttstate            ; process regularly
  1161.                     ; D470 ANSI mode operations
  1162. anstt13:test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  1163.     jz    anstt14            ; z = yes
  1164.     jmp    ttstate            ; process regularly
  1165. anstt14:jmp    dgansctl        ; do controls
  1166.  
  1167. anstt20:and    al,7fh            ; Wyse, chop 8th bit
  1168.     cmp    ttstate,offset atnrm    ; normal state?
  1169.     je    anstt21            ; e = yes
  1170.     jmp    ttstate            ; do state
  1171.  
  1172. anstt21:cmp    al,20h            ; control code?
  1173.     jae    atnrm            ; ae = no, process as text
  1174.     xor    ah,ah            ; clear for word use below
  1175.     mov    di,ax            ; use AL as a word index
  1176.     shl    di,1
  1177.     jmp    wyc0[di]        ; dispatch on C0 control codes
  1178. anstty    endp
  1179.  
  1180. ; [HF]940130 translation procedure for Japanese
  1181. ; [HF]940130 Carry set if AL is leading byte of bouble byte char.
  1182. jpnxlat    proc    near            ; [HF]940130
  1183.     cmp    al,DEL            ;[HF] DEL?
  1184.     jne    jpnxlat4        ;[HF] ne = no
  1185.     stc                ;[HF] yes, just ignore
  1186.     ret                ;[HF]
  1187. jpnxlat4:                ;[HF]
  1188.     push    ax            ;[HF] save Char
  1189.     mov    ax,[bx+gsize+1]        ;[HF] get ident
  1190.     cmp    ax,'$B'            ;[HF] JIS-Kanji?
  1191.     je    jpnxlat1        ;[HF] e = yes
  1192.     jmp    short jpnxlat2        ;[HF]
  1193. jpnxlat1:                ;[HF]
  1194.     pop    ax            ;[HF] restore char
  1195.     cmp    doublebyte,0        ;[HF] Leading byte?
  1196.     jne    jpnxlat3        ;[HF] ne = no
  1197.     mov    doublebyte,al        ;[HF] yes save it
  1198.     stc                ;[HF] dont display
  1199.     ret                ;[HF]
  1200. jpnxlat3:                ;[HF]
  1201.     mov    ah,doublebyte        ;[HF] set leading byte
  1202.     call    fjpnxtof        ;[HF] xlat to local code
  1203.     mov    doublebyte,al        ;[HF] save 2nd byte
  1204.     mov    al,ah            ;[HF] set leading byte
  1205.     clc                ;[HF] display the char in AL
  1206.     ret                ;[HF]
  1207. jpnxlat2:                ;[HF] single byte char
  1208.     mov    doublebyte,0        ;[HF]
  1209.     pop    ax            ;[HF] restore char
  1210.     xlatb                ;[HF]
  1211.     cmp    rxtable+256,0        ;[HF] TRANSLATION INPUT turned off?
  1212.     je    jpnxlat5        ;[HF] e = yes, use ISO mechanisms
  1213.     mov    bx,offset rxtable    ;[HF] address of translate table
  1214.     mov    ah,al            ;[HF] copy char
  1215.     xlatb                ;[HF] new char is in al
  1216. jpnxlat5:                ;[HF]
  1217.     clc                ; [HF]940130 display it
  1218.     ret                ; [HF]940130
  1219. jpnxlat    endp                ; [HF]940130
  1220.  
  1221. atign:    ret                ; something to be ignored
  1222.  
  1223. atnorm: mov    ttstate,offset atnrm    ; reset state to "normal"
  1224.     mov    ttstateST,offset atnorm    ; reset state for ST seen
  1225.     ret
  1226.             
  1227. atnrm    proc    near            ; Normal character (in AL) processor
  1228.     mov    issoft,0        ; presume hard char set
  1229.     cmp    SSptr,0            ; single shift needed?
  1230.     je    atnrm10            ; e = no
  1231.     and    al,not 80h        ; strip high bit
  1232.     mov    bx,SSptr        ; pointer to desired char set
  1233.     mov    SSptr,0            ; clear single shift indicator
  1234.     jmp    short atnrm12        ; process
  1235.  
  1236. atnrm10:test    al,80h            ; high bit set for GRight?
  1237.     jnz    atnrm11            ; nz = yes
  1238.     mov    bx,GLptr        ; GL char set
  1239.     jmp    short atnrm11a        ; process
  1240.  
  1241. atnrm11:and    al,not 80h        ; strip high bit
  1242.     mov    bx,GRptr        ; GR char set
  1243.  
  1244. atnrm11a:cmp    isps55,0        ; [HF]940130 Japanese PS/55 ?
  1245.     je    atnrm12            ; [HF]940130 e = no
  1246.     call    jpnxlat            ; [HF]940130 yes, need special xlat
  1247.     jnc    atnrm14            ; [HF]940130 nc = display the char
  1248.     clc                ; [HF]940130 clear carry
  1249.     ret
  1250.  
  1251. atnrm12:mov    ch,byte ptr [bx+gsize+3] ; get hard/soft char set indicator
  1252.     or    ch,ch            ; hard character set?
  1253.     jz    atnrm12a        ; z = yes
  1254. ifndef    no_graphics
  1255.     mov    issoft,ch        ; activate soft
  1256.     cmp    tekflg,tek_active+tek_sg ; inited already?
  1257.     je    atnrm12a        ; e = yes
  1258.     push    ax
  1259.     push    bx
  1260.     call    dgsettek        ; to graphics mode
  1261.     pop    bx
  1262.     pop    ax
  1263. endif    ; no_graphics
  1264. atnrm12a:xlatb                ; translate al to new char in al
  1265. atnrm13:cmp    rxtable+256,0        ; TRANSLATION INPUT turned off?
  1266.     je    atnrm14            ; e = yes, use ISO mechanisms
  1267.     mov    bx,offset rxtable    ; address of translate table
  1268.     mov    ah,al            ; copy char
  1269.     xlatb                ; new char is in al
  1270. atnrm14:cmp    al,DEL            ; ANSI Delete char?
  1271.     jne    atnrm15            ; ne = no
  1272.     ret                ; ignore DEL
  1273. atnrm15:cmp    atinvisible,0        ; invisible char?
  1274.     je    atnrm2            ; e = no, visible
  1275.     mov    al,' '            ; invisible, write as space
  1276.                     ; use atdeb for debug simple tty dsp
  1277. atnrm2:    mov    dx,cursor        ; get cursor virtual position
  1278.     push    bx
  1279.     mov    bl,dh            ; get row
  1280.     xor    bh,bh
  1281.     mov    bl,linetype[bx]        ; line width
  1282.     mov    thisline,bl        ; save for current reference
  1283.     cmp    issoft,0        ; soft font being used?
  1284.     je    atnrm2f            ; e = no
  1285.     or    dgwindcomp[bx],2    ; say soft font on this line
  1286. atnrm2f:pop    bx
  1287.     test    vtemu.vtflgop,decawm    ; Autowrap active?
  1288.     jz    atnrm2a            ; z = no
  1289.     mov    cl,mar_right        ; logical right margin
  1290.     cmp    thisline,0        ; single width line?
  1291.     je    atnrm2c            ; e = yes, single
  1292.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1293.     jnz    atnrm2c            ; nz = yes, these double the margins
  1294.     shr    cl,1            ; halve right column # for wide chars
  1295. atnrm2c:cmp     isps55,0                ; [HF]941103 Japanese PS/55 mode?
  1296.         je      atnrm2h                 ; [HF]941103 e = no
  1297.         cmp     doublebyte,0            ; [HF]940226 doublebyte char ?
  1298.         je      atnrm2h                 ; [HF]940226 e = no
  1299.         dec     cl                      ; [HF]940226 check one more space
  1300.         cmp     dl,cl                   ; [HF]940226 enough space?
  1301.         jbe     atnrm2a                 ; [HF]940226 be = yes
  1302.         inc     cl                      ; [HF]940226 restore right margin
  1303.         mov     dl,cl                   ; [HF]940226 set it to DL
  1304.         inc     dl                      ; [HF]940226 set beyond pos for wrap
  1305.         mov     atwrap,dh               ; [HF]940226 mark wrap
  1306.         inc     atwrap                  ; [HF]940226 to next line
  1307. atnrm2h:cmp     dl,cl                   ; want to write beyond right margin?
  1308.     jb    atnrm2a            ; b = no
  1309.     cmp    atwrap,0        ; autowrap pending?
  1310.     je    atnrm2a            ; e = no
  1311.     test    anspflg,vtautop        ; printing desired?
  1312.     jz    atnrm2a            ; e = no
  1313.     push    dx
  1314.     push    ax            ; save char
  1315.     mov    dh,atwrap        ; get 1+last display line's row
  1316.     dec    dh            ; up one line
  1317.     call    pntlin            ; print line
  1318.     mov    al,LF            ; terminate in LF
  1319.     call    fpntchr
  1320.     call    fpntflsh        ; flush printer buffer
  1321.     pop    ax            ; recover char in AL
  1322.     pop    dx
  1323. atnrm2a:push    ax            ; save character
  1324.     cmp    protectena,0        ; protected mode enabled?
  1325.     je    atnrm2d            ; e = no
  1326.     call    getatch            ; check for protected field
  1327.     test    cl,att_protect        ; protected?
  1328.     jz    atnrm2d            ; z = no
  1329.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1330.     jz    atnrm2d            ; z = no
  1331.     call    dgcuf            ; do DG cursor right
  1332.     mov    dx,cursor
  1333. atnrm2d:cmp    decrlm,0        ; host right-left mode active?
  1334.     je    atnrm2e            ; e = no
  1335.     cmp    atwrap,0        ; wrap pending?
  1336.     je    atnrm2e            ; e = no
  1337.     mov    dl,mar_right
  1338.     inc    dl            ; set to wrap in normal sense
  1339.  
  1340. atnrm2e:call    atscur            ; set cursor physical position
  1341.     pop    ax
  1342.     cmp    insmod,0        ; insert mode off?
  1343.     je    atnrm3            ; e = yes
  1344.     push    ax
  1345.     call    inschr            ; open a char space in this line
  1346.     cmp    doublebyte,0        ; [HF] doublebyte display?
  1347.     jne    atnrm2g            ; [HF] ne = yes
  1348.     cmp    thisline,0        ; single width line?
  1349.     je    atnrm2b            ; e = yes
  1350. atnrm2g:call    inschr            ; open second space for double width
  1351. atnrm2b:pop    ax            ; restore char
  1352.                     ; set cursor before writing char
  1353. atnrm3:    cmp    thisline,0        ; check for double characteristic
  1354.     je    atnrm3a            ; e = normal, not doubles
  1355.     shl    dl,1            ; double the column number
  1356. atnrm3a:push    dx
  1357.     call    direction        ; set dx to desired position
  1358.     mov    ah,curattr        ; current attribute
  1359.     mov    cl,extattr        ; extended attribute
  1360.     test    cl,att_protect        ; protected?
  1361.     jz    atnrm3h            ; z = no
  1362.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1363.     jz    atnrm3h            ; z = no
  1364.     mov    ah,byte ptr wyse_protattr ; use Wyse protected char attributes
  1365.     mov    cl,byte ptr wyse_protattr+1
  1366. atnrm3h:mov    ch,issoft
  1367.     or    ch,ch            ; soft font?
  1368.     jz    atnrm3d            ; z = no
  1369.     sub    ch,100            ; remove local bias (leaves 1..31)
  1370.     shl    ch,1
  1371.     shl    ch,1
  1372.     shl    ch,1            ; move to upper 5 bits
  1373.      and    cl,not 0f8h        ; clear soft set bits
  1374.     or    cl,ch            ; new extended attribute
  1375. atnrm3d:call    setatch            ; write char (al) and attribute (ah)
  1376.     cmp    doublebyte,0        ;[HF] doublebyte display?
  1377.     je    atnrm3g            ;[HF] e = no
  1378.     pop    dx            ;[HF]
  1379.     inc    dl            ;[HF] next column
  1380.     mov    cursor,dx        ;[HF] set cursor position
  1381.     push    dx            ;[HF]
  1382.     call    direction        ;[HF] set dx to desired position
  1383.     mov    al,doublebyte        ;[HF] set 2nd byte
  1384.     mov    ah,curattr        ;[HF] current attribute
  1385.     mov    cl,extattr        ; extended attribute
  1386.  
  1387.     test    cl,att_protect        ; protected?
  1388.     jz    atnrm3i            ; z = no
  1389.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1390.     jz    atnrm3i            ; z = no
  1391.     mov    ah,byte ptr wyse_protattr ; use Wyse protected char attributes
  1392.     mov    cl,byte ptr wyse_protattr+1
  1393. atnrm3i:
  1394.     mov    ch,issoft
  1395.     or    ch,ch            ; soft font?
  1396.     jz    atnrm3f            ; z = no
  1397.     sub    ch,100            ; remove local bias (leaves 1..31)
  1398.     shl    ch,1
  1399.     shl    ch,1
  1400.     shl    ch,1            ; move to upper 5 bits
  1401.      and    cl,not 0f8h        ; clear soft set bits
  1402.     or    cl,ch            ; new extended attribute
  1403. atnrm3f:call    setatch            ;[HF] write 2nd char and attrib.
  1404.     mov    doublebyte,0        ;[HF] clear doublebyte ind
  1405. atnrm3g:mov    issoft,0
  1406.     pop    dx
  1407.     cmp    thisline,0        ; check for double characteristic
  1408.     je    atnrm4            ; e = normal, not doubles
  1409.     cmp    decrlm,0        ; host writing direction active?
  1410.     je    atnrm3b            ; e = no
  1411.     dec    dl            ; next col
  1412.     jmp    short atnrm3c
  1413. atnrm3b:inc    dl            ; next column
  1414. atnrm3c:push    dx
  1415.     call    direction        ; set dx to desired position
  1416.     mov    ah,curattr        ; current attribute
  1417.     mov    cl,extattr        ; extended attribute
  1418.     test    cl,att_protect        ; protected?
  1419.     jz    atnrm3j            ; z = no
  1420.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1421.     jz    atnrm3j            ; z = no
  1422.     mov    ah,byte ptr wyse_protattr ; use Wyse protected char attributes
  1423.     mov    cl,byte ptr wyse_protattr+1
  1424. atnrm3j:
  1425.     mov    al,' '            ; use a space for doubling
  1426.     mov    ch,issoft
  1427.     or    ch,ch            ; soft font?
  1428.     jz    atnrm3e            ; z = no
  1429.     sub    ch,100            ; remove local bias (leaves 1..31)
  1430.     shl    ch,1
  1431.     shl    ch,1
  1432.     shl    ch,1            ; move to upper 5 bits
  1433.      and    cl,not 0f8h        ; clear soft set bits
  1434.     or    cl,ch            ; new extended attribute
  1435. atnrm3e:call    setatch            ; write char (al) and attribute (ah)
  1436.     pop    dx
  1437.     shr    dl,1            ; keep "cursor" in single units
  1438.  
  1439. atnrm4:    test flags.vtflg,ttd463+ttd470+ttd217+ttheath+ttwyse; no wrap & scroll?
  1440.     jz    atnrm4d            ; z = no
  1441.     jmp    dgcuf            ; do DG cursor forward
  1442.  
  1443. atnrm4d:test    vtemu.vtflgop,decawm    ; Autowrap active?
  1444.     jz    atnrm5            ; z = no
  1445.     cmp    decrlm,0        ; host writing left to right?
  1446.     je    atnrm4e            ; e = no
  1447.     or    dl,dl            ; wrote in left most col?
  1448.     jnz    atnrm5            ; nz = no
  1449.     mov    dl,mar_right        ; set next column to the right
  1450.     jmp    short atnrm4b        ; do not move cursor now
  1451.  
  1452. atnrm4e:mov    cl,mar_right        ; logical right margin
  1453.     cmp    thisline,0        ; single width line?
  1454.     je    atnrm4a            ; e = yes, single
  1455.     shr    cl,1            ; halve right column # for wide chars
  1456. atnrm4a:cmp    dl,cl            ; wrote in right-most column?
  1457.     jb    atnrm5            ; b = no
  1458.     inc    dl            ; say want to use next column
  1459. atnrm4b:mov    atwrap,dh        ; turn on wrap flag with 1 + this row
  1460.     inc    atwrap            ;  so 0 means no wrap pending
  1461.     test    flags.vtflg,ttheath    ; H-19?
  1462.     jnz    atscur            ; nz = yes, show wrap now
  1463.     mov    cursor,dx        ; virtual cursor position
  1464.     ret                ; exit without moving cursor from eol
  1465.  
  1466. atnrm5:    mov    dx,cursor        ; restore cursor position
  1467.     cmp    decrlm,0        ; host writing direction active?
  1468.     je    atnrm5a            ; e = no
  1469.     or    dl,dl
  1470.     jz    atnrm5b
  1471.     dec    dl            ; next column
  1472.     jmp    short atnrm5b
  1473. atnrm5a:inc    dl            ; next column
  1474. atnrm5b:mov    atwrap,0        ; say not about to wrap
  1475. ;;    jmp    short atscur
  1476. atnrm    endp
  1477.  
  1478. atscur:    cmp    dl,mar_left        ; left of left margin?
  1479.     jae    atscu1            ; ae = no, continue
  1480.     mov    dl,mar_left        ; set at left margin
  1481. atscu1:    mov    cl,mar_right        ; copy logical margin; cl = right col
  1482.     push    bx
  1483.     mov    bl,dh            ; get row
  1484.     xor     bh,bh
  1485.     cmp    linetype [bx],0        ; single width lines?
  1486.     pop    bx
  1487.     je    atscu1a            ; e = yes, single width
  1488.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1489.     jnz    atscu1a            ; nz = yes, these double the margins
  1490.     shr    cl,1            ; halve column # for double wides
  1491. atscu1a:cmp    dl,cl            ; right of right margin?
  1492.     jbe    atscu3            ; be = no, continue
  1493.     mov    dl,cl            ; assume no autowrap
  1494.     test    vtemu.vtflgop,decawm    ; Autowrap?
  1495.     jz    atscu3            ; z = no
  1496.     mov    dl,mar_left        ; set to left margin
  1497.     cmp    decrlm,0        ; host right-left mode active?
  1498.     je    atscu1e            ; e = no
  1499.     mov    dl,mar_right
  1500. atscu1e:cmp    dh,byte ptr low_rgt+1    ; at bottom of screen?
  1501.     je    atscu1b            ; e = yes
  1502.     cmp    dh,mar_bot        ; at bottom of scrolling region?
  1503.     jl    atscu2            ; l = no, bump cursor and continue
  1504. atscu1b:test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1505.     jz    atscu1d            ; z = no
  1506.     cmp    dgroll,0        ; is DG roll enabled?
  1507.     jne    atscu1d            ; ne = yes, do the scroll
  1508.     mov    dh,mar_top        ; move to top of window
  1509.     jmp    short atscu3
  1510. atscu1d:mov    scroll,1        ; scroll count = 1 line
  1511.     call    atscru            ; scroll up
  1512.     dec    dh            ; offset inc dh below
  1513. atscu2: inc    dh            ; just bump it
  1514. atscu3: or    dh,dh            ; constrain row to valid range
  1515.     jge    atscu4            ; ge = non-negative row, ok
  1516.     xor    dh,dh
  1517. atscu4: cmp    dh,byte ptr low_rgt+1    ; 25th line?
  1518.     jle    atsetcur        ; le = no
  1519.     mov    dh,byte ptr low_rgt+1    ; set to 24th line
  1520.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  1521.         je      atscu4c                 ; [HF]940227 e = yes, Heath-19
  1522.         cmp     isps55,0                ; [HF]941103 Japanese PS/55 ?
  1523.         je      atscu4a                 ; [HF]941103 e = no
  1524.         cmp     flags.modflg,2          ; [HF]940227 mode line owned by host?
  1525.         jne     atsetcur                ; [HF]940227 ne = no, don't touch
  1526.         jmp     short atscu4a           ; [HF]940227 host wants to go to 25th
  1527. atscu4c:test    h19stat,h19l25          ; Heath 25th line enabled?
  1528.     jz    atsetcur        ; z = no
  1529. atscu4a:inc    dh            ; go to line 25 [hlk]
  1530.     test    yflags,modoff        ; is mode line off?
  1531.     jnz    atscu4b            ; nz = yes
  1532.     push    dx            ; save cursor position
  1533.     call    fclrmod            ; clear the line
  1534.     or    yflags,modoff        ; now say it's off (owned by host)
  1535.     pop    dx
  1536. atscu4b:mov    flags.modflg,2        ; say mode line is owned by host
  1537.  
  1538. atsetcur:cmp    dh,slen            ; beyond last screen row we support?
  1539.     jbe    atsetcur0a        ; be = no
  1540.     mov    dh,slen            ; put on last row
  1541. atsetcur0a:cmp    dl,mar_right        ; beyond right edge?
  1542.     jbe    atsetcur0b        ; be = no
  1543.     mov    dl,mar_right        ; limit to right edge
  1544. atsetcur0b:
  1545.     mov    cursor,dx        ; set cursor and return
  1546.     push    dx
  1547.     mov    bl,dh            ; get row
  1548.     xor    bh,bh            ; clear high byte
  1549.     cmp    linetype[bx],0        ; single width line?
  1550.     je    atsetcu1        ; e = yes
  1551.     shl    dl,1            ; double the column number
  1552. atsetcu1:call    direction        ; set dx to desired position
  1553.     call    setpos            ; set cursor physical position
  1554.     pop    dx
  1555.     test    vtemu.vtflgop,vsmarginbell; do we care about margin bell?
  1556.     jz    atsetcu2        ; z = no, return if no margin bell
  1557.     cmp    kbiflg,0        ; is keyboard input flag set?
  1558.     je    atsetcu2        ; e = no, just return
  1559.     mov    bx,kbicsr        ; cursor at previous keyboard input
  1560.     cmp    bh,dh            ; same row as now?
  1561.     jne    atsetcu2        ; ne = no, just return
  1562.     cmp    bl,belcol        ; old cursor at or left of bell column?
  1563.     ja    atsetcu2        ; a = no, just return
  1564.     cmp    dl,belcol        ; new cursor past bell column?
  1565.     jbe    atsetcu2        ; be = no, just return
  1566.     push    dx
  1567.     call    vtbell            ; ring the bell
  1568.     pop    dx
  1569. atsetcu2:ret
  1570.  
  1571. ; Control-character dispatcher
  1572. atctrl:    cmp    al,escape        ; an escape sequence starting?
  1573.     je    atctrl1            ; e = yes, don't print it
  1574.     cmp    al,CSI            ; this kind of escape?
  1575.     je    atctrl1            ; e = yes
  1576.     cmp    al,18h            ; CAN (cancel)?
  1577.     je    atctrl6            ; e = yes
  1578.     cmp    al,1ah            ; SUB (treated as CAN)?
  1579.     je    atctrl6            ; e = yes
  1580.     cmp    al,9ch            ; ST?
  1581.     jne    atctrl5            ; ne = no
  1582.     jmp    ttstateST
  1583. atctrl5:cmp    ttstate,offset atesc1    ; state is second char of ST?
  1584.     jne    atctrl6            ; ne = no
  1585.     jmp    ttstate            ; go process second char
  1586. atctrl6:test    anspflg,vtcntp        ; printing desired?
  1587.     jz    atctrl1            ; z = no
  1588.     call    fpntchr            ; print char in al
  1589. atctrl1:xor    ah,ah            ; clear for word use below
  1590.     test    al,80h            ; high bit set?
  1591.     jnz    atctrl2            ; nz = yes
  1592.     mov    di,ax            ; use AL as a word index
  1593.     shl    di,1
  1594. atctrl3:jmp    ansc0[di]        ; dispatch on C0 control codes
  1595. atctrl2:and    al,not 80h        ; strip high bit
  1596.     mov    di,ax            ; use AL as a word index
  1597.     shl    di,1
  1598.     test    flags.vtflg,ttvt320+ttvt220 ; doing VT320/VT220?
  1599.     jz    atctrl3            ; z = no, trim back to C0
  1600. atctrl4:jmp    ansc1[di]        ; dispatch on C1 control codes
  1601.  
  1602. ; Control code routines
  1603. atbs:    cmp    decrlm,0        ; host writing direction active?
  1604.     jne    atbs2            ; ne = yes
  1605.     or    dl,dl            ; Backspace, too far?
  1606.     jz    atbs1            ; z = at column 0 already
  1607.     dec    dl            ; backup cursor
  1608. atbs1:    call    atccpc            ; check range
  1609.     mov    atwrap,0        ; cancel wrap pending
  1610.     jmp    atsetcur        ; set cursor and return
  1611.  
  1612. atbs2:    cmp    dl,mar_right        ; at right margin now?
  1613.     je    atbs1            ; e = yes, stop
  1614.     inc    dl
  1615.     jmp    short atbs1
  1616.  
  1617. atht:    cmp    flags.vtflg,ttheath    ; Horizontal Tab, Heath-19 mode?
  1618.     je    atht2            ; e = yes, handle specially
  1619.     xor    ch,ch
  1620.     mov    cl,mar_right
  1621.     cmp    dl,cl            ; at or beyond last column?
  1622.     jae    atht1a            ; ae = yes check range, set cursor
  1623. atht1:    inc    dl            ; tab always moves at least one column
  1624.     push    si
  1625.     mov    si,vtemu.vttbst        ; active buffer
  1626.     call    istabs            ; returns carry set if at a tabstop
  1627.     pop    si
  1628.     jc    atht1a            ; c = at a tabstop
  1629.     loopz    atht1
  1630. atht1a:    call    atccpc            ; check range
  1631. atht1b:    call    atsetcur        ; set cursor and return
  1632.     ret
  1633.  
  1634. atht2:    mov    dx,cursor        ; Heath-19. get cursor position
  1635.     add    dl,8            ; tabs are every 8 columns
  1636.     and    dl,not 7        ; do modulo 8
  1637.     cmp    dl,mar_right        ; check against right edge
  1638.     jbe    atht3            ; be = in range
  1639.     mov    dl,mar_right        ; else go to right margin
  1640. atht3:    jmp    atht1b            ; set cursor and return
  1641.  
  1642. atlf:    test    vtemu.vtflgop,anslnm    ; Line Feed, New-line mode?
  1643.     jz    atlf2            ; z = no, just move to next line down
  1644. atlf1:    mov    dl,mar_left        ; move to left margin also
  1645.     cmp    decrlm,0        ; host writing direction active?
  1646.     je    atlf2            ; e = no
  1647.     mov    dl,mar_right
  1648. atlf2:    test    anspflg,vtautop        ; printing desired?
  1649.     jz    atlf3            ; e = no
  1650.     push    dx
  1651.     push    ax            ; save char
  1652.     call    pntlin            ; print current line
  1653.     pop    ax            ; recover char in AL, print it too
  1654.     call    fpntchr
  1655.     call    fpntflsh        ; flush printer buffer
  1656.     pop    dx
  1657. atlf3:    inc    dh            ; index line down
  1658.     call    atccic            ; check indexing
  1659.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1660.     jz    atlf4            ; z = no, do the scroll if any
  1661.     cmp    protectena,0        ; protected mode on?
  1662.     je    atlf4            ; e = no, can scroll
  1663.     cmp    ax,offset atign        ; scroll requested?
  1664.     je    atlf5            ; e = no
  1665.     mov    dh,mar_top        ; roll over to the top
  1666.     jmp    short atlf5
  1667. atlf4:    call    ax            ; call scrolling routine
  1668. atlf5:    jmp    atsetcur        ; set cursor
  1669.  
  1670. atcr:     mov    dl,mar_left        ; Carriage Return, go to left margin
  1671.     mov    atwrap,0        ; cancel wrap pending
  1672.     cmp    decrlm,0        ; host writing direction active?
  1673.     je    atcr2            ; e = no
  1674.     mov    dl,mar_right
  1675. atcr2:    cmp    flags.vtflg,ttheath    ; Heath-19?
  1676.     jne    atcr1            ; ne = no
  1677.     test    h19stat,h19alf        ; auto line feed on?
  1678.     jnz    atlf2            ; nz = yes, do the LF part above
  1679. atcr1:    cmp    crdisp_mode,0        ; CR-display is normal?
  1680.     jne    atlf2            ; ne = no, do CR-LF
  1681.     jmp    atsetcur        ; set cursor and return
  1682.  
  1683. atff:    cmp    flags.vtflg,ttansi    ; ansi terminal?
  1684.     jne    atff2            ; ne = no
  1685.     cmp    ttstate,offset atescf    ; Form Feed, parsing escape sequence?
  1686.     je    atff1            ; e = yes
  1687.     mov    ninter,0        ; prepare for CSI 2 J simulation
  1688.     mov    lparam,0
  1689.     mov    param,2
  1690.     jmp    ated            ; erase screen, home cursor
  1691.  
  1692. atff2:    cmp    ttstate,offset atescf    ; Form Feed, parsing escape sequence?
  1693.     jne    atlf            ; ne = no, do as line feed
  1694. atff1:    test    denyflg,tekxflg        ; is auto Tek mode disabled?
  1695.     jnz    atlf            ; nz = yes, treat as line feed
  1696. ifndef    no_graphics
  1697.     call    atsc            ; save cursor and associated data
  1698.     mov    al,escape
  1699.     call    TEKEMU
  1700.     mov    al,FF
  1701.     call    TEKEMU            ; feed to Tektronix Emulator, al=FF
  1702.     jmp    atnorm
  1703. else
  1704.     jmp    atlf
  1705. endif    ; no_graphics
  1706.  
  1707. atcan:    mov    parstate,0        ; CAN, clear esc seq parser
  1708.     jmp    atnorm
  1709.  
  1710. atenq:    mov    cx,ENQhstrl-1        ; length of Honeywell string-1
  1711.     mov    si,offset ENQhstr    ; ptr to string
  1712.     mov    ttyact,0        ; start grouping for networks
  1713.     cmp    flags.vtflg,tthoney    ; ENQ, Honeywell terminal?
  1714.     je    atenq1            ; e = yes
  1715.     cmp    vtenqenable,0        ; VTxxx response enabled?
  1716.     je    atenq4            ; e = no
  1717.     cmp    enqbuf,0        ; safe?
  1718.     jne    atenq1f            ; ne = no, unsafe, no prefix
  1719.     mov    cx,ENQstrl        ; length of string
  1720.     mov    si,offset ENQstr    ; ptr to string
  1721. atenq1:    cld    
  1722.     lodsb                ; get a byte
  1723.     push    cx            ; save regs
  1724.     push    si
  1725.     call    prtbout            ; send to port WITHOUT echo
  1726.     pop     si
  1727.     pop    cx
  1728.     loop    atenq1            ; loop for all characters
  1729. atenq1f:cmp    flags.vtflg,tthoney    ; ENQ, Honeywell terminal?
  1730.     je    atenq3            ; e = yes
  1731.     mov    rdbuf,' '
  1732.     mov    di,offset rdbuf        ; place to work
  1733.     cmp    enqbuf,0        ; safe message?
  1734.     jne    atenq1b            ; ne = no, unsafe, no prefix
  1735.     inc    di            ; start with space prefix
  1736.     mov    ax,version        ; Kermit version
  1737.     call    dec2di
  1738.     mov    byte ptr [di],'_'    ; _terminal name
  1739.     inc    di
  1740.     call    getled            ; get terminal name to si
  1741.     mov    cx,8            ; max of 8 bytes
  1742. atenq1a:lodsb                ; read a byte
  1743.     cmp    al,' '            ; still in visibles?
  1744.     jbe    atenq1b            ; be = no
  1745.     mov    [di],al            ; store
  1746.     inc    di
  1747.     loop    atenq1a            ; do more
  1748.  
  1749. atenq1b:mov    si,offset enqbuf+1    ; user postfix, asciiz
  1750.     cmp    byte ptr [si],0        ; anything there?
  1751.     je    atenq1d            ; e = no
  1752.     cmp    byte ptr [si-1],0    ; safe message?
  1753.     jne    atenq1c            ; ne = no, unsafe, no prefix
  1754.     mov    byte ptr [di],'_'    ; separator
  1755.     inc    di
  1756.     dec    cx            ; one less slot
  1757. atenq1c:lodsb
  1758.     or    al,al
  1759.     jz    atenq1d            ; z = end of string
  1760.     cmp    enqbuf,0        ; safe?
  1761.     jne    atenq1e            ; ne = no, unsafe, use as-is
  1762.     cmp    al,' '            ; control code?
  1763.     jae    atenq1e            ; ae = no
  1764.     mov    al,'_'            ; force in separator
  1765. atenq1e:mov    [di],al
  1766.     inc    di
  1767.     jmp    short atenq1c        ; while there is text
  1768.  
  1769. atenq1d:mov    byte ptr [di],CR    ; CR terminator
  1770.     inc    di
  1771.     mov    cx,di
  1772.     mov    si,offset rdbuf
  1773.     sub    cx,si
  1774.     dec    cx            ; do all but last char in loop
  1775. atenq2:    lodsb
  1776.     push    cx            ; save regs
  1777.     push    si
  1778.     call    prtbout            ; send to port WITHOUT echo
  1779.     pop     si
  1780.     pop    cx
  1781.     loop    atenq2
  1782. atenq3:    lodsb                ; last char
  1783.     mov    ttstate, offset atnrm    ; reset to normal and return
  1784.     mov    ttyact,1        ; end group output for networks
  1785.     call    prtbout            ; last byte trips the group trigger
  1786. atenq4:    ret
  1787.  
  1788. atesc:    cmp    ttstate,offset atdcsnul    ; consuming a DCS?
  1789.     jne    atesc3            ; ne = no
  1790.     mov    ttstate,offset atesc1    ; stay here
  1791.     ret
  1792. atesc1:    cmp    al,'\'            ; end of ST?
  1793.     je    atesc2            ; e = yes
  1794.     jmp    atdcsnul        ; continue to consume DCS
  1795. atesc2:    jmp    atgotst            ; reset DCS processing
  1796.  
  1797. atesc3:    mov    ttstate,offset atescf    ; ESC, next state is escape follower
  1798.     ret
  1799.  
  1800. ; Respond to character following Escape, dispatch on that char
  1801. atescf:    call    atpclr            ; clear parser argument list
  1802.     mov    dcstabptr,offset dcstab    ; VT DCS dispatch table
  1803.     mov    atescftab,offset ansesc    ; ANSI escape table, for atdispat
  1804.     mov    ansifinptr,offset anstab
  1805.     mov    cx,flags.vtflg
  1806.     test    cx,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttansi ; VT320 etc?
  1807.     jnz    atescf2            ; nz = yes
  1808.     mov    atescftab,offset v52esc ; VT52 escape table
  1809.     cmp    cx,ttvt52        ; VT52?
  1810.     je    atescf1            ; e = yes
  1811.     mov    atescftab,offset h19esc ; use Heath-19 table
  1812.     cmp    cx,ttheath        ; Heath-19?
  1813.     je    atescf1            ; e = yes
  1814.     mov    atescftab,offset pt200esc
  1815.     cmp    cx,ttpt200        ; Prime PT200?
  1816.     je    atescf2            ; e = yes
  1817.     mov    atescftab,offset dgescftab ; use D470 escape follower table
  1818.     mov    dcstabptr,offset dgdcstab ; DG DCS dispatch table
  1819.     mov    ansifinptr,offset dganstab 
  1820.     cmp    cx,ttd470        ; D470?
  1821.     je    atescf2            ; e = yes
  1822.     ret                ; return on error
  1823. atescf1:mov    ttstate,offset atnrm    ; reset state to "normal"
  1824.     mov    bx,atescftab        ; get offset of escape follower table
  1825.     jmp    atdispat        ; perform dispatch via table in BX
  1826.  
  1827. atescf2:test    al,not (2fh)        ; in intermediates (column 2)?
  1828.     jnz    atescf1            ; nz = no, dispatch on this char
  1829.     mov    ttstate,offset atescf2    ; stay in this state til col 3 or more
  1830.     mov    bx,ninter        ; number of intermediates
  1831.     cmp    bx,maxinter        ; done enough already?
  1832.     jae    atescf3            ; ae = yes, ignore the excess
  1833.     mov    inter[bx],al        ; store this one
  1834.     inc    ninter            ; one more
  1835. atescf3:ret                ; get more input
  1836.  
  1837.                     ; CSI, char 9bh (ANSI CSI == ESC [)
  1838. atcsi0:    cmp    ninter,0        ; any intermediates from ESC..[?
  1839.     je    atcsi            ; e = no, else not this item
  1840.     jmp    atnorm            ; reset state to "normal"
  1841.                     ; enter here with real CSI char
  1842. atcsi:    mov    ttstate,offset atparse    ; next state is parse control seq
  1843.     mov    parfail,offset atnorm    ; where to jmp if failure
  1844.     mov    pardone,offset atcsi1    ; where to jmp when done
  1845.     jmp    atpclr            ; clear parser parameters and return
  1846.  
  1847. atcsi1:    mov    bx,ansifinptr        ; ANSI Final character table
  1848.     mov    ttstate,offset atnrm    ; reset state to "normal"
  1849.     jmp    atdispat        ; dispatch on character
  1850.  
  1851. h19csi:    test    vtemu.vtflgop,decanm    ; Heath-19 "ESC [", is ANSI mode on?
  1852.     jnz    h19csi1            ; nz = yes
  1853.     mov    ttstate,offset atnrm    ; else ignore the "[" (kbd lock)
  1854.     ret
  1855. h19csi1:mov    ttstate,offset atparse    ; H-19, ESC [ parser
  1856.     mov    pardone,offset h19csi2     ; where to jmp when done
  1857.     mov    parfail,offset atnorm    ; where to jmp if failure
  1858.     ret                ; get next char
  1859. h19csi2:mov    bx,offset h19ans    ; H-19 ANSI Final character table
  1860.     mov    ttstate,offset atnrm    ; reset state to "normal"
  1861.     jmp    atdispat        ; dispatch on character
  1862.  
  1863. ; Process Device Control Strings (DCS or ESC P lead-in chars, already read).
  1864. atdcs0:    cmp    ninter,0        ; any intermediates?
  1865.     je    atdcs            ; e = no, else not this item
  1866.     jmp    atnorm            ; reset state to normal
  1867.                     ; enter here with real DCS char
  1868. atdcs:    mov    ttstate,offset atparse    ; next state is parse control seq
  1869.     mov    pardone,offset atdcs1    ; where to jmp when done
  1870.     mov    parfail,offset atdcsnul    ; where to jmp if failure
  1871.     ret
  1872. atdcs1:    mov    dcsstrf,al        ; record Final char
  1873.     mov    emubufc,0        ; clear string count
  1874.     mov    cx,maxparam        ; number of DCS parameters
  1875.     push    si            ; copy these to the DCS area so that
  1876.     push    di            ;  they are not lost when an ST is
  1877.     push    es            ;  parsed (parser clears ESC items)
  1878.     push    ds
  1879.     pop    es
  1880.     mov    si,offset param        ; ESC paramater storage area, numeric
  1881.     mov    di,offset dparam    ; DCS parameter storage area, numeric
  1882.     cld
  1883.     rep    movsw            ; copy set to DCS storage area
  1884.     mov    cl,lparam         ; copy letter Paramter
  1885.     mov    dlparam,cl
  1886.     mov    cx,maxinter        ; number of intermediate characters
  1887.     mov    si,offset inter        ; source
  1888.     mov    di,offset dinter    ; destination
  1889.     rep    movsb
  1890.     mov    si,nparam        ; number of parameters
  1891.     mov    dnparam,si
  1892.     mov    si,ninter
  1893.     mov    dninter,si        ; number of intermediates
  1894.     pop    es
  1895.     pop    di
  1896.     pop    si
  1897.     mov    ttstateST,offset atnorm ; default ST completion state
  1898.     mov    emubufc,0        ; clear processed string length
  1899.     mov    al,dcsstrf        ; get DCS Final char
  1900.     mov    bx,dcstabptr        ; DCS dispatch table
  1901.     call    atdispat        ; go to DCS handler
  1902.     ret
  1903.  
  1904. ; Process ST or ESC \  String Terminator.
  1905. atgotst0:cmp    ninter,0        ; any intermediates in ESC..\?
  1906.     je    atgotst            ; e = no, else not this item
  1907.     jmp    atnorm            ; reset state to normal
  1908.                     ; enter here with real ST char
  1909. atgotst:jmp    ttstateST        ; go to state for ST arrival
  1910.  
  1911. ; Read and discard OSC (ESC ]), PM (ESC ^) control sequences
  1912. ; through final ST (ESC \) terminator.
  1913. atdcsnul0:cmp    ninter,0        ; any intermediates in ESC..\?
  1914.     je    atdcsnul        ; e = no, else not this item
  1915.     ret
  1916.                     ; enter here with real ST char
  1917. atdcsnul:mov    dcsstrf,0        ; simulate a null (dummy) Final char
  1918.     mov    emubufc,0        ; clear string count
  1919.     mov    ttstate,offset atdcsnul    ; keep coming here
  1920.     mov    ttstateST,offset atnorm    ; where to go when ST has been seen
  1921.     ret                ; consume chars
  1922.  
  1923. ; Process Application Process Control string (APC or ESC _ lead-in chars,
  1924. ; already read). Mallocs 1KB buffer, passes buffer to apcmacro for execution
  1925. ; as a Take file. Curly braces protect comma command separators.
  1926. atapc:    cmp    ninter,0        ; any intermediates?
  1927.     je    atapc0            ; e = no, else not this item
  1928.     jmp    atnorm            ; reset state to normal
  1929.                     ; enter here with real DCS char
  1930. atapc0:    mov    ax,apcstring        ; old string buffer segment
  1931.     or    ax,ax            ; used?
  1932.     jz    atapc1            ; z = no
  1933.     push    es
  1934.     mov    es,ax
  1935.     mov    ah,freemem        ; free that string memory
  1936.     int    dos
  1937.     pop    es
  1938.     mov    apcstring,0        ; clear pointer
  1939. atapc1:    mov    bx,(1024+3+15)/16    ; 1K buffer
  1940.     mov    cx,bx            ; remember desired paragraphs
  1941.     mov    ah,alloc        ; allocate a memory block
  1942.     int    dos
  1943.     jc    atapc2            ; c = error, not enough memory
  1944.      cmp    bx,cx            ; obtained vs wanted
  1945.     jae    atapc3            ; ae = enough
  1946.     push    es
  1947.     mov    es,ax            ; allocated segment
  1948.     mov    ah,freemem        ; free it again
  1949.     int    dos
  1950.     pop    es
  1951. atapc2:    jmp    atnorm            ; fail
  1952.  
  1953. atapc3:    mov    apcstring,ax        ; remember segment
  1954.     mov    bracecount,0        ; count of curly braces in string
  1955.     mov    emubufc,0        ; preset string buffer count
  1956.     mov    ttstate,offset atapc4    ; next state is read string
  1957.     mov    ttstateST,offset atapc5    ; where to go when ST has been seen
  1958.     ret
  1959.                     ; read bytes of APC string
  1960. atapc4:    mov    bx,emubufc        ; count of buffer chars
  1961.     cmp    bx,1024            ; too many?
  1962.     ja    atapc6            ; a = yes, ignore string
  1963.     push    es
  1964.     mov    cx,apcstring        ; segment of string buffer
  1965.     mov    es,cx
  1966.     cmp    al,braceop        ; opening brace?
  1967.     jne    atapc4a            ; ne = no
  1968.     inc    bracecount        ; count up braces
  1969. atapc4a:cmp    al,bracecl        ; closing brace?
  1970.     jne    atapc4b            ; ne = no
  1971.     sub    bracecount,1        ; count down braces
  1972.     jnc    atapc4b            ; nc = not below zero
  1973.     mov    bracecount,0        ; clamp to zero
  1974. atapc4b:cmp    al,','            ; comma command separator?
  1975.     jne    atapc4c            ; ne = no
  1976.     cmp    bracecount,0        ; in curly braces?
  1977.     jne    atapc4c            ; ne = yes, leave comma as comma
  1978.     mov    al,CR            ; replace bare comma as CR
  1979. atapc4c:xor    ah,ah
  1980.     mov    es:[bx+2],ax        ; store incoming byte + null
  1981.     pop    es
  1982.     inc    emubufc            ; count bytes in buffer
  1983.     ret                ; accumulate more bytes
  1984.  
  1985. atapc5:    mov    ax,apcstring        ; get here upon ST for APC
  1986.     or    ax,ax            ; string buffer in use?
  1987.     jz    atapc6            ; z = no, quit
  1988.     mov    ttstate,offset atnrm    ; reinit state before leaving
  1989.     mov    ttstateST,offset atnorm
  1990.     mov    bracecount,0        ; count of curly braces in string
  1991.     cmp    apcenable,0        ; is APCMACRO enabled?
  1992.     je    atapc6            ; e = no, quit
  1993.     push    es
  1994.     mov    es,ax
  1995.     mov    bx,emubufc        ; count of bytes in string
  1996.     mov    emubufc,0        ; clear for later users
  1997.     mov    byte ptr es:[bx+2],CR    ; append CR C to renter Connect mode
  1998.     mov    byte ptr es:[bx+2+1],'C'
  1999.     add    bx,2            ; two more bytes in buffer
  2000.     mov    es:[0],bx        ; length of string
  2001.     pop    es
  2002.     mov    cx,bx            ; CX used to pass string length
  2003.     call    APCMACRO        ; create and execute Take file
  2004.                     ; does not return if success
  2005. atapc6:    mov    ax,apcstring        ; segment of string buffer
  2006.     or    ax,ax            ; in use?
  2007.     jz    atapc7            ; z = no
  2008.     mov    es,ax
  2009.     mov    ah,freemem        ; free buffer
  2010.     int    dos
  2011. atapc7:    mov    apcstring,0        ; clear buffer
  2012.     mov    emubufc,0        ; clear string count
  2013.     mov    bracecount,0        ; count of curly braces in string
  2014.     jmp    atnorm            ; exit this sequence
  2015.  
  2016.  
  2017. ; User Definable Key processor of DCS strings.
  2018. atudk:    cmp    dinter,0        ; no intermediates?
  2019.     je    atudk1            ; e = correct
  2020.     mov    ninter,0        ; setup atdcsnul for proper form
  2021.     jmp    atdcsnul        ; bad, consume the rest
  2022.  
  2023. atudk1:    cmp    dparam,1        ; is initial Parameter Pc a 1?
  2024.     jae    atudk2            ; ae = yes, clear only this key
  2025.     call    udkclear        ; clear all UDKeys
  2026.     mov    dparam,1        ; and turn off Parameter
  2027. atudk2:    mov    ttstate,offset atudk3    ; next state is get a substring
  2028.     mov    ttstateST, offset atudk6 ; for when ST has been seen
  2029.     ret
  2030.  
  2031. atudk3:    cmp    al,';'            ; string separator?
  2032.     je    atudk5            ; e = yes, process string to-date
  2033.     mov    bx,emubufc        ; count of chars in string buffer
  2034.     cmp    bx,emubufl        ; too many?
  2035.     jae    atudk4            ; ae = too many, ignore extras
  2036.     mov    emubuf[bx],al        ; store the char
  2037.     inc    emubufc            ; count it
  2038. atudk4:    ret
  2039. atudk5:    mov    si,offset emubuf    ; address of string buffer is DS:SI
  2040.     mov    cx,emubufc        ; count of buffer contents
  2041.     call    setudk            ; insert string definition
  2042.     mov    emubufc,0        ; clear string buffer
  2043.     ret
  2044. atudk6:    call    atudk5            ; ST seen, process last string
  2045.     jmp    atnorm            ; reset state to normal
  2046.  
  2047. ; Call this routine to deliver Parameters in succession. Each call points to
  2048. ; a Parameter as param[si], where si is maintained here. If there are no
  2049. ; Parameters the effect is the same as one Parameter with a value of zero.
  2050. ; Enter with di = offset of action routine to be called for each Parameter.
  2051. ; cx, si, and di are preserved over the call to the action routine.
  2052.  
  2053. atreps    proc    near
  2054.     xor    si,si            ; initialize parm index
  2055.     mov    cx,nparam        ; number of Parameters
  2056.     or    cx,cx            ; zero?
  2057.     jnz    atrep1            ; nz = no
  2058.     inc    cx            ; zero parms is same as 1
  2059. atrep1: push    cx            ; save loop counter
  2060.     push    si            ; save parameter index
  2061.     push    di            ; save call vector
  2062.     call    DI            ; call indicated routine
  2063.     pop    di            ; restore registers
  2064.     pop    si
  2065.     pop    cx
  2066.     add    si,2            ; advance to next parameter
  2067.     loop    atrep1            ; loop for all
  2068.     ret
  2069. atreps    endp
  2070.  
  2071.                     ; Action routines
  2072. atind0:    cmp    ninter,0        ; any intermediates?
  2073.     je    atind            ; e = no, else not this item
  2074.     ret
  2075. atind:    inc    dh            ; IND (index), move cursor down one
  2076. atind1: call    atccic            ; check cursor position
  2077.     call    ax            ; scroll if necessary
  2078.     jmp    atsetcur        ; set cursor, etc. and return
  2079.  
  2080. atnel0:    cmp    ninter,0        ; any intermediates from ESC..E?
  2081.     je    atnel            ; e = no, else not this item
  2082.     jmp    atdgnrc            ; try Nowegian/Danish NRC designator
  2083.                     ; enter here with real NEL char
  2084. atnel:    mov    dl,mar_left        ; NEL, next line - sort of like CRLF
  2085.     inc    dh            ; ... all in one command
  2086.     jmp    short atind1        ; check cursor, etc., and return
  2087.  
  2088. atri0:    cmp    ninter,0        ; any intermediates?
  2089.     je    atri            ; e = no, else not this item
  2090.     ret
  2091. atri:    cmp    flags.vtflg,ttheath    ; Heath-19?
  2092.     jne    atri1            ; ne = no
  2093.     cmp    dh,byte ptr low_rgt+1    ; on 25th line?
  2094.     jbe    atri1            ; be = no
  2095.     ret                ; no vertical for Heath on 25th line
  2096. atri1:    dec    dh            ; RI, reverse index
  2097.     jmp    short atind1        ; check cursor, etc., and return
  2098.  
  2099.                     ; HTS, horizontal tab set in this col
  2100. athts0:    cmp    ninter,0        ; any intermediates from ESC..H?
  2101.     je    athts            ; e = no, else not this item
  2102.         cmp     isps55,0                ; [HF] Japanese mode ?
  2103.         je      athts1                  ; [HF] e = no
  2104.         jmp     atdgfJ                  ; [HF] else possible old wrong JISRoman
  2105. athts1: jmp     atdgnrc                 ; try Swedish NRC designator
  2106. athts:    call    atccpc            ; make column number valid
  2107.     mov    si,vtemu.vttbst        ; active buffer
  2108.     jmp    tabset            ; say set tab in this column (DL)
  2109.  
  2110.                     ; DECSC
  2111. atsc:    mov    si,offset savelist    ; save cursor, attribute, char set etc
  2112.     mov    di,offset savecu    ; place to save the stuff
  2113.     mov    cl,extattr        ; extended attributes
  2114.     mov    savextattr,cl        ; it's real storage is in msyibm
  2115.     mov    cl,scbattr
  2116.     mov    savscbattr,cl
  2117.     mov    havesaved,1        ; say have saved something
  2118.     mov    cx,lsavecu        ; length of save area
  2119.     push    es            ; save es
  2120.     mov    ax,data            ; seg of save area
  2121.     mov    es,ax            ; set es to data segment
  2122.     cld
  2123.     shr    cx,1            ; divide by two for word moves
  2124.     jnc    atsc1            ; nc = even number of bytes
  2125.     movsb                ; do the odd byte
  2126. atsc1:    rep    movsw            ; save it
  2127.     pop    es
  2128.     mov    cx,vtemu.vtflgop    ; save a copy of the flags
  2129.     mov    savflgs,cx
  2130.     ret
  2131.                     ; DECRC
  2132. atrc:    cmp    havesaved,0        ; saved anything yet?
  2133.     jne    atrc1            ; ne = yes
  2134.     ret
  2135. atrc1:    mov    si,offset savecu    ; restore cursor, attributes, etc
  2136.     mov    di,offset savelist    ; where stuff goes
  2137.     mov    cx,lsavecu        ; length of save area
  2138.     push    es            ; save es
  2139.     push    ds
  2140.     mov    ax,seg savecu        ; seg of savecu storage
  2141.     mov    ds,ax
  2142.     mov    ax,seg savelist        ; seg of regular storage
  2143.     mov    es,ax
  2144.     cld
  2145.     shr    cx,1            ; divide by two for word moves
  2146.     jnc    atrc2            ; nc = even number of bytes
  2147.     movsb                ; do the odd byte
  2148. atrc2:    rep    movsw            ; put the stuff back
  2149.     pop    ds
  2150.     pop    es
  2151.     mov    al,savextattr        ; extended attributes
  2152.     mov    extattr,al
  2153.     mov    al,savscbattr
  2154.     mov    scbattr,al
  2155.     mov    ax,savflgs        ; get saved flags
  2156.     xor    ax,vtemu.vtflgop    ; exclusive-or with current flags
  2157.     mov    al,atctype        ; get cursor shape
  2158.     call    csrtype            ; restore it
  2159. atrc3:    mov    ax,vtemu.vtflgop    ; reset flags in case called again
  2160.     and    ax, not(decckm+deckpam+decom)  ; remove old bits [dlk]
  2161.     and    savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
  2162.     or    ax,savflgs        ; restore saved bits [dlk]
  2163.     or    vtemu.vtflgop,ax    ; update these flags
  2164.     mov    savflgs,ax
  2165.     mov    bx,offset Gsetid    ; restore character sets
  2166.     call    chrsetup        ; go remake G0..G3
  2167.     mov    dx,cursor        ; get cursor
  2168.     mov    kbiflg,0        ; don't bother them with beeps here
  2169.     jmp    atsetcur        ; set cursor
  2170.  
  2171. atkpam:    cmp    ninter,0        ; any intermediates?
  2172.     jne    atkpam1            ; ne = yes, not this item
  2173.     or    vtemu.vtflgop,deckpam    ; turn on keypad applications mode
  2174.     ret
  2175. atkpam1:jmp    atdgnrc            ; try Swiss NRC designator
  2176.  
  2177. atkpnm: and    vtemu.vtflgop,not deckpam ; turn off keypad applications mode
  2178.     ret                ; (to numeric mode)
  2179.  
  2180.                     ; Privileged sequence, ignore it
  2181. atpriv:    cmp    ninter,0        ; any intermediates?
  2182.     jne    atpriv1            ; ne = yes, not this item
  2183.     mov    ttstate,offset atnorm    ; ignore next char
  2184. atpriv1:ret                ; and return to normal afterward
  2185.  
  2186. ; ISO 2022 three byte Announcer Summary    <ESC> <space> <final char>
  2187. ;Esc Sequence  7-Bit Environment          8-Bit Environment
  2188. ;----------    ------------------------   ----------------------------------
  2189. ;<ESC><SP>A    G0->GL                     G0->GL
  2190. ;<ESC><SP>B    G0-(SI)->GL, G1-(SO)->GL   G0-(LS0)->GL, G1-(LS1)->GL
  2191. ;<ESC><SP>C    (not used)                 G0->GL, G1->GR
  2192. ;<ESC><SP>D    G0-(SI)->GL, G1-(SO)->GL   G0->GL, G1->GR
  2193. ;<ESC><SP>E    Full preservation of shift functions in 7 & 8 bit environments
  2194. ;<ESC><SP>F    C1 represented as <ESC>F   C1 represented as <ESC>F
  2195. ;<ESC><SP>G    C1 represented as <ESC>F   C1 represented as 8-bit quantity
  2196. ;<ESC><SP>H    All graphic character sets have 94 characters
  2197. ;<ESC><SP>I    All graphic character sets have 94 or 96 characters
  2198. ;<ESC><SP>J    In a 7 or 8 bit environment, a 7 bit code is used
  2199. ;<ESC><SP>K    In an 8 bit environment, an 8 bit code is used
  2200. ;<ESC><SP>L    Level 1 of ISO 4873 is used
  2201. ;<ESC><SP>M    Level 2 of ISO 4873 is used
  2202. ;<ESC><SP>N    Level 3 of ISO 4873 is used
  2203. ;<ESC><SP>P    G0 is used in addition to any other sets:
  2204. ;              G0 -(SI)-> GL              G0 -(LS0)-> GL
  2205. ;<ESC><SP>R    G1 is used in addition to any other sets:
  2206. ;              G1 -(SO)-> GL              G1 -(LS1)-> GL
  2207. ;<ESC><SP>S    G1 is used in addition to any other sets:
  2208. ;              G1 -(SO)-> GL              G1 -(LS1R)-> GR
  2209. ;<ESC><SP>T    G2 is used in addition to any other sets:
  2210. ;              G2 -(LS2)-> GL             G2 -(LS2)-> GL
  2211. ;<ESC><SP>U    G2 is used in addition to any other sets:
  2212. ;              G2 -(LS2)-> GL             G2 -(LS2R)-> GR
  2213. ;<ESC><SP>V    G3 is used in addition to any other sets:
  2214. ;              G3 -(LS2)-> GL             G3 -(LS3)-> GL
  2215. ;<ESC><SP>W    G3 is used in addition to any other sets:
  2216. ;              G3 -(LS2)-> GL             G3 -(LS3R)-> GR
  2217. ;<ESC><SP>Z    G2 is used in addition to any other sets:
  2218. ;              SS2 invokes a single character from G2
  2219. ;<ESC><SP>[    G3 is used in addition to any other sets:
  2220. ;              SS3 invokes a single character from G3
  2221. ;
  2222. ; ISO Escape Sequences for Alphabet Designation ("F" = Final char)
  2223. ; Sequence     Function                                         Invoked By
  2224. ;  <ESC>(F     assigns 94-character graphics set "F" to G0.     SI  or LS0
  2225. ;  <ESC>)F     assigns 94-character graphics set "F" to G1.     SO  or LS1
  2226. ;  <ESC>*F     assigns 94-character graphics set "F" to G2.     SS2 or LS2
  2227. ;  <ESC>+F     assigns 94-character graphics set "F" to G3.     SS3 or LS3
  2228. ;  <ESC>-F     assigns 96-character graphics set "F" to G1.     SO  or LS1
  2229. ;  <ESC>.F     assigns 96-character graphics set "F" to G2.     SS2 or LS2
  2230. ;  <ESC>/F     assigns 96-character graphics set "F" to G3.     SS3 or LS3
  2231. ;  <ESC>$(F    assigns multibyte character set "F" to G0.       SI  or LS0
  2232. ;  <ESC>$)F    assigns multibyte character set "F" to G1.       SO  or LS1
  2233. ;  <ESC>$*F    assigns multibyte character set "F" to G2.       SS2 or LS2
  2234. ;  <ESC>$+F    assigns multibyte character set "F" to G3.       SS3 or LS3
  2235. ;     
  2236. ; Designate character sets, AL has final character, inter has all preceeding.
  2237. ;
  2238. ;  <ESC> $ B       designate JIS X 208 code set (ISO(ECMA)#87) to G0 (old)
  2239. ;  <ESC> $ <char> B  designates JIS X 208 code set (ISO(ECMA)#87)
  2240. ;
  2241. ;  The following sequences are for JIS C 6226-1978 code set (ISO(ECMA)#42), but
  2242. ;  treated as the same as the above in this version of MS-Kermit, becuase that the
  2243. ;  diffrence is quite small.
  2244. ;
  2245. ;  <ESC> $ @
  2246. ;  <ESC> $ <char> @
  2247. ;
  2248. ;  <ESC> <char> J  designates JIS X 201 Roman code set (ISO(ECMA)#14)
  2249. ;
  2250. ;  Note: The ESC sequences for U.S. ASCII code set are treated as the same
  2251. ;        as above because there is no fonts are available for U.S. ASCII .
  2252. ;        The differences between U.S. ASCII and JIS X 201 Roman are only
  2253. ;        backslash and tilde.
  2254. ;
  2255. atdgfA:    call    atdgset            ; 'A' ISO Latin-1, UK-ASCII
  2256.     jc    atdgfA1            ; c = no matching pointer
  2257.     cmp    inter,'+'        ; in the 94 byte set?
  2258.     ja    atdgfA2            ; a = no, 96 'A' is Latin1
  2259.     mov    ax,flags.vtflg        ; terminal type
  2260.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttansi ; VTxxx?
  2261.     jz    atdgfA1            ; z = no
  2262.     jmp    mkukascii        ; make UK ASCII table
  2263. atdgfA1:ret
  2264.  
  2265. atdgfA2:jmp    mklatin1        ; make Latin1 char set
  2266.  
  2267. atdgfA3:jmp    atdgnrc            ; try British NRC
  2268.  
  2269. atdgfB:    cmp    inter,'$'        ; [HF] 940130 multibyte set?
  2270.     je    atdgfB2            ; [HF] 940130 e = yes
  2271.     call    atdgset            ; 'B' ASCII, get setptr from inter
  2272.     jc    atdgfA1            ; c = no matching pointer
  2273.     cmp    inter,'+'        ; in the 94 byte set?
  2274.     ja    atdgfB1            ; a = no, do Latin2
  2275.     jmp    mkascii            ; make US ASCII set
  2276.  
  2277. atdgfB1:jmp    mklatin2        ; make Latin2 ("B"/96)
  2278.  
  2279. atdgfB2:cmp    ninter,1        ; [HF] any intermediates?
  2280.     jne    atdgfB3            ; [HF] ne = yes we have
  2281.     mov    inter,'('        ; [HF] implicit G0 /94
  2282.     jmp    short atdgfB4        ; [HF]
  2283. atdgfB3:push    ax            ; [HF]
  2284.     mov    al,inter[1]        ; [HF]
  2285.     mov    inter,al        ; [HF]
  2286.     mov    ninter,1        ; [HF]
  2287.     pop    ax            ; [HF]
  2288. atdgfB4:call    atdgset            ; [HF]
  2289.     jc    atdgfA1            ; [HF]
  2290.     jmp    mkjiskanji        ; [HF]
  2291.  
  2292. ;[HF] Japanese JIS-Katakana and JIS-Roman
  2293. ;[HF]
  2294. atdgfI:    call    atdgset            ; [HF] JIS-Katakana
  2295.     jc    atdgfI1            ; [HF] c = no matching pointer
  2296.     cmp    inter,'+'        ; [HF] in the 94 byte set?
  2297.     ja    atdgfI1            ; [HF] a = no, just ignore
  2298.     mov    ax,flags.vtflg        ; [HF] terminal type
  2299.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; [HF] VTxxx?
  2300.     jz    atdgfI1            ; [HF] z = no
  2301.     jmp    mkjiskana        ; [HF] make JIS Katakana table
  2302. atdgfI1:ret                ; [HF]
  2303.  
  2304. atdgfJ:    call    atdgset            ; [HF] JIS-Roman
  2305.     jc    atdgfJ1            ; [HF] c = no matching pointer
  2306.     cmp    inter,'+'        ; [HF] in the 94 byte set?
  2307.     ja    atdgfJ1            ; [HF] a = no, just ignore
  2308.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; [HF] VTxxx?
  2309.     jz    atdgfJ1            ; [HF] z = no
  2310.     jmp    mkascii            ; [HF] treat as US ASCII
  2311. atdgfJ1:ret                ; [HF]
  2312.  
  2313. atdgf0:    call    atdgset            ; '0', '2', DEC Special Graphics
  2314.     jc    atdgfA1            ; c = no matching pointer
  2315.     cmp    inter,'+'        ; in the 94 byte set?
  2316.     ja    atdgfA1            ; a = no, ignore
  2317.     jmp    mkdecspec        ; init set to DEC Special Graphics
  2318.  
  2319. atdgf1:    call    atdgset            ; '1' ALT-ROM
  2320.     jc    atdgf1b            ; c = no matching pointer
  2321.     jmp    mkaltrom        ; make ALT-ROM set
  2322.  
  2323. atdgf1b:
  2324. ;    cmp    ninter,0        ; ESC 1? (Special enter Tek mode)
  2325. ;    jne    atdgf1c            ; ne = some, not ESC 1
  2326. ;    cmp    nparam,0
  2327. ;    jne    atdgf1c            ; ne = some, not ESC 1
  2328. ;    jmp    atff1            ; treat the same as ESC ^L
  2329. atdgf1c:ret
  2330.  
  2331. atdgft:    call    atdgset            ; '>' Dec Technical Set
  2332.     jc    atdgft1            ; c = no matching pointer
  2333.     cmp    inter,'+'        ; in the 94 byte set?
  2334.     ja    atdgft1            ; a = no
  2335.     jmp    mkdectech        ; make DEC Tech set
  2336.  
  2337. atdgft1:cmp    ninter,0        ; ESC > DECKNPNM set numeric keypad?
  2338.     jne    atdgft2            ; ne = no
  2339.     and    vtemu.vtflgop,not deckpam ; turn off application keypad bit
  2340. atdgft2:ret                ;  (to numeric)
  2341.                     ; '<' User Preferred Supplemental Set
  2342. atdgfu:    call    atdgset            ; get set pointer
  2343.     jc    atdgfu2            ; c = no matching pointer
  2344.     test    flags.vtflg,ttvt220    ; in VT220 mode?
  2345.     jnz    atdgfu1b        ; nz = yes, force DEC Supplemental
  2346. ; DEC VT320's ignore the set size designator when picking UPSS sets here
  2347.     cmp    word ptr upss+1,0+'A'    ; is ISO Latin-1 the preferred set?
  2348.     jne    atdgfu0a        ; ne = no
  2349.     jmp    mklatin1        ; make Latin1 set
  2350. atdgfu0a:cmp    word ptr upss+1,0+'H'    ; is Hebrew-ISO preferred?
  2351.     jne    atdgfu1            ; ne = no
  2352.     jmp    mklatin_Hebrew        ; make Hebrew-ISO
  2353.  
  2354. atdgfu1:cmp    word ptr upss+1,'5%'    ; DEC Supplemental Graphics?
  2355.     jne    atdgfu1a        ; ne = no
  2356. atdgfu1b:jmp    mkdecmn            ; make DEC Multinat/Supp Graphics
  2357. atdgfu1a:cmp    word ptr upss+1,'4"'    ; DEC Hebrew?
  2358.     jne    atdgfu2
  2359.     jmp    mkdec_Hebrew        ; make DEC Hebrew 
  2360. atdgfu2:ret
  2361.  
  2362. atdgfq:    call    atdgset            ; '?' Transparent
  2363.     jc    atdgfu2            ; c = no matching pointer
  2364.     jmp    mkxparent        ; make transparent table
  2365.  
  2366.                     ; ESC <...> <1-8>  series
  2367. atsdhl:    cmp    ninter,1        ; just one intermediate?
  2368.     jne    atsdh0            ; ne = no
  2369.     cmp    inter,'#'        ; this intermediate?
  2370.     jne    atdgnrc            ; ne = no, try NRC char set designator
  2371.     cmp    al,'3'            ; Double high lines. Top half?
  2372.     je    atsdh2            ; e = yes
  2373.     cmp    al,'4'            ; bottom half?
  2374.     je    atsdh2            ; e = yes
  2375.     cmp    al,'5'            ; restore line to single width?
  2376.     je    atsdh1            ; e = yes
  2377.     cmp    al,'6'            ; double width single height?
  2378.     je    atsdh2            ; e = yes
  2379.     cmp    al,'8'            ; screen alignment?
  2380.     je    atsdh8            ; e = yes
  2381. atsdhx:    ret                ; else ignore
  2382.  
  2383. atsdh1:    jmp    linesgl            ; set line to single width
  2384. atsdh2:    jmp    linedbl            ; expand the line to double width
  2385. atsdh8:    jmp    atalign            ; do screen alignment
  2386.  
  2387. atsdh0:    cmp    ninter,0        ; zero intermediates?
  2388.     jne    atdgf5            ; ne = no, try for more
  2389.     cmp    al,'7'            ; save cursor?
  2390.     jne    atsdh0a            ; ne = no
  2391.     jmp    atsc            ; do save cursor, ESC 7
  2392. atsdh0a:cmp    al,'8'            ; restore cursor?
  2393.     jne    atsdh0b            ; ne = no
  2394.     jmp    atrc            ; do restore cursor, ESC 8
  2395. atsdh0b:ret
  2396.  
  2397. atdgf5:    cmp    ninter,2        ; two intermediates?
  2398.     jne    atdgf5a            ; ne = no, ignore remainder
  2399.     cmp    al,'6'            ; '%6' NRC designator?
  2400.     je    atdgnrc            ; e = yes, do that above
  2401.     cmp    al,'5'            ; '%5' DEC Supplemental Graphic?
  2402.     jne    atdgf5a            ; ne = no
  2403.     cmp    inter,'+'        ; in the 94 byte set?
  2404.     ja    atdgf5a            ; a = no, ignore
  2405.     cmp    inter[1],'%'        ; '%5'?
  2406.     jne    atdgf5a            ; ne = no
  2407.     mov    ninter,1        ; help atdgset find our set
  2408.     call    atdgset            ; get set pointer
  2409.     jc    atdgf5a            ; c = no matching pointer
  2410.     jmp    mkdecmn            ; make DEC Multinat/Supp Gr
  2411. atdgf5a:ret
  2412.  
  2413. ; Enter with Final esc char in al, others in array inter. Setup Gn if success.
  2414. atdgnrc    proc    near            ; check for NRC set designator
  2415.     cmp    ninter,0        ; ESC Z?
  2416.     jne    atdgnr1            ; ne = no
  2417.     cmp    al,'Z'            ; the Z?
  2418.     jne    atdgnrx            ; ne = not ESC Z
  2419.     jmp    atda            ; process ident request
  2420. atdgnr1:cmp    inter,'+'        ; in the 94 byte set?
  2421.     ja    atdgnrx            ; a = no, ignore
  2422.     call    findctry        ; find NRC country number in CX
  2423.     jc    atdgnrx            ; c = not found, ignore
  2424.     mov    ninter,1        ; help atdgset find our set
  2425.     call    atdgset            ; check for Gn designator
  2426.     jc    atdgnrx            ; c = not found
  2427.     jmp    mknrc            ; make NRC set
  2428. atdgnrx:ret                ; ignore
  2429. atdgnrc    endp
  2430.  
  2431. ; Find NRC country number, putting it into CX, given Final char in AL and
  2432. ; intermediates in array inter. Return carry set if not found.
  2433. findctry proc    near
  2434.     cmp    ninter,2        ; second intermediate (%)?
  2435.     jb    findct1            ; b = no
  2436.     ja    findct3            ; a = three or more, no match
  2437.     mov    ah,inter+1        ; get NRC intermediate
  2438.     cmp    ax,'%6'            ; Portugese NRC?
  2439.     jne    findct4            ; ne = no, try Hebrew
  2440.     mov    cx,9            ; Portuguese NRC is number 9
  2441.     clc
  2442.     ret
  2443. findct4:cmp    ax,'%='            ; Hebrew NRC?
  2444.     jne    findct3            ; ne = no, fail
  2445.     mov    cx,13            ; Hebrew NRC is number 13
  2446.     clc
  2447.     ret
  2448. findct1:cmp    ninter,0        ; no intermediate?
  2449.     je    findct3            ; e = yes, no designator, fail
  2450.     mov    cx,nrcflen        ; number of NRC letters to consider
  2451.     cld
  2452.     push    di            ; save regs
  2453.     push    es
  2454.     push    ds
  2455.     pop    es
  2456.     mov    di,offset nrcfinal    ; list of NRC final chars
  2457.     repne    scasb            ; look for a match
  2458.     pop    es            ; recover reg
  2459.     jne    findct2            ; ne = failed
  2460.     dec    di            ; compenstate for auto-inc
  2461.     sub    di,offset nrcfinal    ; get distance covered
  2462.     mov    cl,nrcnum[di]        ; country number from parallel list
  2463.     xor    ch,ch            ; return number in CX
  2464.     pop    di
  2465.     clc                ; success
  2466.     ret
  2467. findct2:pop    di            ; carry set = failure
  2468. findct3:stc
  2469.     ret
  2470. findctry endp
  2471.  
  2472. ; Worker for atdgf routines. Return setptr looking at Gnset (n=0..3) and
  2473. ; carry clear, based on ninter=1, inter = Gn designator. Carry set if fail.
  2474. ; Modifies AL
  2475. atdgset    proc    near
  2476.     cmp    ninter,1        ; one intermediate?
  2477.     jne    atdgsex            ; ne = no, ignore
  2478.     mov    al,inter        ; inter, from parser
  2479.     cmp    al,'('            ; 94 char sets, designate G0?
  2480.     je    atdgse0            ; e = yes
  2481.     cmp    al,')'            ; G1?
  2482.     je    atdgse1
  2483.     cmp    al,'*'            ; G2?
  2484.     je    atdgse2
  2485.     cmp    al,'+'            ; G3?
  2486.     je    atdgse3
  2487.     cmp    al,'-'            ; 96 char sets, designate G1?
  2488.     je    atdgse1
  2489.     cmp    al,'.'            ; G2?
  2490.     je    atdgse2
  2491.     cmp    al,'/'            ; G3?
  2492.     je    atdgse3
  2493. atdgsex:stc                ; carry set for failure
  2494.     ret
  2495. atdgse0:mov    setptr,offset G0set    ; designate G0 set
  2496.     clc
  2497.     ret
  2498. atdgse1:mov    setptr,offset G1set    ; designate G1 set
  2499.     clc
  2500.     ret
  2501. atdgse2:mov    setptr,offset G2set    ; designate G2 set
  2502.     clc
  2503.     ret
  2504. atdgse3:mov    setptr,offset G3set    ; designate G3 set
  2505.     clc
  2506.     ret
  2507. atdgset endp
  2508.                     ; S7C1T/S8C1T select 7/8-bit controls
  2509. ats7c:    test    flags.vtflg,ttvt320+ttvt220 ; in VT320/VT220 mode?
  2510.     jz    atdgsex            ; z = no, ignore command
  2511.     cmp    ninter,1        ; one intermediate?
  2512.     jne    ats7ca            ; ne = no
  2513.     cmp    inter,' '        ; proper intermediate?
  2514.     jne    ats7ca            ; ne = no
  2515.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls bit
  2516. ats7ca:ret                ; done
  2517.  
  2518. ats8c:    cmp    inter,' '        ; proper intermediate?
  2519.     jne    ats8ca            ; ne = no
  2520.     cmp    ninter,1        ; just one?
  2521.     jne    ats8ca            ; ne = no
  2522.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls bit
  2523. ats8ca:    ret
  2524.  
  2525. ; Designate User Preferred Supplemental Set as
  2526. ;  'A' ISO Latin-1  or '%','5' DEC Supplemental Graphics, or
  2527. ;  'H' Hebrew-ISO,  or '"','4' DEC-Hebrew
  2528. ; Store the selection letters in array upss for later use by ESC <char> '<'
  2529. atupss:    cmp    word ptr dinter,0+'!'    ; "!u" proper intermediate?
  2530.     je    atupss0            ; e = yes
  2531.     mov    ninter,0        ; set up atdcsnul for proper form
  2532.     jmp    atdcsnul        ; consume unknown command
  2533. atupss0:mov    ah,94            ; assume 94 byte set
  2534.     cmp    dparam,1        ; 96 byte char size indicator?
  2535.     jb    atupss1            ; b = no, 94
  2536.     ja    atupss2            ; a = illegal Parameter
  2537.     mov    ah,96            ; say 96
  2538. atupss1:mov    upss,ah            ; store char set size
  2539.     mov    ttstateST,offset atupss4; where to go when ST has been seen
  2540.     mov    emubufc,0        ; clear buffer count
  2541.     mov    ttstate,offset atupss2    ; next state is get string
  2542.     ret
  2543. atupss2:mov    bx,emubufc        ; count of chars in string buffer
  2544.     cmp    bx,emubufl        ; too many?
  2545.     jae    atupss3            ; ae = too many, ignore extras
  2546.     mov    emubuf[bx],al        ; store the char
  2547.     inc    emubufc            ; count it
  2548. atupss3:ret
  2549. atupss4:mov    si,emubufc        ; count of chars in string
  2550.     mov    emubuf[si],0        ; terminate string in null
  2551.     mov    ax,word ptr emubuf    ; copy two chars from string to
  2552.     mov    word ptr upss+1,ax    ;  upss char set ident storage area
  2553.     mov    emubufc,0        ; clear the string count
  2554.     ret
  2555.  
  2556. ; Select/map character sets
  2557. atls0:    test    flags.vtflg,ttansi    ; ANSI-BBS?
  2558.     jnz    atlsx            ; nz = yes, avoid BBS stupidities
  2559.     mov    GLptr,offset G0set    ; LS0,  map G0 char set into GLeft
  2560.     ret                ; Control-O
  2561. atls1:    test    flags.vtflg,ttansi    ; ANSI-BBS?
  2562.     jnz    atlsx            ; nz = yes, avoid BBS stupidities
  2563.     mov    GLptr,offset G1set    ; LS1,  map G1 char set into GLeft
  2564.     ret                ; Control-N
  2565. atls1r:    cmp    ninter,0        ; any intermediate chars?
  2566.     jne    atlsx            ; ne = yes, not a Locking Shift
  2567.     mov    GRptr,offset G1set    ; LS1R, map G1 char set into GRight
  2568.     ret
  2569. atss2:    cmp    ninter,0        ; any intermediate chars?
  2570.     jne    atlsx            ; ne = yes, not a Single Shift
  2571.     mov    SSptr,offset G2set    ; SS2,  use G2 for next graphics only
  2572.     ret
  2573. atls2:    cmp    ninter,0        ; any intermediate chars?
  2574.     jne    atlsx            ; ne = yes, not a Locking Shift
  2575.     mov    GLptr,offset G2set    ; LS2,  map G2 char set into GLeft
  2576.     ret
  2577. atls2r:    cmp    ninter,0        ; any intermediate chars?
  2578.     jne    atlsx            ; ne = yes, not a Locking Shift
  2579.     mov    GRptr,offset G2set    ; LS2R, map G2 char set into GRight
  2580.     ret
  2581. atss3:    cmp    ninter,0        ; any intermediate chars?
  2582.     jne    atlsx            ; ne = yes, not a Single Shift
  2583.     mov    SSptr,offset G3set    ; SS3,  use G3 for next graphics only
  2584.     ret
  2585. atls3:    cmp    ninter,0        ; any intermediate chars?
  2586.     jne    atlsx            ; ne = yes, not a Locking Shift
  2587.     mov    GLptr,offset G3set    ; LS3,  map G3 char set into GLeft
  2588.     ret
  2589. atls3r:    cmp    ninter,0        ; any intermediate chars?
  2590.     jne    atlsx            ; ne = yes, not a Locking Shift
  2591.     mov    GRptr,offset G3set    ; LS3R, map G3 char set into GRight
  2592. atlsx:    ret
  2593.  
  2594.  
  2595. ; Routine to set default character set.
  2596. chrdef    proc    near
  2597.       mov    GLptr,offset G0set    ; map G0 set to GLeft
  2598.     mov    GRptr,offset G2set    ; map G2 set to GRight
  2599.     mov    SSptr,0            ; clear single shift
  2600.     mov    bx,offset emubuf    ; temp table of char set idents
  2601.     mov    word ptr [bx],C_ASCII    ; G0 and G1 to ASCII
  2602.     mov    al,vtemu.vtchset    ; user specifed char set for GL
  2603.     mov    byte ptr [bx+2],al    ; set G2 and G3 to user selected set
  2604.     mov    byte ptr [bx+3],al
  2605.     cmp    al,C_SHORT_KOI        ; Short KOI?
  2606.     jne    chrdef0b        ; ne = no
  2607.     mov    byte ptr [bx],al    ; force into all sets, as if an NRC
  2608.     mov    byte ptr [bx+1],al
  2609. chrdef0b:test    flags.vtflg,ttvt320+ttvt220
  2610.     jnz    chrdef1            ; nz = yes, 8-bit terminals
  2611.     mov    GRptr,offset G1set    ; map G1 set to GRight
  2612.     mov    byte ptr [bx+1],C_DECTECH ; assume Dec Special Graphics in G1
  2613.     test    flags.vtflg,ttansi    ; ANSI-BBS?
  2614.     jz    chrdef0a        ; z = no
  2615.     mov    byte ptr [bx+1],C_XPARENT ; set TRANSPARENT
  2616.     jmp    short chrdef1
  2617. chrdef0a:test    flags.vtflg,ttwyse    ; Wyse-50?
  2618.     jz    chrdef1            ; z = no
  2619.     mov    byte ptr [bx+1],C_WYSEGR ; Wyse-50 graphics to G1
  2620.  
  2621. chrdef1:cmp     vtemu.vtchset,C_JISKANJI        ;[HF] JIS-Kanji?
  2622.         jne     chrdef1a                        ;[HF] ne = no
  2623.         mov     byte ptr [bx+2],C_JISKAT        ;[HF] G2 = JIS-Katakana
  2624.         mov     byte ptr [bx+3],al              ;[HF] G3 = JIS-Kanji
  2625.         mov     GRptr,offset G3set              ;[HF] GR = G3 (as VT382)
  2626.         jmp     short chrdef2                   ;[HF]
  2627. chrdef1a:test   vtemu.vtflgop,vsnrcm    ; doing National Replacement Chars?
  2628.     jz    chrdef2            ; z = no
  2629.     mov    al,vtemu.vtchset    ; get country number
  2630.     mov    dgkbl,al        ; keyboard language
  2631.     cmp    al,C_DHEBNRC        ; max NRC country
  2632.     ja    chrdef2            ; a = out of bounds, ignore
  2633.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  2634.     mov    ah,al            ; country number 1..12
  2635.     mov    [bx],al            ; set G0
  2636.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  2637.     jnz    chrdef2            ; nz = yes, don't touch G1..G3 here
  2638.     mov    [bx+1],ah
  2639.     mov    word ptr [bx],ax    ; same char set in G0..G3
  2640.     mov    word ptr [bx+2],ax
  2641.  
  2642. chrdef2:test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  2643.     jz    chrdef5            ; z = no (should have all cases now)
  2644.     mov    al,C_DGINT        ; D463/D470 DG International to G1
  2645.     test    flags.remflg,d8bit    ; 8 bit mode?
  2646.     jnz    chrdef4            ; nz = yes
  2647. chrdef3:mov    al,C_DGWP        ; D463/D470 DG Word Processing to G1
  2648. chrdef4:mov    [bx+1],al        ; D463/D470 G1 default
  2649.     mov    dgkbl,al        ; DG keyboard language
  2650.     mov    vtemu.vtchset,al
  2651.     mov    ah,[bx]            ; G0
  2652.     or    ah,ah            ; using NRCs?
  2653.     jz    chrdef5            ; z = no
  2654.     mov    dgkbl,ah        ; yes, state NRC in use for kbd
  2655.     jmp    short chrdef5
  2656.  
  2657. chrdef5:call    chrsetup        ; worker to setup G0..G3
  2658.                     ; do table of Gn overrides
  2659.     mov    bx,offset vtemu.vttable    ; table of char set overrides
  2660. chrdef6:call    chrsetup                ; worker to setup G0..G3
  2661.     ret
  2662. chrdef    endp
  2663.  
  2664. ; Load G0..G3 with character sets whose idents (0..24) are in byte array 
  2665. ; pointed to by BX. Update Gsetid with those byte idents enroute.
  2666. chrsetup proc    near
  2667.     push    ninter            ; preserve these
  2668.     mov    ch,inter
  2669.     push    cx            ; save them
  2670.     mov    ninter,1        ; one intermediate
  2671.     mov    inter,'('        ; init inter for atdgset
  2672.     xor    cx,cx            ; count sets from 0
  2673. chrset1:push    cx            ; save loop counter
  2674.     push    bx
  2675.     call    atdgset            ; get setptr = offset Gnset (n=0..3)
  2676.     mov    al,[bx]            ; get char set ident from 4 byte list
  2677.     cmp    al,0ffh            ; none?
  2678.     je    chrset90        ; e = none
  2679.     mov    bx,cx            ; update Gsetid table with set ident
  2680.     mov    Gsetid[bx],al
  2681.     cmp    al,C_ASCII        ; ASCII (0)?
  2682.     jne    chrset13        ; ne = no
  2683.     call    mkascii            ; make ASCII
  2684.     jmp    chrset90
  2685.  
  2686. chrset13:cmp    al,C_DHEBNRC        ; in NRC's?
  2687.     ja    chrset14              ; a = no
  2688.     mov    cl,al            ; put country number in cx
  2689.     xor    ch,ch
  2690.     call    mknrc            ; setup an NRC, using cx and setptr
  2691.     jmp    chrset90
  2692.  
  2693. chrset14:cmp    al,C_ALTROM        ; want ALT-ROM?
  2694.     jne    chrset15        ; ne = no
  2695.     call    mkaltrom        ; do ALT-ROM setup
  2696.     jmp    chrset90
  2697.  
  2698. chrset15:cmp    al,C_XPARENT        ; Transparent (15)?
  2699.     jne    chrset16        ; ne = no
  2700.     call    mkxparent        ; do Transparent setup
  2701.     jmp    chrset90
  2702.  
  2703. chrset16:cmp    al,C_LATIN1        ; Latin1 (16)?
  2704.     jne    chrset17
  2705.     cmp    setptr,offset G0set    ; want 96 byte set in G0?
  2706.     je    chrset90        ; e = yes, can not do this
  2707.     call    mklatin1        ; make Latin1
  2708.     jmp    chrset90
  2709.  
  2710. chrset17:cmp    al,C_DMULTINAT        ; DEC-MCS (17)?
  2711.     jne    chrset18        ; ne = no
  2712.     call    mkdecmn            ; make DEC Supplement Graph (DEC-MCS)
  2713.     jmp    chrset90
  2714.  
  2715. chrset18:cmp    al,C_DECTECH        ; DEC-Technical (18)?
  2716.     jne    chrset19        ; ne = no
  2717.     call    mkdectech        ; make DEC Technical
  2718.     jmp    chrset90
  2719.  
  2720. chrset19:cmp    al,C_DECSPEC        ; DEC-Special-Graphics?
  2721.     jne    chrset20        ; ne = no
  2722.     call    mkdecspec        ; make DEC Special Graphics
  2723.     jmp    chrset90
  2724.  
  2725. chrset20:cmp    al,C_DGINT        ; DG International?
  2726.     jne    chrset21        ; ne = no
  2727.     call    mkdgint            ; make DG International
  2728.     jmp    short chrset90
  2729.  
  2730. chrset21:cmp    al,C_DGLINE        ; DG Line Drawing?
  2731.     jne    chrset22        ; ne = no
  2732.     call    mkdgld            ; make DG line drawing
  2733.     jmp    short chrset90
  2734.  
  2735. chrset22:cmp    al,C_DGWP        ; DG Word Processing?
  2736.     jne    chrset23        ; ne = no
  2737.     call    mkdgwp            ; make DG Word Procssing
  2738.     jmp    short chrset90
  2739.     
  2740. chrset23:cmp    al,C_LATIN2        ; Latin2/CP852?
  2741.     jne    chrset24        ; ne = no
  2742.     call    mklatin2
  2743.     jmp    short chrset90
  2744.  
  2745. chrset24:cmp    al,C_HEBREWISO        ; Hebrew-ISO (CP862)?
  2746.     jne    chrset26        ; ne = no
  2747.     call    mklatin_hebrew
  2748.     jmp    short chrset90
  2749.  
  2750. chrset26:cmp    al,C_WYSEGR        ; Wyse-50 graphics chars?
  2751.     jne    chrset27        ; ne = no
  2752.     call    mkwyse
  2753.     jmp    short chrset90
  2754.  
  2755. chrset27:cmp    al,C_HPROMAN8        ; HP-Roman8?
  2756.     jne    chrset28        ; ne = no
  2757.     call    mkhpr8
  2758.     jmp    short chrset90
  2759.  
  2760. chrset28:cmp    al,C_CYRILLIC_ISO    ; Cyrillic to CP866?
  2761.     jne    chrset29        ; ne = no
  2762.     call    mkcyiso
  2763.     jmp    short chrset90
  2764.  
  2765. chrset29:cmp    al,C_KOI8        ; Cyrillic KOI8 to CP866?
  2766.     jne    chrset30        ; ne = no
  2767.     call    mkkoi8
  2768.     jmp    short chrset90
  2769.  
  2770. chrset30:cmp    al,C_SHORT_KOI        ; Cyrillic Short-KOI to CP866?
  2771.     jne    chrsetj13        ; ne = no
  2772.     call    mkkoi7
  2773.     jmp    short chrset90
  2774.  
  2775.  
  2776. chrsetj13:cmp   al,C_JISKAT             ; [HF] JIS-Katakana?
  2777.         jne     chrsetj87               ; [HF] ne = no
  2778.         call    mkjiskana               ; [HF]
  2779.         jmp     short chrset90          ; [HF]
  2780.  
  2781. chrsetj87:cmp    al,C_JISKANJI        ; [HF] JIS-Kanji?
  2782.     jne    chrset100        ; [HF] ne = no
  2783.     call    mkjiskanji        ; [HF]
  2784.     jmp    short chrset90        ; [HF]
  2785.  
  2786. chrset100:cmp    al,100+1        ; possible DG soft set?
  2787.     jb    chrset90        ; ne = no
  2788.     cmp    al,100+31        ; in range of soft sets?
  2789.     ja    chrset90        ; a = no
  2790.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  2791.     jz    chrset90        ; z = no
  2792.     call    mkdgsoft        ; do it (softset # + 100+1 is in al)
  2793.  
  2794. chrset90:pop    bx
  2795.     pop    cx
  2796.     inc    bx            ; next byte of table
  2797.     inc    inter            ; next set pointer
  2798.     inc    cx
  2799.     cmp    cx,4            ; done all sets?
  2800.     jae    chrset92        ; ae = yes
  2801.     jmp    chrset1            ; b = no (counting sets as 0..3)
  2802. chrset92:pop    cx            ; recover saved parsing items
  2803.     mov    inter,cl        ; restore
  2804.     pop    ninter            ; this too
  2805.     ret
  2806. chrsetup endp
  2807.  
  2808. ; Make Data General International to Gn table. 
  2809. ; Enter with destination in setptr
  2810. mkdgint    proc    near
  2811.     push    si
  2812.     push    di
  2813.     push    es
  2814.     mov    di,setptr
  2815.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  2816.     xor    ah,ah
  2817.     mov    si,ax
  2818.     mov    Gsetid[si],C_DGINT    ; store our char set ident
  2819.     mov    ax,ds
  2820.     mov    es,ax
  2821.     PUSH    DS
  2822.     call    flatin1        ; get DS:BX to Code Page dependent Latin1
  2823.     mov    si,bx
  2824.     cld
  2825.     push    di
  2826.     mov    cx,gsize        ; gsize chars
  2827.     rep    movsb            ; copy appropriate Latin1 xlat table
  2828.     pop    di
  2829.     mov    cx,dgi2len        ; number of new chars
  2830.     mov    si,offset dgi2lat    ; source of chars to be translated
  2831.     add    di,20h            ; where new chars start
  2832.  
  2833. mkdgin1:PUSH    DS
  2834.     mov    ax,seg dgi2lat
  2835.     mov    ds,ax
  2836.     lodsb                ; read Latin1 code point from dgi2lat
  2837.     POP    DS
  2838.     cmp    al,80h            ; "?" unknown indicator or ASCII?
  2839.     jb    mkdgin2            ; b = yes, reproduce it literally
  2840.     sub    al,80h            ; map down to indexable value
  2841.     xlatb                ; translate through Latin1 table
  2842. mkdgin2:stosb                ; store in active table
  2843.     loop    mkdgin1            ; do all necessary
  2844.     POP    DS
  2845.     mov    di,setptr
  2846.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2847.     mov    word ptr[di+gsize+1],'ID' ; set ident code
  2848.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2849.     pop    es
  2850.     pop    di
  2851.     pop    si
  2852.     call    invcopy            ; create keyboard table by inversion
  2853.     ret
  2854. mkdgint    endp
  2855.  
  2856. ; Make Data General line drawing graphics to Gn table. 
  2857. ; Enter with destination in setptr
  2858. mkdgld    proc    near
  2859.     push    si
  2860.     push    di
  2861.     mov    di,setptr
  2862.     mov    al,[di+gsize+3+1]        ; get Gn number (0..3)
  2863.     xor    ah,ah
  2864.     mov    si,ax
  2865.     mov    Gsetid[si],C_DGLINE        ; store our char set ident
  2866.     mov    cx,gsize        ; first fill with spaces
  2867.     mov    al,20h
  2868.     push    es
  2869.     push    ds
  2870.     pop    es
  2871.     push    di            ; save starting location
  2872.     cld
  2873.     rep    stosb            ; spaces
  2874.     pop    di
  2875.     add    di,20h            ; where new chars start
  2876.     mov    si,offset dgldc        ; replacement chars
  2877.     mov    cx,dgldclen        ; number of new chars
  2878.     rep    movsb            ; copy them to the table
  2879.     mov    di,setptr
  2880.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2881.     mov    word ptr[di+gsize+1],'LD' ; set ident code
  2882.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2883.     pop    es
  2884.     pop    di
  2885.     pop    si
  2886.     call    invcopy            ; create keyboard table by inversion
  2887.     ret
  2888. mkdgld    endp
  2889.  
  2890. ; Make Data General word processing to Gn table. 
  2891. ; Enter with destination in setptr
  2892. mkdgwp    proc    near
  2893.     push    si
  2894.     push    di
  2895.     mov    di,setptr
  2896.     mov    al,[di+gsize+3+1]        ; get Gn number (0..3)
  2897.     xor    ah,ah
  2898.     mov    si,ax
  2899.     mov    Gsetid[si],C_DGWP    ; store our char set ident
  2900.     mov    cx,gsize        ; first fill with spaces
  2901.     mov    al,20h
  2902.     push    es
  2903.     push    ds
  2904.     pop    es
  2905.     push    di            ; save starting location
  2906.     cld
  2907.     rep    stosb            ; spaces
  2908.     pop    di
  2909.     add    di,20h            ; where new chars start
  2910.     mov    si,offset dgwpcp437    ; replacement chars
  2911.     mov    cx,dgwplen        ; number of new chars
  2912.     push    ds
  2913.     mov    ax,seg dgwpcp437
  2914.     mov    ds,ax
  2915.     rep    movsb            ; copy them to the table
  2916.     pop    ds
  2917.     mov    di,setptr
  2918.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2919.     mov    word ptr[di+gsize+1],'WD' ; set ident code
  2920.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2921.     pop    es
  2922.     pop    di
  2923.     pop    si
  2924.     call    invcopy            ; create keyboard table by inversion
  2925.     ret
  2926. mkdgwp    endp
  2927.  
  2928. ; Make Data General soft set to Gn table. 
  2929. ; Enter with destination in setptr, reg AL holding 100d + softset-20h+1
  2930. mkdgsoft proc    near
  2931.     push    ax
  2932.     call    mkascii
  2933.     pop    ax
  2934. ifndef    no_graphics
  2935.     push    ax
  2936.     call    mksoftspace        ; create space for soft set, uses AL
  2937.     pop    ax
  2938.     jnc    mkdgsoft1        ; nc = got the memory
  2939.     ret                ; c = failed, use ASCII
  2940. endif    ; no_graphics
  2941. mkdgsoft1:push    bx
  2942.     mov    bx,setptr
  2943.     mov    byte ptr[bx+gsize],94    ; say this is a 94 byte set
  2944.     mov    word ptr[bx+gsize+1],'UD' ; set ident code
  2945.     mov    byte ptr[bx+gsize+3],al    ; say hard char set (101..131)
  2946.     mov    bl,[bx+gsize+3+1]    ; get Gn number (0..3)
  2947.     xor    bh,bh
  2948.     mov    Gsetid[bx],al        ; store our char set ident
  2949.     pop    bx
  2950.     call    invcopy            ; create keyboard table by inversion
  2951.     ret
  2952. mkdgsoft endp
  2953.  
  2954. ; Make DEC Alt-ROM to Gn table.
  2955. ; Enter with destination in setptr
  2956. mkaltrom proc    near
  2957.     call    mkascii            ; init set to ASCII
  2958.     push    si
  2959.     push    di
  2960.     push    es
  2961.     push    ds
  2962.     pop    es            ; point es at data segment
  2963.     mov    di,setptr
  2964.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  2965.     xor    ah,ah
  2966.     mov    si,ax
  2967.     mov    Gsetid[si],C_ALTROM    ; store our char set ident
  2968.     add    di,60h            ; replace a..z with 20h + (a..z)
  2969.     mov    si,di            ; special graphics table
  2970.     mov    cx,27            ; number of chars to do (a..z)
  2971.     cld
  2972. decalt1:lodsb                ; get a char
  2973.     add    al,20h            ; map up by 20h
  2974.     stosb
  2975.     loop    decalt1
  2976.     mov    di,setptr
  2977.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2978.     mov    word ptr[di+gsize+1],0+'1' ; set ident code
  2979.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2980.     pop    es
  2981.     pop    di
  2982.     pop    si
  2983.     call    invcopy            ; create keyboard table by inversion
  2984.     ret
  2985. mkaltrom endp
  2986.  
  2987. ; Make DEC special graphics to Gn table.
  2988. ; Enter with destination in setptr
  2989. mkdecspec proc    near
  2990.     call    mkascii            ; init set to ASCII
  2991.     push    si
  2992.     push    di
  2993.     mov    di,setptr
  2994.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  2995.     xor    ah,ah
  2996.     mov    si,ax
  2997.     mov    Gsetid[si],C_DECSPEC    ; store our char set ident
  2998.     add    di,95            ; replace chars 95-126
  2999.     mov    si,offset sgrtab    ; use DEC special graphics table
  3000.     mov    cx,sgrtabl        ; table length
  3001.     test    flags.vtflg,ttheath    ; Heath rather than VT?
  3002.     jz    mkdecsp1        ; z = no
  3003.     mov    si,offset hgrtab    ; use Heath table
  3004.     mov    cx,hgrtabl
  3005.     dec    di            ; work from 94 rather than 95
  3006. mkdecsp1:push    es
  3007.     push    ds
  3008.     pop    es
  3009.     push    ds
  3010.     mov    ax,seg sgrtab
  3011.     mov    ds,ax
  3012.     cld
  3013.     rep    movsb            ; replace chars with sgrtab items
  3014.     pop    ds
  3015.     mov    di,setptr
  3016.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3017.     mov    word ptr[di+gsize+1],0+'0' ; set ident code
  3018.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3019.     pop    es
  3020.     pop    di
  3021.     pop    si
  3022.     call    invcopy            ; create keyboard table by inversion
  3023.     clc
  3024.     ret
  3025. mkdecspec endp
  3026.  
  3027. ; Make Dec Technical to Gn table
  3028. ; Enter with destination in setptr
  3029. mkdectech proc    near
  3030.     push    si
  3031.     push    di
  3032.     mov    di,setptr
  3033.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3034.     xor    ah,ah
  3035.     mov    si,ax
  3036.     mov    Gsetid[si],C_DECTECH    ; store our char set ident
  3037.     push    es
  3038.     push    ds
  3039.     pop    es
  3040.     cld
  3041.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3042.     mov    di,setptr        ; destination
  3043.     mov    si,offset dectech    ; source data
  3044.     push    ds
  3045.     mov    ax,seg dectech
  3046.     mov    ds,ax
  3047.     rep    movsb
  3048.     pop    ds
  3049.     pop    es
  3050.     mov    di,setptr
  3051.     mov    byte ptr[di+gsize],94    ; say this is a 96 byte set
  3052.     mov    word ptr[di+gsize+1],0+'>' ; set ident code
  3053.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3054.     pop    di
  3055.     pop    si
  3056.     call    invcopy            ; create keyboard table by inversion
  3057.     clc
  3058.     ret
  3059. mkdectech endp
  3060.  
  3061. ; Make Cyrillic_ISO to CP866
  3062. ; Enter with destination in setptr
  3063. mkcyiso proc    near
  3064.     push    si
  3065.     push    di
  3066.     mov    di,setptr
  3067.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3068.     xor    ah,ah
  3069.     mov    si,ax
  3070.     mov    Gsetid[si],C_CYRILLIC_ISO ; store our char set ident
  3071.     push    es
  3072.     push    ds
  3073.     pop    es
  3074.     cld
  3075.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3076.     mov    di,setptr        ; destination
  3077.     mov    si,offset lccp866r    ; source data
  3078.     push    ds
  3079.     mov    ax,seg lccp866r
  3080.     mov    ds,ax
  3081.     rep    movsb
  3082.     pop    ds
  3083.     pop    es
  3084.     mov    di,setptr
  3085.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3086.     mov    word ptr[di+gsize+1],'CI' ; set ident code
  3087.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3088.     push    es
  3089.     mov    cx,gsize
  3090.     mov    di,seg cp866lci
  3091.     mov    es,di
  3092.     mov    di,offset cp866lci
  3093.     call    tblcopy            ; create keyboard table
  3094.     pop    es
  3095.     pop    di
  3096.     pop    si
  3097.     clc
  3098.     ret
  3099. mkcyiso endp
  3100.  
  3101. ; Make Cyrillic KOI8 to CP866
  3102. ; Enter with destination in setptr
  3103. mkkoi8 proc    near
  3104.     push    si
  3105.     push    di
  3106.     mov    di,setptr
  3107.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3108.     xor    ah,ah
  3109.     mov    si,ax
  3110.     mov    Gsetid[si],C_KOI8    ; store our char set ident
  3111.     push    es
  3112.     push    ds
  3113.     pop    es
  3114.     cld
  3115.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3116.     mov    di,setptr        ; destination
  3117.     mov    si,offset k8cp866r    ; source data
  3118.     push    ds
  3119.     mov    ax,seg k8cp866r
  3120.     mov    ds,ax
  3121.     rep    movsb
  3122.     pop    ds
  3123.     pop    es
  3124.     mov    di,setptr
  3125.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3126.     mov    word ptr[di+gsize+1],'CK' ; set ident code
  3127.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3128.     push    es
  3129.     mov    cx,gsize
  3130.     mov    di,seg cp866koi8
  3131.     mov    es,di
  3132.     mov    di,offset cp866koi8
  3133.     call    tblcopy            ; create keyboard table
  3134.     pop    es
  3135.     pop    di
  3136.     pop    si
  3137.     clc
  3138.     ret
  3139. mkkoi8 endp
  3140.  
  3141. ; Make Short-KOI (7 bit) to CP866
  3142. ; Enter with destination in setptr
  3143. mkkoi7 proc    near
  3144.     push    si
  3145.     push    di
  3146.     mov    di,setptr
  3147.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3148.     xor    ah,ah
  3149.     mov    si,ax
  3150.     mov    Gsetid[si],C_SHORT_KOI    ; store our char set ident
  3151.     push    es
  3152.     push    ds
  3153.     pop    es
  3154.     cld
  3155.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3156.     mov    di,setptr        ; destination
  3157.     mov    si,offset k7cp866r    ; source data
  3158.     push    ds
  3159.     mov    ax,seg k7cp866r
  3160.     mov    ds,ax
  3161.     rep    movsb
  3162.     pop    ds
  3163.     pop    es
  3164.     mov    di,setptr
  3165.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3166.     mov    word ptr[di+gsize+1],'CS' ; set ident code
  3167.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3168.     push    es
  3169.     mov    cx,gsize
  3170.     mov    di,seg cp866koi7
  3171.     mov    es,di
  3172.     mov    di,offset cp866koi7
  3173.     call    tblcopy            ; create keyboard table
  3174.     pop    es
  3175.     pop    di
  3176.     pop    si
  3177.     clc
  3178.     ret
  3179. mkkoi7 endp
  3180.  
  3181. ; Make Heath-19 special graphics to Gn table. Enter with dest of setptr.
  3182.  
  3183. ; Initialize a char set to ASCII values 0..127 and ident of 94/B
  3184. ; Enter with setptr holding offset of G0set, G1set, G2set, or G3set char set
  3185. mkascii    proc    near
  3186.     push    ax
  3187.     push    cx
  3188.     push    di
  3189.     push    es
  3190.     mov    di,setptr        ; char set to init (G0..G3)
  3191.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3192.     xor    ah,ah
  3193.     mov    si,ax
  3194.     mov    Gsetid[si],C_ASCII    ; store our char set ident
  3195.     mov    cx,gsize        ; number of bytes to do
  3196.     xor    al,al            ; initial value
  3197.     push    ds
  3198.     pop    es            ; set es to data segment
  3199.     cld
  3200. mkascii1:stosb                ; copy value to char set table
  3201.     inc    al
  3202.     loop    mkascii1
  3203.     mov    di,setptr
  3204.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3205.     mov    word ptr[di+gsize+1],0+'B' ; set ident code to ASCII "B"
  3206.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3207.     pop    es
  3208.     pop    di
  3209.     pop    cx
  3210.     pop    ax
  3211.     call    invcopy            ; create keyboard table by inversion
  3212.     ret
  3213. mkascii    endp
  3214.  
  3215. ; Make UK ASCII to table Gn
  3216. ; Enter with destination in setptr
  3217. mkukascii proc    near
  3218.     call    mkascii            ; make US ASCII table
  3219.     push    di
  3220.     mov    di,setptr        ; get set pointer
  3221.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3222.     xor    ah,ah
  3223.     mov    si,ax
  3224.     mov    Gsetid[si],C_UKNRC    ; store our char set ident
  3225.     mov    byte ptr[di+23h],156    ; replace sharp 2/3 with Sterling sign
  3226.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3227.     mov    word ptr[di+gsize+1],0+'A' ; set ident code
  3228.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3229.     pop    di
  3230.     call    invcopy            ; create keyboard table by inversion
  3231.     ret
  3232. mkukascii endp
  3233.  
  3234. ; Make DEC Multinational Char Set (DEC-MCS/DEC Supplemental Graphics)
  3235. ; and put into Gn table indicated by AL = 0..3
  3236. ; Enter with destination in setptr
  3237. mkdecmn    proc    near
  3238.     push    si
  3239.     push    di
  3240.     mov    di,setptr        ; get set pointer
  3241.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3242.     xor    ah,ah
  3243.     mov    si,ax
  3244.     mov    Gsetid[si],C_DMULTINAT ; store our char set ident
  3245.     push    es
  3246.     mov    ax,seg G0set        ; segment of Gn's
  3247.     mov    es,ax
  3248.     PUSH    DS
  3249.     call    flatin1            ; get Latin1 to DS:BX
  3250.     mov    si,bx
  3251.     cld
  3252.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3253.     rep    movsb
  3254.     POP    DS
  3255.     mov    di,setptr
  3256.     mov    al,[di+24h]        ; 10/4 Latin1 (currency) to
  3257.     mov    [di+28h],al        ; 10/8 DEC-MCS
  3258.     mov    byte ptr [di+57h],3fh     ; 13/7 OE to ?
  3259.     mov    al,[di+7fh]        ; 15/15 Latin1 (lower y umlate) to
  3260.     mov    [di+7dh],al        ; 15/13 DEC-MCS
  3261.     mov    cx,13            ; number of updates
  3262.     xor    bh,bh
  3263.     mov    ax,seg MNlatin
  3264.     mov    es,ax
  3265.     mov    si,offset MNlatin    ; get update table
  3266. mkdecmn1:mov    bl,es:[si]        ; get Latin1 code point to be changed
  3267.     and    bl,not 80h        ; map down to 0..127 range
  3268.     mov    byte ptr [di+bx],20h    ; store new value (space)
  3269.     inc    si
  3270.     loop    mkdecmn1
  3271.     pop    es
  3272.     mov    di,setptr
  3273.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3274.     mov    word ptr[di+gsize+1],'5%' ; set ident code
  3275.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3276.     pop    di
  3277.     pop    si
  3278.     call    invcopy            ; create keyboard table by inversion
  3279.     ret
  3280. mkdecmn    endp
  3281.  
  3282. ;[HF] Put JIS Katakana char set (128..255) into Gn table.
  3283. ;[HF] Enter with destination in setptr
  3284. mkjiskana proc    near
  3285.     call    mkascii            ; init set to ASCII
  3286.     push    si
  3287.     push    di
  3288.     mov    di,setptr        ; point at character set
  3289.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3290.     xor    ah,ah
  3291.     mov    si,ax
  3292.     mov    Gsetid[si],C_JISKAT    ; store our char set ident
  3293.     add    di,33        ;[HF]941227 start position
  3294.     mov    cx,63        ;[HF]941227 number of chars to do (16 x 4 - 1)
  3295.     mov    al,(33+128)    ;[HF]941227 start with 8th bit on
  3296.     cld
  3297.     push    es
  3298.     push    ds
  3299.     pop    es            ; point es at data segment
  3300. mkjiskana2:stosb            ; store codes 128..223
  3301.     inc    al
  3302.     loop    mkjiskana2
  3303.     mov    di,setptr
  3304.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3305.     mov    word ptr[di+gsize+1],0+'I' ; set ident code
  3306.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3307.     pop    es
  3308.     pop    di
  3309.     pop    si
  3310.     call    invcopy            ; create keyboard table by inversion
  3311.     ret
  3312. mkjiskana endp
  3313.  
  3314. ; [HF] Construct JIS-Kanji table to Gn table.
  3315. ; [HF] Enter with destination in setptr
  3316. ; [HF] Actually, because the JIS-Kanji set is double byte charater set,
  3317. ; [HF] this procedure simply sets only the ident code.
  3318. ; [HF] Actual translation is done by (f)jpnxtof.
  3319. mkjiskanji proc    near
  3320.     push    si            ; [HF]
  3321.     push    di            ; [HF]
  3322.     mov    di,setptr        ; [HF]
  3323.     mov    al,[di+gsize+3+1]    ; [HF] get Gn number (0..3)
  3324.     xor    ah,ah            ; [HF] clear high byte
  3325.     mov    si,ax            ; [HF] set SI reg.
  3326.     mov    Gsetid[si],C_JISKANJI    ; [HF] set our char set ident
  3327.     mov    byte ptr[di+gsize],94    ; [HF] say this is 94 x 94 byte set
  3328.     mov    word ptr[di+gsize+1],'$B' ; [HF] set ident code
  3329.     pop    di            ; [HF]
  3330.     pop    si            ; [HF]
  3331.     call    invcopy            ; create keyboard table by inversion
  3332.     ret                ; [HF]
  3333. mkjiskanji endp
  3334.  
  3335. ; Put transparent char set (128..255) into Gn table.
  3336. ; Enter with destination in setptr
  3337. mkxparent proc    near
  3338.     call    mkascii            ; init set to ASCII
  3339.     push    si
  3340.     push    di
  3341.     mov    di,setptr        ; point at character set
  3342.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3343.     xor    ah,ah
  3344.     mov    si,ax
  3345.     mov    Gsetid[si],C_XPARENT    ; store our char set ident
  3346.     mov    cx,gsize        ; number of chars to do, 128
  3347.     cld
  3348.     mov    al,cl            ; start with 128 char value
  3349.     push    es
  3350.     push    ds
  3351.     pop    es            ; point es at data segment
  3352. mkxpar2:stosb                ; store codes 128..255
  3353.     inc    al
  3354.     loop    mkxpar2
  3355.     mov    di,setptr
  3356.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3357.     mov    word ptr[di+gsize+1],0+'?' ; set ident code
  3358.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3359.     pop    es
  3360.     pop    di
  3361.     pop    si
  3362.     call    invcopy            ; create keyboard table by inversion
  3363.     ret
  3364. mkxparent endp
  3365.  
  3366. ; Construct NRC table.
  3367. ; Enter with destination in setptr
  3368. ; and CX holding the desired country code (1..13).
  3369. mknrc    proc near
  3370.     call    mkascii            ; init set to ASCII
  3371.     push    bx
  3372.     push    cx
  3373.     push    si
  3374.     push    di
  3375.     push    word ptr emubuf
  3376.     push    word ptr emubuf+2
  3377.     push    es
  3378.     mov    di,setptr
  3379.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3380.     xor    ah,ah
  3381.     mov    si,ax
  3382.     mov    Gsetid[si],cl        ; store our char set ident
  3383.     mov    emubuf+2,cl        ; local copy
  3384.     cmp    cl,13            ; DEC Hebrew case?
  3385.     je    mknrc10            ; e = yes
  3386.         ; copy from NRC table (si) to set pointed at by di, cx chars
  3387.                     ;  plus 3 ident bytes at table end
  3388.     mov    word ptr emubuf,offset nrclat ; start of NRC to Latin1 table
  3389.     mov    ax,cx            ; country code 1..12
  3390.     mov    bl,15            ; 15 bytes per entry
  3391.     mul    bl            ; distance down the table to country
  3392.     add    word ptr emubuf,ax    ; point at country line
  3393.     mov    cx,12            ; do 12 bytes of new chars
  3394.     push    ds
  3395.     pop    es
  3396.     cld
  3397.     PUSH    DS
  3398.     call    flatin1            ; returns DS:BX = Latin1 to CPnnn
  3399.     xor    si,si
  3400. mknrc2:    mov    al,ES:nrclat[si]    ; get code point to change
  3401.     xor    ah,ah
  3402.     mov    di,ES:setptr        ; start of destination table
  3403.     mov    byte ptr ES:[di+gsize+3],0    ; say hard char set
  3404.     add    di,ax            ; destination of new char
  3405.     push    bx
  3406.     mov    bx,word ptr ES:emubuf    ; ptr to country entries
  3407.     mov    al,ES:[bx+si]        ; read char from NRC table
  3408.     pop    bx
  3409.     inc    si
  3410.     test    al,80h            ; in GR Latin1 area?
  3411.     jz    mknrc3            ; z = no, in ASCII GL area
  3412.     and    al,not 80h        ; trim high bit for xlat
  3413.     xlatb                  ; translate through Latin1 Code Page
  3414. mknrc3:    stosb                ; move replacement char from nrc list
  3415.     loop    mknrc2
  3416.     POP    DS
  3417.  
  3418.     mov    di,setptr
  3419.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  3420.     jz    mknrc8            ; z = no
  3421.     mov    cl,emubuf+2        ; country code again
  3422.     cmp    cl,3            ; French NRC?
  3423.     jne    mknrc4            ; ne = no
  3424.     mov    al,07fh            ; apply DG French NRC patch
  3425.     jmp    short mknrc7
  3426. mknrc4:    cmp    cl,6            ; Spanish NRC?
  3427.     jne    mknrc5            ; ne = no
  3428.     mov    al,07fh            ; apply DG Spanish NRC patch
  3429.     jmp    short mknrc7
  3430. mknrc5:    cmp    cl,7            ; DG Danish/Norweigen NRC?
  3431.     jne    mknrc6            ; ne = no
  3432.     mov    al,0fch            ; apply DG Danish/Norweigen NRC patch
  3433.     jmp    short mknrc7
  3434. mknrc6:    cmp    cl,8            ; Swiss NRC?
  3435.     jne    mknrc7            ; ne = no
  3436.     mov    al,0e9h            ; apply DG Swiss NRC patch
  3437. mknrc7:    and    al,not 80h
  3438.     xlatb                ; push through Latin1 translation
  3439.     mov    [di+7fh],al        ; new value
  3440. mknrc8:    add    di,gsize        ; look at end of set, to id bytes
  3441.     movsb                ; copy set size and two ident chars
  3442.     movsw
  3443.     jmp    short mknrc11
  3444.  
  3445. mknrc10:mov    vtcpage,862        ; Hebrew NRC CP862
  3446.     mov    di,ds
  3447.     mov    es,di
  3448.     mov    di,setptr
  3449.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3450.     add    di,6*16
  3451.     mov    cx,27            ; number of characters
  3452.     PUSH    DS
  3453.     call    flatin1            ; get SI appropriate for Code Page
  3454.     mov    si,bx            ; point to Latin 1 for this code page
  3455.     add    si,6*16            ; get Hebrew part of CP862
  3456.     cld
  3457.     rep    movsb
  3458.     POP    DS
  3459. mknrc11:pop    es
  3460.     pop    word ptr emubuf+2
  3461.     pop    word ptr emubuf
  3462.     pop    di
  3463.     pop    si
  3464.     pop    cx
  3465.     pop    bx
  3466.     call    invcopy            ; create keyboard table by inversion
  3467.     ret
  3468. mknrc    endp
  3469.     
  3470. ; Construct Latin1 table to Gn table.
  3471. ; Enter with destination in setptr
  3472. mklatin1 proc    near
  3473.     push    si
  3474.     push    di
  3475.     mov    di,setptr        ; destination
  3476.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3477.     xor    ah,ah
  3478.     mov    si,ax
  3479.     mov    Gsetid[si],C_LATIN1    ; store our char set ident
  3480.     mov    cx,gsize        ; bytes
  3481.     push    es
  3482.     push    ds
  3483.     pop    es
  3484.     PUSH    DS
  3485.     call    flatin1            ; get DS:BX appropriate for Code Page
  3486.     mov    si,bx
  3487.     cld
  3488.     rep    movsb            ; copy bytes
  3489.     POP    DS
  3490.     mov    di,setptr
  3491.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3492.     mov    word ptr[di+gsize+1],0+'A' ; set ident code
  3493.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3494.     pop    es
  3495.     pop    di
  3496.     pop    si
  3497.     call    invcopy            ; create keyboard table by inversion
  3498.     ret
  3499. mklatin1 endp
  3500.  
  3501. ; Construct Latin2 table to Gn table.
  3502. ; Enter with destination in setptr
  3503. mklatin2 proc    near
  3504.     push    si
  3505.     push    di
  3506.     mov    di,setptr        ; destination
  3507.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3508.     xor    ah,ah
  3509.     mov    si,ax
  3510.     mov    Gsetid[si],C_LATIN2    ; store our char set ident
  3511.     mov    vtcpage,852        ; set emulator's CP to CP852
  3512.     mov    cx,gsize        ; bytes
  3513.     push    es
  3514.     push    ds
  3515.     pop    es
  3516.     PUSH    DS
  3517.     call    flatin1            ; get BX appropriate for Code Page
  3518.     mov    si,bx
  3519.     cld
  3520.     rep    movsb            ; copy bytes
  3521.     POP    DS
  3522.     mov    di,setptr
  3523.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3524.     mov    word ptr[di+gsize+1],0+'B' ; set ident code
  3525.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3526.     pop    es
  3527.     pop    di
  3528.     pop    si
  3529.     call    invcopy            ; create keyboard table by inversion
  3530.     ret
  3531. mklatin2 endp
  3532.  
  3533. ; Make DEC Hebrew (94) 8-bit Supplemental
  3534. ; Same code points as Hebrew-ISO at this time
  3535. mkdec_Hebrew    proc    near
  3536.     call    mklatin_hebrew
  3537.     push    es
  3538.     push    ds
  3539.     pop    es
  3540.     mov    di,setptr
  3541.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3542.     mov    word ptr[di+gsize+1],'4"' ; set ident code
  3543.     pop    es
  3544.     call    invcopy            ; create keyboard table by inversion
  3545.     ret
  3546. mkdec_Hebrew    endp
  3547.  
  3548. ; Make Hebrew-ISO (96) 8-bit Supplemental to Gn pointer
  3549. ; Enter with destination in setptr
  3550. ; Presumes CP 862 is loaded
  3551. mklatin_Hebrew    proc    near
  3552.     push    si
  3553.     push    di
  3554.     mov    di,setptr        ; destination
  3555.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3556.     xor    ah,ah
  3557.     mov    si,ax
  3558.     mov    Gsetid[si],C_HEBREWISO    ; store our char set ident
  3559.     mov    cx,gsize        ; bytes
  3560.     mov    vtcpage,862        ; set emulator's CP to CP862
  3561.     push    es
  3562.     push    ds
  3563.     pop    es
  3564.     PUSH    DS
  3565.     call    flatin1            ; get DS:BX appropriate for Code Page
  3566.     mov    si,bx
  3567.     cld
  3568.     rep    movsb            ; copy bytes
  3569.     POP    DS
  3570.     mov    di,setptr
  3571.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3572.     mov    word ptr[di+gsize+1],0+'H' ; set ident code
  3573.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3574.     pop    es
  3575.     pop    di
  3576.     pop    si
  3577.     call    invcopy            ; create keyboard table by inversion
  3578.     ret
  3579. mklatin_Hebrew    endp
  3580.  
  3581.  
  3582. ; Make HP-Roman8 to Gn table. 
  3583. ; Enter with destination in setptr
  3584. mkhpr8    proc    near
  3585.     push    si
  3586.     push    di
  3587.     push    es
  3588.     mov    di,setptr
  3589.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3590.     xor    ah,ah
  3591.     mov    si,ax
  3592.     mov    Gsetid[si],C_HPROMAN8    ; store our char set ident
  3593.     mov    ax,ds
  3594.     mov    es,ax
  3595.     PUSH    DS
  3596.     call    flatin1        ; get DS:BX to Code Page dependent Latin1
  3597.     mov    si,bx
  3598.     cld
  3599.     push    di
  3600.     mov    cx,gsize        ; gsize chars
  3601.     rep    movsb            ; copy appropriate Latin1 xlat table
  3602.     pop    di
  3603.     add    di,20h            ; where new chars start
  3604.     mov    cx,hr8L1len        ; number of new chars
  3605.     mov    si,offset hr8L1    ; source of chars to be translated
  3606.     push    DS
  3607.     mov    ax,seg trans
  3608.     mov    ds,ax
  3609.     cmp    trans.xchri,0        ; readable (vs invertible)?
  3610.     pop    ds
  3611.     je    mkhpr81            ; e = yes, do nothing
  3612.     mov    cx,ihr8L1len        ; number of new chars
  3613.     mov    si,offset ihr8L1    ; source of chars to be translated
  3614.  
  3615. mkhpr81:PUSH    DS
  3616.     mov    ax,seg ihr8L1        ; same seg for readable and invertable
  3617.     mov    ds,ax
  3618.     lodsb                ; read Latin1 code point from dgi2lat
  3619.     POP    DS
  3620.     cmp    al,80h            ; "?" unknown indicator or ASCII?
  3621.     jb    mkhpr82            ; b = yes, reproduce it literally
  3622.     sub    al,80h            ; map down to indexable value
  3623.     xlatb                ; translate through Latin1 table
  3624. mkhpr82:stosb                ; store in active table
  3625.     loop    mkhpr81            ; do all necessary
  3626.     POP    DS
  3627.     mov    di,setptr
  3628.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3629.     mov    word ptr[di+gsize+1],'HP' ; set ident code
  3630.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3631.     pop    es
  3632.     pop    di
  3633.     pop    si
  3634.     call    invcopy            ; create keyboard table by inversion
  3635.     ret
  3636. mkhpr8    endp
  3637.  
  3638. ; Make Wyse-50 graphics character set. Enter with setptr ready.
  3639. mkwyse    proc    near
  3640.     push    si
  3641.     push    di
  3642.     push    es
  3643.     call    mkascii            ; make US ASCII table
  3644.     mov    di,setptr        ; get set pointer
  3645.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3646.     mov    word ptr[di+gsize+1],'YW' ; set ident code
  3647.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3648.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3649.     xor    ah,ah
  3650.     mov    si,ax
  3651.     mov    Gsetid[si],C_WYSEGR    ; store our char set ident
  3652.     mov    si,offset wyse_grch    ; Wyse chars, from "0"
  3653.     mov    cx,16            ; qty of them
  3654.     add    di,'0'            ; index table
  3655.     cld
  3656. mkwyse1:lodsb                ; read replacement byte
  3657.     mov    [di],al            ; store new graphics char
  3658.     inc    di
  3659.     loop    mkwyse1
  3660.     pop    es
  3661.     pop    di
  3662.     pop    si
  3663.     call    invcopy            ; create keyboard table by inversion
  3664.     ret
  3665. mkwyse    endp
  3666.  
  3667. ; Get output byte in AL from keyboard raw reader and convert through active
  3668. ; character set translation. Return final output byte in AL.
  3669. ; Uses table xltkeytable for translation.
  3670. xltkey    proc    FAR
  3671.     cmp    al,80h            ; regular ASCII key?
  3672.     jb    xltkey1            ; b = yes, do not translate
  3673.     cmp    flags.xltkbd,0        ; keyboard translation is off?
  3674.     jne    xltkey2            ; ne = no
  3675. xltkey1:ret
  3676.  
  3677. xltkey2:push    bx
  3678.     mov    bx,offset xltkeytable    ; translation table
  3679.     and    al,not 80h        ; strip high bit to use as index
  3680.     xlatb                ; table replaces high bit
  3681.     pop    bx
  3682.     ret
  3683. xltkey    endp
  3684.  
  3685. ; Create keyboard translation table by inverse lookup of wire to screen
  3686. ; table. Effective only if setptr equals GRptr.
  3687. invcopy    proc    near
  3688.     push    es
  3689.     push    ds
  3690.     pop    es
  3691.     push    di
  3692.     mov    di,setptr
  3693.     cmp    di,GRptr        ; points to GR?
  3694.     jne    invcopy4        ; ne = no, not our condition
  3695.     mov    si,offset xltkeytable    ; output table
  3696.     mov    al,80h            ; start here
  3697.     mov    cx,gsize        ; loop counter
  3698. invcopy2:push    ax
  3699.     push    cx
  3700.     mov    di,GRptr        ; high bit is where GR points
  3701.     mov    cx,gsize
  3702.     add    di,cx
  3703.     std
  3704.     repne    scasb            ; scan looking for this code
  3705.     cld
  3706.     jne    invcopy3        ; ne = not found
  3707.     inc    di            ; backup to found code
  3708.     sub    di,GRptr        ; minus start
  3709.     mov    ax,di
  3710.     or    al,80h            ; put back high bit
  3711.     cmp    vtemu.vtchset,13    ; ASCII (0) or NRC's (1-13) active?
  3712.     ja    invcopy3        ; a = no
  3713.     cmp    vtemu.vtchset,0        ; ASCII?
  3714.     je    invcopy3        ; e = yes
  3715.     and    al,7fh            ; yes, NRCs force chars to 7-bits
  3716. invcopy3:mov    [si],al            ; want only lower byte
  3717.     pop    cx
  3718.     pop    ax
  3719.     inc    si
  3720.     inc    al
  3721.     loop    invcopy2
  3722. invcopy4:pop    di
  3723.     pop    es
  3724.     ret
  3725. invcopy    endp
  3726.  
  3727. ; Copy table pointed to be es:di to xltkeytable, cx values.
  3728. ; If es:di is NULL then create identity table, cx values.
  3729. tblcopy    proc    near
  3730.     push    si
  3731.     push    di
  3732.     push    es
  3733.     push    ds
  3734.     mov    si,setptr
  3735.     cmp    si,GRptr        ; points to GR?
  3736.     jne    tblcopy3        ; ne = no, not our condition
  3737.     mov    si,es
  3738.     mov    ax,seg xltkeytable
  3739.     mov    es,ax
  3740.     mov    ds,si
  3741.     mov    si,di
  3742.     mov    di,offset xltkeytable
  3743.     mov    ax,ds
  3744.     or    ax,si            ; null pointer?
  3745.     jz    tblcopy1        ; z = yes, create identity
  3746.     cld
  3747.     rep    movsb            ; copy table
  3748.     jmp    short tblcopy3
  3749.  
  3750. tblcopy1:mov    al,80h            ; create identity table 80h..cx+80h
  3751. tblcopy2:stosb
  3752.     inc    al
  3753.     loop    tblcopy2
  3754.  
  3755. tblcopy3:pop    ds
  3756.     pop    es
  3757.     pop    di
  3758.     pop    si
  3759.     ret
  3760. tblcopy    endp
  3761.  
  3762. ; cursor movements
  3763. atcup:    test    dspstate,dsptype    ; on VT320 status line?
  3764.     jz    atcup0            ; z = no
  3765.     mov    param,0            ; yes, do not change rows
  3766. atcup0:    mov    ax,param        ; get row
  3767.     or    ah,ah            ; too large?
  3768.     jz    atcup0a            ; z = not too too large
  3769.     mov    al,200            ; limit row
  3770. atcup0a:mov    dh,al            ; temp row
  3771.     mov    ax,param+2        ; get column
  3772.     or    ah,ah            ; too large?
  3773.     jz    atcup0b            ; z = not yet
  3774.     mov    al,mar_right        ; limit column
  3775.     inc    al
  3776. atcup0b:mov    dl,al
  3777.     or    dh,dh            ; zero row number?
  3778.     jz    atcup1            ; z = yes, continue
  3779.     dec    dh            ; normalize to 0,0 system
  3780. atcup1:    or    dl,dl            ; ditto for column
  3781.     jz    atcup2
  3782.     dec    dl
  3783. atcup2:    test    vtemu.vtflgop,decom    ; Origin mode?
  3784.     jz    atcup3            ; z = no, skip this stuff
  3785.     add    dh,mar_top        ; yes, it was relative to top margin
  3786.     jno    atcup2a            ; if no overflow, continue
  3787.     mov    dh,byte ptr low_rgt+1    ; otherwise just set to screen bottom
  3788. atcup2a:cmp    dh,mar_bot        ; going below bottom margin?
  3789.     jbe    atcup3            ; be = no
  3790.     mov    dh,mar_bot        ; clip to bottom margin
  3791. atcup3:    mov    al,mar_right        ; right margin
  3792.     cmp    dl,al            ; too far to the right?
  3793.     jbe    atcup4            ; ne = no
  3794.     mov    dl,al            ; limit to right margin
  3795. atcup4:    mov    ah,byte ptr low_rgt+1    ; last regular text line
  3796.     cmp    dh,ah            ; going to 25th line?
  3797.     jbe    atcup7            ; be = no
  3798.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  3799.     je    atcup5            ; e = yes
  3800.     mov    dh,ah            ; VTxxx: clamp to bottom line
  3801.     jmp    short atcup7
  3802. atcup5:    inc    ah            ; "25th" status line
  3803.     cmp    dh,ah            ; going too far?
  3804.     ja    atcup6            ; a = yes
  3805.     test    h19stat,h19l25        ; Heath 25th mode line enabled?
  3806.     jnz    atcup8            ; nz = yes
  3807. atcup6:    mov    dh,byte ptr cursor+1    ; do not change rows
  3808. atcup7: call    atccpc            ; check position
  3809. atcup8:    jmp    atsetcur        ; set cursor position and return
  3810.  
  3811. atcuarg:mov    al,byte ptr param    ; worker, get cursor movement argument
  3812.     or    al,al            ; zero?
  3813.     jnz    atcua1            ; nz = no
  3814.     inc    al            ; default to one
  3815. atcua1: ret
  3816.                     ; cursor up
  3817. atcuu:    cmp    dh,byte ptr low_rgt+1    ; on 25th line?
  3818.     jbe    atcuu1            ; be = no
  3819.     cmp    flags.vtflg,ttansi    ; emulating ANSI?
  3820.     je    atcuu1            ; e = yes
  3821.     ret                ; no vertical on 25th line
  3822. atcuu1:    call    atcuarg            ; get cursor move up argument into al
  3823.     sub    dh,al            ; compute new cursor position
  3824.     jnc    atcuu2            ; nc = ok [dlk]
  3825.     xor    dh,dh            ; overflow, restrict range. [dlk]
  3826. atcuu2:    call    atccic            ; check indexing, ignore action in ax
  3827.     jmp    atsetcur        ; set the cursor at its new position
  3828.  
  3829. atcud:    call    atcuarg            ; cursor down
  3830.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  3831.     jbe    atcud1            ; be = no
  3832.     ret                ; else leave it on status line
  3833. atcud1:    add    dh,al            ; compute new cursor position
  3834.     jnc    atcud2            ; nc = ok [dlk]
  3835.     mov    dh,byte ptr low_rgt+1    ; default bottom [dlk]
  3836. atcud2:    call    atccic            ; check indexing, ignore action in ax
  3837.     jmp    atsetcur        ; set the cursor at its new position
  3838.  
  3839.                     ; Allow horiz movement on 25th line
  3840. atcuf:    call    atcuarg            ; cursor forward
  3841.     add    dl,al            ; compute new cursor position
  3842.     jnc    atcup3            ; nc = no problem
  3843.     mov    dl,byte ptr low_rgt    ; else set to right margin
  3844.     jmp    atcup3            ; check/set cursor, return
  3845.  
  3846. atcub:    call    atcuarg            ; cursor back
  3847.     sub    dl,al            ; compute new cursor position
  3848.     jnc    atcub1            ; nc = no problem
  3849.     xor    dl,dl            ; else set to left margin
  3850. atcub1:    jmp    atcup3            ; check/set cursor, return
  3851.  
  3852. atcha:    call    atcuarg            ; absolute horizontal address
  3853.     mov    dl,al            ; new column, counted from 1
  3854.     sub    dl,1            ; column, count from 0 internally
  3855.     jns    atcha1            ; ns = no problem
  3856.     xor    dl,dl            ; else set to left margin
  3857. atcha1:    jmp    atcup3            ; check/set cursor, return
  3858.  
  3859. atcht:    call    atcuarg            ; move cursor forward # horiz tabs
  3860.     inc    dl            ; next column
  3861.     mov    cl,al            ; number of tabstops to locate
  3862.     xor    ch,ch
  3863.     mov    si,offset tabs        ; active tabs buffer
  3864. atcht1:    cmp    dl,mar_right        ; at end of line?
  3865.     jae    atcht2            ; ae = yes, stop here
  3866.     call    istabs            ; is dl column a tabstop?
  3867.     inc    dl            ; try next column, preserves carry
  3868.     jnc    atcht1            ; nc = no, find one
  3869.     loop    atcht1            ; do cx tabstops
  3870. atcht2:    jmp    atcup3            ; set cursor
  3871.  
  3872. atcva:    inc    dl            ; count columns from 1 here
  3873.     mov    byte ptr param+2,dl    ; set column in second parameter
  3874.     mov    param+3,0        ; high byte
  3875.     jmp    atcup            ; do absolute vertical positioning
  3876.  
  3877. atcnl:    call    atcuarg            ; do # Next-Lines
  3878.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  3879.     jbe    atcnl1            ; be = no
  3880.     ret                ; else leave it on status line
  3881. atcnl1:    mov    cl,al            ; number to do
  3882.     xor    ch,ch
  3883. atcnl2:    push    cx
  3884.     inc    dh            ; number to do
  3885.     mov    dl,mar_left
  3886.     call    atccic            ; check cursor position
  3887.     call    ax            ; scroll if necessary
  3888.     call    atsetcur        ; set cursor, etc. and return
  3889.     pop    cx
  3890.     loop    atcnl2
  3891.     ret
  3892. atcpl:    call    atcuarg            ; do # Previous-Lines
  3893.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  3894.     jbe    atcpl1            ; be = no
  3895.     ret                ; else leave it on status line
  3896. atcpl1:    mov    cl,al            ; number to do
  3897.     xor    ch,ch
  3898.     mov    dl,mar_left
  3899. atcpl2:    dec    dh            ; do one line
  3900.     push    cx            ; save counter
  3901.     call    atccic            ; check cursor position
  3902.     call    ax            ; scroll if necessary
  3903.     call    atsetcur        ; set cursor
  3904.     pop    cx
  3905.     loop    atcpl2            ; do cx times
  3906.     ret
  3907.  
  3908. ; Screen erasure commands
  3909.                     ; Erase in display
  3910. ated:    cmp    ninter,0        ; zero intermediates?
  3911.     je    ated0            ; e = yes, else try protected mode
  3912.     ret
  3913.  
  3914. ated0:    cmp    lparam,0
  3915.     je    ated0a
  3916.     jmp    atedsel
  3917. ated0a:    cmp    param,0            ; was arg zero?
  3918.     jne    ated1            ; ne = no
  3919.     jmp    ereos            ; do erase cursor to end of screen
  3920.  
  3921. ated1:    cmp    param,1            ; was arg one?
  3922.     jne    ated2            ; ne = no
  3923.     jmp    ersos            ; do erase start of screen to cursor
  3924.  
  3925. ated2:    cmp    param,2            ; was arg two?
  3926.     je    ated2a            ; e = yes, erase entire screen
  3927.     ret                ; else ignore
  3928. ated2a:    push    dx            ; save dynamic cursor
  3929.     push    word ptr mar_top
  3930.     mov    mar_bot,dh
  3931.     mov    mar_top,0        ; row of cursor
  3932.     inc    dh            ; number of lines to scroll
  3933.     mov    scroll,dh
  3934.     call    atscru            ; scroll them up before erasure
  3935.     pop    word ptr mar_top
  3936.     pop    dx
  3937.     call    ersos            ; erase start of screen to cursor
  3938.     call    ereos            ; erase cursor to end of screen
  3939.     cmp    flags.vtflg,ttansi    ; ANSI-BBS terminal?
  3940.     je    ated2b            ; e = yes, home the cursor
  3941.     ret
  3942. ated2b:    xor    dx,dx
  3943.     jmp    atsetcur
  3944.  
  3945. atedsel    proc    near            ; DECSED selective erase in display
  3946.     cmp    lparam,'?'        ; proper intermediate?
  3947.     jne    atedsel3        ; ne = no
  3948.     mov    ax,param        ; get parameter
  3949.     or    ax,ax            ; 0?
  3950.     jnz    atedsel1        ; nz = no
  3951.     mov    al,mar_top        ; 0: erase cursor to end of screen
  3952.     mov    ah,mar_bot        ; save margins
  3953.     push    ax
  3954.     mov    mar_top,dh        ; use current row
  3955.     mov    ah,byte ptr low_rgt+1    ; bottom screen row for text
  3956.     mov    mar_bot,ah
  3957.     call    erprot            ; do protected mode erasure
  3958.     pop    ax
  3959.     mov    mar_top,al        ; restore margins
  3960.     mov    mar_bot,ah
  3961.     jmp    short atedsel3
  3962. atedsel1:cmp    al,1            ; 1? erase start of line to cursor
  3963.     jne    atedsel2        ; ne = no
  3964.     mov    al,mar_top        ; 1: erase start to cursor
  3965.     mov    ah,mar_bot        ; save margins
  3966.     push    ax
  3967.     mov    al,mar_right
  3968.     mov    ah,dl            ; save right margin and cursor col
  3969.     push    ax
  3970.     mov    mar_right,dl        ; stop at current cursor
  3971.     mov    dl,mar_left        ; start at this pseudo cursor
  3972.     mov    mar_top,dh        ; use current row
  3973.     mov    mar_bot,dh
  3974.     call    erprot            ; do protected mode erasure
  3975.     pop    ax
  3976.     mov    mar_right,al        ; restore right margin
  3977.     mov    dl,ah            ; restore cursor row
  3978.     pop    ax
  3979.     mov    mar_top,al        ; restore margins
  3980.     mov    mar_bot,ah
  3981.     jmp    short atedsel3
  3982. atedsel2:cmp    al,2            ; 2? erase whole screen
  3983.     jne    atedsel3        ; ne = no
  3984.     mov    al,mar_top        ; 2: erase whole screen
  3985.     mov    ah,mar_bot        ; save margins
  3986.     push    ax
  3987.     mov    ah,mar_right
  3988.     mov    al,mar_left
  3989.     push    ax
  3990.     push    dx            ; save cursor
  3991.     xor    dx,dx            ; set to top left corner
  3992.     mov    mar_right,dl        ; starting point
  3993.     mov    mar_top,dh
  3994.     mov    ax,low_rgt        ; lower right corner of text area
  3995.     mov    mar_right,al        ; end here
  3996.     mov    mar_bot,ah
  3997.     call    erprot            ; do protected mode erasure
  3998.     pop    dx            ; restore cursor
  3999.     pop    ax
  4000.     mov    mar_left,al
  4001.     mov    mar_right,ah
  4002.     pop    ax
  4003.     mov    mar_top,al        ; restore margins
  4004.     mov    mar_bot,ah
  4005. atedsel3:ret
  4006. atedsel    endp
  4007.  
  4008.  
  4009. p20ed:    xor    dx,dx            ; Prime PT200, set cursor to 0,0
  4010.     call    ereos            ; erase cursor to end of screen
  4011.     jmp    atsetcur            ; put cursor at 0,0 and return
  4012.  
  4013.                     ; Erase in current line
  4014. atel:    cmp    ninter,0        ; zero intermediates?
  4015.     je    atel0            ; e = yes
  4016.     ret
  4017.  
  4018. atel0:    cmp    lparam,0        ; letter parameter?
  4019.     je    atel0a
  4020.     jmp    atelsel            ; try protected mode erasure
  4021. atel0a:    cmp    param,0            ; was arg zero?
  4022.     jne    atel1            ; ne = no
  4023.     mov    al,dl            ; erase from cursor
  4024.     mov    bl,byte ptr low_rgt    ;  to end of line, inclusive
  4025.     jmp    erinline        ; do the erasure
  4026.  
  4027. atel1:    cmp    param,1            ; was arg one?
  4028.     jne    atel2            ; ne = no
  4029.     xor    al,al            ; erase from start of line
  4030.     mov    bl,dl            ;  to cursor, inclusive
  4031.     jmp    erinline        ; do the erasure
  4032.  
  4033. atel2:    cmp    param,2            ; was arg two?
  4034.     jne    atel3            ; ne = no, ignore
  4035.     xor    al,al            ; erase entire line
  4036.     mov    bl,byte ptr low_rgt
  4037.     jmp    erinline        ; clear it
  4038. atel3:    ret
  4039.  
  4040.  
  4041. atelsel    proc    near            ; DECSEL selective erase in line
  4042.     cmp    lparam,'?'        ; proper intermediate?
  4043.     jne    atelsel3        ; ne = no
  4044.     mov    ax,param        ; get parameter
  4045.     or    ax,ax            ; 0?
  4046.     jnz    atelsel1        ; nz = no
  4047.     mov    al,mar_top        ; 0: erase cursor to end of line
  4048.     mov    ah,mar_bot        ; save margins
  4049.     push    ax
  4050.     mov    mar_top,dh        ; use current row
  4051.     mov    mar_bot,dh
  4052.     call    erprot            ; do protected mode erasure
  4053.     pop    ax
  4054.     mov    mar_top,al        ; restore margins
  4055.     mov    mar_bot,ah
  4056.     ret
  4057. atelsel1:cmp    al,1            ; 1? erase start of line to cursor
  4058.     jne    atelsel2        ; ne = no
  4059.     mov    al,mar_top        ; 1: erase start to cursor
  4060.     mov    ah,mar_bot        ; save margins
  4061.     push    ax
  4062.     mov    al,mar_right
  4063.     mov    ah,dl            ; save right margin and cursor col
  4064.     push    ax
  4065.     mov    mar_right,dl        ; stop at current cursor
  4066.     mov    dl,mar_left        ; start at this pseudo cursor
  4067.     mov    mar_top,dh        ; use current row
  4068.     mov    mar_bot,dh
  4069.     call    erprot            ; do protected mode erasure
  4070.     pop    ax
  4071.     mov    mar_right,al        ; restore right margin
  4072.     mov    dl,ah            ; restore cursor row
  4073.     pop    ax
  4074.     mov    mar_top,al        ; restore margins
  4075.     mov    mar_bot,ah
  4076.     ret
  4077. atelsel2:cmp    al,2            ; 2? erase whole line
  4078.     jne    atelsel3        ; ne = no
  4079.     mov    al,mar_top        ; 2: erase whole line
  4080.     mov    ah,mar_bot        ; save margins
  4081.     push    ax
  4082.     mov    ah,dl            ; save right margin and cursor col
  4083.     mov    al,mar_right
  4084.     push    ax
  4085.     mov    mar_right,dl        ; stop at current cursor
  4086.     mov    dl,mar_left        ; start at this pseudo cursor
  4087.     mov    mar_top,dh        ; use current row
  4088.     mov    mar_bot,dh
  4089.     call    erprot            ; do protected mode erasure
  4090.     pop    ax
  4091.     mov    mar_right,al        ; restore right margin
  4092.     mov    dl,ah            ; restore cursor row
  4093.     pop    ax
  4094.     mov    mar_top,al        ; restore margins
  4095.     mov    mar_bot,ah
  4096. atelsel3:ret
  4097. atelsel    endp
  4098.  
  4099.                     ; ECH, erase chars in this line
  4100. atech:    mov    ax,dx            ; get cursor position
  4101.     mov    bx,ax            ; erase ax to bx
  4102.     cmp    byte ptr param,0    ; 0 argument
  4103.     je    atech1            ; e = yes
  4104.     dec    bl            ; count from 1
  4105. atech1:    add    bl,byte ptr param    ; number of characters
  4106.     jmp    erinline        ; erase in this line
  4107.  
  4108.  
  4109. ; Set Graphics Rendition commands (video attributes)
  4110.  
  4111. atsgr:    cmp    lparam,0        ; any letter parameter?
  4112.     jne    atsgr0            ; ne = yes, fail
  4113.     mov    ah,curattr        ; get current cursor attribute
  4114.     mov    di,offset atsgr1    ; routine to call
  4115.     call    atreps            ; repeat for all parms
  4116.     mov    curattr,ah        ; store new attribute byte
  4117.     test    flags.vtflg,ttwyse    ; Wyse-50?
  4118.     jz    atsgr0a            ; z = no
  4119.     mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attribute
  4120. atsgr0a:cmp     isps55,0                ; [HF]941103 Japanese PS/55 ?
  4121.     je      atsgr0                  ; [HF]941103 e = no
  4122.     mov     scbattr,ah              ; [HF]940225 and background also
  4123. atsgr0:    ret
  4124.  
  4125. atsgr1:    mov    bx,param[si]        ; fetch an argument
  4126.     or    bl,bl            ; 0, clear all attributes?
  4127.     jnz    atsgr2            ; nz = no, do selectively below
  4128.     call    clrbold            ; clear bold attribute
  4129.     call    clrblink        ; clear blink attribute
  4130.     call    clrrev            ; clear reverse video attribute
  4131.     call    clrunder        ; clear underline attribute
  4132.     mov    atinvisible,0        ; clear invisible attribute
  4133.     mov    cl,extattr
  4134.     and    cl,att_protect        ; preserve protected attribute
  4135.     mov    extattr,cl        ; clear extended attributes
  4136.     cmp    reset_color,0        ; reset colors?
  4137.     je    atsgr1a            ; e = no
  4138.     mov    ah,scbattr
  4139. atsgr1a:ret
  4140.  
  4141. atsgr2:    cmp    lparam,0        ; letter parameter?
  4142.     jne    atsgr9            ; ne = yes, go directly to colors
  4143.     cmp    bl,1            ; 1, set bold?
  4144.     jne    atsgr2a            ; ne = no
  4145.     jmp    setbold            ; set bold attribute
  4146.  
  4147. atsgr2a:cmp    bl,2            ; D470 / PT200 - 2, set dim?
  4148.     jne    atsgr3            ; ne = no
  4149.     cmp    flags.vtflg,ttd470    ; DG d470?
  4150.     je    atsgr2b            ; e = yes
  4151.     cmp    flags.vtflg,ttpt200    ; PT200 '2' = half intensity
  4152.     jne    atsgr3              ; ne = no, do next attrib test
  4153.     jmp    setbold            ; set half intensity
  4154.  
  4155. atsgr2b:mov    ah,scbattr        ; D470, "set dim" get default coloring
  4156.     jmp    clrbold            ; make it dim
  4157.  
  4158. atsgr3: cmp    bl,4            ; 4, set underline?
  4159.     jne    atsgr4            ; ne = no
  4160.     jmp    setunder        ; set underline attribute
  4161.  
  4162. atsgr4: cmp    bl,5            ; 5, set blink?
  4163.     jne    atsgr5            ; ne = no
  4164.     jmp    setblink        ; set blink attribute
  4165.  
  4166. atsgr5: cmp    bl,7            ; 7, reverse video for chars?
  4167.     jne    atsgr5a            ; ne = no, try coloring
  4168.     jmp    setrev            ; set reversed video attribute (AH)
  4169.  
  4170. atsgr5a:cmp    bl,8            ; 8, invisbile on?
  4171.     jne    atsgr6            ; ne = no, try coloring
  4172.     mov    atinvisible,1        ; set invisible coloring
  4173.     ret
  4174.  
  4175. atsgr6:    cmp    flags.vtflg,ttheath    ; Heath-19?
  4176.     jne    atsgr9            ; ne = no
  4177.     cmp    bl,10            ; 10, enter graphics mode?
  4178.     jne    atsgr7            ; ne = no
  4179.     push    ax            ; save ah
  4180.     mov    al,'F'            ; simulate final char of 'F'
  4181.     call    v52sgm            ; do character setup like VT52
  4182.     pop    ax
  4183.     ret
  4184. atsgr7:    cmp    bl,11            ; 11, exit graphics mode?
  4185.     jne    atsgr8            ; ne = no, ignore
  4186.     push    ax            ; save ah
  4187.     mov    al,'G'            ; simulate final char of 'G'
  4188.     call    v52sgm            ; do character setup like VT52
  4189.     pop    ax
  4190. atsgr8:    ret
  4191.  
  4192. atsgr9:    cmp    flags.vtflg,ttd470    ; DG D470?
  4193.     je    atsgr15            ; e = yes
  4194.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  4195.     jz    atsgr14            ; z = no, 22-27 are VT220/320 only
  4196.     cmp    bl,22            ; 22, bold off?
  4197.     jne    atsgr10            ; ne = no
  4198.     jmp    clrbold
  4199. atsgr10:cmp    bl,24            ; 24, underline off?
  4200.     jne    atsgr11            ; ne = no
  4201.     jmp    clrunder
  4202. atsgr11:cmp    bl,25            ; 25, blinking off?
  4203.     jne    atsgr12            ; ne = no
  4204.     jmp    clrblink
  4205. atsgr12:cmp    bl,27            ; 27, reverse video off?
  4206.     jne    atsgr13            ; ne = no
  4207.     jmp    clrrev            ; clear reversed video attribute (AH)
  4208. atsgr13:cmp    bl,28            ; 28, invisible off?
  4209.     jne    atsgr14            ; ne = no
  4210.     mov    atinvisible,0        ; clear invisible attribute
  4211.     ret
  4212. atsgr14:jmp    setcolor        ; BL = color, AH = attribute byte
  4213.  
  4214.  
  4215. atsgr15:cmp    bl,30            ; in foreground colors?
  4216.     jae    atsgr16            ; ae = yes, make bold
  4217.     cmp    lparam,'<'        ; DG dim code?
  4218.     jb    atsgr17            ; b = no, do nothing
  4219.     call    clrbold            ; assume dim
  4220.     mov    al,lparam
  4221.     sub    al,'<'+30h
  4222.     add    bl,al            ; compose dim color
  4223.     jmp    setcolor
  4224.  
  4225. atsgr16:call    setbold            ; then make it bold
  4226.     jmp    setcolor
  4227. atsgr17:ret
  4228.  
  4229. ; Tabulation char commands
  4230. attbc:    call    atccpc            ; make sure cursor is kosher
  4231.     cmp    ninter,0        ; zero intermediates?
  4232.     je    attbc0            ; e = yes, else quit
  4233.     ret
  4234.                     ; Tabstop set/clears
  4235. attbc0: cmp    param,0            ; was argument zero?
  4236.     jne    attbc1            ; ne = no
  4237.     push    si
  4238.     mov    si,vtemu.vttbst        ; active buffer
  4239.     call    tabclr            ; clear tabstop in column DL
  4240.     pop    si
  4241.     ret
  4242.  
  4243. attbc1: cmp    param,3            ; was arg 3 (clear all tab stops)?
  4244.     je    attbc2            ; e = yes
  4245.     ret                ; else ignore
  4246. attbc2:    mov    cx,(swidth+7)/8        ; get ready to zap swidth columns
  4247.     mov    di,offset tabs        ; point to the tab stop table
  4248.     xor    al,al            ; zero indicates no tab stop
  4249.     push    es            ; save es
  4250.     push    ds
  4251.     pop    es            ; use data segment for es:di below
  4252.     cld                ; set direction forward
  4253.     rep    stosb            ; clear all bits
  4254.     pop    es
  4255.     ret
  4256.                     ; set scrolling margins
  4257. atstbm:    test    dspstate,dsptype    ; on status line?
  4258.     jnz    atstb3            ; nz = yes, ignore this command
  4259.     mov    al,byte ptr param    ; get the two line number args
  4260.     mov    ah,byte ptr param+2
  4261.     or    al,al            ; was first zero?
  4262.     jnz    atstb1            ; nz = no, continue
  4263.     inc    al            ; default is one
  4264. atstb1: or    ah,ah            ; was second zero?
  4265.     jnz    atstb2            ; nz = no
  4266.     mov    ah,byte ptr low_rgt+1    ; yes, default is last line on screen
  4267.     inc    ah
  4268. atstb2: dec    al            ; normalize to 0,0 coordinate system
  4269.     dec    ah
  4270.     cmp    ah,al            ; size of region at least two lines?
  4271.     jbe    atstb3            ; be = no, indicate an error
  4272.     or    al,al            ; check against screen limits
  4273.     jl    atstb3            ; l = out of range
  4274.     cmp    ah,byte ptr low_rgt+1
  4275.     ja    atstb3            ; a = too far down
  4276.     mov    mar_top,al        ; set the limits
  4277.     mov    mar_bot,ah
  4278.     xor    dx,dx            ; Home cursor
  4279.     jmp    atsetcur        ; set cursor position and return
  4280. atstb3:    ret                ; ignore bad requests
  4281.  
  4282. ; Device attributes commands
  4283. atda:    cmp    param,0            ; was argument zero?
  4284.     je    decid            ; e = send the i.d. string
  4285.     ret                ; no, only an echo
  4286. decid:    cmp    ninter,0        ; any intermediates?
  4287.     je    decid1            ; e = no, else not this item
  4288.     jmp    atdgnrc            ; try Spanish NRC designator
  4289. decid1:    mov    ax,flags.vtflg        ; get terminal ident type
  4290.     mov    cx,36            ; assumed length of asciiz string
  4291.     mov    ttyact,0        ; group output for networks
  4292.     mov    si,offset v32str    ; VT320 ident string
  4293.     cmp    ax,ttvt320        ; VT320?
  4294.     je    decid2            ; e = yes
  4295.     mov    si,offset v22str
  4296.     cmp    ax,ttvt220        ; VT220?
  4297.     je    decid2            ; e = yes
  4298.     mov    si,offset v102str
  4299.     cmp    ax,ttvt102        ; VT102?
  4300.     je    decid2            ; e = yes
  4301.     mov    si,offset v100str
  4302.     cmp    ax,ttvt100        ; VT100?
  4303.     je    decid2            ; e = yes
  4304.     cmp    ax,ttansi        ; ANSI-BBS?
  4305.     je    decid2            ; e = yes
  4306.     cmp    ax,tthoney        ; Honeywell?
  4307.     je    decid2            ; e = yes
  4308.     mov    si,offset v52str
  4309.     cmp    ax,ttvt52        ; VT52?
  4310.     je    decid2            ; e = yes
  4311.     mov    si,offset h19str
  4312.     cmp    ax,ttheath        ; Heath-19 mode?
  4313.     je    decid2            ; e = yes
  4314.     mov    si,offset pt20str    ; Prime PT200 string
  4315. decid2:    cmp    lparam,'>'        ; this letter parameter?
  4316.     jne    decid3            ; ne = no
  4317.     test    ax,ttvt320+ttvt220    ; VT320/VT220 mode?
  4318.     jz    decid4            ; z = no, ignore
  4319.     mov    si,offset v32sda    ; Secondary DA response string
  4320. decid3:    cld
  4321.     lodsb                ; read string
  4322.     or    al,al            ; end of string?
  4323.     jz    decid4            ; z = yes
  4324.     push    cx
  4325.     push    si
  4326.     cmp    byte ptr [si],0        ; last byte to be sent?
  4327.     je    decid3a            ; e = yes
  4328.     cmp    cx,1            ; last possible byte?
  4329.     ja    decid3b            ; a = no
  4330. decid3a:mov    ttyact,1        ; finished grouping output for net
  4331. decid3b:call    prtbout            ; send it to port with no local echo
  4332.     pop    si
  4333.     pop    cx
  4334.     loop    decid3            ; do all characters
  4335. decid4:    mov    ttyact,1        ; finished grouping output for net
  4336.     ret
  4337.                     ; Display LED's
  4338. atll:    mov    di,offset atleds    ; get pointer to routine to call
  4339.     call    atreps            ; repeat for selective parameters
  4340.     ret
  4341.  
  4342. atleds:    push    si            ; set LED indicators
  4343.     call    getled            ; set si to term type (led) string
  4344.     mov    di,si
  4345.     pop    si
  4346.     jc    atled2            ; c = no leds 1..4, ignore
  4347. atled4:    cmp    param[si],0        ; zero argument?
  4348.     jne    atled3            ; ne = no, check further
  4349.     mov    al,led_off        ; set all off
  4350.     mov    ah,al
  4351.     mov    [di+6],ax        ; where dots go after name
  4352.     mov    [di+6+2],ax
  4353. atled1:    test    yflags,modoff        ; mode line supposed to be off?
  4354.     jnz    atled2            ; nz = yes
  4355.     push    dx
  4356.     call    fmodlin            ; update status line
  4357.     pop    dx
  4358. atled2: ret
  4359. atled3: mov    ax,param[si]        ; get the argument
  4360.     cmp    al,1            ; must be 1 to 4
  4361.     jb    atled2            ; b = out of range
  4362.     cmp    al,4
  4363.     ja    atled2            ; a = out of range
  4364.     dec    ax            ; zero base it
  4365.     push    di
  4366.     add    di,ax
  4367.     add    al,'1'            ; add ascii offset for digit
  4368.     mov    [di+6],al         ; turn the "LED" on by storing digit
  4369.     pop    di
  4370.     jmp    short atled1        ; update display and return
  4371.  
  4372. decsca    proc    near            ; DEC Select Character Attributes
  4373.     cmp    ninter,1        ; one intermediate?
  4374.     jne    atll            ; no, try led routine
  4375.     cmp    inter,'"'        ; CSI Pn " q ?
  4376.     jne    decsca2            ; ne = no
  4377.     cmp    param,1            ; 0, 2 mean protected mode goes off
  4378.     jne    decsca1            ; ne = not 1, protected mode goes on
  4379.     call    setprot            ; start protecting
  4380.     ret
  4381. decsca1:call    clrprot            ; end protecting
  4382. decsca2:ret
  4383. decsca    endp
  4384.  
  4385.  
  4386. ; Set/Reset mode commands
  4387.                     ; ESC [ ? xxx h/l Set/Reset series
  4388. atrm:    mov    modeset,0        ; say we are resetting modes
  4389.     mov    di,offset atrsm        ; Reset/Set modes
  4390.     call    atreps            ; repeat for all parms
  4391.     test    vtemu.vtflgop,decanm    ; did ansi mode get reset?
  4392.     jnz    atrm1            ; nz = no, return
  4393.     cmp    flags.vtflg,ttheath    ; were we a Heath-19?
  4394.     je    atrm0            ; e = yes, don't change terminal types
  4395.     cmp    flags.vtflg,ttpt200    ; were we a PT200?
  4396.     je    atrm0            ; e = yes, don't change terminal types
  4397.     mov    flags.vtflg,ttvt52    ; say VT52 now
  4398. atrm0:    call    chrdef            ; set default char sets
  4399.     call    atsc            ; save cursor status
  4400.     test    yflags,modoff        ; mode line supposed to be off?
  4401.     jnz    atrm1            ; nz = yes
  4402.     call    fmodlin            ; update mode line
  4403. atrm1:    ret
  4404.  
  4405. atsm:    mov    modeset,1        ; say we are setting modes
  4406.     mov    di,offset atrsm        ; Reset/Set modes
  4407.     jmp    atreps            ; repeat for all parms
  4408.  
  4409. atrsm:    mov    ax,param[si]        ; pick up the argument
  4410.     cmp    lparam,'?'        ; DEC private mode? ESC [ ?
  4411.     je    atrsm1            ; e = yes, do DEC specific things
  4412.     cmp    lparam,'>'        ; Heath-19 private mode? ESC [ >
  4413.     jne    atrsma            ; ne = no
  4414.     jmp    htrsm1            ; do Heath specific things
  4415.                     ; ANSI level
  4416. atrsma:    cmp    al,20            ; 20, ANSI new-line mode?
  4417.     jne    atrsm0            ; ne = no, try insert mode
  4418.     and    vtemu.vtflgop,not vsnewline ; assume resetting
  4419.     cmp    modeset,0        ; resetting?
  4420.     je    atrsmb            ; e = yes
  4421.     or    vtemu.vtflgop,vsnewline    ; setting
  4422. atrsmb:    mov    ax,anslnm        ; get the flag bit
  4423.     jmp    atrsflg            ; set or reset it
  4424. atrsm0:    cmp    al,4            ; toggle insert mode?
  4425.     jne    atrsmc            ; ne = no
  4426.     mov    al,modeset        ; set/reset insert mode
  4427.     mov    insmod,al        ; store it
  4428.     ret
  4429. atrsmc:    cmp    al,12            ; 12? Control local echo
  4430.     jne    atrsmx            ; ne = no
  4431.     cmp    modeset,0        ; resetting mode (ESC [ 12 l)?
  4432.     jne    atrsmc1            ; ne = no
  4433.     or    yflags,lclecho        ; (l) turn on local echoing
  4434.     jmp    short atrsmc2
  4435. atrsmc1:and    yflags,not lclecho    ; (h) turn off local echoing
  4436. atrsmc2:test    yflags,modoff        ; is mode line off?
  4437.     jnz    atrsmx            ; nz = yes
  4438.     push    dx            ; save cursor position
  4439.     call    fmodlin            ; write mode line
  4440.     pop    dx
  4441. atrsmx:    ret
  4442.                     ; DEC specifics
  4443. atrsm1: cmp    al,1            ; cursor keys mode?
  4444.     jne    atrsm2            ; ne = no
  4445.     mov    ax,decckm        ; get the bit
  4446.     jmp    atrsflg            ; set or reset it and return
  4447.  
  4448. atrsm2: cmp    al,7            ; Auto-wrap?
  4449.     jne    atrsm3            ; ne = no
  4450.     and    vtemu.vtflgop,not vswrap ; assume resetting line wrap
  4451.     cmp    modeset,0        ; resetting?
  4452.     je    atrsm2a            ; e = yes
  4453.     or    vtemu.vtflgop,vswrap    ; set the bit
  4454. atrsm2a:mov    ax,decawm        ; get the bit
  4455.     jmp    atrsflg            ; set or reset it and return
  4456.  
  4457. atrsm3: cmp    al,6            ; Origin mode?
  4458.     jne    atrsm4            ; ne = no
  4459.     jmp    atrsom            ; change decom and return
  4460.  
  4461. atrsm4: cmp    al,5            ; change the video?
  4462.     jne    atrsm5            ; ne = no
  4463.     jmp    atrsscnm        ; yes, change it if necessary
  4464.  
  4465. atrsm5: cmp    al,2            ; Change VT52 compatibility mode?
  4466.     jne    atrsm6            ; ne = no
  4467.     test    dspstate,dsptype    ; on status line?
  4468.     jnz    atrsm5b            ; nz = yes, ignore switch
  4469.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  4470.     jne    atrsm5a            ; ne = no
  4471.     mov    modeset,0        ; Heath  ESC [ ? 2 h  resets ANSI mode
  4472. atrsm5a:mov    ax,decanm        ; get ansi mode flag
  4473.     call    atrsflg            ; set or reset it
  4474.     test    yflags,modoff        ; mode line supposed to be off?
  4475.     jnz    atrsm5b            ; nz = yes
  4476.     push    dx            ; save cursor position
  4477.     call    fmodlin            ; write mode line
  4478.     pop    dx
  4479. atrsm5b:ret
  4480.  
  4481. atrsm6:    cmp    al,3            ; 132/80 column mode change?
  4482.     jne    atrsm7            ; ne = no
  4483.     mov    al,curattr        ; save current video attributes
  4484.     mov    ah,extattr        ; and extended attributes
  4485.     push    ax
  4486.     xor    ah,ah            ; high byte: not exiting Connect mode
  4487.     and    vtemu.vtflgop,not deccol; assume mode is reset
  4488.     mov    al,modeset        ; pass set/reset request to chgdsp
  4489.     or    al,al
  4490.     jz    atrsm6a            ; z = set 80 columns
  4491.     or    vtemu.vtflgop,deccol    ; assume it will work (tell msy)
  4492. atrsm6a:call    chgdsp            ; call Change Display proc in msy
  4493.     and    vtemu.vtflgop,not deccol; assume mode is reset
  4494.     cmp    modeset,0        ; want 80 cols?
  4495.     je    atrsm6n            ; e = yes, else 132 cols
  4496.     cmp    byte ptr low_rgt,79
  4497.     jbe    atrsm6b
  4498.     or    vtemu.vtflgop,deccol    ; set the status bit
  4499.     mov    byte ptr low_rgt,132-1    ; screen capability
  4500.     jmp    short atrsm6e
  4501. atrsm6b:and    vtemu.vtflgst,not deccol; turn off setup 132 col bit too
  4502. atrsm6n:cmp    byte ptr low_rgt,79    ; want 80 cols, is it wider?
  4503.     jbe    atrsm6e            ; be = no
  4504.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  4505. atrsm6e:test    flags.vtflg,ttd463+ttd470+ttd217+ttwyse ; D463/D470 or Wyse?
  4506.     jnz    atrsm6f            ; nz = yes, no reset for them
  4507.     CALL    ATRES2            ; do partial reset of emulator
  4508. atrsm6f:pop    ax
  4509.     mov    curattr,al        ; restore saved items
  4510.     mov    extattr,ah
  4511.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  4512.     jz    atrsm6g            ; z = no
  4513. atrsm6h:call    frepaint        ; repaint new screen
  4514.     ret                ; D463/D470 gets no other changes
  4515. atrsm6g:mov    dx,low_rgt        ; text lines (leave status line intact)
  4516.     mov    mar_top,0
  4517.     mov    mar_bot,dh        ; reset scrolling region
  4518.     mov    dl,byte ptr low_rgt    ; right margin
  4519.     mov    mar_right,dl
  4520.     mov    mar_left,0
  4521.     test    flags.vtflg,ttwyse     ; Wyse?
  4522.     jnz    atrsm6h            ; nz = yes, leave cursor alone, repaint
  4523.     xor    dx,dx            ; new cursor position is 0,0
  4524.     mov    cursor,dx
  4525.     jmp    atsetcur        ; place it there and return
  4526.  
  4527. atrsm7:    cmp    al,18            ; 18?  18 & 19 = printer support
  4528.     jne    atrsm8            ; ne = no
  4529.     cmp    modeset,0        ; resetting?
  4530.     jne    atrsm7a            ; ne = no, setting
  4531.     and    anspflg,not vtffp    ; no form feed after printing
  4532.     ret
  4533. atrsm7a:or    anspflg,vtffp        ; use form feed after printing
  4534.     ret
  4535.  
  4536. atrsm8:    cmp    al,19            ; 19, print region?
  4537.     jne    atrsm9            ; ne = no
  4538.     cmp    modeset,0        ; resetting?
  4539.     jne    atrsm8a            ; ne = no, setting
  4540.     and    anspflg,not vtextp    ; reset print region to scrolling reg
  4541.     ret
  4542. atrsm8a:or    anspflg,vtextp        ; set print region to whole screen
  4543.     ret
  4544.  
  4545. atrsm9:    cmp    al,25            ; ESC [ ? 25 h/l? cursor on/off
  4546.     jne    atrsm10            ; ne = no
  4547.     mov    al,4            ; assume cursor to be turned off (4)
  4548.     cmp    modeset,0        ; resetting (invisible cursor)?
  4549.     je    atrsm9a            ; e = yes
  4550.     mov    al,1            ; assume underline (1)
  4551.     test    vtemu.vtflgop,vscursor    ; underline?
  4552.     jnz    atrsm9a            ; nz = yes
  4553.     inc    al            ; block (2)
  4554. atrsm9a:mov    atctype,al        ; save VTxxx cursor type here
  4555.     jmp    atsctyp            ; set the cursor type
  4556.  
  4557.                     ; DECRLM (alt VT320 right/left write)
  4558. atrsm10:cmp    al,34            ; ESC [ ? 34 h/l? Invoke special macro
  4559.     jne    atrsm10b        ; ne = no
  4560.     and    vtemu.vtflgop,not vswdir; writing direction to normal
  4561.     and    vtemu.vtflgst,not vswdir; writing direction to normal
  4562.     cmp    modeset,0        ; resetting?
  4563.     jne    atrsm10a        ; ne = no, setting
  4564.     mov    decrlm,0        ; writing direction to left to right
  4565.     ret
  4566. atrsm10a:mov    decrlm,1        ; writing direction to right to left
  4567.     ret
  4568.                     ; DECHEBM (alt VT320 keyboard map)
  4569. atrsm10b:cmp    al,35            ; ESC [ ? 35 h/l? Invoke special macro
  4570.     jne    atrsm10d        ; ne = no
  4571.     cmp    modeset,0        ; resetting?
  4572.     jne    atrsm10c        ; ne = no, setting
  4573.     call    fvtkrmac        ; perform on-line macro
  4574.     ret
  4575.                     ;  code is located in file msy
  4576. atrsm10c:call    fvtksmac        ; do set macro
  4577.     ret
  4578.  
  4579. atrsm10d:cmp    al,36            ; DECHEM Hebrew encoding mode?
  4580.     jne    atrsm11            ; ne = no
  4581.     cmp    modeset,0        ; resetting?
  4582.     jne    atrsm10e        ; ne = no
  4583.     mov    al,13            ; Hebrew NRC
  4584.     mov    ah,al            ; GR = GL = 13
  4585.     or    vtemu.vtflgop,vsnrcm    ; set NRC active bit
  4586.     or    vtemu.vtflgst,vsnrcm
  4587.     and    vtemu.vtflgop,not vscntl ; no 8-bit controls
  4588.     jmp    short atrsm10f
  4589. atrsm10e:mov    al,17            ; DEC Multinational set (17)
  4590.     xor    ah,ah            ; GLeft is ASCII (0)
  4591.     and    vtemu.vtflgop,not vsnrcm ; clear NRC active bit
  4592.     and    vtemu.vtflgst,not vsnrcm
  4593. atrsm10f:mov    vtemu.vtchset,al
  4594.     mov    bx,offset emubuf    ; temp table of char set idents
  4595.     xchg    ah,al            ; order correctly
  4596.     mov    [bx],ax            ; char sets for G0..G3
  4597.     mov    [bx+2],ax
  4598.     call    chrsetup        ; invoke NRC
  4599.     ret
  4600.  
  4601. atrsm11:cmp    al,38            ; 38? Enter Tek sub-mode. VT340 seq
  4602.     jne    atrsm12            ; ne = no
  4603.     cmp    modeset,1        ; setting mode (ESC [ ? 38 h)?
  4604.     jne    atrsm12            ; ne = no, ignore sequence
  4605. ifndef    no_graphics
  4606.     test    denyflg,tekxflg        ; is auto Tek mode disabled?
  4607.     jnz    atrsm12            ; nz = yes, just ignore command
  4608.     call    atsc            ; save cursor and associated data
  4609.     xor    al,al            ; enter with this received character
  4610.     call    TEKEMU            ; go to Tektronix Emulator, al=null
  4611.     jmp    atnorm
  4612. endif    ; no_graphics
  4613. atrsm12:cmp    al,42            ; 42, use NRC 7-bit command?
  4614.     jne    atrsm15            ; ne = no
  4615.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
  4616.     jz    atrsm14            ; z = no
  4617.     cmp    vtemu.vtchset,0        ; ASCII?
  4618.     je    atrsm14            ; e = yes, no NRC
  4619.     cmp    vtemu.vtchset,13    ; highest NRC ident?
  4620.     ja    atrsm14            ; a = not NRC
  4621.     cmp    modeset,0        ; resetting?
  4622.     je    atrsm13            ; e = yes
  4623.     or    vtemu.vtflgop,vsnrcm    ; set NRC flag bit
  4624.     jmp    chrdef            ; and set NRC characters
  4625. atrsm13:mov    ax,vtemu.vtflgop    ; run time flags
  4626.     and    vtemu.vtflgop,not vsnrcm ; turn off NRC flag bit
  4627.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  4628.     jmp    chrdef
  4629. atrsm14:ret
  4630. atrsm15:cmp    al,66            ; 66, keypad to applications mode?
  4631.     jne    atrsm16            ; ne = no
  4632.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
  4633.     jz    atrsm16            ; z = no
  4634.     mov    ax,deckpam        ; bit to control
  4635.     jmp    atrsflg            ; control the flag and return
  4636. atrsm16:ret
  4637.  
  4638. ; VT340  CSI number $ |   number is 0 or 80 for 80 cols, 132 for 132 columns
  4639. ; DECSCPP, set columns per page
  4640. atscpp:    cmp    inter,'$'        ; correct intermediate letter?
  4641.     jne    atscpp2            ; ne = no, ignore
  4642.     cmp    ninter,1        ; one intermediate?
  4643.     jne    atscpp2            ; ne = no, ignore
  4644.     mov    modeset,1        ; assume 132 columns wanted
  4645.     cmp    param,80        ; 80 or 132 columns?
  4646.     ja    atscpp1            ; a = 132 columns
  4647.     mov    modeset,0        ; set to 80 columns
  4648. atscpp1:mov    al,3            ; set up CSI ? 3 h/l command
  4649.     jmp    atrsm6            ; process that command
  4650. atscpp2:ret
  4651.  
  4652.         ; Heath-19  ESC [ > Ps h or l where Ps = 1, 4, 7, or 9
  4653. htrsm1:    cmp    al,1            ; 25th line?
  4654.     jne    htrsm4            ; ne = no
  4655.     and    h19stat,not h19l25    ; clear 25th line bit
  4656.     cmp    modeset,0        ; clearing?
  4657.     je    htrsm1a            ; e = yes
  4658.     or    h19stat,h19l25        ; set bit
  4659.     jmp    htrsmx            ; we are done
  4660. htrsm1a:mov    ah,byte ptr low_rgt+1    ; point to status (25th) line
  4661.     inc    ah            ;  which is here
  4662.     xor    al,al            ; from column 0
  4663.     mov    bh,ah            ; to same line
  4664.     mov    bl,byte ptr low_rgt    ; physical width
  4665.     call    vtsclr            ; disabling status line clears it
  4666.     ret
  4667.  
  4668. htrsm4:    cmp    al,4            ; 4, block/line cursor?
  4669.     jne    htrsm5            ; ne = no
  4670.     and    h19ctyp,4        ; save on/off bit (4)
  4671.     cmp    modeset,0        ; reset?
  4672.     je    htrsm4a            ; e = yes
  4673.     or    h19ctyp,2        ; remember block kind here
  4674.     jmp    atsctyp
  4675. htrsm4a:or    h19ctyp,1        ; remember underline kind here
  4676.     jmp    atsctyp
  4677.      
  4678. htrsm5: cmp     al,5                    ; 5, on/off cursor?
  4679.         jne     htrsm7                  ; ne = no
  4680.         cmp     modeset,0               ; on?
  4681.         je      htrsm5a                 ; e = yes
  4682.     or    h19ctyp,4        ; remember off state in this bit
  4683.         jmp     atsctyp
  4684. htrsm5a:and    h19ctyp,not 4        ; set cursor on
  4685.         jmp     atsctyp
  4686.  
  4687. htrsm7:    cmp    al,7            ; 7, alternate application keypad?
  4688.     jne    htrsm8            ; ne = no
  4689.     mov    ax,deckpam        ; get keypad application mode bit
  4690.     jmp    atrsflg            ; set or reset appl keypad mode
  4691.  
  4692. htrsm8:    cmp    al,8            ; 8, received CR => CR/LF?
  4693.     jne    htrsm9
  4694.     and    h19stat,not h19alf    ; clear autoline feed bit
  4695.     cmp    modeset,0        ; resetting?
  4696.     je    htrsmx            ; yes
  4697.     or    h19stat,h19alf        ; turn on the mode
  4698.     ret
  4699.  
  4700. htrsm9:    cmp    al,9            ; 9, auto newline mode? (add cr to lf)
  4701.     jne    htrsmx            ; ne = no
  4702.     mov    ax,anslnm        ; get the bit
  4703.     jmp    atrsflg            ; set or reset newline mode
  4704. htrsmx:    ret                ; ignore the code
  4705.  
  4706. atrsflg:cmp    modeset,0        ; reset?
  4707.     je    atrsf1            ; e = yes, reset it
  4708.     or    vtemu.vtflgop,ax    ; set, OR in the flag
  4709.     test    ax,decanm        ; changing ansi mode?
  4710.     jz    atrsfx            ; z = no
  4711.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  4712.     je    atrsfx            ; e = yes, don't flip terminal kinds
  4713.     mov    ax,oldterm        ; terminal type at startup
  4714.     mov    flags.vtflg,ax        ; restore it
  4715.     ret
  4716. atrsf1: not    ax            ; reset bit, complement
  4717.     and    vtemu.vtflgop,ax    ; clear the bit
  4718.     not    ax            ; recover the bit
  4719.     test    ax,decanm        ; changing ansi mode?
  4720.     jz    atrsfx            ; z = no
  4721.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  4722.     je    atrsfx            ; e = yes, don't flip terminal kinds
  4723.     mov    flags.vtflg,ttvt52    ; say VT52 now
  4724. atrsfx:    ret
  4725.                     ; Set/Clear Origin mode
  4726. atrsom:    test    dspstate,dsptype    ; on status line?
  4727.     jz    atrsom1            ; z = no
  4728.     ret                ; else ignore this command
  4729. atrsom1:cmp    modeset,0        ; clearing DEC origin mode?
  4730.     jne    atrsom2            ; ne = no, setting
  4731.     and    vtemu.vtflgop,not decom ; reset Origin mode
  4732.     xor    dx,dx            ; go to the home position
  4733.     jmp    atsetcur        ; set cursor and return
  4734. atrsom2:or    vtemu.vtflgop,decom    ; set Origin mode
  4735.     mov    dx,cursor        ; get the cursor
  4736.     xor    dl,dl            ; go to right margin
  4737.     mov    dh,mar_top        ; go to home of scrolling region
  4738.     jmp    atsetcur        ; set the cursor and return
  4739.  
  4740. atrsscnm:cmp    modeset,0        ; resetting?
  4741.     je    atrss1            ; e = yes, reset
  4742.     test    vtemu.vtflgop,vsscreen    ; setting, set already?
  4743.     jnz    atrss3            ; nz = yes, don't do it again
  4744.     or    vtemu.vtflgop,vsscreen    ; set and tell Status display
  4745.     jmp    short atrss2        ; do it
  4746.  
  4747. atrss1: test    vtemu.vtflgop,vsscreen    ; resetting, reset already?
  4748.     jz    atrss3            ; z = yes, don't do it again
  4749.     and    vtemu.vtflgop,not vsscreen ; clear and tell Status
  4750.                     ; fall through to atrss2
  4751.  
  4752. ; Note: This is also called from the stblmds initialization routine.
  4753. ; Reverse video the entire screen, update scbattr and curattr to match.
  4754. atrss2:    push    ax
  4755.     mov    ah,scbattr        ; current screen attributes
  4756.     call    revideo            ; reverse them
  4757.     mov    scbattr,ah        ; set screen background attribute
  4758.     mov    ah,curattr        ; get current cursor attribute
  4759.     call    revideo            ; reverse it
  4760.     mov    curattr,ah        ; store it
  4761.     call    revscn            ; reverse everything on the screen
  4762.     pop    ax
  4763. atrss3:    ret
  4764.  
  4765.                     ; Self tests DECTST
  4766. atctst:    cmp    inter,0            ; any intermediate char?
  4767.     jne    atcts3            ; ne = yes, not a selftest command
  4768.     cmp    param,2            ; VT102 selftest?
  4769.     je    atcts1            ; e = yes
  4770.     cmp    param,4            ; VT320 selftest?
  4771.     jne    atcts6            ; ne = no
  4772. atcts1:    test    dspstate,dsptype    ; cursor is on status line?
  4773.     jz    atcts2            ; z = no
  4774.     push    param            ; save first parameter
  4775.     mov    ah,inter        ;  and first intermediate char
  4776.     push    ax
  4777.     mov    param,0            ; select main display
  4778.     mov    inter,'$'        ; setup proper intermediate
  4779.     call    atssdt            ; select status line of off
  4780.     call    atsasd            ; select main display
  4781.     pop    ax
  4782.     pop    param            ; restore parameter
  4783.     mov    inter,ah        ;  and intermediate char
  4784. atcts2:    xor    al,al            ; init test weight
  4785.     mov    di,offset atcts4    ; routine to call
  4786.     call    atreps            ; repeat for all parms
  4787.     test    al,80H            ; reset?
  4788.     jz    atcts3            ; z = no, return
  4789.     jmp    atreset            ; reset everything
  4790. atcts3: ret
  4791.  
  4792. atcts4:    or    si,si            ; initial arg?
  4793.     jz    atcts5            ; z = yes, skip it (examined above)
  4794.     cmp    param[si],1        ; power up test (0, 1) included?
  4795.     ja    atcts5            ; a = no, ignore printer/comms/repeats
  4796.     or    al,80H            ; say we want reset
  4797. atcts5: ret
  4798.  
  4799. atcts6:    cmp    nparam,0        ; absence of parameters?
  4800.      jne    atcts5            ; ne = no, ignore sequence
  4801.     jmp    athoney            ; try Honeywell ESC [ y  ident response
  4802.  
  4803. atalign    proc    near            ; Align screen, fill screen with 'E's
  4804.     mov    al,'E'            ; char to use as filler
  4805.     test    dspstate,dsptype    ; is cursor on status line?
  4806.     jz    atalig1            ; z = no
  4807.     ret                ; yes, ignore the command
  4808. atalig1:cmp    flags.modflg,0        ; is mode line off?
  4809.     je    atalig2            ; e = yes
  4810.     and    yflags,not modoff    ; say it's on
  4811.     mov    flags.modflg,1        ;  and owned by us
  4812. atalig2:push    ax            ; save displayed char
  4813.     push    vtemu.vtflgst        ; save setup flags
  4814.     mov    ax,vtemu.vtflgop    ; operational flags
  4815.     and    ax,deccol        ; get 80/132 column indicator
  4816.     and    vtemu.vtflgst,not deccol ; clear for set below
  4817.     or    vtemu.vtflgst,ax    ; set it so reset preserves it
  4818.     call    atreset            ; clear system
  4819.     pop    vtemu.vtflgst        ; recover setup flags
  4820.     or    vtemu.vtflgop,decawm    ; set wrap
  4821.     mov    cl,byte ptr low_rgt    ; number of columns-1
  4822.     inc    cl
  4823.     mov    al,byte ptr low_rgt+1    ; number of rows-1
  4824.     inc    al
  4825.     mul    cl            ; ax = number of chars on screen
  4826.     mov    cx,ax
  4827.     pop    ax            ; recover displayed char in AL
  4828.     mov    emubuf,al        ; keep it here while looping
  4829. atalig3:push    cx
  4830.     mov    al,emubuf        ; write screen full of this char
  4831.     call    atnrm            ; write the 'E' or whatever
  4832.     pop    cx
  4833.     loop    atalig3            ; cx times
  4834.     ret
  4835. atalign    endp
  4836.  
  4837.  
  4838. ; Reports
  4839. atreqt: cmp    param,1            ; want report?
  4840.     jbe    atreq1            ; be = yes
  4841. atreq0:    ret                ; Gee, must have been an echo (> 1)
  4842.  
  4843. atreq1:    test    flags.vtflg,ttvt102+ttvt100+tthoney+ttansi ; VT102 etc?
  4844.     jz    atreq0            ; z = no, ignore
  4845.     mov    ttyact,0        ; group output for networks
  4846.     mov    al,Escape
  4847.     call    prtbout
  4848.     mov    al,'['
  4849.     call    prtbout
  4850.     mov    al,'3'            ; we report only upon request
  4851.     cmp    param,0            ; was argument a zero?
  4852.     jne    atreq1b            ; ne = no
  4853.     mov    al,'2'            ; yes
  4854. atreq1b:call    prtbout
  4855.     mov    al,';'            ; separate
  4856.     call    prtbout
  4857.     mov    bl,parcode        ; get the parity code
  4858.     xor    bh,bh
  4859.     mov    al,partab[bx]        ; get VT100 parity code
  4860.     push    ax            ; save parity code
  4861.     call    prtnout            ; send number to the port
  4862.     mov    al,';'            ; separate
  4863.     call    prtbout
  4864.     mov    al,'2'            ; assume 7 data bits
  4865.     pop    bx            ; get parity code into bl
  4866.     cmp    bl,1            ; is parity none?
  4867.     jne    atreq2            ; ne = no, so 7 data bits
  4868.     test    flags.remflg,d8bit    ; 8 bit display?
  4869.     jz    atreq2            ; z = no
  4870.     mov    al,'1'            ; must be eight
  4871. atreq2: call    prtbout            ; send it to the port
  4872.     mov    al,';'
  4873.     call    prtbout
  4874.     mov    bl,baudidx        ; baud rate index
  4875.     xor    bh,bh
  4876.     mov    al,baudtab[bx]        ; get DEC baud rate code
  4877.     push    ax
  4878.     call    prtnout            ; sending speed index
  4879.     mov    al,';'
  4880.     call    prtbout
  4881.     pop    ax
  4882.     cmp    bl,lbaudtab-1        ; using the split speed entry?
  4883.     jne    atreq2a            ; ne = no
  4884.     mov    al,[bx+1]        ; get trailing receive speed (75 baud)
  4885. atreq2a:call    prtnout            ; receiving speed index
  4886.     mov    al,';'
  4887.     call    prtbout
  4888.     mov    al,'1'            ; clock rate multiplier is always 1
  4889.     call    prtbout
  4890.     mov    al,';'
  4891.     call    prtbout
  4892.     mov    al,'0'            ; Flags are always zero (no STP)
  4893.     call    prtbout
  4894.     mov    ttyact,1        ; end group output for networks
  4895.     mov    al,'x'
  4896.     call    prtbout
  4897.     ret
  4898.  
  4899.                     ; Single Controls
  4900. ; Note DEC manual incorrectly says DECSCL's do a hard rather than soft reset
  4901. decscl:    cmp    inter,'!'        ; "CSI ! p" soft reset?
  4902.     jne    decsc0            ; ne = no
  4903.     jmp    atsres            ; do a soft reset
  4904.  
  4905. decsc0:    cmp    inter,'"'        ; "CSI Psc; Ps1 " p"  operating level?
  4906.     je    decsc1            ; e = yes
  4907.     cmp    inter,'$'        ; "CSI Pn $ p"  DECRQM?
  4908.     jne    decsc0a            ; ne = no, ignore others
  4909.     jmp    decsc5            ; do isolated controls report
  4910. decsc0a:ret                ; else ignore
  4911. decsc1:    cmp    param,61        ; Psc, select VT100?
  4912.     jne    decsc2            ; ne = no
  4913.     mov    flags.vtflg,ttvt102    ; set VT102
  4914.     mov    oldterm,ttvt102        ; and remember it
  4915.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  4916.     mov    al,anspflg        ; preserve screen print flag
  4917.     push    ax
  4918.     call    atsres            ; do soft reset of emulator
  4919.     pop    ax
  4920.     mov    anspflg,al
  4921.     ret
  4922. decsc2:    cmp    param,62        ; go to VT2xx level?
  4923.     jne    decsc3            ; ne = no
  4924.     test    flags.vtflg,ttvt320+ttvt102 ; at VT300/VT102 level now?
  4925.     jnz    decsc3a            ; nz = yes, don't change types
  4926.     mov    flags.vtflg,ttvt220    ; set VT220 mode
  4927.     mov    oldterm,ttvt220
  4928.     jmp    short decsc3b        ; finish up
  4929.     
  4930. decsc3:    cmp    param,63        ; go to VT300 level?
  4931.     jne    decsc4            ; ne = no
  4932. decsc3a:mov    flags.vtflg,ttvt320    ; set VT320 mode
  4933.     mov    oldterm,ttvt320
  4934. decsc3b:cmp    param[2],2        ; Ps1, range here is 0, 1, 2
  4935.     ja    decsc4            ; a = out of range, ignore
  4936.     mov    al,anspflg        ; preserve screen print flag
  4937.     push    ax
  4938.     call    atsres            ; do soft reset of emulator
  4939.     pop    ax
  4940.     mov    anspflg,al
  4941.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  4942.     cmp    param[2],1        ; select 7-bit controls?
  4943.     je    decsc4            ; e = yes, we have done so
  4944.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  4945. decsc4:    ret
  4946.                            ; single controls report request
  4947. decsc5:    cmp    lparam,'?'        ; want DEC Private modes?
  4948.     jne    decsc5a            ; ne = no
  4949.     call    decscpre        ; do standard prefix
  4950.     mov    al,'2'            ; assume mode is reset
  4951.     call    decsc20            ; do DEC Private mode report
  4952.     jmp    decscend        ; do end of sequence
  4953. decsc5a:cmp    inter,0            ; intermediate char?
  4954.     je    decsc5b            ; e = no, ignore
  4955.     call    decscpre        ; do standard prefix
  4956.     mov    al,'2'            ; assume mode is reset
  4957.     call    decsc5c            ; do ANSI report
  4958.     jmp    decscend        ; do end of sequence
  4959. decsc5b:ret                ; else return failure
  4960.                     
  4961. decsc5c:mov    cx,param        ; ANSI report:
  4962.     cmp    cx,2            ; 2, Keyboard action?
  4963.     jne    decsc6            ; ne = no
  4964.     ret
  4965. decsc6:    cmp    cx,3            ; control representation?
  4966.     jne    decsc7            ; ne = no
  4967.     ret                ; say reset(acting on controls)
  4968. decsc7:    cmp    cx,4            ; 4, Insert/Replace mode?
  4969.     jne    decsc8            ; ne = no
  4970.     cmp    insmod,0        ; insert mode off?
  4971.     je    decsc7a            ; e = yes, off
  4972.     dec    al            ; say is on
  4973. decsc7a:ret
  4974. decsc8:    cmp    cx,10            ; 10, Horizontal editing?
  4975.     jne    decsc9            ; ne = no
  4976.     mov    al,'4'            ; permanently reset
  4977.     ret
  4978. decsc9:    cmp    cx,12            ; 12, Send/Receive (local echo)?
  4979.     jne    decsc11            ; ne = no
  4980.     test    yflags,lclecho        ; echoing on?
  4981.     jz    decsc12            ; z = no
  4982.     dec    al            ; say set
  4983.     ret
  4984. decsc11:cmp    cx,20            ; 20, new line mode?
  4985.     jne    decsc13            ; ne = no
  4986.     test    vtemu.vtflgop,anslnm    ; new line set?
  4987.     jz    decsc12            ; z = no, reset
  4988.     dec    al            ; say set
  4989. decsc12:ret
  4990. decsc13:mov    al,'0'            ; say not recognized
  4991.     ret
  4992.  
  4993.                            ; DEC Private mode report
  4994. decsc20:mov    cx,param
  4995.     cmp    cx,1            ; 1, cursor keys?
  4996.     jne    decsc22            ; ne = no
  4997.     test    vtemu.vtflgop,decckm    ; set?
  4998.     jz    decsc31            ; z = no, reset
  4999.     dec    al
  5000.     ret
  5001. decsc22:cmp    cx,2            ; 2, ANSI mode
  5002.     jne    decsc24            ; ne = no
  5003.     test    vtemu.vtflgop,decanm    ; set?
  5004.     jz    decsc31            ; z = no, reset
  5005.     dec    al
  5006.     ret
  5007. decsc24:cmp    cx,3            ; 3, column
  5008.     jne    decsc26            ; ne = no
  5009.     test    vtemu.vtflgop,deccol    ; 132 column mode set?
  5010.     jz    decsc31            ; z = no, reset (80 columns)
  5011.     dec    al
  5012.     ret
  5013. decsc26:cmp    cx,4            ; 4, scrolling mode
  5014.     je    decsc31            ; e = yes always say reset (jump)
  5015.                     ;
  5016.     cmp    cx,5            ; 5, screen
  5017.     jne    decsc28            ; ne = no
  5018.     test    vtemu.vtflgop,decscnm    ; set (light background)?
  5019.     jz    decsc31            ; z = no, reset
  5020.     dec    al
  5021.     ret
  5022. decsc28:cmp    cx,6            ; 6, Origin mode?
  5023.     jne    decsc30            ; ne = no
  5024.     test    dspstate,dsptype    ; on status line?
  5025.     jz    decsc29            ; z = no, main display
  5026.     test    dspstate,dspdecom    ; main display Origin mode set?
  5027.     jz    decsc31            ; z = no, reset
  5028.     dec    al
  5029.     ret
  5030. decsc29:test    vtemu.vtflgop,decom    ; Origin mode set?
  5031.     jz    decsc31            ; z = no, reset
  5032.     dec    al
  5033.     ret
  5034. decsc30:cmp    cx,7            ; 7, autowrap?
  5035.     jne    decsc32            ; ne = no
  5036.     test    vtemu.vtflgop,decawm    ; set?
  5037.     jz    decsc31            ; z = no, reset
  5038.     dec    al
  5039. decsc31:ret                ; common return point
  5040. decsc32:cmp    cx,8            ; 8, autorepeat?
  5041.     jne    decsc34            ; ne = no
  5042.     dec    al
  5043.     ret                ; say set
  5044. decsc34:cmp    cx,18            ; 18, print Form Feed?
  5045.     jne    decsc36            ; ne = no
  5046.     test    anspflg,vtffp        ; set?
  5047.     jz    decsc31            ; z = no, reset
  5048.     dec    al
  5049.     ret
  5050. decsc36:cmp    cx,19            ; 19, printer extent?
  5051.     jne    decsc38            ; ne = no
  5052.     test    anspflg,vtextp        ; set?
  5053.     jz    decsc31            ; z = no, reset
  5054.     dec    al
  5055.     ret
  5056. decsc38:cmp    cx,25            ; 25, text cursor enabled?
  5057.     jne    decsc40            ; ne = no
  5058.     test    atctype,4        ; 4 is off
  5059.     jnz    decsc31            ; nz = off/disabled
  5060.     dec    al            ; say enabled
  5061.     ret
  5062. decsc40:cmp    cx,42            ; 42, NRC's
  5063.     jne    decsc42            ; ne = no
  5064.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  5065.     jz    decsc31            ; z = no
  5066.     test    vtemu.vtflgop,vsnrcm    ; NRC's active?
  5067.     jz    decsc31            ; z = no
  5068.     dec    al            ; say enabled
  5069.     ret
  5070. decsc42:cmp    cx,66            ; 66, numeric keypad?
  5071.     jne    decsc44            ; ne = no
  5072.     test    vtemu.vtflgop,deckpam    ; set?
  5073.     jz    decsc31            ; z = no, reset
  5074.     dec    al            ; say set
  5075.     ret
  5076. decsc44:cmp    cx,68            ; 68, keyboard usage?
  5077.     jne    decsc45            ; ne = no
  5078.     mov    al,'4'            ; say always typewriter mode
  5079.     ret
  5080. decsc45:mov    al,'0'            ; say unknown kind
  5081.     ret
  5082.  
  5083. decscpre:mov    ttyact,0        ; group output for networks
  5084.     mov    al,Escape        ; do standard report beginning
  5085.     call    prtbout
  5086.     mov    al,'['
  5087.     call    prtbout
  5088.     mov    al,lparam        ; with query mark
  5089.     or    al,al            ; any letter param?
  5090.     jz    decscpre1        ; z = no
  5091.     call    prtbout
  5092. decscpre1:
  5093.     mov    al,byte ptr param    ; get parameter
  5094.     call    prtnout            ; send the number
  5095.     mov    al,';'
  5096.     call    prtbout
  5097.     ret
  5098.  
  5099. decscend:call    prtbout            ; do standard rpt end, send char in al
  5100.     mov    al,'$'
  5101.     call    prtbout
  5102.     mov    ttyact,1        ; end group output for networks
  5103.     mov    al,'y'
  5104.     call    prtbout
  5105.     ret
  5106.  
  5107. ; DEC style Soft Reset
  5108. ; Note: graphics rendition is NOT changed by soft reset, DEC manual is wrong.
  5109. atsres    proc    near            ; do soft reset of terminal
  5110.     test    dspstate,dsptype    ; on status line?
  5111.     jz    atsres1            ; z = no, on main display
  5112.     mov    param,0
  5113.     mov    inter,'$'        ; setup entry for atsasd
  5114.     call    atsasd            ; select main display
  5115. atsres1:and    vtemu.vtflgop,not(decawm+decckm+deckpam+decom) ; these go off
  5116.     mov    insmod,0        ; insert mode off
  5117.     mov    mar_top,0        ; reset scrolling margins
  5118.     mov    al,byte ptr low_rgt+1
  5119.     mov    mar_bot,al        ; to full screen
  5120.     mov    anspflg,0        ; clear printer flag
  5121.     mov    al,1            ; restore cursor, assume underline (1)
  5122.     test    vtemu.vtflgop,vscursor    ; underline?
  5123.     jnz    atsres2            ; nz = yes
  5124.     inc    al            ; block (2)
  5125. atsres2:mov    atctype,al        ; save VTxxx cursor type here
  5126.     call    atsctyp            ; set the cursor type
  5127.     push    cursor
  5128.     mov    cursor,0        ; set save cursor to Home
  5129.     call    atsc            ; save attributes
  5130.     pop    cursor            ; restore active cursor
  5131.     call    chrdef            ; set default character set
  5132.         cmp     isps55,0                ; [HF]941103 Japanese PS/55?
  5133.         je      atsres4                 ; [HF]941103 e = no
  5134.         cmp     flags.modflg,0          ; [HF]940227 mode line is off?
  5135.         je      atsres3                 ; [HF]940227 e = yes
  5136.         mov     flags.modflg,1          ; [HF]940227 mode line is owned by us
  5137.         jmp     short atsres5           ; [HF]941103
  5138. atsres4:test    yflags,modoff           ; mode line is to be off?
  5139.     jnz    atsres3            ; nz = yes
  5140. atsres5:call    fmodlin            ; rewrite mode line
  5141. atsres3:ret
  5142. atsres    endp
  5143.                     ; DECRQSS/DECRPSS Control Settings
  5144.  
  5145.                     ; Handle DCS ... q string ST
  5146. atcrq:    cmp    ninter,1        ; one intermediate?
  5147.     je    atcrq1            ; e = yes
  5148.     ja    atcrq0            ; a = too many
  5149.     jmp    atcrqq            ; none, do Sixel DCS params q...ST
  5150. atcrq0:    mov    ninter,0        ; set up atdcsnul for proper form
  5151.     mov    ttstate,offset atdcsnul    ; not understood, consume til ST
  5152.     ret
  5153.  
  5154. atcrq1:    cmp    inter,'$'        ; correct intermediate?
  5155.     jne    atcrq0            ; ne = no
  5156.     cmp    nparam,0        ; and no parameters?
  5157.     jne    atcrq0            ; ne = have some, not ours
  5158.     mov    ttstateST,offset atcrq4    ; set state for ST arrival
  5159.     mov    ttstate,offset atcrq2    ; next state gets string contents
  5160.     mov    emubufc,0        ; clear buffer counter
  5161.     mov    word ptr emubuf,0    ; empty start of buffer
  5162.     ret
  5163. atcrq2:    mov    bx,emubufc        ; count of chars in string buffer
  5164.     cmp    bx,emubufl        ; too many?
  5165.     jae    atcrq3            ; ae = too many, ignore extras
  5166.     mov    emubuf[bx],al        ; store the char
  5167.     inc    emubufc            ; count it
  5168. atcrq3:    ret
  5169.                     ; here after ST has been seen
  5170. atcrq4:    cmp    emubufc,2        ; max string chars we want
  5171.     jbe    atcrq4a            ; be = ok
  5172.     jmp    atnorm            ; a = too many, ignore
  5173. atcrq4a:mov    ax,word ptr emubuf    ; get first two chars
  5174.     cmp    ax,'}$'            ; select active display?
  5175.     jne    atcrq5            ; ne = no
  5176.     jmp    atcrqd            ; do the routine
  5177. atcrq5:    cmp    ax,'p"'            ; set conformance level?
  5178.     jne    atcrq7            ; ne = no
  5179.     jmp    atcrqp
  5180. atcrq7:    cmp    ax,'~$'            ; set status line type
  5181.     jne    atcrq8
  5182.     jmp    atcrqt
  5183. atcrq8:    cmp    ax,'r'            ; set top and bottom margins?
  5184.     jne    atcrq9
  5185.     jmp    atcrqr
  5186. atcrq9:    cmp    ax,'m'            ; set graphic rendition?
  5187.     jne    atcrq10
  5188.     jmp    atcrqm
  5189. atcrq10:jmp    atcrqxx            ; unknown command
  5190.                     ; DCS $ q  response routines
  5191. atcrqr:    call    atcrqbeg        ; 'r', top/bottom margins
  5192.     test    dspstate,dsptype    ; doing status line display?
  5193.     jz    atcrqr2            ; z = no
  5194.     mov    al,byte ptr dspmsave    ; get saved top margin
  5195.     inc    al
  5196.     call    prtnout
  5197.     mov    al,';'
  5198.     call    prtbout
  5199.     mov    al,byte ptr dspmsave+1    ; get saved bottom margin
  5200.     jmp    short atcrqr3        ; finish up
  5201. atcrqr2:mov    al,mar_top        ; top margin
  5202.     inc    al            ; move to 1,1 system
  5203.     call    prtnout
  5204.     mov    al,';'
  5205.     call    prtbout
  5206.     mov    al,mar_bot
  5207. atcrqr3:inc    al            ; move to 1,1 system
  5208.     call    prtnout
  5209.     mov    al,'r'            ; final char
  5210.     jmp    atcrqend        ; do epilogue
  5211.  
  5212. atcrqm:    call    atcrqbeg        ; 'm', graphics rendition
  5213.     mov    al,'0'            ; say start with all attributes off
  5214.     call    prtbout
  5215.     call    getbold            ; returns ah with bold attr or 0
  5216.     or    ah,ah            ; bold set?
  5217.     jz    atcrqm2            ; z = no
  5218.     mov    al,';'
  5219.     call    prtbout
  5220.     mov    al,'1'            ; say bold is on
  5221.     call    prtbout
  5222. atcrqm2:call    getunder        ; underline
  5223.     or    cl,cl            ; underline on?
  5224.     jz    atcrqm3            ; z = no, do next
  5225.     mov    al,';'
  5226.     call    prtbout
  5227.     mov    al,'4'            ; say underlining is on
  5228.     call    prtbout
  5229. atcrqm3:mov    ah,scbattr
  5230.     call    getblink        ; blinking
  5231.     or    ah,ah            ; blinking on?
  5232.     jz    atcrqm4            ; z = no
  5233.     mov    al,';'
  5234.     call    prtbout
  5235.     mov    al,'5'            ; say blinking is on
  5236.     call    prtbout
  5237. atcrqm4:test    extattr,att_rev        ; chars in reversed video?
  5238.     jz    atcrqm5            ; z = no
  5239.     mov    al,';'
  5240.     call    prtbout
  5241.     mov    al,'7'            ; say underlining is on
  5242.     call    prtbout
  5243. atcrqm5:mov    al,'m'            ; final char
  5244.     jmp    atcrqend        ; do epilogue
  5245.  
  5246. atcrqd:    call    atcrqbeg        ; '$}', writing to screen/status line
  5247.     mov    al,'0'            ; assume writing to main display
  5248.     test    dspstate,dsptype    ; get type of display
  5249.     jz    atcrqd2            ; z = main display
  5250.     inc    al            ; say writing to mode line
  5251. atcrqd2:call    prtbout
  5252.     mov    al,'$'            ; final chars
  5253.     call    prtbout
  5254.     mov    al,7dh            ; right curly brace
  5255.     jmp    atcrqend        ; do epilogue
  5256.  
  5257. atcrqt:    call    atcrqbeg        ; '$~', status line
  5258.     mov    al,'0'            ; assume mode line is off
  5259.     test    yflags,modoff        ; is mode line off?
  5260.     jnz    atcrqt2            ; nz = yes
  5261.     mov    al,'2'            ; mode line is on and host writable
  5262. atcrqt2:call    prtbout
  5263.     mov    al,'c'            ; final chars
  5264.     call    prtbout
  5265.     mov    al,7eh            ; tilde
  5266.     jmp    atcrqend        ; do epilogue
  5267.                     ; '"p' set conformance level
  5268. atcrqp:    cmp    oldterm,ttvt100        ; main-mode terminal is VT100?
  5269.     je    atcrqp2            ; e = yes
  5270.     cmp    oldterm,tthoney        ; Honeywell?
  5271.     je    atcrqp2            ; e = yes
  5272.     cmp    oldterm,ttansi        ; ANSI-BBS?
  5273.     je    atcrqp2            ; e = yes
  5274.     cmp    oldterm,ttvt102        ; VT102?
  5275.     je    atcrqp2            ; e = yes
  5276.     cmp    oldterm,ttvt320        ; how about VT320?
  5277.     je    atcrqp2            ; e = yes
  5278.     jmp    atcrqxx            ; say invalid request
  5279. atcrqp2:mov    ttyact,0        ; group output for networks
  5280.     mov    al,Escape        ; '"p', conformance level
  5281.     call    prtbout
  5282.     mov    al,'P'            ; DCS, ESC P
  5283.     call    prtbout
  5284.     mov    al,'0'            ; valid request
  5285.     call    prtbout
  5286.     mov    al,'$'
  5287.     call    prtbout
  5288.     mov    al,61            ; assume VT102
  5289.     cmp    oldterm,ttvt100        ; VT100?
  5290.     je    atcrqp2a        ; e = yes
  5291.     cmp    oldterm,tthoney        ; Honeywell
  5292.     je    atcrqp2a        ; e = yes
  5293.     cmp    oldterm,ttansi        ; ANSI-BBS?
  5294.     je    atcrqp2a        ; e = yes
  5295.     cmp    oldterm,ttvt102        ; are we a VT102?
  5296.     jne    atcrqp3            ; ne = no
  5297. atcrqp2a:call    prtnout
  5298.     jmp    short atcrqp5        ; finish the report
  5299.  
  5300. atcrqp3:mov    al,63            ; say VT320
  5301.     call    prtnout
  5302.     mov    al,';'
  5303.     call    prtbout
  5304.     mov    al,'2'            ; assume 8-bit controls are on
  5305.     test    vtemu.vtflgop,vscntl    ; 8-bit controls active?
  5306.     jnz    atcrqp4            ; nz = yes
  5307.     mov    al,'1'            ; else say only 7-bit controls
  5308. atcrqp4:call    prtbout
  5309. atcrqp5:mov    al,'"'            ; final characters
  5310.     call    prtbout
  5311.     mov    al,'p'
  5312.     jmp    atcrqend        ; do epilogue
  5313.  
  5314. atcrqbeg:mov    ttyact,0        ; group output for networks
  5315.     mov    al,Escape        ; report prologue
  5316.     call    prtbout
  5317.     mov    al,'P'            ; DCS, ESC P
  5318.     call    prtbout
  5319.     mov    al,'0'            ; valid request
  5320.     call    prtbout
  5321.     mov    al,'$'
  5322.     jmp    prtbout
  5323.  
  5324. atcrqend:call    prtbout            ; report epilogue, al has char
  5325.     mov    ttyact,1        ; end group output for networks
  5326.     mov    emubufc,0        ; clear work buffer count
  5327.     mov    al,Escape
  5328.     call    prtbout
  5329.     mov    al,'\'            ; string terminator ST (ESC \)
  5330.     jmp    prtbout
  5331.  
  5332. atcrqxx:mov    ttyact,0        ; group output for networks
  5333.     mov    al,Escape        ; report invalid request
  5334.     call    prtbout
  5335.     mov    al,'P'            ; DCS, ESC P
  5336.     call    prtbout
  5337.     mov    al,'1'            ; invalid request
  5338.     call    prtbout
  5339.     mov    al,'$'
  5340.     cmp    emubufc,1        ; any first char?
  5341.     jb    atcrqend        ; b = no
  5342.     call    prtbout
  5343.     mov    al,emubuf        ; first string char
  5344.     cmp    emubufc,2        ; two string chars?
  5345.     jne    atcrqend        ; ne = no
  5346.     call    prtbout
  5347.     mov    al,emubuf+1        ; second string char
  5348.     jmp    atcrqend        ; do epilogue
  5349.  
  5350.                     ; DCS P1; P2; P3 <char> Sixel command
  5351. atcrqq:    cmp    dcsstrf,'q'        ; final char of 'q'? Sixel draw
  5352.     je    atcrqq1            ; e = yes
  5353.     cmp    dcsstrf,'p'        ; 'p', restore palette?
  5354.     jne    atcrqq0            ; ne = no
  5355.     cmp    dinter,'$'        ; DCS 2 $ p?
  5356.     jne    atcrqq0            ; ne = no
  5357.     cmp    param,2            ; this too?
  5358.     jne    atcrqq1            ; ne = no
  5359. ifndef    no_graphics
  5360.     call    tekinq            ; get Tek screen state
  5361.     jmp    tekrcol            ; restore palette
  5362. endif    ; no_graphics
  5363.  
  5364. atcrqq0:mov    ninter,0        ; setup atdcsnul for proper form
  5365.     jmp    atdcsnul        ; consume unknown command
  5366.  
  5367. atcrqq1:test    denyflg,tekxflg        ; is auto Tek mode disabled?
  5368.     jnz    atcrqq0            ; nz = yes, consume
  5369. ifndef    no_graphics
  5370.     mov    di,offset emubuf    ; temp buffer
  5371.     mov    byte ptr [di],escape    ; do ESC ^L to erase screen
  5372.     inc    di
  5373.     mov    byte ptr [di],FF
  5374.     inc    di
  5375.     mov    byte ptr [di],escape    ; start DCS
  5376.     inc    di
  5377.     mov    byte ptr [di],'P'
  5378.     inc    di
  5379.     mov    ax,dparam[0]        ; get first parameter
  5380.     call    dec2di
  5381.     mov    byte ptr [di],';'
  5382.     inc    di
  5383.     mov    ax,dparam[2]        ; get second parameter
  5384.     call    dec2di            ; write ascii value
  5385.     mov    byte ptr [di],';'
  5386.     inc    di
  5387.     mov    ax,dparam[4]        ; get third parameter
  5388.     call    dec2di            ; write ascii value
  5389.     mov    al,dcsstrf
  5390.     mov    byte ptr [di],al    ; final char
  5391.     mov    byte ptr [di+1],0    ; terminator
  5392.     mov    di,offset emubuf
  5393.     mov    al,yflags        ; get yflags
  5394.     and    al,capt            ; save logging bit
  5395.     push    ax
  5396.     and    yflags,not capt        ; turn off logging bit
  5397. atcrqq2:mov    al,[di]
  5398.     inc    di
  5399.     or    al,al            ; at the end?
  5400.     jz    atcrqq3            ; z = yes
  5401.     push    di
  5402.     call    tekemu            ; feed Tek emulator this string
  5403.     pop    di
  5404.     jmp    short atcrqq2        ; do another string member
  5405. atcrqq3:mov    chcontrol,1        ; turn on full cell char writing
  5406.     pop    ax            ; recover logging bit
  5407.     or    yflags,al        ; restate logging bit
  5408. endif    ; no_graphics
  5409.     jmp    atnorm
  5410.  
  5411. ifndef    no_graphics
  5412. ; State machine to process DCS strings of type "p" (restore color palette)
  5413. ; Enter with "p" char in AL.
  5414. tekrcol    proc    near
  5415.     mov    ttstate,offset tekrco1    ; next state is get parameter
  5416.     mov    ttstateST,offset tekrcost ; go here on ST
  5417.     push    es
  5418.     push    ds
  5419.     pop    es
  5420.     mov    cx,5            ; five words
  5421.     xor    ax,ax
  5422.     mov    di,offset param        ; clear parameters Pc,Pu,Px,Py,Pz
  5423.     cld
  5424.     rep    stosw
  5425.     pop    es
  5426.     mov    nparam,0        ; work on initial parameter first
  5427.     ret
  5428. tekrco1:push    bx
  5429.     mov    bx,nparam        ; parameter number
  5430.     shl    bx,1            ; make it a word index
  5431.     mov    cx,param[bx]        ; accumulated parameter
  5432.     call    getdec            ; accumulate decimal value
  5433.     mov    param[bx],cx        ; remember accumulation
  5434.     pop    bx
  5435.     jnc    tekrcos1        ; nc = got a digit char
  5436.     inc    nparam            ; say have another complete parameter
  5437.     cmp    al,'/'            ; this kind of separator?
  5438.     je    tekrco3            ; e = yes, finish
  5439.     cmp    al,';'            ; break char is separator?
  5440.     jne    tekrco4            ; ne = no, decode current sequence
  5441. tekrco3:cmp    nparam,5        ; have 5 params already?
  5442.     jb    tekrcos1        ; n = no, continue reading
  5443. tekrco4:call    tekrpal            ; process parameters in msgibm file
  5444.     jmp    tekrcol            ; start over on next field
  5445.  
  5446. tekrcost:mov    ttstate,offset atnrm    ; get here on ST
  5447.     mov    ttstateST,offset atnorm ; default ST completion state
  5448.     cmp    nparam,5        ; enough parameters to finish cmd?
  5449.     jb    tekrcos1        ; b = no, abandon it
  5450.     call    tekrpal            ; update from last data item
  5451. tekrcos1:ret
  5452. tekrcol    endp
  5453. endif    ; no_graphics
  5454.  
  5455. ; Accumulate decimal value in CX using ascii char in al.
  5456. ; Return with value in CX. Return carry clear if ended on a digit,
  5457. ; return carry set and ascii char in al if ended on a non-digit.
  5458. getdec    proc    near
  5459.     cmp    al,'0'            ; a number?
  5460.     jb    getdecx            ; b = no, quit
  5461.     cmp    al,'9'
  5462.     ja    getdecx            ; a = not a number, quit
  5463.     sub    al,'0'            ; remove ascii bias
  5464.     xchg    cx,ax            ; put char in cx, decimal value in ax
  5465.     push    dx            ; save reg
  5466.     push    bx
  5467.     mov    bx,10
  5468.     mul    bx            ; times ten for a new digit
  5469.     pop    bx
  5470.     pop    dx            ; recover reg, ignore overflow
  5471.     add    al,cl            ; add current digit
  5472.     adc    ah,0            ; 16 bits worth
  5473.     xchg    ax,cx            ; rpt cnt back to cx
  5474.     clc                ; say found a digit
  5475.     ret
  5476. getdecx:stc                ; say non-digit (in al)
  5477.     ret
  5478. getdec    endp
  5479.                     ; Device Status Reports
  5480. atdsr:    mov    di,offset atdsr1    ; routine to call
  5481.     call    atreps            ; do for all parms
  5482.     ret
  5483.                     ; DSR workers
  5484. atdsr1:    mov    ax,param[si]
  5485.     cmp    lparam,0        ; any intermediate?
  5486.     jne    atdsr2            ; ne = yes, an intermediate
  5487.     cmp    ax,5            ; operating status report?
  5488.     je    rpstat            ; e = yes
  5489.     cmp    ax,6            ; cursor position report?
  5490.     je    rpcup            ; e = yes
  5491.     ret
  5492. atdsr2:    cmp    lparam,'?'        ; DEC mode queries for below?
  5493.     jne    atdsr3            ; no, skip them
  5494.     cmp    ax,6            ; VT340 cursor report?
  5495.     je    rpcup            ; e = yes
  5496.     cmp    ax,15            ; printer status report?
  5497.     je    rpstap            ; e = yes
  5498.     cmp    ax,25            ; UDK status?
  5499.     jne    atdsr3            ; ne = no
  5500.     jmp    rpudk            ; do udk status rpt
  5501. atdsr3:    cmp    ax,26            ; keyboard type?
  5502.     jne    atdsr4            ; ne = no
  5503.     jmp    rpkbd            ; do keyboard type report
  5504. atdsr4:    cmp    ax,256            ; WordPerfect Tek screen query?
  5505.     jne    atdsr5            ; ne = no
  5506. ifndef    no_graphics
  5507.     jmp    tekrpt            ; do Tek report
  5508. endif    ; no_graphics
  5509. atdsr5:    ret                ; must have been an echo
  5510.  
  5511. rpstat:    mov    ttyact,0        ; group output for networks
  5512.     mov    al,Escape        ; operating status query
  5513.     call    prtbout
  5514.     mov    al,'['
  5515.     call    prtbout
  5516.     mov    al,'0'            ; tell them we think we are OK
  5517.     call    prtbout
  5518.     mov    ttyact,1        ; end group output for networks
  5519.     mov    al,'n'
  5520.     call    prtbout
  5521.     ret
  5522.  
  5523. rpcup:    mov    ttyact,0        ; group output for networks
  5524.     mov    al,Escape        ; cursor position report
  5525.     call    prtbout
  5526.     mov    al,'['
  5527.     call    prtbout
  5528.     mov    al,byte ptr cursor+1    ; get row
  5529.     inc    al            ; map to origin at 1,1 system
  5530.     test    vtemu.vtflgop,decom    ; Origin mode set?
  5531.     jz    rpcup1            ; z = no
  5532.     sub    al,mar_top        ; subtract off top margin
  5533. rpcup1: call    prtnout            ; output the number
  5534.     mov    al,';'
  5535.     call    prtbout
  5536.     mov    al,byte ptr cursor    ; column number
  5537.     inc    al            ; map to origin at 1,1 system
  5538.     call    prtnout
  5539.     mov    ttyact,1        ; end group output for networks
  5540.     mov    al,'R'            ; final char
  5541.     call    prtbout
  5542.     ret
  5543.  
  5544. rpstap:    mov    ttyact,0        ; group output for networks
  5545.     mov    al,Escape        ; printer port query
  5546.     call    prtbout
  5547.     mov    al,'['
  5548.     call    prtbout
  5549.     mov    al,'?'            ;  10 = printer ready, 13 = not ready
  5550.     call    prtbout
  5551.     mov    al,'1'
  5552.     call    prtbout
  5553.     mov    ah,ioctl        ; get printer status, via DOS
  5554.     mov    al,7            ; status for output
  5555.     push    bx
  5556.     mov    bx,4            ; std handle for system printer
  5557.     int    dos
  5558.     pop    bx
  5559.     jc    rpstap1            ; c = call failed
  5560.     cmp    al,0ffh            ; code for Ready
  5561.     jne    rpstap1            ; ne = not ready
  5562.     mov    al,'0'            ; ready, send final digit
  5563.     jmp    short rpstap2
  5564. rpstap1:mov    al,'3'            ; not ready, say printer disconnected
  5565. rpstap2:call    prtbout
  5566.     mov    ttyact,1        ; end group output for networks
  5567.     mov    al,'n'            ; final char of response
  5568.     call    prtbout
  5569.     ret
  5570.  
  5571. rpudk:    mov    ttyact,0        ; group output for networks
  5572.     mov    al,Escape        ; response to UDK locked query
  5573.     call    prtbout
  5574.     mov    al,'['
  5575.     call    prtbout
  5576.     mov    al,'?'
  5577.     call    prtbout
  5578.     mov    al,20            ; say keys are unlocked (locked=21)
  5579.     call    prtnout
  5580.     mov    ttyact,1        ; end group output for networks
  5581.     mov    al,'n'            ; final char
  5582.     call    prtbout
  5583.     ret
  5584.  
  5585. rpkbd:    mov    ttyact,0        ; group output for networks
  5586.     mov    al,Escape        ; response to kbd type query
  5587.     call    prtbout
  5588.     mov    al,'['
  5589.     call    prtbout
  5590.     mov    al,'?'
  5591.     call    prtbout
  5592.     mov    al,27            ; keyboard dialect follows
  5593.     call    prtnout
  5594.     mov    al,';'
  5595.     call    prtbout
  5596.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  5597.     xor    bh,bh
  5598.     mov    al,nrckbd[bx]        ; get DEC keyboard code from table
  5599.     call    prtnout
  5600.     mov    ttyact,1        ; end group output for networks
  5601.     mov    al,'n'
  5602.     call    prtbout
  5603.     ret
  5604.  
  5605. ifndef    no_graphics
  5606. tekrpt:    call    tekinq            ; get Tek screen size and num colors
  5607.     push    cx            ; screen colors
  5608.     push    bx            ; screen width
  5609.     push    ax            ; screen height
  5610.     mov    ttyact,0        ; group output for networks
  5611.     mov    al,Escape        ; response to Tek query
  5612.     call    prtbout
  5613.     mov    al,'['
  5614.     call    prtbout
  5615.     mov    al,'?'
  5616.     call    prtbout
  5617.     mov    di,offset emubuf    ; working buffer
  5618.     mov    byte ptr [di],0        ; insert terminator
  5619.     mov    ax,256            ; first parameter
  5620.     call    dec2di            ; write ascii digits
  5621.     mov    byte ptr [di],';'    ; separator
  5622.     inc    di
  5623.     pop    ax            ; get screen height
  5624.     call    dec2di
  5625.     mov    byte ptr [di],';'    ; separator
  5626.     inc    di
  5627.     pop    ax            ; get screen width
  5628.     call    dec2di
  5629.     mov    byte ptr [di],';'    ; separator
  5630.     inc    di
  5631.     pop    ax            ; get number screen color (0, 1 or 16)
  5632.     call    dec2di
  5633.     mov    byte ptr[di],'n'    ; end of sequence
  5634.     inc    di
  5635.     mov    cx,di            ; compute string length
  5636.     mov    di,offset emubuf
  5637.     sub    cx,di
  5638. tekrpt1:mov    al,[di]            ; get a string char
  5639.     inc    di
  5640.     cmp    cx,1            ; last char?
  5641.     ja    tekrpt2            ; a = no
  5642.     mov    ttyact,1        ; end group output for networks
  5643. tekrpt2:call    prtbout            ; send it
  5644.     loop    tekrpt1
  5645.     ret
  5646. endif    ; no_graphics
  5647.  
  5648. atrqtsr:cmp    flags.vtflg,ttheath    ; Heath-19? ESC [ u
  5649.     jne    atrqts1            ; ne = no
  5650.     cmp    nparam,0        ; ought to have no parameters
  5651.     jne    atrqts2            ; ne = oops, not H-19 command, ignore
  5652.     jmp    atrc            ; H19, restore cursor pos and attrib
  5653.     
  5654. atrqts1:cmp    inter,'$'        ; VT320 Terminal State Rpt DECRQTSR?
  5655.     jne    atrqts2            ; ne = no
  5656.     cmp    param,1            ; report required?
  5657.     je    atrqts4            ; e = yes
  5658.     cmp    param,2            ; VT340 color palette report?
  5659.     jne    atrqts1a        ; ne = no
  5660. ifndef    no_graphics
  5661.     call    tekinq            ; get Tek screen state
  5662.     call    tekpal            ; do palette report in Tek emulator
  5663. endif    ; no_graphics
  5664. atrqts1a:ret
  5665. atrqts2:cmp    inter,'&'        ; DECRQUPSS, User preferred Supp Set?
  5666.     je    atrqts5            ; e = yes
  5667.     cmp    ninter,0        ; any intermediates?
  5668.     jne    atrqts3            ; ne = yes
  5669.     jmp    atrc            ; ANSI restore cursor ESC [ s
  5670. atrqts3:ret                ; else ignore
  5671. atrqts4:mov    al,Escape        ; Terminal state report
  5672.     call    prtbout
  5673.     mov    al,'P'            ; DCS, ESC P
  5674.     call    prtbout
  5675.     mov    al,byte ptr param
  5676.     call    prtnout            ; output as ascii digits, no echo
  5677.     mov    al,'$'
  5678.     call    prtbout            ; output char, no echo
  5679.     mov    al,'s'            ; Final char to main DCS part
  5680.     call    prtbout
  5681.     mov    al,Escape
  5682.     call    prtbout
  5683.     mov    al,'\'            ; string terminator ST (ESC \)
  5684.     call    prtbout
  5685.     ret
  5686.  
  5687. atrqts5:mov    al,Escape        ; User Preferred Supplemental Set
  5688.     call    prtbout
  5689.     mov    al,'P'            ; DCS, ESC P
  5690.     call    prtbout            ;  report
  5691.     mov    al,'0'            ; assume 94 byte set
  5692.     cmp    upss,94            ; 94 byte set?
  5693.     je    atrqts6            ; e = yes
  5694.     inc    al            ; change to 96 byte size
  5695. atrqts6:call    prtbout
  5696.     mov    al,'!'
  5697.     call    prtbout
  5698.     mov    al,'u'
  5699.     call    prtbout
  5700.     mov    al,upss+1        ; first ident char
  5701.     call    prtbout
  5702.     mov    al,upss+2        ; second char, if any
  5703.     or    al,al
  5704.     jz    atrqts7            ; z = no second char
  5705.     call    prtbout
  5706. atrqts7:mov    al,Escape
  5707.     call    prtbout
  5708.     mov    al,'\'            ; string terminator ST (ESC \)
  5709.     call    prtbout
  5710.     ret
  5711.                     ; Request Presentation State Report
  5712. atrqpsr:cmp    inter,'$'        ; proper form?
  5713.     jne    atrqps1            ; ne = no, ignore
  5714.     cmp    param,1            ; cursor report?
  5715.     je    atrqps2            ; e = yes
  5716.     cmp    param,2            ; tabstop report?
  5717.     jne    atrqps1            ; ne = no, ignore
  5718.     jmp    atrqps40        ; do tabstop report
  5719. atrqps1:ret                ; else ignore
  5720.  
  5721. atrqps2:mov    al,Escape        ; cursor report, start
  5722.     call    prtbout
  5723.     mov    al,'P'            ; DCS, ESC P
  5724.     call    prtbout
  5725.     mov    al,'1'
  5726.     call    prtbout
  5727.     mov    al,'$'
  5728.     call    prtbout
  5729.     mov    al,'u'
  5730.     call    prtbout
  5731.     mov    al,dh            ; row of cursor
  5732.     inc    al            ; count from 1,1
  5733.     call    prtnout            ; output number
  5734.     mov    al,';'
  5735.     call    prtbout
  5736.     mov    al,dl            ; column of cursor
  5737.     inc    al            ; count from 1,1
  5738.     call    prtnout            ; output number
  5739.     mov    al,';'
  5740.     call    prtbout
  5741.     mov    al,'1'            ; video page, always 1 for VT320
  5742.     call    prtbout
  5743.     mov    al,';'
  5744.     call    prtbout
  5745.     mov    al,40h            ; start bit field template
  5746.     test    extattr,att_rev        ; reverse video char writing on?
  5747.     jz    atrqps3            ; z = no
  5748.     or    al,8            ; set the bit
  5749. atrqps3:call    getblink        ; ah will be non-zero if blinking
  5750.     or    ah,ah            ; blinking?
  5751.     jz    atrqps4            ; z = no
  5752.     or    al,4            ; set the bit
  5753. atrqps4:call    getunder        ; ah will be non-zero if underlining
  5754.     or    cl,cl            ; underlining?
  5755.     jz    atrqps5            ; z = no
  5756.     or    al,2            ; set the bit
  5757. atrqps5:call    getbold            ; ax will be non-zero if bolding
  5758.     or    ah,ah            ; bold?
  5759.     jz    atrqps6            ; z = no
  5760.     or    al,1            ; set the bit
  5761. atrqps6:call    prtbout
  5762.     mov    al,';'
  5763.     call    prtbout
  5764.     mov    al,40h            ; Satt (Selective params)
  5765.     test    extattr,att_protect    ; is char protected?
  5766.     jz    atrqps6a        ; z = no
  5767.     or    al,1            ; say char is protected
  5768. atrqps6a:call    prtbout            ; output required skeleton
  5769.     mov    al,';'
  5770.     call    prtbout
  5771.     mov    al,40h            ; Sflag (shift/wrap/origin mode)
  5772.     cmp    atwrap,0        ; wrap pending?
  5773.     je    atrqps7            ; e = no
  5774.     or    al,8            ; set the bit
  5775. atrqps7:cmp    SSptr,offset G3set    ; SS3: G3 mapped to GL for next char?
  5776.     jne    atrqps8            ; ne = no
  5777.     or    al,4            ; set the bit
  5778. atrqps8:cmp    SSptr,offset G2set    ; SS2: G2 mapped to GL for next char?
  5779.     jne    atrqps9            ; ne = no
  5780.     or    al,2            ; set the bit
  5781. atrqps9:test    vtemu.vtflgop,decom    ; Origin mode set?
  5782.     jz    atrqps10        ; z = no
  5783.     or    al,1            ; set the bit
  5784. atrqps10:call    prtbout
  5785.     mov    al,';'
  5786.     call    prtbout
  5787.     mov    al,'0'            ; Pgl, say which set is in GL
  5788.     mov    si,GLptr        ; setup for worker
  5789.     call    atrqps30        ; worker returns proper al
  5790.     call    prtbout
  5791.     mov    al,';'
  5792.     call    prtbout
  5793.     mov    al,'0'            ; Pgr, say which set is in GR
  5794.     mov    si,GRptr        ; setup for worker
  5795.     call    atrqps30        ; worker returns proper al
  5796.     call    prtbout
  5797.     mov    al,';'
  5798.     call    prtbout
  5799.     mov    al,40h            ; Scss, char set size bit field
  5800.     call    atrqp15            ; call worker to fill in al
  5801.     call    prtbout    
  5802.     mov    al,';'
  5803.     call    prtbout
  5804.     mov    bx,offset G0set        ; Sdesig, get 1-2 letter ident
  5805.     call    atrqps20        ; G0, let worker fill in response
  5806.     mov    bx,offset G1set
  5807.     call    atrqps20        ; G1, let worker fill in response
  5808.     mov    bx,offset G2set
  5809.     call    atrqps20        ; G2, let worker fill in response
  5810.     mov    bx,offset G3set
  5811.     call    atrqps20        ; G3, let worker fill in response
  5812.     mov    al,Escape
  5813.     call    prtbout
  5814.     mov    al,'\'            ; string terminator ST (ESC \)
  5815.     call    prtbout
  5816.     ret
  5817.  
  5818. ; worker for Character set size reporting
  5819. atrqp15:cmp    G0set+gsize,96        ; is G0 a 96 byte set?
  5820.     jne    atrqp16            ; ne = no
  5821.     or    al,1            ; say 96
  5822. atrqp16:cmp    G1set+gsize,96        ; is G1 a 96 byte set?
  5823.     jne    atrqp17            ; ne = no
  5824.     or    al,2            ; say 96
  5825. atrqp17:cmp    G2set+gsize,96        ; G2 set?
  5826.     jne    atrqp18
  5827.     or    al,4            ; say 96
  5828. atrqp18:cmp    G3set+gsize,96        ; G3 set?
  5829.     jne    atrqp19
  5830.     or    al,8            ; say 96
  5831. atrqp19:ret                ; return with al setup
  5832.  
  5833. ; worker for Character set ident reporting at atrqps16: et seq
  5834. atrqps20:mov    al,[bx+gsize+1]        ; Gn set pointer, first letter
  5835.     call    prtbout
  5836.     mov    al,[bx+gsize+2]        ; second letter
  5837.     or    al,al            ; is there one?
  5838.     jz    atrqps21        ; z = no, nothing there
  5839.     call    prtbout
  5840. atrqps21:ret
  5841.  
  5842. ; worker. Enter with SI holding GLptr or GRptr and al = '0'
  5843. ; Returns al = '0' .. '3' to match set pointed at
  5844. atrqps30:cmp    si,offset G0set        ; si points at G0?
  5845.     je    atrqps31        ; e = yes
  5846.     inc    al            ; try next set
  5847.     cmp    si,offset G1set        ; si points at G1?
  5848.     je    atrqps31
  5849.     inc    al
  5850.     cmp    si,offset G2set        ; si points at G2?
  5851.     je    atrqps31
  5852.     inc    al            ; must be G3
  5853. atrqps31:ret
  5854.  
  5855. atrqps40:mov    al,Escape        ; start tabstop report
  5856.     call    prtbout
  5857.     mov    al,'P'            ; DCS, ESC P
  5858.     call    prtbout
  5859.     mov    al,'2'            ; tabs
  5860.     call    prtbout
  5861.     mov    al,'$'
  5862.     call    prtbout
  5863.     mov    al,'u'
  5864.     call    prtbout
  5865.     mov    cl,mar_right        ; right most column number
  5866.     inc    cl            ; number of columns
  5867.     xor    ch,ch
  5868.     push    dx            ; save dx
  5869.     xor    dx,dx            ; dh for done one output, dl = column
  5870.     mov    si,offset tabs        ; active tabs buffer
  5871. atrqps41:call    istabs            ; tab inquiry routine, column is in dl
  5872.     jnc    atrqps43        ; nc = no tab
  5873.     or    dh,dh            ; sent one value already?
  5874.     je    atrqps42        ; e = no, so no separator
  5875.     mov    al,';'            ; separator (DEC used '/')
  5876.     call    prtbout
  5877. atrqps42:mov    al,dl            ; get column
  5878.     inc    al            ; count columns from 1 for host
  5879.     call    prtnout            ; output the number
  5880.     inc    dh            ; say sent a number
  5881. atrqps43:inc    dl            ; next column, say sent one output
  5882.     loop    atrqps41        ; do the rest
  5883.     pop    dx            ; recover dx
  5884.     mov    al,Escape
  5885.     call    prtbout
  5886.     mov    al,'\'            ; string terminator ST (ESC \)
  5887.     call    prtbout
  5888.     ret
  5889.     
  5890. ; Process Restore Presentation Reports, for cursor and tab stops
  5891. ; Uses bytes dinter+5 and dinter+6 as internal variables
  5892. atrp:    cmp    dinter,0+'$'        ; correct intermediate?
  5893.     je    atrp1            ; e = yes
  5894.     jmp    atcrqxx            ; send back "illegal restore" response
  5895. atrp1:    cmp    dparam,1        ; cursor info?
  5896.     je    atrp4            ; e = yes
  5897.     mov    modeset,1        ; say setting tabs
  5898.     call    atrpw            ; call worker to do ascii to binary
  5899.     dec    dl            ; count internally from col 0
  5900.     call    tabset            ; set tab in column dl
  5901. atrp3:    mov    emubufc,0        ; clear the string count
  5902.     ret
  5903.                       ; start cursor info report playback
  5904. atrp4:    cmp    dinter+5,0        ; our internal counter in vacant byte
  5905.     jne    atrp5            ; not initial byte
  5906.     inc    dinter+5        ; point to next item next time
  5907.     call    atrpw            ; ascii to binary worker
  5908.     xchg    dh,dl            ; get row to correct byte
  5909.     mov    dl,byte ptr cursor+1    ; get column
  5910.     jmp    atsetcur        ; set the cursor
  5911. atrp5:    cmp    dinter+5,1        ; column?
  5912.     jne    atrp6
  5913.     inc    dinter+5        ; point to next item next time
  5914.     call    atrpw            ; ascii to binary worker
  5915.     mov    dh,byte ptr cursor    ; get row
  5916.     jmp    atsetcur        ; set the cursor
  5917. atrp6:    cmp    dinter+5,2        ; page?
  5918.     jne    atrp7
  5919.     inc    dinter+5        ; omit page byte
  5920.     ret
  5921. atrp7:    cmp    dinter+5,3
  5922.     jne    atrp8
  5923.     inc    dinter+5        ; Srend
  5924.     mov    al,emubuf        ; string byte
  5925.     mov    ah,curattr        ; attributes field
  5926.                     ; ought to clear attributes first
  5927.     test    al,1            ; set bold?
  5928.     jz    atrp7a            ; z = no
  5929.     call    setbold
  5930. atrp7a:    test    al,2            ; set underline?
  5931.     jz    atrp7b            ; z = no
  5932.     call    setunder
  5933. atrp7b:    test    al,4            ; set blink?
  5934.     jz    atrp7c            ; z = no
  5935.     call    setblink
  5936. atrp7c:    mov    curattr,ah        ; attributes so far
  5937.     test    al,8            ; set per char rev video?
  5938.     jz    atrp7d            ; z = no
  5939.     call    setrev            ; set reversed video
  5940.     mov    curattr,ah        ; gather main attributes
  5941. atrp7d:    ret
  5942. atrp8:    cmp    dinter+5,4
  5943.     jne    atrp9
  5944.     inc    dinter+5        ; Satt, skip it
  5945.     ret
  5946. atrp9:    cmp    dinter+5,5
  5947.     jne    atrp10
  5948.     inc    dinter+5
  5949.     mov    al,emubuf        ; string byte
  5950.     mov    ah,al
  5951.     and    ah,8            ; autowrap bit
  5952.     mov    atwrap,ah        ; set it
  5953.     mov    SSptr,0            ; say no single shift needed
  5954.     test    al,4            ; SS3 bit?
  5955.     jz    atrp9a            ; z = no
  5956.     mov    SSptr,offset G3set    ; set the pointer
  5957. atrp9a:    test    al,2            ; SS2 bit?
  5958.     jz    atrp9b            ; z = no
  5959.     mov    SSptr,offset G2set    ; set the pointer
  5960. atrp9b:    and    vtemu.vtflgop,not decom ; clear origin bit
  5961.     test    al,1            ; origin mode?
  5962.     jz    atrp9c            ; z = no
  5963.     or    vtemu.vtflgop,decom    ; set origin mode
  5964. atrp9c:    ret
  5965. atrp10:    cmp    dinter+5,6        ; Pgl
  5966.     jne    atrp11
  5967.     inc    dinter+5
  5968.     mov    al,emubuf        ; string byte
  5969.     call    atrpw5            ; call worker to setup bx with ptr
  5970.     mov    GLptr,bx
  5971.     ret
  5972. atrp11:    cmp    dinter+5,7        ; Pgr
  5973.     jne    atrp12
  5974.     inc    dinter+5
  5975.     mov    al,emubuf        ; string byte
  5976.     call    atrpw5            ; call worker to setup bx with ptr
  5977.     mov    GRptr,bx
  5978.     ret
  5979. atrp12:    cmp    dinter+5,8        ; Scss
  5980.     jne    atrp13            ; ne = no
  5981.     inc    dinter+5
  5982.     mov    al,emubuf        ; string byte
  5983.     and    al,0fh            ; strip ascii bias
  5984.     mov    dinter+6,al        ; save here for Sdesig byte, next
  5985.     ret
  5986. atrp13:    cmp    dinter+5,9        ; Sdesig
  5987.     jne    atrp14
  5988.     inc    dinter+5
  5989.     mov    si,offset emubuf    ; string
  5990.     xor    cx,cx            ; init loop counter to 0
  5991. atrp13a:mov    al,'('            ; assume G0 is 94 byte set
  5992.     add    al,cl            ; plus loop index to get set pointer
  5993.     shr    dinter+6,1        ; get set size bit
  5994.     jnc    atrp13b            ; e = correct
  5995.     add    al,4            ; map to 96 byte indicator
  5996. atrp13b:mov    inter,al        ; store size byte as intermediate
  5997.     mov    ninter,1        ; one char
  5998.     cld
  5999. atrp13c:lodsb                ; next string byte
  6000.     test    al,not 2fh        ; is there a second intermediate byte?
  6001.     jnz    atrp13d            ; nz = no
  6002.     mov    inter+1,al        ; store intermediate
  6003.     inc    ninter            ; count them
  6004.     jmp    short atrp13c        ; try again for a Final char
  6005. atrp13d:push    si
  6006.     push    cx
  6007.     mov    bx,offset ansesc    ; table to use
  6008.     call    atdispat        ; dispatch on final char to set ptr
  6009.     pop    cx
  6010.     pop    si
  6011.     inc    cx
  6012.     cmp    cx,3            ; doing last one?
  6013.     jbe    atrp13a            ; be = no, do all four
  6014.     ret
  6015. atrp14:    jmp    atcrqxx            ; send back "illegal restore" response
  6016.  
  6017.                     ; worker, ascii string to decimal byte
  6018. atrpw:    mov    cx,emubufc        ; length of this string
  6019.     jcxz    atrpw3            ; nothing there
  6020.     mov    si,offset emubuf    ; address of string
  6021.     xor    dl,dl            ; init final value
  6022.     cld
  6023. atrpw2:    lodsb                ; read a digit
  6024.     sub    al,'0'            ; ascii to numeric
  6025.     jc    atrpw3            ; c = trouble
  6026.     shl    dl,1            ; previous contents times 10
  6027.     mov    dh,dl
  6028.     shl    dl,1
  6029.     shl    dl,1
  6030.     add    dl,dh
  6031.     add    dl,al            ; plus new value
  6032.     loop    atrpw2            ; do all digits
  6033. atrpw3:    ret
  6034.                        ; char set selector worker
  6035. atrpw5:    cmp    al,'0'            ; bx gets G0set...G3set, based on AL
  6036.     jne    atrpw5a
  6037.     mov    bx,offset G0set
  6038.     ret
  6039. atrpw5a:cmp    al,'1'
  6040.     jne    atrpw5b
  6041.     mov    bx,offset G1set
  6042.     ret
  6043. atrpw5b:cmp    al,'2'
  6044.     jne    atrpw5c
  6045.     mov    bx,offset G2set
  6046.     ret
  6047. atrpw5c:mov    bx,offset G3set
  6048.     ret
  6049.  
  6050. ; Select Active Display. When selecting the status line make new scrolling
  6051. ; margins be just the status line and force on Origin mode. Save the regular
  6052. ; margins and origin mode for restoration when regular display is re-selected.
  6053. ; Also CSI Pn; Pn; Pn; Pn ~ invokes Lotus macro PRODUCT
  6054. atsasd    proc    near
  6055.     cmp    inter,'$'        ; correct intermediate?
  6056.     jne    atsasd1            ; ne = no
  6057.     cmp    param,1            ; select which display
  6058.     jb    atsasd4            ; b = select main display
  6059.     ja    atsasd1            ; a = illegal value
  6060.     cmp    flags.modflg,2        ; mode line host owned?
  6061.     jne    atsasd1            ; ne = no, ignore command
  6062.     test    dspstate,dsptype    ; was previous display = status line?
  6063.     jz    atsasd2            ; z = no
  6064. atsasd1:ret                ; else do nothing
  6065.  
  6066. atsasd2:push    word ptr mar_top    ; save scrolling margins
  6067.     pop    dspmsave        ; save scrolling margins
  6068.     or    dspstate,dsptype    ; say status line is active
  6069.     mov    al,byte ptr low_rgt+1    ; get last text line
  6070.     inc    al            ; status line
  6071.     mov    mar_top,al
  6072.     mov    mar_bot,al        ; new scrolling margins
  6073.     and    dspstate,not dspdecom    ; clear remembered origin mode
  6074.     test    vtemu.vtflgop,decom    ; was origin mode active?
  6075.     jz    atsasd3            ; z = no
  6076.     or    dspstate,dspdecom    ; remember origin mode was active
  6077. atsasd3:or    vtemu.vtflgop,decom    ; set origin mode
  6078.     call    atsc            ; save cursor material
  6079.     call    chrdef            ; reinit char sets from master setup
  6080.     mov    dx,dspcstat        ; get status line cursor
  6081.     mov    dh,mar_top        ; set row
  6082.     jmp    atsetcur        ; set cursor
  6083.  
  6084. atsasd4:test    dspstate,dsptype    ; was previous display = status line?
  6085.     jnz    atsasd5            ; nz = yes
  6086.     ret                ; else do nothing    
  6087. atsasd5:push    dspmsave        ; restore scrolling margins
  6088.     pop    word ptr mar_top
  6089.     and    vtemu.vtflgop,not decom    ; clear origin mode bit
  6090.     test    dspstate,dspdecom    ; was origin mode on for main screen?
  6091.     jz    atsasd6            ; z = no
  6092.     or    vtemu.vtflgop,decom    ; set it now
  6093. atsasd6:push    cursor            ; get status line cursor position
  6094.     pop    dspcstat        ; save it
  6095.     mov    dspstate,0        ; say now doing main screen
  6096.     jmp    atrc            ; restore cursor material
  6097. atsasd    endp
  6098.  
  6099. atssdt    proc    near            ; Select Status Line Type, DECSSDT
  6100.     cmp    inter,'$'        ; correct intermediate char?
  6101.     je    atssdt1            ; e = yes
  6102.     cmp    ninter,0        ; no intermediates?
  6103.     jne    atssdt0            ; ne = no
  6104.     call    fproduct        ; do PRODUCT macro
  6105. atssdt0:ret
  6106. atssdt1:test    dspstate,dsptype    ; on mode line already?
  6107.     jnz    atssdt4            ; nz = yes, cannot reselect now
  6108.     cmp    param,0            ; turn off status line?
  6109.     jne    atssdt2            ; ne = no
  6110.     push    dx            ; save cursor position
  6111.     call    fclrmod            ; clear the line
  6112.     pop    dx
  6113.     or    yflags,modoff        ; now say it's off
  6114.     mov    flags.modflg,1        ; say mode line is owned by us
  6115.     ret
  6116. atssdt2:cmp    param,1            ; regular status line?
  6117.     jne    atssdt3            ; ne = no
  6118.     push    dx
  6119.     call    fmodlin            ; turn on regular mode line
  6120.     pop    dx
  6121.     and    yflags,not modoff    ; and say it's on
  6122.     mov    flags.modflg,1        ; say mode line is owned by us
  6123.     ret
  6124. atssdt3:cmp    param,2            ; host writable?
  6125.     jne    atssdt4            ; ne = no
  6126.     mov    flags.modflg,2        ; say mode line is owned by host
  6127. atssdt4:ret
  6128. atssdt    endp
  6129.  
  6130. ; VT52 compatibility mode routines.
  6131.  
  6132. ; Return to ANSI mode.
  6133.  
  6134. v52ans: or    vtemu.vtflgop,decanm    ; turn on ANSI flag
  6135.     mov    ax,oldterm        ; terminal type at startup
  6136.     cmp    ax,ttvt52        ; was VT52 the prev kind?
  6137.     jne    v52ans1            ; ne = no
  6138.     mov    ax,ttvt320        ; use VT320
  6139. v52ans1:mov    oldterm,ax
  6140.     mov    flags.vtflg,ax        ; restore it
  6141.     call    chrdef            ; set default char sets
  6142.     call    atsc            ; save cursor status
  6143.     test    yflags,modoff        ; mode line supposed to be off?
  6144.     jnz    v52ans2            ; nz = yes
  6145.     call    fmodlin            ; rewrite mode line
  6146. v52ans2:ret
  6147.     
  6148. ; VT52 cursor positioning.
  6149.  
  6150. v52pos: mov    ttstate,offset v52pc1    ; next state
  6151.     ret
  6152. v52pc1: sub    al,' '-1        ; minus offset
  6153.     xor    ah,ah
  6154.     mov    param,ax        ; stash it here
  6155.     mov    ttstate,offset v52pc2    ; next state
  6156.     ret
  6157. v52pc2: sub    al,' '-1        ; minus offset
  6158.     xor    ah,ah
  6159.     mov    param+2,ax        ; stash here
  6160.     mov    ttstate,offset atnrm    ; reset state to "normal"
  6161.     jmp    atcup            ; position and return
  6162.  
  6163. ; VT52 print controls
  6164.  
  6165. v52ps:    mov    param,0            ; print screen
  6166.     mov    lparam,0
  6167.     jmp    ansprt            ; simulate ESC [ 0 i
  6168. v52pl:    mov    param,1            ; print line
  6169.     jmp    short v52pcom        ; simulate ESC [ ? 1 i
  6170. v52pcb:    mov    param,5            ; Enter printer controller on
  6171.     jmp    short v52pcom        ; simulate ESC [ ? 5 i
  6172. v52pce:    mov    param,4            ; Exit printer controller on
  6173. ;    jmp    short v52pcom        ; simulate ESC [ ? 4 i
  6174. v52pcom:mov    lparam,'?'        ; simulate ESC [ ? <number> i
  6175.     jmp    ansprt            ; process command
  6176.  
  6177. v52sgm:    mov    setptr,offset G0set    ; enter/exit special graphics mode
  6178.     cmp    al,'F'            ; enter VT52 graphics mode?
  6179.     jne    v52sgm1            ; ne = no, exit and return to ASCII
  6180.     jmp    mkdecspec        ; 'G' make DEC special graphics in G0
  6181. v52sgm1:jmp    mkascii            ; make ASCII in G0
  6182.  
  6183. ; Heath-19 special functions
  6184.  
  6185. h19sans:or    vtemu.vtflgop,decanm    ; Turn on ANSI flag. ESC <
  6186.     jmp    chrdef            ; set default char sets
  6187.                     ; clear screen and go home
  6188.  
  6189. h19ed:    cmp    param,0            ; Erase cursor to end of screen?
  6190.     jne    h19ed2            ; ne = no
  6191.     mov    ax,dx            ; start at cursor
  6192.     mov    bx,low_rgt        ; lower right corner
  6193.     cmp    bh,dh            ; on status line?
  6194.     jae    h19ed1            ; ae = no
  6195.     mov    bh,dh            ; put end on status line
  6196. h19ed1:    call    vtsclr            ; clear it
  6197.     ret
  6198. h19ed2:    cmp    param,1            ; erase start of display to cursor?
  6199.     je    h19esos            ; e = yes
  6200.     cmp    param,2            ; erase entire screen?
  6201.     je    h19clrs            ; e = yes
  6202.     ret                ; else ignore
  6203.  
  6204.                     ; erase entire screen
  6205. h19clrs:cmp    dh,byte ptr low_rgt+1    ; on status line?
  6206.     ja    h19erl            ; a = yes, do just erase in line
  6207.     xor    dx,dx            ; go to upper left corner
  6208.     call    atsetcur        ; do it
  6209.     xor    ax,ax            ; clear screen from (0,0)
  6210.     mov    bx,low_rgt        ; to lower right corner
  6211.     call    vtsclr            ; clear it
  6212.     ret
  6213.  
  6214. h19erl:    xor    al,al            ; erase whole line
  6215.     mov    bl,byte ptr low_rgt    ; physical width
  6216.     jmp    erinline        ; erase whole line, cursor stays put
  6217.  
  6218. h19ero:    xor    al,al            ; erase start of line to cursor
  6219.     mov    bl,dl
  6220.     jmp    erinline        ; clear that part of line
  6221.  
  6222.                     ; erase start of screen to cursor
  6223. h19esos:cmp    dh,byte ptr low_rgt+1    ; on status line?
  6224.     ja    h19ero            ; a = yes, do just erase in line
  6225.     jmp    ersos            ; do regular erase start of screen
  6226.  
  6227. h19wrap:or    vtemu.vtflgop,decawm    ; turn on line wrapping
  6228.     ret
  6229. h19nowrp:and    vtemu.vtflgop,not decawm ; turn off line wrapping
  6230.     ret
  6231.  
  6232. h19herv:mov    ah,curattr        ; get current cursor attribute
  6233.     mov    cl,extattr
  6234.     call    setrev            ; ESC p set reversed video
  6235.     mov    curattr,ah        ; store new attribute byte
  6236.     ret
  6237.  
  6238. h19hxrv:mov    ah,curattr        ; get current cursor attribute
  6239.     mov    cl,extattr
  6240.     call    clrrev            ; ESC q set normal video
  6241.     mov    curattr,ah        ; store new attribute byte
  6242.     ret
  6243.  
  6244. h19sc:    mov    dx,cursor
  6245.     mov    h19cur,dx        ; save cursor position
  6246.     ret
  6247.  
  6248. h19rc:    mov    dx,h19cur        ; saved cursor position
  6249.     jmp    atsetcur            ; set cursor and return
  6250.  
  6251.                     ; Heath-19 set mode "ESC x "
  6252. h19smod:mov    ttstate,offset hsmod    ; setup to parse rest of seq
  6253.     ret
  6254. hsmod:    mov    modeset,1        ; say set mode
  6255.     mov    ttstate,offset atnrm
  6256.     sub    al,'0'            ; remove ascii bias
  6257.     jmp    htrsm1            ; perform mode set
  6258.  
  6259. h19cmod:mov    ttstate,offset hcmod    ; setup to parse rest of seq
  6260.     ret
  6261.  
  6262. hcmod:    mov    modeset,0        ; say reset mode
  6263.     mov    ttstate,offset atnrm
  6264.     sub    al,'0'            ; remove ascii bias
  6265.     jmp    htrsm1            ; perform mode reset
  6266.  
  6267. hrcup:    mov    al,escape        ; send "ESC Y row col" cursor report
  6268.     call    prtbout            ; send with no local echo
  6269.     mov    al,'Y'
  6270.     call    prtbout
  6271.     mov    al,byte ptr cursor+1    ; get row
  6272.     add    al,' '            ; add ascii bias
  6273.  
  6274.     call    prtbout            ; send it
  6275.     mov    al,byte ptr cursor    ; get column
  6276.     add    al,' '            ; add ascii bias
  6277.     call    prtbout            ; and send it too
  6278.     ret
  6279.  
  6280. ; Insert/Delete characters and lines
  6281. inslin    proc    near
  6282.     mov    ax,param        ; insert line
  6283.     or    ax,ax            ; any args?
  6284.     jne    insli1            ; ne = yes
  6285.     inc    ax            ; insert one line
  6286. insli1:    mov    scroll,al        ; lines to scroll
  6287.     mov    dx,cursor        ; current position
  6288.     cmp    dh,mar_bot        ; below bottom margin?
  6289.     ja    insli3            ; a = below bottom margin
  6290.     push    word ptr mar_top
  6291.     mov    mar_top,dh        ; call present position the top
  6292.     call    atscrd            ; scroll down
  6293.     pop    word ptr mar_top    ; restore margins
  6294.     xor    dl,dl            ; go to left margin
  6295.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6296.     jz    insli2            ; z = no
  6297.     jmp    dgsetcur        ; DG set cursor with protection
  6298. insli2:    jmp    atsetcur        ; reposition cursor and return
  6299. insli3: ret
  6300. inslin    endp
  6301.  
  6302. dellin    proc    near
  6303.     mov    ax,param        ; delete line(s)
  6304.     or    ax,ax            ; any args?
  6305.     jne    delli1            ; ne = yes
  6306.     inc    ax            ; insert one line
  6307. delli1:    mov    scroll,al        ; line count
  6308.     mov    dx,cursor        ; where we are presently
  6309.     cmp    dh,mar_bot        ; at or below bottom margin?
  6310.     jae    delli3            ; ae = yes, do not scroll
  6311.     push    word ptr mar_top    ; save current scrolling margins
  6312.     mov    mar_top,dh        ; temp top margin is here
  6313.     call    atscru            ; scroll up
  6314.     pop    word ptr mar_top    ; restore scrolling margins
  6315.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6316.     jz    delli2            ; z = no
  6317.     jmp    dgsetcur        ; DG set cursor with protection
  6318. delli2:    jmp    atsetcur        ; restore cursor
  6319. delli3: ret
  6320. dellin    endp
  6321.  
  6322. ansich    proc    near            ; ANSI insert characters ESC [ Pn @
  6323.     mov    cx,param
  6324.     or    cx,cx            ; any arguments?
  6325.     jne    ansic1            ; ne = no, ignore
  6326.     inc    cx            ; use one
  6327. ansic1:    push    bx            ; use this as insert/delete flag
  6328.     mov    bh,1            ; do an insert operation
  6329. ansic2:    call    insdel            ; do common insert/delete code
  6330.     pop    bx
  6331.     ret
  6332. ansich    endp
  6333.  
  6334. inschr    proc    near            ; insert open (space) char at cursor
  6335.     push    bx            ; use this as insert/delete flag
  6336.     mov    bh,1            ; do an insert operation
  6337.     mov    cx,1            ; do one character
  6338.     call    insdel            ; do common insert/delete code
  6339.     pop    bx
  6340.     ret
  6341. inschr    endp
  6342.  
  6343. atdelc    proc    near
  6344.     mov    cx,param        ; Delete characters(s)
  6345.     or    cx,cx            ; zero becomes one operation
  6346.     jnz    atdelc1
  6347.     inc    cx            ; delete one char. Heath ESC N
  6348. atdelc1:push    bx            ; use this as insert/delete flag
  6349.     mov    bh,-1            ; do a delete operation
  6350. atdelc2:call    insdel            ; do common insert/delete code
  6351.     pop    bx
  6352.     ret
  6353. atdelc    endp
  6354.  
  6355.                     ; Common code for insert/delete char
  6356. insdel    proc    near            ; BH has insert/delete code
  6357.     mov    dx,cursor        ; logical cursor
  6358.     cmp    decrlm,0        ; host writing direction active?
  6359.     je    insdel11        ; e = no
  6360.     call    hldirection
  6361. insdel11:
  6362.     push    bx
  6363.     mov    bl,dh            ; row
  6364.     xor    bh,bh
  6365.     mov    bl,linetype[bx]
  6366.     mov    thisline,bl
  6367.     or    bl,bl            ; single width line?
  6368.     pop    bx
  6369.     jz    insdel1            ; z = yes
  6370.     add    dl,dl            ; double the cursor column
  6371.     add    cx,cx            ; double repeat count
  6372.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6373.     jz    insdel1            ; z = no
  6374.     shl    mar_right,1        ; this one doubles the margins
  6375. insdel1:mov    bl,mar_right
  6376.     inc    bl            ; number of screen columns
  6377.     sub    bl,dl            ; width - cursor
  6378.     cmp    cl,bl            ; skipping more than screen width?
  6379.     jbe    insdel2            ; be = no
  6380.     mov    cl,bl            ; limit to screen width please
  6381. insdel2:
  6382. ; dh=logical cursor row, dl= logical cursor column, cx has repeat count
  6383. ; bl = logical screen width - 1, bh = +1 for insert, -1 for delete chars.
  6384.     mov    bl,cl            ; offset
  6385.     xor    ch,ch
  6386.     or    bh,bh            ; ins or del?
  6387.     jl    insdel5            ; l = delete
  6388.                     ; Insert processor
  6389.     mov    cl,mar_right        ; right margin
  6390.     sub    cl,dl            ; minus cursor location
  6391.     mov    dl,mar_right        ; start at right margin
  6392.     jcxz    insdel7            ; z = nothing to do
  6393. insdel4:push    cx
  6394.     push    dx
  6395.     sub    dl,bl            ; back up by offset
  6396.     call    hldirection
  6397.     call    getatch            ; read char from vscreen
  6398.     pop    dx
  6399.     push    dx
  6400.     call    hldirection
  6401.     call    qsetatch        ; write it farther to the right
  6402.     pop    dx
  6403.     pop    cx
  6404.     dec    dl            ; backup one column
  6405.     loop    insdel4
  6406.     jmp    short insdel7
  6407.                       ; Delete processor
  6408. insdel5:mov    cl,mar_right        ; right margin
  6409.     sub    cl,dl            ; minus starting position
  6410.     sub    cl,bl            ; minus displacement (num deletes)
  6411.     inc    cl            ; count column 0
  6412. insdel6:push    cx
  6413.     push    dx
  6414.     add    dl,bl            ; look to right
  6415.     call    hldirection
  6416.     call    getatch            ; read char from vscreen
  6417.     pop    dx
  6418.     push    dx
  6419.     call    hldirection
  6420.     call    qsetatch        ; write it farther to the left
  6421.     pop    dx
  6422.     pop    cx
  6423.     inc    dl            ; next column
  6424.     loop    insdel6
  6425.  
  6426. insdel7:mov    cl,bl            ; fill count
  6427.     xor    ch,ch
  6428.     jcxz    insdel9            ; z = empty
  6429.     mov    ah,scbattr        ; get fill
  6430.     mov    al,' '
  6431. insdel8:push    cx
  6432.     xor    cl,cl            ; extended attributes
  6433.     push    dx
  6434.     call    hldirection
  6435.     call    qsetatch        ; write new char
  6436.     pop    dx
  6437.     inc    dl            ; next column
  6438.     pop    cx
  6439.     loop    insdel8
  6440.  
  6441. insdel9:mov    dx,cursor        ; logical cursor again
  6442.     push    cursor
  6443.     cmp    thisline,0        ; is line already single width?
  6444.     je    insde10            ; e = yes
  6445.     add    dl,dl            ; move to double char cell
  6446.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6447.     jz    insde10            ; z = no
  6448.     shr    mar_right,1        ; this one doubles the margins
  6449. insde10:call    atsetcur        ; set it to current char
  6450.     mov    dl,dh            ; rows to update
  6451.     call    touchup
  6452.     pop    cursor
  6453.     mov    dx,cursor        ; in case we are called indirectly
  6454.     ret
  6455. insdel    endp
  6456.  
  6457. noins:    mov    insmod,0        ; turn off insert mode
  6458.     ret
  6459.  
  6460. entins:    mov    insmod,0ffh        ; enter insert mode
  6461.     ret
  6462.  
  6463. ; Line type to/from single or double
  6464. linesgl    proc    near            ; convert line to single width char
  6465.     push    ax
  6466.     push    bx
  6467.     push    cx
  6468.     push    dx
  6469.     mov    bx,dx            ; cursor
  6470.     mov    bl,bh
  6471.     xor    bh,bh            ; bx now holds row
  6472.     cmp    linetype [bx],0        ; is line already single width?
  6473.     je    linsglx            ; e = yes
  6474.     mov    linetype [bx],0        ; say will be single now
  6475.     mov    dh,byte ptr cursor+1    ; row
  6476.     xor    dl,dl            ; start in column 0
  6477.     mov    cl,mar_right        ; number of columns on screen - 1
  6478.     inc    cl
  6479.     shr    cl,1            ; number of columns to do
  6480.     xor    ch,ch
  6481.     push    cx            ; save around loop below
  6482. linsgl1:push    cx            ; save loop counter
  6483.     push    dx
  6484.     shl    dl,1            ; double column number
  6485.     call    direction        ; set dx to desired position
  6486.     call    getatch            ; read char (al) and attribute (ah)
  6487.     pop    dx            ; logical attribute to cl
  6488.     push    dx
  6489.     call    direction        ; set dx to desired position
  6490.     call    qsetatch        ; write char (al) and attribute (ah)
  6491.     pop    dx            ; and logical attribute is in cl
  6492.     inc    dl            ; next column
  6493.     pop    cx
  6494.     loop    linsgl1
  6495.     pop    cx            ; recover column counter
  6496.     mov    dl,cl
  6497. linsgl2:push    cx            ; save counter
  6498.     push    dx
  6499.     call    direction        ; set dx to desired position
  6500.     mov    ah,scbattr        ; screen background
  6501.     xor    cl,cl            ; extended attribute
  6502.     mov    al,' '
  6503.     call    qsetatch        ; write char
  6504.     pop    dx
  6505.     pop    cx
  6506.     inc    dl            ; next column
  6507.     loop    linsgl2            ; repeat for all characters
  6508.     mov    dl,dh            ; rows to touchup
  6509.     call    touchup
  6510. linsglx:pop    dx
  6511.     pop    cx
  6512.     pop    bx
  6513.     pop    ax
  6514.     push    cursor
  6515.     call    atsetcur        ; set visible cursor
  6516.     pop    cursor
  6517.     ret
  6518. linesgl    endp
  6519.  
  6520. linedbl    proc    near            ; convert line to double width char
  6521.     push    ax            ; must reset physical cursor
  6522.     push    bx            ; to same char as before expansion
  6523.     push    cx            ; but does not modify variable cursor
  6524.     push    dx
  6525.     mov    bx,dx            ; cursor
  6526.     mov    bl,bh
  6527.     xor    bh,bh            ; bx now holds row
  6528.     cmp    linetype [bx],0        ; is line single width?
  6529.     jne    lindblx            ; ne = no. nothing to do
  6530.     mov    linetype [bx],1        ; say will be double width now
  6531.     mov    cl,mar_right        ; number of columns on the screen - 1
  6532.     inc    cl
  6533.     xor    ch,ch
  6534.     shr    cl,1            ; number of items to do
  6535.     mov    dl,cl
  6536.     dec    dl
  6537. lindbl1:push    cx            ; save loop counter
  6538.     push    dx
  6539.     call    direction        ; set dx to desired position
  6540.     call    getatch            ; read char (al) and attribute (ah)
  6541.     pop    dx            ; extended attribute is in cl
  6542.     shl    dl,1            ; double the column number
  6543.     push    dx
  6544.     call    direction        ; set dx to desired position
  6545.     call    qsetatch        ; write char and attribute
  6546.     pop    dx
  6547.     inc    dl            ; move to second column of double
  6548.     push    dx
  6549.     call    direction        ; set dx to desired position
  6550.     mov    al,' '            ; space as filler
  6551.     call    qsetatch        ; write that char
  6552.     pop    dx
  6553.     dec    dl
  6554.     shr    dl,1
  6555.     dec    dl
  6556.     pop    cx
  6557.     loop    lindbl1
  6558.     mov    dl,dh            ; rows to touchup
  6559.     call    touchup
  6560. lindblx:pop    dx
  6561.     pop    cx
  6562.     pop    bx
  6563.     pop    ax
  6564.     push    cursor
  6565.     call    atsetcur        ; set visible cursor
  6566.     pop    cursor
  6567.     ret
  6568. linedbl    endp
  6569.  
  6570. ; Printer support routines
  6571. ansprt    proc near
  6572.     mov    di,offset ansprt0    ; routine to process arguments
  6573.     call    atreps            ; repeat for all parms
  6574.     ret
  6575.  
  6576. ansprt0:mov    ax,param[si]        ; pick up the argument
  6577.     or    ax,ax            ; 0 (print all/part of screen)?
  6578.     jnz    ansprt1            ; nz = no
  6579.     cmp    ninter,0        ; unwanted intermediates?
  6580.     jne    anspr4a            ; ne = got one, illegal here
  6581.     call    fpntchk            ; check printer
  6582.     call    pntext            ; do whole screen or scrolling extent
  6583.     jmp    atsetcur        ; reposition cursor and return
  6584.  
  6585. ansprt1:cmp    ax,1            ; 1 (print current line)?
  6586.     jne    ansprt4            ; ne = no
  6587.     call    fpntchk            ; check for printer ready
  6588.     call    pntlin            ; print current line
  6589.     mov    al,LF
  6590.     call    fpntchr
  6591.     call    fpntflsh        ; flush printer buffer
  6592.     jmp    atsetcur        ; reposition cursor and return
  6593.  
  6594. ansprt4:cmp    ax,4            ; 4 (auto print disable)?
  6595.     jne    ansprt5            ; ne = no
  6596.     cmp    lparam,'?'        ; was it ESC [ ? 4 i
  6597.     jne    anspr4a            ; ne = no, so it was ESC [ 4 i
  6598.     test    anspflg,vtautop        ; check state of print flag
  6599.     jz    anspr4a            ; z = off already
  6600.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  6601.     call    ftrnprs            ; toggle mode line PRN indicator
  6602. anspr4a:ret
  6603.  
  6604. ansprt5:cmp    ax,5            ; 5 (auto print enable)?
  6605.     jne    ansprtx            ; ne = no
  6606.     call    fpntchk            ; check printer, ignore carry ret
  6607.     cmp    lparam,'?'        ; was it ESC [ ? 5 i
  6608.     jne    anspr5a            ; ne = no
  6609.     test    anspflg,vtautop        ; is print already enabled?
  6610.     jnz    ansprtx            ; nz = yes, leave trnprs intact
  6611.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  6612.     call    ftrnprs            ; toggle on mode line PRN indicator
  6613.     ret
  6614. anspr5a:test    anspflg,vtcntp        ; controller print already enabled?
  6615.     jnz    ansprtx            ; nz = yes
  6616.     mov    emubufc,0        ; clear string buffer
  6617.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  6618.     call    ftrnprs            ; toggle on mode line PRN indicator
  6619.     jc    ansprtx            ; c = printer not ready failure
  6620.     or    anspflg,vtcntp        ; controller print enabled
  6621.     mov    ttstate,offset ansmc    ; do transparent print
  6622. ansprtx:ret
  6623. ansprt    endp
  6624.  
  6625. ; State machine active while Media Copy On (Print Controller ON). Copies all
  6626. ; chars to the printer until and excluding Media Copy Off (ESC [ 4 i) or a
  6627. ; repeated Media Copy On (ESC [ 5 i) has been received or the emulator reset.
  6628. ; New char is in al.
  6629. ansmc    proc    near
  6630.     mov    ttstate,offset ansmc    ; stay in this state
  6631.     cmp    al,ESCAPE        ; start a new sequence?
  6632.     je    ansmc1            ; e = yes
  6633.     cmp    al,CSI            ; start a new sequence?
  6634.     je    ansmc0a            ; e = yes
  6635.     mov    emubufc,0        ; say no matched chars
  6636.     call    fpntchr            ; print char in al, ignore errors
  6637.     ret
  6638.                     ; CSI seen
  6639. ansmc0a:call    ansmc5            ; playback previous matches
  6640.     call    atpclr            ; clear parser
  6641.     mov    pardone,offset ansmc4    ; where to go when done
  6642.     mov    parfail,offset ansmc5    ; where to go when fail, playback
  6643.     mov    ttstate,offset ansmc3    ; get numeric arg
  6644.     mov    emubuf,CSI        ; stuff CSI
  6645.     mov    emubufc,1
  6646.     ret
  6647.                     ; Escape seen
  6648. ansmc1:    call    ansmc5            ; playback previous matches
  6649.     mov    ttstate,offset ansmc2    ; get left square bracket
  6650.     mov    emubufc,1        ; one char matched
  6651.     mov    emubuf,al        ; store it
  6652.     ret
  6653.  
  6654. ansmc2:    cmp    al,'['            ; left square bracket?
  6655.     je    ansmc2a            ; e = yes
  6656.     cmp    al,ESCAPE        ; ESC?
  6657.     je    ansmc1            ; e = yes, start over
  6658.     cmp    al,CSI            ; CSI?
  6659.     je    ansmc0a            ; e = yes, start over
  6660.     call    ansmc5            ; playback previous matches
  6661.     call    fpntchr            ; print char in al, ignore errors
  6662.     ret
  6663.  
  6664. ansmc2a:inc    emubufc            ; say matched "ESC ["
  6665.     mov    emubuf+1,al        ; store left square brace
  6666.     call    atpclr            ; clear parser
  6667.     mov    pardone,offset ansmc4    ; where to go when done
  6668.     mov    parfail,offset ansmc4c    ; where to go when fail, playback
  6669.     mov    ttstate,offset ansmc3    ; get numeric arg
  6670.     ret
  6671.                     ; CSI or ESC [ seen
  6672. ansmc3:    cmp    al,ESCAPE        ; ESC?
  6673.     je    ansmc1            ; e = yes, start over
  6674.     cmp    al,CSI            ; CSI?
  6675.     je    ansmc0a            ; e = yes, start over
  6676.     inc    emubufc            ; another char
  6677.     mov    bx,emubufc        ; qty stored
  6678.     mov    emubuf[bx-1],al        ; store it
  6679.     mov    ah,al            ; check for C0 and C1 controls
  6680.     and    ah,not 80h
  6681.     cmp    ah,20h            ; control range?
  6682.     jb    ansmc5            ; b = yes, mismatch, playback
  6683.     jmp    atparse            ; parse control sequence
  6684.                     ; parse succeeded, al has Final char
  6685. ansmc4:    cmp    al,'i'            ; correct Final char?
  6686.     jne    ansmc5            ; ne = no, playback previous matches
  6687.     cmp    lparam,0        ; missing letter parameter?
  6688.     jne    ansmc5            ; ne = no, mismatch
  6689.     cmp    ninter,0        ; missing intermediates?
  6690.     jne    ansmc5            ; ne = no, mismatch
  6691.     mov    cx,nparam        ; number of parameters
  6692.     xor    bx,bx            ; subscript
  6693. ansmc4a:mov    ax,param[bx]
  6694.     add    bx,2            ; next param
  6695.     cmp    ax,4            ; CSI 4 i  MC OFF?
  6696.     je    ansmc4b            ; e = yes, stop printing
  6697.     loop    ansmc4a            ; keep trying all parameters
  6698.     jmp    short ansmc7        ; forget this one, start over
  6699.  
  6700.                     ; Media OFF found
  6701. ansmc4b:mov    ttstate,offset atnrm    ; return to normal state
  6702.     call    fpntflsh        ; flush printer buffer
  6703.     test    anspflg,vtcntp        ; was printing active?
  6704.     jz    ansmc7            ; z = no
  6705.     and    anspflg,not vtcntp    ; yes, disable print controller
  6706.     call    ftrnprs            ; toggle mode line PRN indicator
  6707.     ret
  6708.                     ; atparse exited failure, char in AL
  6709. ansmc4c:cmp    al,ESCAPE        ; ESC?
  6710.     je    ansmc1            ; e = yes, start over
  6711.     cmp    al,CSI            ; CSI?
  6712.     je    ansmc0a            ; e = yes, start over, else playback
  6713.  
  6714.                     ; playback emubufc matched chars
  6715. ansmc5:    mov    cx,emubufc        ; matched char count
  6716.     jcxz    ansmc7            ; z = none
  6717.     push    ax            ; save current char in al
  6718.     push    si
  6719.     mov    si,offset emubuf    ; matched sequence, cx chars worth
  6720.     cld
  6721. ansmc6:    lodsb                ; get a char
  6722.     call    fpntchr            ; print it, ignore errors
  6723.     loop    ansmc6            ; do all matched chars
  6724.     pop    si
  6725.     pop    ax
  6726.     mov    emubufc,cx        ; clear this counter
  6727. ansmc7:    mov    ttstate,offset ansmc    ; reset state to the beginning
  6728.     ret
  6729. ansmc    endp
  6730.  
  6731. dgprt    proc    near            ; RS F ? <char>     DG Print routines
  6732.     mov    ttstate,offset dgprt1    ; get the <char>
  6733.     ret
  6734. dgprt1:    mov    ttstate,offset atnrm    ; reset state
  6735.     and    al,0fh
  6736.     cmp    al,0            ; Simulprint off?
  6737.     jne    dgprt2            ; ne = no
  6738.     mov    al,7            ; reform to be VT autoprint off
  6739.  
  6740. dgprt2:    cmp    al,1            ; Simulprint on?
  6741.     jne    dgprt3            ; ne = no
  6742.     mov    al,8            ; reform to be VT autoprint on
  6743.  
  6744. dgprt3:    cmp    al,3            ; Print Pass Through on?
  6745.     jne    dgprt4            ; ne = no
  6746. dgprt3a:                ; RS F `   alternative to RS F ? 3
  6747.     test    anspflg,vtcntp        ; controller print already enabled?
  6748.     jnz    dgprt7            ; nz = yes
  6749.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  6750.     or    anspflg,vtcntp        ; controller print enabled
  6751.     mov    emubufc,0        ; clear string buffer
  6752.     mov    ttstate,offset dgmc    ; do transparent print
  6753.     call    ftrnprs            ; toggle on mode line PRN indicator
  6754.     ret
  6755.  
  6756. dgprt4:    cmp    al,8            ; VT-style autoprint on?
  6757.     jne    dgprt5            ; ne = no
  6758.     call    fpntchk            ; check printer, ignore carry ret
  6759.     test    anspflg,vtautop        ; is print already enabled?
  6760.     jnz    dgprt7            ; nz = yes, leave trnprs intact
  6761.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  6762.     call    ftrnprs            ; toggle on mode line PRN indicator
  6763.     ret
  6764.  
  6765. dgprt5:    cmp    al,7            ; VT-style autoprint off?
  6766.     jne    dgprt6            ; ne = no
  6767.     test    anspflg,vtautop        ; check state of print flag
  6768.     jz    dgprt7            ; z = off already
  6769.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  6770.     call    ftrnprs            ; toggle mode line PRN indicator
  6771.     ret
  6772.  
  6773. dgprt6:    cmp    al,':'            ; Print Screen?
  6774.     jne    dgprt7            ; ne = no
  6775.     mov    ah,mar_bot        ; save margins
  6776.     mov    al,mar_top
  6777.     push    ax
  6778.     mov    mar_top,0        ; set to full screen height
  6779.     mov    al,byte ptr low_rgt+1    ; bottom text row
  6780.     mov    mar_bot,al
  6781.     push    cursor
  6782.     xor    dx,dx            ; cursor to home
  6783.     call    dgprtwn            ; print this window
  6784.     pop    cursor
  6785.     pop    ax
  6786.     mov    mar_top,al        ; restore margins
  6787.     mov    mar_bot,ah
  6788. dgprt7:    ret
  6789. dgprt    endp
  6790.  
  6791. dgppb    proc    near            ; RS F x <n> Printer Pass back to host
  6792.     mov    bx,offset dgppb1    ; call back routine
  6793.     jmp    get1n            ; setup consume one <n>
  6794. dgppb1:    mov    al,dgescape        ; send RS R x 0  cannot set
  6795.     call    prtbout            ; out, no echo
  6796.     mov    al,'R'
  6797.     call    prtbout
  6798.     mov    al,'x'
  6799.     call    prtbout
  6800.     mov    al,'0'            ; say cannot set NRC printer mode
  6801.     call    prtbout
  6802.     ret
  6803. dgppb    endp
  6804.  
  6805. ; State machine active while DG Simulprint is  On. Copies all chars to the 
  6806. ; printer until and excluding Simulprint Off (RS F ? 0) has been received 
  6807. ; or the emulator reset.
  6808. ; New char is in al.
  6809. dgmc    proc    near
  6810.     mov    ttstate,offset dgmc    ; stay in this state
  6811.     cmp    al,dgescape        ; start a new sequence?
  6812.     je    dgmc1            ; e = yes
  6813.     mov    emubufc,0        ; say no matched chars
  6814.     call    fpntchr            ; print char in al, ignore errors
  6815.     ret
  6816.                     ; RS seen
  6817. dgmc1:    call    ansmc5            ; playback previous matches
  6818.     mov    ttstate,offset dgmc2    ; get next char
  6819.     mov    emubufc,1        ; one char matched
  6820.     mov    emubuf,al        ; store it
  6821.     ret
  6822.  
  6823. dgmc2:    cmp    al,'F'            ; 'F' part of RS F ? 2
  6824.     jne    dgmc7            ; ne = no
  6825.     inc    emubufc            ; say matched "RS F"
  6826.     mov    emubuf+1,al        ; store it
  6827.     mov    ttstate,offset dgmc3    ; get query char
  6828.     ret
  6829.                     ; RS F seen
  6830. dgmc3:    cmp    al,'?'            ; 'F' part of RS F ? 2
  6831.     jne    dgmc4            ; ne = no
  6832.     inc    emubufc            ; say matched "RS F ?"
  6833.     mov    emubuf+1,al        ; store it
  6834.     mov    ttstate,offset dgmc5    ; get final char
  6835.     ret
  6836.  
  6837. dgmc4:    cmp    al,'a'            ; RS F a  alternative?
  6838.     jne    dgmc7            ; ne = no
  6839.     jmp    short dgmc8        ; finish up
  6840.  
  6841. dgmc5:    and    al,0fh
  6842.     cmp    al,2            ; RS F ? seen, correct final char?
  6843.     je    dgmc8            ; e = yes
  6844.     
  6845. dgmc7:    call    ansmc5            ; playback previous matches
  6846.     call    fpntchr            ; print char in al, ignore errors
  6847.     mov    ttstate,offset dgmc    ; start over
  6848.     ret
  6849.  
  6850. dgmc8:    mov    ttstate,offset atnrm    ; return to normal state
  6851.     call    fpntflsh        ; flush printer buffer
  6852.     test    anspflg,vtcntp        ; was printing active?
  6853.     jz    dgmc9            ; z = no
  6854.     and    anspflg,not vtcntp    ; yes, disable print controller
  6855.     mov    al,6            ; send Control-F to host
  6856.     call    prtbout            ; output, no echo
  6857.     call    ftrnprs            ; toggle mode line PRN indicator
  6858. dgmc9:    ret
  6859. dgmc    endp
  6860.  
  6861. pntlin    proc    near            ; print whole line given by dx
  6862.     push    ax
  6863.     push    bx
  6864.     push    cx
  6865.     push    dx
  6866.     xor    ch,ch
  6867.     mov    cl,mar_right        ; number of columns - 1
  6868.     mov    dl,cl            ; Bios column counter, dh = row
  6869.     inc    cl            ; actual line length, count it down
  6870.     test    vtemu.vtflgop,vswdir    ; writing right to left?
  6871.     jnz    pntlin2            ; nz = yes, do not trim spaces
  6872.     cmp    decrlm,0        ; host writing direction active?
  6873.     jne    pntlin2            ; ne = yes
  6874. pntlin1:push    cx
  6875.     call    getatch            ; read char (al) and attribute (ah)
  6876.     pop    cx            ;  and extended bit pair to cl
  6877.     cmp    al,' '            ; is this a space?
  6878.     jne    pntlin2            ; no, we have the end of the line
  6879.     dec    dl            ; else move left one column
  6880.     loop    pntlin1            ; and keep looking for non-space
  6881.  
  6882. pntlin2:jcxz    pntlin4            ; z = empty line
  6883.     xor    dl,dl            ; start in column 0, do cl chars
  6884. pntlin3:push    cx
  6885.     call    getatch            ; read char (al) and attribute (ah)
  6886.     pop    cx
  6887.     inc    dl            ; inc to next column
  6888.     call    fpntchr            ; print the char (in al)
  6889.     jc    pntlin5            ; c = printer error
  6890.     loop    pntlin3            ; do cx columns
  6891. pntlin4:mov    al,cr            ; add trailing cr for printer
  6892.     call    fpntchr
  6893. pntlin5:pop    dx
  6894.     pop    cx
  6895.     pop    bx
  6896.     pop    ax
  6897.     ret                ; C bit controlled by pntchr
  6898. pntlin    endp
  6899.  
  6900. pntext    proc    near            ; print an extent of lines, depending
  6901.     push    ax            ; on flag bit vtextp
  6902.     push    bx
  6903.     push    dx
  6904.     xor    dx,dx            ; assume starting at top left
  6905.     mov    bx,low_rgt        ;  and extending to lower right
  6906.     test    anspflg,vtextp        ; full screen wanted?
  6907.     jnz    pntext1            ; nz = yes, else scrolling region
  6908.     mov    dh,mar_top        ; top of scrolling region
  6909.     mov    bh,mar_bot        ; bottom of scrolling region
  6910. pntext1:call    pntlin            ; print a line
  6911.     jc    pntext2            ; c = printer error
  6912.     mov    al,LF
  6913.     call    fpntchr
  6914.     jc    pntext2
  6915.     inc    dh
  6916.     cmp    dh,bh            ; done all requested lines?
  6917.     jbe    pntext1            ; be = not yet, do another
  6918.     test    anspflg,vtffp        ; form feed needed at end?
  6919.     jz    pntext2            ; z = no
  6920.     mov    al,ff
  6921.     call    fpntchr            ; print the form feed char
  6922. pntext2:pop    dx
  6923.     pop    bx
  6924.     pop    ax
  6925.     ret
  6926. pntext    endp
  6927.  
  6928. ; Set cursor coordinate DL (row) with consideration for writing direction.
  6929. ; Active only under local writing direction control
  6930. direction proc    near
  6931.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  6932.     jz    direct1            ; z = yes, no changes needed
  6933.     sub    dl,mar_right        ; right margin column number
  6934.     neg    dl            ; make a positive value again
  6935. direct1:ret
  6936. direction endp
  6937.  
  6938. ; Like direction, but functions if host writing direction decrlm is active
  6939. ; as well as local control
  6940. hldirection proc near
  6941.     cmp    decrlm,0        ; host mode inactive?
  6942.     jne    hldirect1        ; ne = no, obey
  6943.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  6944.     jz    hldirect2        ; z = yes, no changes needed
  6945. hldirect1:sub    dl,mar_right        ; right margin column number
  6946.     neg    dl            ; make a positive value again
  6947. hldirect2:ret
  6948. hldirection endp
  6949.  
  6950. ; Erase from cursor (DX, inclusive) to end of screen
  6951. ; sense double width/height
  6952. ereos    proc    near
  6953.     mov    ax,dx            ; erase from cursor to end of screen
  6954.     or    dx,dx            ; cursor at home position?
  6955.     jnz    ereos1            ; nz = no
  6956.                     ; e = yes, roll screen before clear
  6957.     push    word ptr mar_top
  6958.     mov    al,byte ptr low_rgt+1    ; bottom row number
  6959.     mov    mar_bot,al
  6960.     mov    mar_top,dh        ; row of cursor
  6961.     inc    al            ; number of lines to scroll
  6962.     mov    scroll,al
  6963.     call    atscru            ; scroll them up before erasure
  6964.     pop    word ptr mar_top
  6965.                     ; removes double w/h lines too
  6966.     xor    ax,ax            ; erase from here (home)
  6967.     mov    bx,low_rgt        ; bh = bottom row number
  6968.     mov    cl,scbattr
  6969.     mov    ch,curattr
  6970.     push    cx
  6971.     cmp     vtclrflg,0        ; use scbattr?
  6972.     je    ereos0a            ; e = yes
  6973.     mov    scbattr,ch        ; use curattr
  6974. ereos0a:call    vtsclr            ; clear screen
  6975.     pop    cx
  6976.     mov    scbattr,cl        ; restore scbattr
  6977.     ret
  6978. ereos1:    push    dx            ; save dx
  6979.     mov    bl,dh            ; get row number
  6980.     xor    bh,bh
  6981.     cmp    linetype [bx],0        ; single width line?
  6982.     je    ereos2            ; e = yes
  6983.     shl    dl,1            ; physical column is twice logical
  6984. ereos2:    or    dl,dl            ; starting at left margin?
  6985.     je    ereos3            ; e = yes, this goes to single width
  6986.     inc    bl            ; else start on next line
  6987. ereos3:    cmp    bl,byte ptr low_rgt+1    ; at the end of the screen?
  6988.     ja    ereos4            ; a = yes, stop singling-up
  6989.     mov    byte ptr linetype [bx],0 ; set to single width
  6990.     inc    bx
  6991.     jmp    short ereos3        ; loop, reset lines to end of screen
  6992. ereos4:    mov    ax,dx            ; cursor
  6993.     pop    dx
  6994.     mov    bx,low_rgt        ; erase from cursor to end of screen
  6995.     cmp    dh,bh            ; on status line?
  6996.     jbe    ereos5            ; be = no
  6997.     mov    bh,dh            ; use status line
  6998. ereos5:    mov    cl,scbattr
  6999.     mov    ch,curattr
  7000.     push    cx
  7001.     cmp     vtclrflg,0        ; use scbattr?
  7002.     je    ereos5a            ; e = yes
  7003.     mov    scbattr,ch        ; use curattr
  7004. ereos5a:call    vtsclr            ; clear it
  7005.     pop    cx
  7006.     mov    scbattr,cl        ; restore scbattr
  7007.     ret
  7008. ereos    endp
  7009.  
  7010. ; Erase from start of screen to cursor (inclusive), sense double width/height
  7011. ersos    proc    near
  7012.     xor    ax,ax            ; erase from start of screen
  7013.                     ;  to cursor, inclusive
  7014.     xor    bx,bx            ; start at top row (0)
  7015. ersos1:    cmp    bl,dh            ; check rows from the top down
  7016.     jae    ersos2            ; ae = at or below current line
  7017.     mov    byte ptr linetype [bx],0; set line to single width
  7018.     inc    bx            ; inc row
  7019.     jmp    short ersos1        ; look at next line
  7020. ersos2:    or    dl,dl            ; at left margin of current line?
  7021.     jne    ersos3            ; ne = no, leave line width intact
  7022.     mov    byte ptr linetype [bx],0 ; convert to single width    
  7023. ersos3:    mov    bl,dh            ; get row number
  7024.     xor    bh,bh
  7025.     cmp    linetype [bx],0        ; single width line?
  7026.     je    ersos4            ; e = yes
  7027.     shl    dl,1            ; physical column is twice logical
  7028. ersos4:    mov    bx,dx            ; cursor position to bx
  7029.     mov    cl,scbattr
  7030.     mov    ch,curattr
  7031.     push    cx
  7032.     cmp     vtclrflg,0        ; use scbattr?
  7033.     je    ersos5            ; e = yes
  7034.     mov    scbattr,ch        ; use curattr
  7035. ersos5:    call    vtsclr            ; clear it
  7036.     pop    cx
  7037.     mov    scbattr,cl        ; restore scbattr
  7038.     ret
  7039. ersos    endp
  7040.  
  7041. ; Erase in line, from column AL to column BL, in row DH
  7042. erinline proc    near
  7043.     mov    ah,dh            ; set row
  7044.     mov    bh,dh
  7045.     mov    cl,byte ptr low_rgt    ; screen width
  7046.     push    bx
  7047.     mov    bl,dh            ; get row
  7048.     xor    bh,bh
  7049.     cmp    linetype [bx],0        ; single width line?
  7050.     pop    bx            ; pop does not affect flags
  7051.     pushf                ; save a copy of the flags for al
  7052.     je    erinli1            ; e = yes
  7053.     shl    bl,1            ; physical column is twice logical
  7054.     jc    erinli2            ; c = overflow
  7055. erinli1:cmp    bl,cl            ; wider than the physical screen?
  7056.     jb    erinli3            ; b = no, not wider than screen
  7057. erinli2:mov    bl,cl            ; physical width
  7058. erinli3:popf                ; recover copy of flags
  7059.     je    erinli4            ; e = single width line
  7060.     shl    al,1
  7061.     jc    erinli5
  7062. erinli4:cmp    al,cl
  7063.     jb    erinli6
  7064. erinli5:mov    al,cl
  7065. erinli6:mov    cl,scbattr
  7066.     mov    ch,curattr
  7067.     push    cx
  7068.     cmp     vtclrflg,0        ; use scbattr?
  7069.     je    erinli7            ; e = yes
  7070.     mov    scbattr,ch        ; use curattr
  7071. erinli7:call    vtsclr            ; clear it
  7072.     pop    cx
  7073.     mov    scbattr,cl        ; restore scbattr
  7074.     ret
  7075. erinline endp
  7076.  
  7077. ; General erasure command which skips over protected chars.
  7078. ; Preset margins and cursor to obtain all three erasure kinds.
  7079. erprot    proc    near            ; erase cursor to end of region
  7080.     mov    cursor,dx        ; preserve cursor
  7081. erprot1:push    dx
  7082.     call    direction
  7083.     call    getatch            ; read a char, get attributes
  7084.     pop    dx
  7085.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7086.     jz    erprot6            ; z = no
  7087.     cmp    protectena,0        ; is protected mode enabled?
  7088.     je    erprot4            ; e = no, erase all
  7089. erprot6:test    cl,att_protect        ; protected?
  7090.     jnz    erprot2            ; nz = yes, retain it
  7091. erprot4:xor    cl,cl            ; clear extended attributes
  7092.     mov    ah,scbattr        ; background attributes
  7093.     cmp     vtclrflg,0        ; use scbattr?
  7094.     je    eprot5            ; e = yes
  7095.     mov    ah,curattr        ; use current colors
  7096. eprot5:    mov    al,' '
  7097.     push    dx
  7098.     call    direction
  7099.     call    qsetatch        ; quietly update char
  7100.     pop    dx
  7101. erprot2:inc    dl            ; next column
  7102.     cmp    dl,mar_right        ; did right margin?
  7103.     jbe    erprot1            ; be = no
  7104.     mov    dl,mar_left        ; rest to left margin
  7105.     inc    dh            ; next line down
  7106.     cmp    dh,mar_bot        ; did the last row?
  7107.     jbe    erprot1            ; be = no
  7108. erprot3:mov    dl,byte ptr cursor+1    ; starting line, dh is ending line
  7109.     mov    dh,mar_bot
  7110.     call    touchup            ; repaint part of screen
  7111.     mov    dx,cursor
  7112.     ret
  7113. erprot    endp
  7114.  
  7115. ; Clear screen from AX to BX, where AH = row, AL = column, ditto for BX.
  7116. ; This routine accomodates right to left writing. BX >= AX.
  7117. vtsclr    proc    near
  7118.     cmp    ax,bx            ; proper order?
  7119.     jbe    vtsclr7            ; be = yes
  7120.     xchg    ax,bx            ; reverse
  7121. vtsclr7:test    vtemu.vtflgop,vswdir    ; writing left to right?
  7122.     jz    vtsclr4            ; z = yes
  7123.     cmp    bh,ah            ; same row?
  7124.     je    vtsclr2            ; e = yes
  7125.     push    ax            ; multiple lines
  7126.     push    bx            ; save both coordinates
  7127.     mov    bl,mar_right
  7128.     mov    bh,ah            ; pick just top line
  7129.     call    vtsclr2            ; delete fraction of top line
  7130.     pop    bx            ; recover ending position
  7131.     push    bx
  7132.     inc    ah            ; omit top row, now done
  7133.     dec    bh            ; omit last line, could be fractional
  7134.     cmp    bh,ah            ; any whole lines remaining to delete?
  7135.     jb    vtsclr1            ; b = no, finish up
  7136.     mov    bl,mar_right        ; get right most physical column
  7137.     xor    al,al            ; to end of line (on left)
  7138.     call    atsclr            ; clear top line and whole remainders
  7139. vtsclr1:pop    bx            ; setup for last line to be cleared
  7140.     push    bx            ; get last row again
  7141.     xor    al,al            ; start at logical left margin
  7142.     jmp    short vtsclr3        ; ax and bx are already pushed
  7143.  
  7144. vtsclr2:push    ax            ; erase single line, whole or part
  7145.     push    bx
  7146. vtsclr3:mov    ah,mar_right        ; borrow reg ah (same as bh)
  7147.     sub    ah,bl            ; reflect right to left
  7148.     mov    bl,ah
  7149.     or    bl,bl            ; overflow?
  7150.     jns    vtsclr5            ; ns = no, is ok
  7151.     xor    bl,bl            ; limit to logical screen
  7152. vtsclr5:mov    ah,mar_right
  7153.     sub    ah,al
  7154.     mov    al,ah
  7155.     jns    vtsclr6
  7156.     mov    al,mar_right        ; limit to logical screen
  7157. vtsclr6:mov    ah,bh            ; restore ah
  7158.     xchg    al,bl            ; reverse to get physical ax < bx
  7159.     call    atsclr            ; erase part/all of single line
  7160.     pop    bx
  7161.     pop    ax
  7162.     ret
  7163.                     ; for writing left to right
  7164. vtsclr4:jmp    atsclr            ; do normal erasure and return
  7165. vtsclr    endp
  7166.  
  7167. ; routines supporting scrolling and double width/height chars
  7168. ; scroll has number of lines to scroll
  7169. atscru    proc    near            ; scroll screen up one line
  7170.     test    vtemu.vtflg,ttwyse    ; Wyse-50?
  7171.     jz    atscru9            ; z = no
  7172.     cmp    wyse_scroll,0        ; ok to scroll?
  7173.     je    atscru9            ; e = yes
  7174.     ret
  7175. atscru9:push    ax            ; assumes dx holds cursor position
  7176.     push    bx            ; returns with dx = old row, new col
  7177.     push    cx
  7178.     push    si
  7179.     xor    bh,bh
  7180.     mov    bl,mar_top        ; top line to move
  7181.     xor    ch,ch
  7182.     mov    cl,scroll        ; number of lines to move
  7183.     mov    al,mar_bot        ; bottom line to scroll
  7184.     sub    al,bl            ; number of lines minus 1
  7185.     inc    al            ; number of lines
  7186.     cmp    al,cl            ; scrolling region smaller than scroll?
  7187.     jge    atscru1            ; ge = no, is ok
  7188.     mov    scroll,al        ; limit to region
  7189.     cmp    al,1            ; at least one line to scroll?
  7190.     jge    atscru1            ; ge = yes
  7191.     mov    scroll,1        ; no, force one
  7192. atscru1:mov    al,scroll
  7193.     mov    ah,byte ptr low_rgt+1    ; last text line on screen
  7194.     inc    ah            ; number of screen lines
  7195.     cmp    al,ah            ; exceeds number of lines on screen?
  7196.     jbe    atscru8            ; be = scrolling not more than that
  7197.     mov    al,ah            ; limit to screen length
  7198.     mov    scroll,al
  7199. atscru8:xor    ah,ah
  7200.     mov    si,ax            ; scroll interval
  7201.     mov    bl,mar_top
  7202.     mov    cl,mar_bot
  7203.     sub    cl,bl
  7204.     inc    cl            ; number  of lines in region
  7205.     sub    cl,scroll        ; cx = those needing movement
  7206.     cmp    cl,0
  7207.     jle    atscru3
  7208. atscru2:mov    al,linetype[bx+si]    ; get old type
  7209.     mov    linetype[bx],al        ; copy to new higher position
  7210.     mov    al,linescroll[bx+si]    ; get horizontal scroll value
  7211.     mov    linescroll[bx],al    ; copy too
  7212.     inc    bx
  7213.     loop    atscru2
  7214. atscru3:mov    bl,mar_bot        ; set fresh lines to single attribute
  7215.     mov    cl,scroll        ; number of fresh lines (qty scrolled)
  7216.     xor    ch,ch
  7217. atscru4:mov    linetype[bx],0
  7218.     mov    linescroll[bx],0
  7219.     dec    bx
  7220.     loop    atscru4            ; clear old bottom lines
  7221.     mov    bl,dh            ; get row of cursor
  7222.     xor    bh,bh
  7223.     cmp    linetype[bx],0        ; single width?
  7224.     je    atscru5            ; e = yes
  7225.     shr    dl,1            ; reindex to single width columns
  7226. atscru5:pop    si
  7227.     pop    cx
  7228.     pop    bx
  7229.     pop    ax
  7230.     test    anspflg,vtcntp        ; controller print active?
  7231.     jz    atscru6            ; z = no, ok to change screen
  7232.     ret                ;  else keep screen intact
  7233. atscru6:jmp    vtscru            ; call & ret the msy scroll routine
  7234. atscru    endp
  7235.  
  7236. atscrd    proc    near            ; scroll screen down scroll lines
  7237.     test    vtemu.vtflg,ttwyse    ; Wyse-50?
  7238.     jz    atscrd7            ; z = no
  7239.     cmp    wyse_scroll,0        ; ok to scroll?
  7240.     je    atscrd7            ; e = yes
  7241.     ret
  7242. atscrd7:push    ax            ; assumes dx holds cursor position
  7243.     push    bx            ; returns with dx = old row, new col
  7244.     push    cx
  7245.     push    si
  7246.     xor    ch,ch
  7247.     mov    cl,scroll        ; number of lines to scroll
  7248.     xor    bh,bh
  7249.     mov    bl,mar_bot        ; bottom line to move
  7250.     mov    al,bl
  7251.     xor    ah,ah
  7252.     sub    al,mar_top        ; number of lines minus 1
  7253.     inc    al            ; number of lines
  7254.     cmp    al,cl            ; scrolling region smaller than scroll?
  7255.     jge    atscrd1            ; ge = no, is ok
  7256.     mov    scroll,al        ; limit to region
  7257.     cmp    al,1            ; at least one line to scroll?
  7258.     jge    atscrd1            ; ge = yes
  7259.     mov    scroll,1        ; no, force one
  7260. atscrd1:mov    al,scroll
  7261.     mov    si,ax            ; si = scroll
  7262.     mov    bl,dh            ; get row of cursor
  7263.     xor    bh,bh            ; make into an index
  7264.     sub    bl,scroll        ; si + this bx will be new bottom line
  7265.     mov    cl,bl
  7266.     sub    cl,mar_top
  7267.     inc    cl
  7268.     cmp    cl,0
  7269.     jle    atscrd3
  7270. atscrd2:mov    al,linetype[bx]        ; get old line's type
  7271.     mov    linetype[bx+si],al    ; copy to new lower position
  7272.     mov    al,linescroll[bx]    ; get per line horizontal scroll
  7273.     mov    linescroll[bx+si],al    ; copy too
  7274.     dec    bx
  7275.     loop    atscrd2
  7276. atscrd3:mov    bl,mar_top        ; start with this line
  7277.     xor    bh,bh
  7278.     mov    cl,scroll        ; number of lines scrolled
  7279.     xor    ch,ch
  7280. atscrd4:mov    linetype[bx],0        ; clear new top lines
  7281.     mov    linescroll[bx],0
  7282.     inc    bx
  7283.     loop    atscrd4
  7284.     mov    bl,dh            ; get row of cursor
  7285.     xor    bh,bh
  7286.     cmp    linetype[bx],0        ; single width?
  7287.     je    atscrd5            ; e = yes
  7288.     shr    dl,1            ; reindex to single width columns
  7289. atscrd5:pop    si
  7290.     pop    cx
  7291.     pop    bx
  7292.     pop    ax
  7293.     test    anspflg,vtcntp        ; controller print active?
  7294.     jz    atscrd6            ; z = no, ok to change screen
  7295.     ret                ;  else keep screen intact
  7296. atscrd6:jmp    vtscrd            ; call & ret the msy scroll routine
  7297. atscrd    endp
  7298.  
  7299. ; Returns carry set if column in DL is a tab stop, else carry clear.
  7300. ; Enter with column number in DL (starts at column 0, max of swidth-1)
  7301. ; and tabstop buffer offset in SI.
  7302. istabs    proc    near
  7303.     push    bx
  7304.     push    cx
  7305.     mov    cl,dl            ; column number (0 to swidth-1)
  7306.     and    cl,00000111b        ; keep bit in byte (0-7)
  7307.     inc    cl            ; map to 1-8
  7308.     mov    bl,dl            ; column
  7309.     shr    bl,1            ; bl / 8 to get byte
  7310.     shr    bl,1
  7311.     shr    bl,1
  7312.     xor    bh,bh            ; clear high byte
  7313.     mov    bl,[si+bx]        ; get a byte of tab bits
  7314.     ror    bl,cl            ; rotate to put tab-set bit into carry
  7315.     pop    cx
  7316.     pop    bx
  7317.     ret
  7318. istabs    endp
  7319.  
  7320. ; Modify (set/clear) a tabstop. Enter with DL holding column (0 to swidth-1)
  7321. ; Set a tabstop into buffer pointed at by SI.
  7322. tabset    proc    near
  7323.     mov    modeset,1        ; set a tabstop
  7324.     jmp    short modtabs
  7325. tabset    endp
  7326.  
  7327. ; Clear a tabstop
  7328. tabclr    proc    near
  7329.     mov    modeset,0        ; clear a tabstop
  7330.     jmp    short modtabs
  7331. tabclr    endp
  7332.  
  7333. ; Worker for set/clear tabstop, si has pointer to tabstops array
  7334. modtabs:push    bx
  7335.     push    cx
  7336.     mov    cl,dl            ; column number (0 to swidth-1)
  7337.     and    cl,00000111b        ; keep bit in byte (0-7)
  7338.     mov    ch,1            ; tab bit to change
  7339.     shl    ch,cl            ; shift to bit-in-byte position
  7340.     mov    bl,dl            ; column
  7341.     shr    bl,1            ; bl / 8 to get byte
  7342.     shr    bl,1
  7343.     shr    bl,1
  7344.     xor    bh,bh            ; clear high byte
  7345.     mov    cl,[si+bx]        ; get byte of tabs bits
  7346.     not    ch            ; invert bit marker to create hole
  7347.     and    cl,ch            ; clear the tab bit
  7348.     not    ch            ; recover setting pattern
  7349.     cmp    modeset,0        ; clear the tab bit?
  7350.     jz    modtab1            ; z = yes
  7351.     or    cl,ch            ; set the tab bit
  7352. modtab1:mov    [si+bx],cl        ; store tab byte
  7353.     pop    cx
  7354.     pop    bx
  7355.     ret
  7356.  
  7357. ; This routine initializes the VT  setups at startup. It is called from
  7358. ; procedure lclyini in module msyibm.
  7359. vsinit    proc    near
  7360.     mov    vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
  7361.     mov    vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
  7362.     mov    savflgs,vsdefaults
  7363.     mov    iniflgs,vsdefaults
  7364.     xor    al,al
  7365.     mov    insmod,al        ; turn off insert mode
  7366.     mov    atinvisible,al
  7367.     xor    dl,dl            ; Column 1 has no tab stop
  7368.     mov    si,vtemu.vttbs        ; from the cold-start buffer
  7369.     call    tabclr            ; clear that tabstop
  7370.     push    es
  7371.     push    ds
  7372.     pop    es
  7373.     cld
  7374.     mov    al,1            ; set tabs at columns 9, spaced by 8
  7375.     mov    cx,(swidth-1)/8        ; bytes to do, at 8 bits/byte
  7376.     mov    di,offset deftabs+1    ; starting byte for column 9 (1...)
  7377.     rep    stosb
  7378.     xor    al,al            ; get a zero
  7379.     mov    cx,slen            ; clear linetype array
  7380.     mov    di,offset linetype
  7381.     rep    stosb
  7382.     mov    cx,slen
  7383.     mov    di,offset linescroll    ; clear horiz scroll per line
  7384.     rep    stosb
  7385.     pop    es
  7386.     mov    vtemu.vttbst,offset tabs ; addrs of active tabs for STATUS
  7387.     mov    vtemu.vttbs,offset deftabs  ; addrs of tabs for setup (SET)
  7388.     call    cpytabs            ; copy default to active
  7389.     mov    vtemu.att_ptr,offset att_normal  ; ptr to video attributes
  7390.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  7391.     sub    ah,8            ; place marker 9 columns from margin
  7392.     mov    belcol,ah        ; store column number to ring bell
  7393.         cmp     isps55,0                ; [HF]940221 Japanese PS/55?
  7394.         je      vsinix                  ; [HF]940221 e=no
  7395.         mov     vtemu.vtchset,C_JISKANJI ; [HF]940221 def = JIS-Kanji
  7396. vsinix: ret
  7397. vsinit    endp
  7398.  
  7399. ; Initialization routine.
  7400. ; Enter with dl = index for baud rate table
  7401. ; dh = parity in bits 4-7, number of data bits in bits 0-3
  7402. ansini    proc    near
  7403.     mov    ax,vtemu.vtflgst    ; setup flags
  7404.     mov    vtemu.vtflgop,ax
  7405.     mov    iniflgs,ax
  7406.     mov    savflgs,ax
  7407.     mov    ax,flags.vtflg        ; get current terminal type
  7408.     cmp    ax,tttek        ; non-text?
  7409.     je    ansin3            ; e = yes
  7410.     mov    oldterm,ax        ; remember it here for soft restarts
  7411. ansin3:    mov    anspflg,0        ; clear printing flag
  7412.     mov    al,byte ptr low_rgt    ; right most column (counted from 0)
  7413.     sub    al,8            ; place marker 9 columns from margin
  7414.     mov    belcol,al        ; store column number to ring bell
  7415.     cmp    dl,lbaudtab        ; out of range index?
  7416.     jb    ansin1            ; b = no, store it
  7417.     mov    dl,lbaudtab-2        ; yes, make it the maximum (128)
  7418. ansin1: mov    baudidx,dl        ; save baud rate index
  7419.     mov    al,dh            ; get parity/number of databits
  7420.     and    al,0FH            ; isolate number of databits
  7421.     mov    datbits,al        ; save
  7422.     mov    cl,4
  7423.     shr    dh,cl            ; isolate parity code
  7424.     cmp    dh,lpartab        ; out of range code?
  7425.     jb    ansin2            ; b = no, store it
  7426.     mov    dh,lpartab-1        ; make it the maximum
  7427. ansin2: mov    parcode,dh        ; save
  7428.     mov    cx,low_rgt
  7429.     mov    oldscrn,cx        ; remember old screen dimensions
  7430.     jmp    atreset            ; reset everything
  7431. ansini    endp
  7432.  
  7433. atxreset proc    near            ; Reset via host command
  7434.     cmp    nparam,0        ; need no Parameters, no Intermediates
  7435.     jne    atxres1            ; ne = not a reset
  7436.     cmp    ninter,0        ; any intermediates?
  7437.     je    atreset            ; e = none, it is a reset
  7438. atxres1:ret                ; ignore command
  7439. atxreset endp
  7440.  
  7441. atreset    proc    near            ; Reset-everything routine
  7442.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7443.     jnz    atres9            ; nz = yes
  7444. ifndef    no_graphics
  7445.     test    tekflg,tek_sg         ; special graphics active?
  7446.     jz    atres9            ; z = no
  7447.     call    tekend            ; exit special graphics
  7448. endif    ; no_graphics
  7449. atres9:    mov    ax,apcstring        ; seg of apcmacro memory area
  7450.     or    ax,ax            ; empty?
  7451.     jz    atres10            ; z = yes
  7452.     mov    es,ax
  7453.     mov    ah,freemem
  7454.     int    dos            ; free that memory
  7455. atres10:xor    ax,ax            ; get a zero
  7456.     mov    apcstring,ax
  7457.     mov    bracecount,al        ; APC-macro worker variables
  7458.     mov    cursor,ax        ; cursor is at 0,0
  7459.     mov    h19cur,ax        ; Heath-19 saved cursor
  7460.     mov    wyse_scroll,al        ; Wyse-50, no-scroll mode to off
  7461.     mov    decrlm,al        ; host writing direction to left-right
  7462.     mov    havesaved,al        ; unmark saved cursor section
  7463.     mov    atinvisible,al        ; clear invisible attribute
  7464.     mov    dspstate,al        ; saved modeline state
  7465.     mov    al,1            ; assume underline cursor
  7466.     test    vtemu.vtflgst,vscursor    ; kind of cursor in setup
  7467.     jnz    atres0            ; nz = underline
  7468.     inc    al            ; else say block
  7469. atres0:    mov    atctype,al        ; VTxxx cursor type
  7470.     call    udkclear        ; clear User Definable Key contents
  7471.     push    vtemu.vtflgst        ; setup flags
  7472.     pop    vtemu.vtflgop        ; operational flags
  7473.     and    vtemu.vtflgop,not vscntl ; assume no 8-bit controls
  7474.     mov    ax,oldterm        ; get terminal at entry time
  7475.     or    ax,ax            ; inited yet? (initing Tek too)
  7476.     jnz    atres0a            ; nz = yes
  7477.     mov    ax,ttvt320        ; pretend initing VT320
  7478.     jmp    short atres0b
  7479. atres0a:mov    flags.vtflg,ax        ; use it again
  7480. atres0b:test    ax,ttvt102+ttvt100+tthoney+ttpt200+ttansi ; VT100 class?
  7481.     jnz    atres1            ; nz = yes, turn on ansi mode
  7482.     test    ax,ttvt320+ttvt220    ; VT320/VT220?
  7483.     jz    atres1a            ; z = no, no ansi, no 8-bit controls
  7484.     test    vtemu.vtflgst,vscntl    ; want 8-bit controls?
  7485.     jz    atres1            ; z = no
  7486.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  7487. atres1:    or    vtemu.vtflgop,decanm    ; turn on ANSI mode
  7488.     or    vtemu.vtflgst,decanm    ; and in permanent setup too
  7489.  
  7490. atres1a:mov    mar_top,0        ; reset scrolling region
  7491.     mov    ax,low_rgt        ; virtual screen lower right corner
  7492.     mov    mar_bot,ah        ; logical bottom of screen
  7493.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7494.     jz    atres1d            ; z = no
  7495. ifndef    no_graphics
  7496.     call    clearsoft        ; clear soft font storage, saves ax
  7497. endif    ; no_graphics
  7498.     mov    al,79            ; trim to 80 col screen
  7499. atres1d:mov    mar_right,al        ; logical right edge of screen
  7500.     mov    mar_left,0        ; DG left/right margins
  7501.     mov    old8bit,-1        ; flags.remflg d8bit status, clear
  7502.     xor    al,al            ; ax is top/bottom margin
  7503.     mov    dgwindow,ax        ; init to first window to full screen
  7504.     mov    dgwindcnt,1        ; DG window count, 1 = full screen
  7505.     mov    cx,slen
  7506.     xor    bx,bx
  7507. atres1i:mov    dgwindcomp[bx],al    ; set lines to uncompressed, no soft
  7508.     inc    bx
  7509.     loop    atres1i
  7510.     xor    ax,ax
  7511.     mov    savdgmar,ax        ; clear DG saved margins
  7512.     mov    protectena,al        ; disable protected fields
  7513.     mov    blinkdis,al        ; disable blink disable
  7514.     mov    dgroll,1        ; DG roll enabled
  7515.     mov    dgaltid,ax        ; DG alternate model id, clear it
  7516.     mov    dghscrdis,al        ; DG horz scroll disable is disabled
  7517.     mov    cx,16
  7518.     xor    bx,bx
  7519. atres1e:mov    dgcursave[bx],ax    ; clear DG cursor named save area
  7520.     add    bx,2
  7521.     loop    atres1e
  7522.     mov    cx,slen/2
  7523.     xor    bx,bx
  7524. atres1f:mov    word ptr linescroll[bx],ax ; clear DG per line horiz scroll
  7525.     add    bx,2
  7526.     loop    atres1f
  7527.     mov    dgnum,ax        ; DG worker word, to be safe
  7528. ifndef    no_graphics
  7529.     call    dgcrossoff        ; DG turn off crosshair
  7530. endif    ; no_graphics
  7531.     mov    dgcross,al        ; DG crosshair activity, off
  7532.     mov    dglinepat,0ffffh    ; DG line pattern, default all dots
  7533.     mov    dgcaller,offset atign    ; DG default callback, ignorance
  7534.     mov    numdigits,al        ; more DG stuff
  7535.     mov    param[0],ax        ; setup call to atleds
  7536.     mov    doublebyte,al        ; Japanese doublebyte state values
  7537.     mov    double2nd,al
  7538.     mov    param[0],ax        ; setup call to atleds
  7539.     xor    si,si
  7540.     call    atleds            ; clear the LED indicators
  7541.     call    cpytabs            ; initialize tab stops
  7542.  test flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttd463+ttd217+ttd470+ttansi
  7543.     jz    atres1c            ; z = no
  7544.     mov    al,vtemu.vtchset    ; setup char set
  7545.     cmp    al,1            ; in range for NRCs?
  7546.     jb    atres1c            ; b = no
  7547.     cmp    al,13            ; highest NRC ident?
  7548.     ja    atres1c            ; a = not NRC
  7549.     or    vtemu.vtflgop,vsnrcm    ; set NRC flag bit to activate NRCs
  7550. atres1c:mov    vtemu.vtchop,al        ; remember char set
  7551.     call    chrdef            ; set default character sets
  7552.     call    vtbell            ; ring bell like VT100
  7553.     cmp    flags.modflg,2        ; mode line owned by host?
  7554.     jne    atres1h            ; ne = no
  7555.     mov    flags.modflg,1        ; say now owned by us
  7556. atres1h:xor    ax,ax            ; not exiting connect mode, 80 col
  7557.     test    vtemu.vtflgst,deccol    ; need 132 columns?
  7558.     jz    atres1g            ; z = no, use 80 columns
  7559.     inc    al            ; say set 132 column mode
  7560. atres1g:call    chgdsp            ; call Change Display proc in msy
  7561.     and    vtemu.vtflgop,not deccol; assume mode is reset (80 cols)
  7562.     cmp    byte ptr low_rgt,79    ; is screen narrow now?
  7563.     jbe    atres2            ; be = yes
  7564.     or    vtemu.vtflgop,deccol    ; set the status bit
  7565.  
  7566.                     ; ATRES2 used in 80/132 col resetting
  7567. ATRES2:    mov    cx,slen            ; typically 24 but do max lines
  7568.     xor    di,di
  7569.     xor    al,al
  7570. atres3:    mov    linetype[di],al        ; clear the linetype array to single
  7571.     mov    linescroll[di],al    ; horizontal scroll per line
  7572.     inc    di
  7573.     loop    atres3
  7574.            mov    ah,att_normal        ; get present normal coloring
  7575.     test    vtemu.vtflgop,vsscreen    ; want reverse video?
  7576.     jz    atres4            ; z = no
  7577.     call    revideo            ; reverse them
  7578. atres4:    mov    scbattr,ah        ; set background attributes
  7579.     mov    curattr,ah        ; and cursor attributes
  7580.     test    flags.vtflg,ttwyse    ; Wyse-50?
  7581.     jz    atres4a            ; z = no
  7582.     mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attributes
  7583.     mov    byte ptr wyse_protattr+1,att_protect
  7584. atres4a:
  7585.     mov    extattr,0        ; no reverse video, no underline etc
  7586.     mov    dx,cursor        ; get cursor
  7587.     call    atsetcur        ; set cursor
  7588.     call    atsctyp            ; set right cursor type
  7589.     xor    ax,ax            ; starting location
  7590.     mov    bx,low_rgt        ; ending location
  7591.     call    vtsclr            ; clear the whole screen
  7592.     cmp    flags.modflg,1        ; mode line on and owned by us?
  7593.     jne    atres5            ; ne = no, leave it alone
  7594.     test    yflags,modoff        ; mode line supposed to be off?
  7595.     jnz    atres5            ; nz = yes
  7596.     push    dx
  7597.     call    fmodlin            ; write normal mode line
  7598.     pop    dx
  7599. atres5:    test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7600.     jz    atres6            ; z = no
  7601.     or    vtemu.vtflgop,decawm    ; Autowrap active
  7602.     or    vtemu.vtflgst,decawm    ; Autowrap active
  7603. atres6:    call    atpclr            ; clear parser work area
  7604.     xor    ax,ax
  7605.     mov    parstate,ax        ; reset parser
  7606.     mov    emubufc,ax        ; clear work buffer
  7607.     mov    atwrap,al        ; clear wrap flag
  7608.     mov    SSptr,ax        ; clear single shift flag
  7609.     mov    insmod,al        ; reset insert mode
  7610.     mov    h19stat,al        ; clear heath extended status byte
  7611.     mov    h19ctyp,1        ; Heath-19 cursor to underline
  7612.     mov    anspflg,al        ; clear printer flag
  7613.     call    atsc            ; save cursor information
  7614.     jmp    atnorm            ; set normal state
  7615. atreset    endp
  7616.  
  7617. ; Re-initialization routine. Called when Term was called but screen was
  7618. ; restored from a previously saved screen, etc.
  7619. ansrei    proc    near
  7620.     mov    dx,cursor
  7621.     call    atsctyp            ; set cursor type [rbv]
  7622.     mov    ax,vtemu.vtflgst    ; setup
  7623.     or    ax,vtemu.vtflgop    ; operational
  7624.     test    ax,deccol        ; want 80 columns?
  7625.     jnz    ansre2            ; nz = no
  7626.     cmp    byte ptr low_rgt,79    ; want 80 cols. Is active screen wider?
  7627.     jbe    ansre2            ; be = no
  7628.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  7629.     and    vtemu.vtflgop,not deccol
  7630. ansre2:    jmp    stblmds            ; check settable modes, set flags
  7631. ansrei    endp
  7632.  
  7633. ; This routine checks to see whether any of the settable modes have changed
  7634. ; (things that can be changed in both SETUP and by host commands), and
  7635. ; changes those that need to be changed.  TMPFLAGS has the new VT100 setup
  7636. ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
  7637. ; Revised to allow MSY to reset scbattr when not in connect mode,
  7638. ; to do "soft reset" if terminal type has changed, and to do a screen clear
  7639. ; reset if the actual screen colors have changed.
  7640.  
  7641. stblmds proc    near
  7642.     mov    ax,flags.vtflg        ; get current terminal type
  7643.     cmp    ax,tttek        ; non-text?
  7644.     je    stblm10            ; e = yes
  7645.     cmp    ax,oldterm        ; same as before?
  7646.     je    stblm10            ; e = yes, skip over soft reset
  7647.     mov    oldterm,ax        ; remember current terminal type
  7648.     mov    insmod,0        ; reset insert mode flag
  7649.     and    iniflgs,not vsnrcm    ; turn off NRC bit from last time
  7650.     mov    mar_top,0        ; reset top scrolling margin
  7651.     mov    al,byte ptr low_rgt+1    ; and scrolling margin
  7652.     mov    mar_bot,al        ; to last normal line on screen
  7653.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  7654.     sub    ah,8            ; place marker 9 columns from margin
  7655.     mov    belcol,ah        ; store column number to ring bell
  7656.     push    es
  7657.     push    ds
  7658.     pop    es
  7659.     xor    al,al            ; get a zero
  7660.     mov    di,offset linetype    ; line type to single width chars
  7661.     mov    cx,slen            ; screen length
  7662.     cld
  7663.     rep    stosb            ; clear
  7664.     mov    di,offset linescroll    ; line horizontal scroll to none
  7665.     mov    cx,slen
  7666.     rep    stosb
  7667.     pop    es
  7668.     and    vtemu.vtflgop,not decanm
  7669.  test    flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttpt200+ttansi
  7670.     jz    stblm10            ; z = no, not ansi class
  7671.     or    vtemu.vtflgop,decanm    ; set ansi flag bit
  7672.     or    vtemu.vtflgst,decanm    ; and in permanent setup too
  7673.  
  7674. stblm10:test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7675.     jz    stblm10a        ; z = no
  7676.     mov    cx,slen-1        ; emulation screen lines
  7677.     xor    al,al
  7678.     xor    bx,bx
  7679. stblm10b:or    al,dgwindcomp[bx]    ; is any line compressed (!= 0)?
  7680.     inc    bx            ; if so remember as non-zero
  7681.     loop    stblm10b
  7682.     or    al,al            ; found any compressed/soft lines?
  7683.     jz    stblm10e        ; z = no
  7684.     test    al,2            ; any soft fonts in use?
  7685.     jnz    stblm10c        ; nz = yes, force graphics mode
  7686.     test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  7687.     jnz    stblm10d        ; nz = no, use 132 column text mode
  7688.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  7689.     jnz    stblm10e        ; nz = yes
  7690. stblm10c:
  7691. ifndef    no_graphics
  7692.     call    dgsettek        ; setup special graphics mode
  7693. endif    ; no_graphics
  7694.     jmp    short stblm10e
  7695. stblm10d:mov    al,3            ; prep call on atrsm6, 132/80 col
  7696.     mov    modeset,1        ; say want 132 columns
  7697.     call    atrsm6            ; common worker
  7698.     cmp    byte ptr low_rgt,79
  7699.     jbe    stblm10c        ; did not work, use graphics anyway
  7700. stblm10e:mov    al,flags.remflg        ; get 7/8 bit configuration
  7701.     and    al,d8bit        ; select the control bit
  7702.     cmp    old8bit,al        ; changed?
  7703.     je    stblm10a        ; e = no
  7704.     mov    old8bit,al        ; save new state
  7705.     mov    vtemu.vtchop,-1        ; force change below
  7706. stblm10a:mov    al,vtemu.vtchset    ; setup character set
  7707.     cmp    al,vtemu.vtchop        ; operational character set
  7708.     je    stblm3            ; e = same, no changes needed
  7709.     mov    vtemu.vtchop,al        ; remember this set
  7710.     and    vtemu.vtflgop,not vsnrcm ; clear NRC active bit
  7711.     and    vtemu.vtflgst,not vsnrcm
  7712.     cmp    al,1            ; in range for NRC?
  7713.     jb    stblm11            ; b = no
  7714.     cmp    al,13            ; above NRCs?
  7715.     ja    stblm11            ; a = yes
  7716.     or    vtemu.vtflgop,vsnrcm    ; set NRC active bit
  7717.     or    vtemu.vtflgst,vsnrcm
  7718.     and    vtemu.vtflgop,not vscntl ; no 8-bit controls
  7719. stblm11:call    chrdef            ; init char sets
  7720.  
  7721. stblm3:    test    vtemu.vtflgst,vswdir    ; writing direction set?
  7722.     jz    stblm3c            ; z = no
  7723.     mov    decrlm,0        ; yes, suppress host indicator
  7724. stblm3c:mov    ax,iniflgs        ; flags at last entry
  7725.     xor    ax,vtemu.vtflgst    ; find which setup ones have changed
  7726.     test    ax,deccol        ; screen width?
  7727.     jz    stblm3b            ; z = no, don't touch it
  7728.     mov    ax,vtemu.vtflgst    ; Setup bits
  7729.     and    ax,deccol        ; select screen width
  7730.     and    vtemu.vtflgop,not deccol ; clear operational flag bit
  7731.     or    vtemu.vtflgop,ax    ; set current width desired
  7732.     or    al,ah            ; collapse all bits
  7733.     mov    modeset,al        ; non-zero if 132 columns
  7734.     mov    al,3            ; setup call to atrsm6
  7735.     call    atrsm6            ; adjust display width
  7736.  
  7737. stblm3b:cmp    vtclear,1        ; screen need updating?
  7738.     mov    vtclear,0        ; preserves cpu status bits
  7739.     jb    stblm9            ; b = no
  7740.     ja    stblm3a            ; 2 or more means do a reset
  7741.     mov    ah,att_normal        ; 1, get new normal attributes setting
  7742.     mov    scbattr,ah        ; store new values
  7743.     test    flags.vtflg,ttwyse    ; Wyse-50?
  7744.     jz    stblm3d            ; z = no
  7745.     mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attributes
  7746.     mov    byte ptr wyse_protattr+1,att_protect
  7747. stblm3d:
  7748.     mov    curattr,ah
  7749.     jmp    short stblm9
  7750. stblm3a:mov    cursor,0        ; reset cursor position
  7751.     jmp    atres2            ; go to semi-reset
  7752.  
  7753.                     ; check on screen normal/reversed
  7754. stblm9:    mov    ax,iniflgs        ; flags at last entry
  7755.     xor    ax,vtemu.vtflgst    ; find which setup ones have changed
  7756.     test    ax,vsscreen        ; screen background?
  7757.     jz    stblm8            ; z = no, don't touch it
  7758.     test    vtemu.vtflgop,vsscreen    ; reverse video flag set?
  7759.     jnz    stblm5            ; nz = yes, do it
  7760.     and    vtemu.vtflgop,not vsscreen ; cleared (normal video)
  7761.     jmp    short stblm6        ; reverse everything
  7762. stblm5: or    vtemu.vtflgop,vsscreen    ; set (reverse video)
  7763. stblm6: call    atrss2            ; reverse screen and cursor attribute
  7764.     mov    ah,scbattr        ; reset saved attribute also
  7765.     mov    savecu+svattr_index,ah
  7766. stblm8:    cmp    flags.modflg,2        ; mode line enabled and owned by host?
  7767.     je    stblm9a            ; e = yes, leave it alone
  7768.     call    fclrmod            ; clear the mode line
  7769.     test    yflags,modoff        ; mode line supposed to be off?
  7770.     jnz    stblm9a            ; nz = yes
  7771.     call    fmodlin            ; write normal mode line
  7772.     and    yflags,not modoff    ; say modeline is not toggled off
  7773. stblm9a:mov    dx,cursor        ; logical cursor
  7774.     push    dx
  7775.     call    direction        ; set cursor for writing direction
  7776.     call    setpos            ; set the cursor physical position
  7777.     pop    dx
  7778.     push    vtemu.vtflgst
  7779.     pop    iniflgs            ; remember setup flags at this entry
  7780.     call    frepaint
  7781.     ret
  7782. stblmds endp
  7783.  
  7784. ; Routine called when something is typed on the keyboard
  7785.  
  7786. anskbi    proc    near
  7787.     mov    ttkbi,0FFH        ; just set a flag
  7788.     ret
  7789. anskbi    endp
  7790.  
  7791.  
  7792. ; This routine copies the new tab stops when they have changed.
  7793. ; Copies all 132 columns.
  7794. cpytabs proc    near
  7795.     mov    cx,(swidth+7)/8        ; number of bytes in screen width
  7796.     jcxz    cpytab1            ; z = none to do
  7797.     mov    si,offset deftabs    ; source is setup array
  7798.     mov    di,offset tabs        ; destination is active array
  7799.     push    es            ; save es
  7800.     push    ds
  7801.     pop    es            ; set es to data segment
  7802.     cld
  7803.     rep    movsb            ; do the copy
  7804.     pop    es            ; recover es
  7805. cpytab1:ret
  7806. cpytabs endp
  7807.  
  7808. ; Routine to toggle between text and Tek graphics modes. No arguments.
  7809. ; Text terminal type remembered in byte OLDTERM.
  7810. ans52t    proc    FAR
  7811.     mov    ax,flags.vtflg
  7812.     cmp    ax,tttek        ; in Tek mode now?
  7813.     je    ans52b            ; e = yes, exit Tek mode
  7814.     test    tekflg,tek_active    ; doing Tek sub mode?
  7815.     jnz    ans52b            ; nz = yes
  7816.     test    ax,ttd463+ttd470+ttd217    ; DG 463/D470/D217?
  7817.     jnz    ans52e            ; nz = yes, go into DG graphics mode
  7818.  
  7819. ifndef    no_graphics
  7820.     test    denyflg,tekxflg        ; is Tek mode disabled?
  7821.     jnz    ans52a            ; nz = yes, disabled
  7822.     mov    oldterm,ax        ; save text terminal type here
  7823.     call    atsc            ; save cursor and associated data
  7824.     mov    flags.vtflg,tttek    ; set Tek mode
  7825.     mov    tekflg,tek_tek        ; not a sub mode
  7826.     call    tekini            ; init Tek to switch screens
  7827. endif    ; no_graphics
  7828. ans52a:    call    atnorm
  7829.     ret
  7830.  
  7831. ans52b:
  7832. ifndef    no_graphics
  7833.     call    tekend            ; exit Tek graphics mode
  7834. endif    ; no_graphics
  7835.     mov    ax,oldterm
  7836.     or    ax,ax            ; inited yet?
  7837.     jnz    ans52c            ; nz = yes
  7838.     mov    ax,ttvt320        ; fall back for initing
  7839. ans52c:    mov    flags.vtflg,ax        ; say text terminal now
  7840.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  7841.     jnz    ans52f            ; nz = yes, cursor is ok already
  7842.     call    atrc            ; restore cursor etc
  7843.     call    atsc            ; save cursor etc
  7844. ans52f:    mov    tekflg,0        ; say not doing tek submode now
  7845.     mov    al,atctype
  7846.     call    atsctyp            ; set correct cursor type
  7847.     test    yflags,modoff        ; is mode line off?
  7848.     jnz    ans52d            ; nz = yes
  7849.     push    dx            ; save cursor position
  7850.     call    frepaint        ; restore text screen
  7851.     call    fmodlin            ; write mode line
  7852.     pop    dx
  7853. ans52d:    call    atnorm
  7854.     ret
  7855.                     ; DG D473 graphics mode entry
  7856. ans52e:    mov    oldterm,ax        ; save text terminal type here
  7857. ifndef    no_graphics
  7858.     call    dgsettek        ; switch to DG graphics
  7859. endif    ; no_graphics
  7860.     jmp    short ans52d
  7861. ans52t    endp
  7862.  
  7863. ;  Honeywell VIP 3.1 i.d. string [FD]
  7864. athoney proc    near
  7865.     cmp    flags.vtflg,tthoney    ; Honeywell mode?
  7866.     jne    athone3            ; ne = no, ignore
  7867.     mov    ttyact,0        ; group for networks
  7868.     mov    cx,VIPstrl        ; length of string
  7869.     mov    si,offset VIPstr    ; ptr to string
  7870.     cld
  7871. athone1:lodsb                ; get a byte
  7872.     push    cx            ; save regs
  7873.     push    si
  7874.     call    prtbout            ; print WITHOUT echo
  7875.     pop    si
  7876.     pop    cx
  7877.     cmp    cx,1            ; last char?
  7878.     ja    athone2            ; a = not yet
  7879.     mov    ttyact,1        ; end of network grouping
  7880. athone2:loop    athone1            ; loop for all characters
  7881. athone3:jmp    atnorm
  7882. athoney endp
  7883.  
  7884. athoncls proc    near            ; Honeywell ESC accent  screen clear
  7885.     cmp    nparam,0        ; absence of parameters?
  7886.     jne    athoncl1        ; ne = no, fail
  7887.     cmp    ninter,0        ; any intermediates?
  7888.     jne    athoncl2        ; ne = yes, not this item
  7889.     cmp    flags.vtflg,tthoney    ; doing Honeywell emulation?
  7890.     jne    athoncl1        ; ne = no
  7891.     xor    dx,dx            ; move cursor to Home position
  7892.     call    ereos            ; erase to end of screen
  7893.     xor    dx,dx
  7894.     jmp    atsetcur        ; set cursor and return
  7895. athoncl1:ret
  7896. athoncl2:jmp    atdgnrc            ; try Norwegian/Danish NRC designation
  7897. athoncls endp
  7898.  
  7899.     ; Data General D463/D470 support routines
  7900.  
  7901.                     ; Data General mode C0 control codes
  7902. dgctrl    proc    near
  7903.     test    anspflg,vtcntp        ; printing desired?
  7904.     jz    dgctrl1            ; z = no
  7905.     call    fpntchr            ; print char in al
  7906. dgctrl1:and    ax,001fh        ; clear for word use below
  7907.     mov    di,ax            ; use AL as a word index
  7908.     shl    di,1
  7909.     jmp    dgc0[di]        ; dispatch on DG C0 control codes
  7910. dgctrl    endp
  7911.  
  7912. ; Control-character dispatcher for DG ANSI mode
  7913. dgansctl proc    near
  7914.     cmp    al,escape        ; an escape sequence starting?
  7915.     jne    dgansctl1        ; ne = no
  7916.     jmp    atesc
  7917. dgansctl1:cmp    al,CSI            ; this kind of escape?
  7918.     jne    dgansctl2        ; ne = no
  7919.     jmp    atcsi0
  7920. dgansctl2:cmp    al,9ch            ; end of DCS?
  7921.     jne    dgansctl3        ; ne = no
  7922.     jmp    atgotst            ; terminate DCS
  7923. dgansctl3:cmp    ttstate,offset atdcsnul    ; consuming a DCS?
  7924.     jne    dgansctl4        ; ne = no
  7925.     ret                ; consume
  7926. dgansctl4:cmp    ttstate,offset atesc1    ; state is second char of ST?
  7927.     jne    dgansctl5        ; ne = no
  7928.     jmp    ttstate            ; go process second char
  7929. dgansctl5:test    anspflg,vtcntp        ; printing desired?
  7930.     jz    dgansctl6        ; z = no
  7931.     call    fpntchr            ; print char in al
  7932. dgansctl6:cmp    al,BELL
  7933.     jne    dgansctl7
  7934.     jmp    vtbell            ; beep
  7935. dgansctl7:cmp    al,BS
  7936.     jne    dgansctl8
  7937.     jmp    dgcub            ; do DG Backspace
  7938. dgansctl8:cmp    al,LF
  7939.     je    dgansctl9        ; e = yes
  7940.     cmp    al,FF
  7941.     jne    dgansctl10
  7942. dgansctl9:jmp    dglf            ; do DG Line Feed
  7943. dgansctl10:ret
  7944. dgansctl endp
  7945.  
  7946. dgesc    proc    near            ; Parse Data General RS commands
  7947.     mov    dgnum,0            ; clear numerical result
  7948.     mov    ttstate,offset dgesc1    ; set up to get next char
  7949.     ret
  7950. dgesc1:    mov    bx,offset dgesctab    ; dispatch table
  7951.     mov    ttstate,offset atnrm    ; reset state
  7952.     jmp    atdispat        ; dispatch on char in AL
  7953. dgesc    endp
  7954.  
  7955. ; Parse RS F/G <letter><DGnumber>(repeated)
  7956. ; F/G has been read, letter is next
  7957. dgFSERIES:mov    ttstate,offset Fdisp    ; dispatcher for incoming RS F
  7958.     ret
  7959. Fdisp:    mov    ttstate,offset atnrm    ; normal state
  7960.     mov    bx,offset fltable    ; table of letters
  7961.     jmp    atdispat        ; dispatch to action routine
  7962.  
  7963. dgGSERIES:mov    ttstate,offset Gdisp    ; dispatcher for incoming RS G
  7964.     ret
  7965. Gdisp:    mov    ttstate,offset atnrm    ; normal state
  7966.     mov    bx,offset gltable    ; table of letters
  7967.     jmp    atdispat        ; dispatch to action routine
  7968.  
  7969. dgRSERIES:test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  7970.     jz    dgnoR            ; z = no
  7971.     mov    ttstate,offset Rdisp    ; dispatcher for incoming RS R
  7972.     ret
  7973. dgnoR:    jmp    atnorm            ; no RS R series in D470
  7974.  
  7975. Rdisp:    mov    ttstate,offset atnrm    ; normal state
  7976.     mov    bx,offset rltable    ; table of letters
  7977.     jmp    atdispat        ; dispatch to action routine
  7978.  
  7979. ; DG <n>,<nn>,<nnn> processors. Enter with BX holding callback address.
  7980. ; Returns number in dgnum and resets state to atnrm.
  7981.                     ; get one DG numeric
  7982. get1n:    mov    ttstate,offset getnum    ; worker routine
  7983.     mov    dgnum,0            ; clear numerical result
  7984.     mov    numdigits,1        ; wanted qty of digits
  7985.     mov    dgcaller,bx        ; call back address
  7986.     ret
  7987.                     ; get two DG hex digits
  7988. get2n:    mov    ttstate,offset getnum    ; worker routine
  7989.     mov    dgnum,0            ; clear numerical result
  7990.     mov    numdigits,2        ; wanted qty of digits
  7991.     mov    dgcaller,bx        ; call back address
  7992.     ret
  7993.                     ; get three DG hex digits
  7994. get3n:    mov    ttstate,offset getnum    ; worker routine
  7995.     mov    dgnum,0            ; clear numerical result
  7996.     mov    numdigits,3        ; wanted qty of digits
  7997.     mov    dgcaller,bx        ; call back address
  7998.     ret
  7999.  
  8000. get3loc:mov    ttstate,offset getloc    ; get three DG Location digits
  8001.     mov    dgnum,0
  8002.     mov    numdigits,3
  8003.     mov    dgcaller,bx
  8004.     ret
  8005.  
  8006. ; get number from lower 5 bits of each byte
  8007. getdd:    mov    ttstate,offset get5num    ; worker routine
  8008.     mov    dgnum,0            ; clear numerical result
  8009.     mov    numdigits,2        ; wanted qty of digits
  8010.     mov    dgcaller,bx        ; call back address
  8011.     ret
  8012.  
  8013. getloc    proc    near
  8014.     or    al,al            ; is it truely null (RS L cmd stuff)?
  8015.     jz    getloc3            ; z = yes, exit now
  8016.     and    al,00011111b        ; keep only five lower bits
  8017.     mov    cl,5
  8018.     mov    bx,dgnum
  8019.     shl    bx,cl
  8020.     or    bl,al
  8021.     mov    dgnum,bx
  8022.     dec    numdigits        ; say one more digit done
  8023.     jz    getloc1            ; z = have done all
  8024.     ret                ; else stay in state getloc
  8025.  
  8026. getloc3:stc                ; set carry to say ended on NULL
  8027. getloc1:call    atnorm            ; set normal state
  8028.     mov    bx,dgcaller        ; get callback address
  8029.     mov    dgcaller,offset atign    ; reset default DG callback processor
  8030.     jmp    bx            ; go to callback address
  8031. getloc    endp
  8032.  
  8033. ; Return binary number in dgnum. When done it resets state to atnrm, 
  8034. ; clears callback address. Note that this proc accepts ALL bytes and uses
  8035. ; only the four lower bits, regardless of what the DG manuals suggest.
  8036. getnum    proc    near
  8037.     and    al,0fh            ; keep lower four bits
  8038.     mov    cl,4
  8039.     mov    bx,dgnum        ; get current value
  8040.     shl    bx,cl            ; times 16
  8041.     or    bl,al            ; add current digit
  8042.     mov    dgnum,bx        ; keep result
  8043.     dec    numdigits        ; say one more digit done
  8044.     jz    getnum2            ; z = have done all digits
  8045.     ret                ; else stay in this state
  8046. getnum2:call    atnorm            ; set normal state
  8047.     mov    bx,dgcaller        ; get callback address
  8048.     mov    dgcaller,offset atign    ; reset default DG callback processor
  8049.     jmp    bx            ; go to callback address
  8050. getnum    endp
  8051.  
  8052. ; Return binary number in dgnum. When done it resets state to atnrm, 
  8053. ; clears callback address. Note that this proc accepts ALL bytes and uses
  8054. ; only the five lower bits, regardless of what the DG manuals suggest.
  8055. get5num    proc    near
  8056.     and    al,1fh            ; keep lower five bits
  8057.     mov    cl,5
  8058.     mov    bx,dgnum        ; get current value
  8059.     shl    bx,cl            ; times 32
  8060.     add    bl,al            ; add current digit
  8061.     adc    bh,0
  8062.     mov    dgnum,bx        ; keep result
  8063.     dec    numdigits        ; say one more digit done
  8064.     cmp    numdigits,0        ; done all?
  8065.     jz    get5num2        ; z = yes
  8066.     ret                ; else stay in this state
  8067. get5num2:call    atnorm            ; set normal state
  8068.     mov    bx,dgcaller        ; get callback address
  8069.     mov    dgcaller,offset atign    ; reset default DG callback processor
  8070.     jmp    bx            ; go to callback address
  8071. get5num    endp
  8072.  
  8073. ; Provide binary number in dgnum from ANSI params, simulating get<kinds>
  8074. ; Enter with bx holding offset of main routine to call first.
  8075. ; Return carry set when no more parameters
  8076. dec2getn proc    near
  8077.     mov    dgparmread,0        ; parameter read
  8078.     call    bx            ; call main routine
  8079.  
  8080. dec2getn1:cmp    ttstate,offset atnrm    ; want to return to normal state?
  8081.     je    dec2getnx        ; e = yes
  8082.     mov    bx,dgparmread        ; number of parameters read
  8083.     cmp    bx,nparam        ; read all parameters?
  8084.     jae    dec2getnx        ; ae = yes
  8085.     shl    bx,1            ; convert to word index
  8086.     mov    bx,param[bx]        ; get parameter
  8087.     inc    dgparmread        ; say have read it
  8088.     mov    dgnum,bx        ; return value
  8089.     clc
  8090.     mov    bx,dgcaller
  8091.     call    bx
  8092.     jmp    short dec2getn1
  8093. dec2getnx:
  8094.     call    atnorm            ; reset state
  8095.     mov    dgnum,0
  8096.     stc                ; return carry set
  8097.     ret
  8098. dec2getn endp
  8099.  
  8100. out2n    proc    near            ; send <nn> report from value in AL
  8101.     push    cx
  8102.     mov    ch,al            ; preserve a copy
  8103.     mov    cl,4
  8104.     shr    al,cl            ; get high nibble
  8105.     and    al,0fh
  8106.     add    al,'0'            ; ascii bias
  8107.     call    prtbout
  8108.     mov    al,ch            ; recover copy
  8109.     and    al,0fh            ; get low nibble
  8110.     add    al,'0'
  8111.     call    prtbout
  8112.     pop    cx
  8113.     ret
  8114. out2n    endp
  8115.  
  8116. out2na    proc    near            ; send <nn> report from value in AL
  8117.     push    cx
  8118.     mov    ch,al            ; preserve a copy
  8119.     mov    cl,4
  8120.     shr    al,cl            ; get high nibble
  8121.     and    al,0fh
  8122.     add    al,'@'            ; ascii bias
  8123.     call    prtbout
  8124.     mov    al,ch            ; recover copy
  8125.     and    al,0fh            ; get low nibble
  8126.     add    al,'@'
  8127.     call    prtbout
  8128.     pop    cx
  8129.     ret
  8130. out2na    endp
  8131.  
  8132. dgign1n    proc    near            ; ignore a <n> command
  8133.     mov    bx,offset atnorm    ; ignore the <n>
  8134.     jmp    get1n
  8135. dgign1n    endp
  8136.  
  8137. dgign2n    proc    near            ; ignore a <nn> command
  8138.     mov    bx,offset atnorm    ; ignore the <nn>
  8139.     jmp    get2n
  8140. dgign2n    endp
  8141.  
  8142. dgprtfm    proc    near            ; Control-A  DG print form
  8143.     mov    cursor,dx        ; save cursor location
  8144. dgprtf1:mov    dl,mar_right        ; start at right margin
  8145.     mov    cl,dl
  8146.     sub    cl,mar_left        ; minus left
  8147.     inc    cl
  8148.     xor    ch,ch            ; number of columns to do
  8149. dgprtf3:push    cx
  8150.     call    dgprta            ; get char which would be printed
  8151.     pop    cx
  8152.     cmp    al,' '            ; space?
  8153.     jne    dgprtf4            ; ne = no, end scan here
  8154.     dec    dl            ; scan backward another column
  8155.     loop    dgprtf3
  8156. dgprtf4:jcxz    dgprtf6            ; z = empty line
  8157.     mov    dl,mar_left        ; start at left margin
  8158. dgprtf5:push    cx
  8159.     push    dx
  8160.     call    dgprta            ; get printable
  8161.     call    fpntchr            ; print char in al
  8162.     pop    dx
  8163.     pop    cx
  8164.     jc    dgprtf7            ; c = printer error
  8165.     inc    dl
  8166.     loop    dgprtf5            ; do count
  8167.  
  8168. dgprtf6:mov    al,CR            ; line terminator for printer
  8169.     push    dx
  8170.     call    fpntchr
  8171.     pop    dx
  8172.     jc    dgprtf7            ; c = printer error
  8173.     mov    al,LF
  8174.     push    dx
  8175.     call    fpntchr
  8176.     pop    dx
  8177.     jc    dgprtf7            ; c = printer error
  8178.     inc    dh            ; next row down
  8179.     cmp    dh,mar_bot        ; below window now?
  8180.     jbe    dgprtf1            ; be = no
  8181. dgprtf7:mov    al,6            ; Control-F to host when done
  8182.     call    prtbout            ; output, no echo
  8183.     mov    dx,cursor
  8184.     ret
  8185. dgprtfm    endp
  8186.  
  8187. dgprta    proc    near            ; worker, report printable char at dx
  8188.     call    getatch            ; read char (al) and attribute (ah)
  8189.     cmp    protectena,0        ; protected mode enabled?
  8190.     je    dgprta1            ; e = no
  8191.     test    cl,att_protect        ; protected mode?
  8192.     jnz    dgprta2            ; nz = yes, use a space
  8193.     ret                ; else use as-is
  8194. dgprta1:test    ah,att_bold        ; bold?
  8195.     jnz    dgprta3            ; nz = yes, use as-is
  8196. dgprta2:mov    al,' '            ; replace with space
  8197. dgprta3:ret
  8198. dgprta    endp
  8199.  
  8200. dgprtwn    proc    near            ; Control-Q  DG print window
  8201.     mov    cursor,dx        ; save cursor location
  8202. dgprtw1:mov    dl,mar_right        ; start at right margin
  8203.     mov    cl,dl
  8204.     sub    cl,mar_left
  8205.     inc    cl
  8206.     xor    ch,ch            ; number of columns to do
  8207. dgprtw3:push    cx
  8208.     call    dgprtb            ; get char which would be printed
  8209.     pop    cx
  8210.     cmp    al,' '            ; space?
  8211.     jne    dgprtw4            ; ne = no, end scan here
  8212.     dec    dl            ; scan backward another column
  8213.     loop    dgprtw3
  8214. dgprtw4:jcxz    dgprtw6            ; z = empty line
  8215.     mov    dl,mar_left        ; start at left margin
  8216. dgprtw5:push    cx
  8217.     push    dx
  8218.     call    dgprtb            ; get printable
  8219.     call    fpntchr            ; print char in al
  8220.     pop    dx
  8221.     pop    cx
  8222.     jc    dgprtw7            ; c = printer error
  8223.     inc    dl
  8224.     loop    dgprtw5            ; do count
  8225. dgprtw6:mov    al,CR            ; line terminator for printer
  8226.     push    dx
  8227.     call    fpntchr
  8228.     pop    dx
  8229.     jc    dgprtw7            ; c = printer error
  8230.     mov    al,LF
  8231.     push    dx
  8232.     call    fpntchr
  8233.     pop    dx
  8234.     jc    dgprtw7            ; c = printer error
  8235.     inc    dh            ; next row down
  8236.     cmp    dh,mar_bot        ; below window now?
  8237.     jbe    dgprtw1            ; be = no
  8238. dgprtw7:mov    al,6            ; Control-F to host when done
  8239.     call    prtbout            ; output, no echo
  8240.     mov    dx,cursor
  8241.     ret
  8242. dgprtwn    endp
  8243.  
  8244. dgprtb    proc    near            ; worker to yield printable char
  8245.     call    getatch            ; read char (al) and attribute (ah)
  8246.     test    al,80h            ; high bit set?
  8247.     jnz    dgprtb1            ; nz = yes, use a space
  8248.     cmp    al,20h            ; in printables?
  8249.     ja    dgprtb2            ; a = yes
  8250. dgprtb1:mov    al,' '            ; replace with space
  8251. dgprtb2:ret
  8252. dgprtb    endp
  8253.  
  8254. dgrevidon:mov    ah,curattr        ; RS D  Control-V  reverse video on
  8255.     call    setrev            ; reverse video on
  8256.     mov    curattr,ah        ; store new attribute byte
  8257.     ret
  8258.  
  8259. dgrevidoff:mov    ah,curattr        ; RS E  Control-B  reverse video off
  8260.     call    clrrev            ; 2, reverse video off
  8261.     mov    curattr,ah        ; store new attribute byte
  8262.     ret
  8263.  
  8264. dgblkena:mov    blinkdis,0        ; Control-C  DG blink enable
  8265.     ret
  8266. dgblkdis:mov    blinkdis,1        ; Control-D  DG blink disable
  8267.     ret
  8268.  
  8269. dgblkon    proc    near            ; Control-N  DG Blink on
  8270.     cmp    blinkdis,0        ; disabled?
  8271.     jne    dgblkon1        ; ne = blink is disabled
  8272.     mov    ah,curattr        ; get current cursor attribute
  8273.     call    setblink        ; blink enable
  8274.     mov    curattr,ah        ; store new attribute byte
  8275. dgblkon1:ret
  8276. dgblkon    endp
  8277.  
  8278. dgblkoff proc    near            ; Control-O  DG Blink off
  8279.     mov    ah,curattr        ; get current cursor attribute
  8280.     call    clrblink        ;  blink disable
  8281.     mov    curattr,ah        ; store new attribute byte
  8282.     ret
  8283. dgblkoff endp
  8284.  
  8285. dgwinhome proc near            ; Control-H  DG window home
  8286.     mov    dl,mar_left        ; want to skip protected chars too
  8287.     mov    dh,mar_top
  8288.     jmp    dgsetcur        ; do protected mode positioning
  8289. dgwinhome endp
  8290.  
  8291. dguson    proc    near            ; Control-T  DG underscoring on
  8292.     mov    ah,curattr        ; get current cursor attribute
  8293.     call    setunder
  8294.     mov    curattr,ah        ; store new attribute byte
  8295.     ret
  8296. dguson    endp
  8297.  
  8298. dgusoff    proc    near            ; Control-U  DG underscoring off
  8299.     mov    ah,curattr        ; get current cursor attribute
  8300.     call    clrunder
  8301.     mov    curattr,ah        ; store new attribute byte
  8302.     ret
  8303. dgusoff    endp
  8304.  
  8305. dgdimon    proc    near            ; Control-\  DG dim on
  8306.     mov    ah,curattr        ; get current cursor attribute
  8307.     call    clrbold
  8308.     mov    curattr,ah        ; store new attribute byte
  8309.     ret
  8310. dgdimon    endp
  8311.  
  8312. dgdimoff proc    near            ; Control-]  DG dim off
  8313.     mov    ah,curattr        ; get current cursor attribute
  8314.     call    setbold
  8315.     mov    curattr,ah        ; store new attribute byte
  8316.     ret
  8317. dgdimoff endp
  8318.  
  8319. dgsfc    proc    near            ; RS A <color>, set foreground color
  8320.     mov    ttstate,offset dgsfc1    ; state to get next char
  8321.     ret
  8322. dgsfc1:    mov    ttstate,offset atnrm    ; reset state
  8323.     test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  8324.     jz    dgsfc2            ; z = no, D470
  8325.     mov    ah,curattr        ; current coloring
  8326.     test    al,0fh            ; setting to background?
  8327.     jnz    dgsfc1a            ; nz = no
  8328.     mov    cl,4
  8329.     rol    ah,cl            ; get background coloring
  8330. dgsfc1a:and    ah,0fh            ; keep foreground
  8331.     mov    dg463fore,ah        ; polygon foreground coloring
  8332.     ret
  8333. dgsfc2:    cmp    al,100            ; select ACM mode?
  8334.     je    dgsfc5            ; ne = no
  8335. dgsfc3:    and    al,0fh            ; keep lower 4 bits
  8336.     jz    dgsfc4            ; z = black
  8337.     xor    al,8            ; invert DG intensity bit
  8338.     jnz    dgsfc4
  8339.     or    al,8            ; pick up dark grey as second except'n
  8340. dgsfc4:    mov    ah,curattr
  8341.     and    ah,not 0Fh        ; remove foreground
  8342.     or    ah,al            ; set new foreground
  8343.     mov    ah,scbattr
  8344.     and    ah,not 0Fh
  8345.     or    ah,al
  8346.     mov    curattr,ah        ; save it
  8347.     mov    scbattr,ah
  8348.     ret
  8349. dgsfc5:    mov    ah,att_normal        ; get normal background colors
  8350.     mov    scbattr,ah
  8351.     mov    curattr,ah        ; set current to them
  8352. dgsfcx:    ret
  8353. dgsfc    endp
  8354.  
  8355. dgsbc    proc    near            ; RS B <color>, set background color
  8356.     mov    ttstate,offset dgsbc1    ; state to get next char
  8357.     ret
  8358. dgsbc1:    mov    ttstate,offset atnrm    ; reset state
  8359.     test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  8360.     jnz    dgsbcx            ; nz = yes, ignore command
  8361.     cmp    al,100            ; select ACM mode?
  8362.     je    dgsbc2            ; e = yes
  8363.     and    al,0fh            ; mask out all but IBM PC background
  8364.     jz    dgsbc3            ; z = black
  8365.     and    al,7            ; remove IBM PC blinking bit
  8366.     mov    cl,4
  8367.     shl    al,cl            ; move bits to high nibble
  8368. dgsbc3:    mov    ah,curattr
  8369.     and    ah,0fh            ; remove background
  8370.     or    ah,al            ; set new background
  8371.     mov    curattr,ah        ; save it
  8372.     mov    ah,scbattr
  8373.     and    ah,0fh            ; remove background
  8374.     or    ah,al            ; set new background
  8375.     mov    scbattr,ah        ; save it
  8376.     ret
  8377. dgsbc2:    mov    ah,att_normal        ; get normal background colors
  8378.     mov    scbattr,ah        ; set current to them
  8379.     mov    curattr,ah        ; set current to them
  8380. dgsbcx:    ret
  8381. dgsbc    endp
  8382.  
  8383. dgeol    proc    near            ; Control-K DG erase cursor to eol
  8384.     mov    ax,dx            ; cursor position
  8385.     mov    bx,ax
  8386.     mov    bl,mar_right        ; end of line
  8387.     call    atsclr            ; erase from ax to bx
  8388.     ret
  8389. dgeol    endp
  8390.  
  8391. dgtoansi proc    near            ; RS F @  D470 mode to ANSI mode
  8392.     test    flags.vtflg,ttd470    ; D470?
  8393.     jz    dgtoansi1        ; z = no
  8394.     mov    dgd470mode,1        ; say doing ANSI mode
  8395. dgtoansi1:ret
  8396. dgtoansi endp
  8397.  
  8398. dgeeos    proc    near            ; RS F F  DG erase cursor to end/scrn
  8399.     jmp    erprot
  8400. dgeeos    endp
  8401.  
  8402. dgescn    proc    near            ; RS F E  DG erase from 0,0 to eos
  8403.     xor    dh,dh
  8404.     mov    dl,mar_left        ; left margin, top row
  8405.     call    dggetmar        ; get margins for this window
  8406.     call    atsetcur        ; set cursor
  8407.     mov    ah,curattr
  8408.     call    clrunder        ; clear underline attribute
  8409.     call    clrblink        ; clear blink
  8410.     call    setbold            ; aka clear dim
  8411.     call    clrrev            ; clear reverse video attribute
  8412.     mov    atinvisible,0        ; clear invisible attribute
  8413.     mov    curattr,ah        ; and cursor attributes
  8414.     mov    extattr,0        ; clear extended attributes
  8415.     xor    ax,ax            ; erase from 0,0
  8416.     mov    bh,byte ptr low_rgt+1    ; to end of screen
  8417.     mov    bl,vswidth-1
  8418.     call    atsclr            ; clear screen
  8419.     ret
  8420. dgescn    endp
  8421.  
  8422. dgewin    proc    near            ; Control-L  DG erase window
  8423.     call    dgusoff            ; underscore off        
  8424.     call    clrblink        ; clear blink
  8425.     call    clrrev            ; remove special video attributes
  8426.     mov    ah,mar_top        ; from top line of window
  8427.     mov    bh,mar_bot        ; to bottom line of window
  8428.     mov    al,mar_left        ; left margin
  8429.     mov    bl,mar_right        ; right margin
  8430.     cmp    savdgmar,0        ; saved permanent margin?
  8431.     je    dgewin1            ; e = no, mar_left/right are permanent
  8432.     mov    al,byte ptr savdgmar    ; use permanent l/r margins
  8433.     mov    bl,byte ptr savdgmar+1
  8434. dgewin1:call    atsclr            ; clear the area
  8435.     jmp    dgwinhome        ; do DG window home
  8436. dgewin    endp
  8437.  
  8438. dgsleft    proc    near            ; RS F C <nn>  DG Scroll Left
  8439.     mov    bx,offset dgslef1    ; get <nn>
  8440.     jmp    get2n
  8441. dgslef1:mov    ax,dgnum        ; qty columns to scroll
  8442.     jmp    dglrworker        ; do common worker
  8443. dgsleft    endp
  8444.  
  8445. dgsright proc    near            ; RS F D <nn>  DG Scroll Right
  8446.     mov    bx,offset dgsrig1    ; get <nn>
  8447.     jmp    get2n
  8448. dgsrig1:mov    ax,dgnum
  8449.     neg    ax            ; go right
  8450.     jmp    dglrworker        ; do common worker
  8451. dgsright endp
  8452.  
  8453. ; Worker to assist dgsleft/dgsright horizontal scroll. Enter with AX holding
  8454. ; the additional scroll value, negative for scrolling left. Updates array
  8455. ; linescroll.
  8456. dglrworker proc    near
  8457.     cmp    dghscrdis,0        ; horiz scrolling disabled?
  8458.     je    dglrwor1        ; e = no
  8459.     ret                ; else ignore request
  8460. dglrwor1:mov    bl,mar_top        ; do entire DG window
  8461.     xor    bh,bh
  8462.     mov    cl,mar_bot
  8463.     xor    ch,ch
  8464.     sub    cx,bx
  8465.     inc    cx            ; number of lines in the window
  8466.     cmp    cl,byte ptr low_rgt+1    ; includes whole screen?
  8467.     jbe    dglrwor2        ; be = no
  8468.     inc    cx            ; include status line
  8469.  
  8470. dglrwor2:push    cx
  8471.     mov    cl,linescroll[bx]    ; get horz scroll value
  8472.     xor    ch,ch
  8473.     add    cx,ax            ; accumulate scroll
  8474.     jge    dglrwor3        ; ge = non-negative
  8475.     xor    cx,cx            ; set to zero
  8476. dglrwor3:cmp    cx,127            ; max scroll
  8477.     jbe    dglrwor4        ; be = in limits
  8478.     mov    cl,127            ; set to max left
  8479. dglrwor4:cmp    linescroll[bx],cl    ; any change?
  8480.     je    dglrwor5        ; e = no
  8481.     mov    linescroll[bx],cl    ; set scroll
  8482.     push    dx
  8483.     mov    dl,bl
  8484.     mov    dh,bl            ; start/stop line numbers
  8485.     call    touchup            ; repaint just this line
  8486.     pop    dx
  8487. dglrwor5:inc    bx            ; next line
  8488.     pop    cx
  8489.     loop    dglrwor2
  8490.     ret
  8491. dglrworker endp
  8492.  
  8493. dginsl    proc    near            ; RS F H  DG Insert Line in window
  8494.     push    dx            ; save cursor
  8495.     mov    param,0            ; set up ANSI call
  8496.     call    inslin            ; do insert line, can scroll
  8497.     pop    dx            ; recover cursor
  8498.     jmp    atsetcur        ; reset cursor
  8499. dginsl    endp
  8500.  
  8501. dgdell    proc    near            ; RS F I  DG Delete Line in window
  8502.     mov    scroll,1        ; line count
  8503.     push    word ptr mar_top    ; save current scrolling margins
  8504.     mov    mar_top,dh        ; temp top margin is here
  8505.     call    atscru            ; scroll up
  8506.     pop    word ptr mar_top    ; restore scrolling margins
  8507.     ret
  8508. dgdell    endp
  8509.  
  8510. dgnarrow proc    near            ; RS F J  DG select normal spacing
  8511.     mov    cx,dgwindcnt        ; number of windows
  8512.     xor    bx,bx
  8513.     jcxz    dgnarr3            ; z = none
  8514.     inc    cx            ; let implied last window be seen
  8515. dgnarr1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  8516.     jbe    dgnarr3            ; be = cursor is in this window
  8517.     add    bx,2            ; skip two margin bytes
  8518.     loop    dgnarr1            ; next window
  8519. dgnarr2:ret
  8520.  
  8521. dgnarr3:mov    cx,dgwindow[bx]        ; get mar_top and mar_bot (ch)
  8522.     push    cx            ; save margins for touchup below
  8523.     mov    bl,cl            ; mar_top
  8524.     xor    bh,bh
  8525.     sub    ch,cl            ; mar_bot - mar_top = lines in win -1
  8526.     xchg    ch,cl
  8527.     xor    ch,ch
  8528.     inc    cx
  8529.     xor    ax,ax            ; zero and make ah a changed flag
  8530. dgnarr4:mov    al,dgwindcomp[bx]
  8531.     and    dgwindcomp[bx],not 1    ; set window to normal width
  8532.     and    al,1            ; select width, ignore font
  8533.     or    ah,al            ; remember if window line were wide
  8534.     inc    bx
  8535.     loop    dgnarr4            ; do all lines in the window
  8536.     mov    cl,byte ptr low_rgt+1    ; see if any screen lines are wide
  8537.     inc    cl            ; text lines
  8538.     xor    ch,ch
  8539.     xor    bx,bx
  8540.     xor    al,al
  8541. dgnarr5:test    dgwindcomp[bx],1    ; count wide lines
  8542.     jz    dgnarr6            ; z = narrow
  8543.     inc    al
  8544.     jmp    short dgnarr7        ; one wide line is enough to count
  8545. dgnarr6:inc    bx
  8546.     loop    dgnarr5
  8547.  
  8548. dgnarr7:pop    cx            ; margins
  8549.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8550.     jz    dgnarr8            ; z = no
  8551.     or    ah,ah            ; any line widths changed?
  8552.     jz    dgnarr7a        ; z = no
  8553.     push    dx
  8554.     mov    dx,cx            ; cx = saved margins 
  8555.     call    touchup            ; dl, dh are start stop rows
  8556.     pop    dx
  8557. dgnarr7a:ret
  8558. dgnarr8:or    al,al            ; count of wide lines
  8559.     jz    dgnarr9            ; z = all are narrow, go to 80 cols
  8560.     ret                ; leave screen as-is with wide line(s)
  8561. dgnarr9:mov    al,3            ; prep call on atrsm6, 132/80 col
  8562.     mov    modeset,0        ; say want 80 columns
  8563.     jmp    atrsm6            ; common worker
  8564. dgnarrow endp
  8565.  
  8566. dgwide    proc    near            ; RS F K  DG select compressed spacing
  8567.     mov    cx,dgwindcnt        ; number of windows
  8568.     xor    bx,bx
  8569.     jcxz    dgwide3            ; z = none, means one as whole screen
  8570.     inc    cx            ; let implied last window be seen
  8571. dgwide1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  8572.     jbe    dgwide3            ; be = cursor is in this window
  8573.     add    bx,2            ; skip two margin bytes
  8574.     loop    dgwide1            ; next window
  8575. dgwide2:ret
  8576.  
  8577. dgwide3:mov    cx,dgwindow[bx]        ; get mar_top and mar_bot (ch)
  8578.     push    cx            ; save them for touchup below
  8579.     mov    bl,cl            ; mar_top
  8580.     xor    bh,bh
  8581.     sub    ch,cl            ; mar_bot - mar_top = lines in win -1
  8582.     xchg    ch,cl
  8583.     xor    ch,ch
  8584.     inc    cx
  8585.     mov    ax,1            ; al is set, ah is changed flag
  8586. dgwide5:mov    al,dgwindcomp[bx]
  8587.     or    dgwindcomp[bx],1    ; set this line to wide width
  8588.     xor    al,1            ; pick out width bit change
  8589.     or    ah,al            ; accumulate changes
  8590.     inc    bx
  8591.     loop    dgwide5            ; do all lines in the window
  8592.     pop    cx            ; margins
  8593. ifndef    no_graphics
  8594.     test    ah,2            ; soft fonts involved?
  8595.     jnz    dgwide5a        ; nz = yes, force graphics mode
  8596.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8597.     jnz    dgwide7            ; nz = yes
  8598.     test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  8599.     jnz    dgwide8            ; nz = no, use 132 column text mode
  8600. dgwide5a:test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8601.     jnz    dgwide7            ; nz = yes
  8602. dgwide6:push    cx
  8603.     push    dx
  8604.     call    dgsettek        ; setup special graphics mode
  8605.     pop    dx
  8606.     pop    cx
  8607.     ret
  8608. dgwide7:or    ah,ah            ; any changes to width?
  8609.     jz    dgwide7a        ; z = no
  8610.     push    dx
  8611.     mov    dx,cx            ; saved margins
  8612.     call    touchup            ; dl, dh are start stop rows
  8613.     pop    dx
  8614. dgwide7a:ret
  8615. endif    ; no_graphics
  8616.  
  8617. dgwide8:mov    al,3            ; prep call on atrsm6, 132/80 col
  8618.     mov    modeset,1        ; say want 132 columns
  8619.     call    atrsm6            ; common worker
  8620. ifndef    no_graphics
  8621.     cmp    byte ptr low_rgt,79
  8622.     jbe    dgwide6            ; did not work, use graphics anyway
  8623. endif    ; no_graphics
  8624.     ret
  8625. dgwide    endp
  8626.  
  8627. ; Toggle Normal/Compressed modes from the keyboard.
  8628. dgnctoggle proc    far
  8629.     mov    dx,cursor        ; get cursor
  8630.     mov    bl,dh            ; get row
  8631.     xor    bh,bh
  8632.     test    dgwindcomp[bx],1    ; normal mode?
  8633.     jz    dgnctog4        ; z = yes, do compressed
  8634.     call    dgnarrow        ; do normal
  8635.     ret
  8636. dgnctog4:call    dgwide            ; do compressed
  8637.     ret
  8638. dgnctoggle endp
  8639.  
  8640. dginsc    proc    near            ; RS J  DG Insert char
  8641.     mov    dx,cursor
  8642.     cmp    protectena,0        ; protected mode enabled?
  8643.     jne    dginsc1            ; ne = yes, find new right margin
  8644.     jmp    inschr            ; do regular inschr
  8645. dginsc1:cmp    dl,mar_right        ; at right margin?
  8646.     jae    dginsc2            ; ae = yes
  8647.     call    dgcurpchk        ; check for protected char
  8648.     jc    dginsc2            ; c = protected
  8649.     inc    dl            ; next column right
  8650.     jmp    short dginsc1        ; continue scanning
  8651.  
  8652. dginsc2:mov    al,mar_right        ; save right margin
  8653.     push    ax
  8654.     dec    dl            ; do not include margin char
  8655.     mov    mar_right,dl
  8656.     mov    dx,cursor
  8657.     call    inschr            ; insert char
  8658.     pop    ax
  8659.     mov    mar_right,al
  8660.     ret
  8661. dginsc    endp
  8662.  
  8663. dgdelc    proc    near            ; RS K  DG Delete char
  8664.     mov    dx,cursor
  8665.     mov    param,0            ; set up ANSI call for one char
  8666.     cmp    protectena,0        ; protected mode enabled?
  8667.     jne    dgdelc1            ; ne = yes, find new right margin
  8668.     jmp    atdelc            ; do delete
  8669. dgdelc1:cmp    dl,mar_right        ; at right margin?
  8670.     jae    dgdelc2            ; ae = yes
  8671.     call    dgcurpchk        ; check for protected char
  8672.     jc    dgdelc2            ; c = protected
  8673.     inc    dl            ; next column right
  8674.     jmp    short dgdelc1        ; continue scanning
  8675.  
  8676. dgdelc2:mov    al,mar_right        ; save right margin
  8677.     push    ax
  8678.     dec    dl            ; do not include margin char
  8679.     mov    mar_right,dl
  8680.     mov    dx,cursor
  8681.     call    atdelc            ; do delete
  8682.     pop    ax
  8683.     mov    mar_right,al
  8684.     ret
  8685. dgdelc    endp
  8686.  
  8687. dgilbm    proc    near            ; RS F [ Insert line between margins
  8688.     mov    al,dghscrdis        ; save horz scrolling disable flag
  8689.     push    ax            ; save til the end
  8690.     mov    dghscrdis,1        ; disable horz scrolling for this cmd
  8691.     mov    cursor,dx        ; save this
  8692.     mov    dl,mar_left        ; start at the left side
  8693.     mov    dh,mar_bot        ; bottom of window
  8694.     or    dh,dh            ; row zero?
  8695.     jz    dgilbm2            ; z = yes, just clear the line
  8696.  
  8697. dgilbm1:dec    dh            ; up one row
  8698.     call    getatch            ; read a char
  8699.     inc    dh            ; go down a row
  8700.     call    qsetatch        ; write the char
  8701.     inc    dl            ; next column
  8702.     cmp    dl,mar_right        ; off end of row yet?
  8703.     jbe    dgilbm1            ; be = no
  8704.     or    dh,dh            ; finished top row?
  8705.     jz    dgilbm2            ; z = yes
  8706.     dec    dh            ; redo this one row up
  8707.     mov    dl,mar_left        ; reset to left window margin
  8708.     cmp    dh,byte ptr cursor+1    ; finished cursor row yet?
  8709.     jae    dgilbm1            ; ae = no
  8710. dgilbm2:mov    dx,cursor        ; clear line cursor was on
  8711.     mov    al,mar_left        ; from left margin
  8712.     mov    bl,mar_right        ; to right window margin
  8713.     call    erinline        ; clear the window line
  8714.     mov    dl,dh
  8715.     mov    dh,mar_bot        ; lines changed
  8716.     call    touchup            ; redisplay the new material
  8717.     mov    dx,cursor
  8718.     pop    ax            ; recover horz scroll disable flag
  8719.     mov    dghscrdis,al
  8720.     ret
  8721. dgilbm    endp
  8722.  
  8723. dgdlbm    proc    near            ; RS F \ Delete line between margins
  8724.     mov    al,dghscrdis        ; get horizontal scroll disable flag
  8725.     push    ax            ; save til the end
  8726.     mov    dghscrdis,1        ; disable horz scrolling for this cmd
  8727.     mov    cursor,dx        ; save cursor position
  8728.     mov    dl,mar_left        ; start at the left side
  8729. dgdlbm1:inc    dh            ; down one row
  8730.     call    getatch            ; read a char
  8731.     dec    dh            ; go up a row
  8732.     call    qsetatch        ; write the char
  8733.     inc    dl            ; next column
  8734.     cmp    dl,mar_right        ; off end of row yet?
  8735.     jbe    dgdlbm1            ; be = no
  8736.     inc    dh            ; redo this one row down
  8737.     mov    dl,mar_left        ; reset to left window margin
  8738.     cmp    dh,mar_bot        ; finished bottom row yet
  8739.     jbe    dgdlbm1            ; be = no
  8740.     mov    dh,mar_bot        ; clear last line in window
  8741.     mov    al,mar_left
  8742.     mov    bl,mar_right
  8743.     call    erinline        ; clear the window line
  8744.     pop    ax            ; recover horz scroll disable flag
  8745.     mov    dghscrdis,al
  8746.     mov    dx,cursor
  8747.     mov    dl,dh            ; region changed
  8748.     mov    dh,mar_bot
  8749.     call    touchup
  8750.     ret
  8751. dgdlbm    endp
  8752.  
  8753. dgscs    proc    near            ; RS F S <nn>  DG Select Char Set
  8754.     mov    bx,dgscs1        ; setup for <nn> value
  8755.     jmp    get2n
  8756. dgscs1:    mov    bx,dgnum        ; get DG char set idents
  8757.     cmp    bl,1fh            ; last hard char set
  8758.     jbe    dgscs2            ; be = in the hard sets
  8759.     cmp    bl,45h            ; end of soft sets
  8760.     jbe    dgscs1a            ; be = in range
  8761.     ret                ; else ignore command
  8762. dgscs1a:add    bl,100-20h+1        ; add local offset for chrsetup
  8763.     jmp    short dgscs4        ; prep for chrsetup
  8764.  
  8765. dgscs2:    or    bl,bl            ; use "keyboard language"?
  8766.     jnz    dgscs3            ; nz = no
  8767.     mov    bl,vtemu.vtchset    ; get setup char set
  8768.     cmp    bl,13            ; top of the NRCs
  8769.     jbe    short dgscs4        ;  as keyboard language
  8770.     xor    bx,bx            ; default to ASCII
  8771. dgscs3:    mov    bl,dgchtab[bx]        ; translate to Kermit idents
  8772. dgscs4:    cmp    GLptr,offset G0set    ; are we shifted out?
  8773.     jne    dgscs5            ; ne = yes, presume G1set
  8774.     mov    Gsetid,bl        ; new set ident for G0
  8775.     jmp    short dgscs6
  8776. dgscs5:    mov    Gsetid+1,bl        ; new set ident for G1
  8777. dgscs6:    mov    bx,offset Gsetid    ; pass list of sets to setup
  8778.     jmp    chrsetup        ; go make the new set
  8779. dgscs    endp
  8780.  
  8781. dgalign    proc    near            ; RS F > char DG fill screen with char
  8782.     mov    ttstate,offset dgalig1    ; get char
  8783.     ret
  8784. dgalig1:mov    ttstate,offset atnrm    ; reset state
  8785.     jmp    atalig1            ; do DEC alignment work, char in AL
  8786. dgalign    endp
  8787.  
  8788. dggrid    proc    near            ; RS F 9 char DG fill screen with grid
  8789.     mov    al,'#'            ; set grid char in standard place
  8790.     jmp    atalig1            ; do DEC alignment work, char in AL
  8791. dggrid    endp
  8792.  
  8793.     
  8794. dgrolldis:mov    dgroll,0        ; Control-S  DG roll disable
  8795.     ret
  8796.  
  8797. dgrollena:mov    dgroll,1        ; Control-R  DG roll enable
  8798.     ret
  8799.  
  8800. dghsena:mov    dghscrdis,0        ; RS F ^  DG horiz scroll enable
  8801.     mov    dx,cursor
  8802.     jmp    atsetcur        ; set cursor to cause screen update
  8803.  
  8804. dghsdis:mov    dghscrdis,1        ; RS F ]  DG horiz scroll disable
  8805.     ret
  8806.  
  8807. dgpton:    call    setprot            ; RS F L  DG Protect on
  8808.     ret
  8809.  
  8810. dgptoff:call    clrprot            ; RS F M  DG Protect off
  8811.     ret
  8812.  
  8813. protena:mov    protectena,1        ; RS F V  DG Protect enable
  8814.     ret                ; 
  8815.     
  8816. protdis:mov    protectena,0        ; RS F W  DG Protect disable
  8817.     ret                ; 
  8818.  
  8819. dg78bit    proc    near            ; RS F U <n>  DG Select 7/8 bit ops
  8820.     mov    bx,dg78bit1        ; get <n>
  8821.     jmp    get1n
  8822. dg78bit1:cmp    dgnum,1            ; 0 is 7 bit, 1 is 8 bit
  8823.     ja    dg78bit3        ; a = illegal value, ignore
  8824.     je    dg78bit2        ; e = 1
  8825.     and    flags.remflg,not d8bit    ; 7-bit, chop DG high bit
  8826.     ret
  8827. dg78bit2:or    flags.remflg,d8bit    ; 8-bit
  8828. dg78bit3:ret
  8829. dg78bit    endp
  8830.  
  8831. dgdhdw    proc    near            ; RS R E <n>  DG Double high/wide
  8832.     mov    bx,offset dgdhdw1
  8833.     jmp    get1n            ; set up for <n> arg
  8834. dgdhdw1:mov    ax,dgnum        ; get <nn> result
  8835.     or    ax,ax            ; 2 and above are double highs
  8836.     jz    dgdhdw2
  8837.     mov    al,2            ; map double highs to 2
  8838.     jmp    linedbl            ; make line double width
  8839. dgdhdw2:jmp    linesgl            ; make single width
  8840. dgdhdw    endp
  8841.  
  8842. dgs25l    proc                ; RS F z <n>  DG go to/set status line
  8843.     mov    bx,offset dgs25l1    ; prep for <n> mode value
  8844.     jmp    get1n
  8845. dgs25l1:mov    ax,dgnum        ; get mode
  8846.     or    ax,ax            ; 0, 25th line is status?
  8847.     jnz    dgs25l2            ; nz = no
  8848.     mov    dspstate,0        ; no longer on mode line
  8849.     mov    param,1            ; turn on regular mode line
  8850.     call    atssdt1            ; do main worker
  8851.     ret
  8852.  
  8853. dgs25l2:cmp    al,3            ; blank the line?
  8854.     jne    dgs25l3            ; ne = no
  8855.     jmp    atssdt1            ; do main worker
  8856.     cmp    al,2            ; use as ordinary text?
  8857.     jne    dgs25l3            ; ne = no
  8858.     ret                ; ignore this request
  8859. dgs25l3:cmp    al,1            ; get msg for line?
  8860.     je    dgs25l4            ; e = yes
  8861.     ret
  8862. dgs25l4:mov    bx,offset dgs25l5    ; prep for <nn> text
  8863.     jmp    get2n
  8864. dgs25l5:mov    dspcmain,dx        ; save cursor in special area
  8865.     mov    dspstate,dsptype    ; say on status line
  8866.     mov    al,mar_left
  8867.     mov    ah,mar_right
  8868.     mov    dspmsave,ax        ; save margins
  8869.     mov    mar_left,0        ; set left to screen left
  8870.     call    fclrmod            ; clear the line
  8871.     and    yflags,not modoff    ; say modeline is not toggled off
  8872.     mov    flags.modflg,2        ; say mode line is owned by host
  8873.     mov    dh,byte ptr low_rgt+1    ; bottom text line
  8874.     inc    dh            ; status line
  8875.     xor    dl,dl            ; absolute left margin
  8876.     call    atsetcur        ; set cursor
  8877.     cmp    dgnum,0            ; number of chars of text
  8878.     je    dgs25l7            ; e = none
  8879.     mov    ttstate,offset dgs25l6    ; come here for text
  8880.     ret
  8881. dgs25l6:call    atnrm            ; write the character
  8882.     dec    dgnum            ; one less to do
  8883.     cmp    dgnum,0            ; done?
  8884.     jle    dgs25l7            ; le = yes
  8885.     ret                ; stay on status line
  8886. dgs25l7:mov    ttstate,offset atnrm    ; reset state
  8887.     mov    dx,dspcmain        ; restore cursor
  8888.     mov    ax,dspmsave        ; saved margins
  8889.     mov    mar_left,al
  8890.     mov    mar_right,ah
  8891.     mov    dspstate,0        ; no longer on mode line
  8892.     jmp    atsetcur        ; set cursor
  8893. dgs25l    endp
  8894.  
  8895. dgnscur    proc    near            ; RS F } <n> <n> DG cursor named save
  8896.     mov    bx,offset dgnscu1    ; get <n> memory cell (name, 0..15)
  8897.     jmp    get1n
  8898. dgnscu1:mov    ax,dgnum        ; get cell number
  8899.     mov    word ptr emubuf,ax    ; save here
  8900.     mov    bx,offset dgnscu2    ; get <n> save (0) / restore (1)
  8901.     jmp    get1n
  8902. dgnscu2:mov    bx,word ptr emubuf    ; get named subscript
  8903.     mov    ax,dgnum        ; get op code
  8904.     cmp    ax,1            ; save?
  8905.     jb    dgnscu3            ; b = save
  8906.     ja    dgnscu4            ; a = illegal, ignore
  8907.     mov    al,dgctypesave[bx]    ; get cursor size/type
  8908.     mov    atctype,al        ; active type
  8909.     call    csrtype            ; set it
  8910.     mov    dx,dgcursave[bx]    ; restore cursor position from storage
  8911.     jmp    dgsetcur        ; set the cursor DG style
  8912. dgnscu3:mov    dgcursave[bx],dx    ; save cursor
  8913.     mov    al,atctype        ; get cursor type
  8914.     mov    dgctypesave[bx],al    ; save
  8915. dgnscu4:ret
  8916. dgnscur    endp
  8917.  
  8918. dgsps    proc    near                 ; DG dual emulation set split screen
  8919.     mov    ttstate,offset dgsps1    ; RS R A 0 <nn><n> or RS R A 1 <nn>
  8920.     ret
  8921. dgsps1:    mov    bx,offset atnrm        ; setup to ignore command
  8922.     cmp    al,1            ; 0 or 1 expected
  8923.     ja    dgsps3            ; a = illegal, ignore
  8924.     je    dgsps2            ; e = case 1 <nn>
  8925.     jmp    get3n            ; case 0 <nn><n> as <nnn>
  8926. dgsps2:    jmp    get2n
  8927. dgsps3:    ret
  8928. dgsps    endp
  8929.  
  8930. dgdchs    proc    near            ; RS F q <nn><nn> Dealloc Char Sets
  8931.     mov    bx,offset dgdchs1    ; ignore for now
  8932.     jmp    get2n
  8933. dgdchs1:mov    bx,offset atnrm
  8934.     jmp    get2n
  8935. dgdchs    endp
  8936.  
  8937. dgdefch    proc    near            ; RS F R <char> 10/12<nn>'s Def Char
  8938.     mov    ttstate,offset dgdefc1    ; get char
  8939.     ret
  8940. dgdefc1:mov    emubufc,0        ; set counter
  8941.     mov    emubuf,al        ; char to be defined
  8942.     mov    cl,14            ; video cell bytes per char (8x14)
  8943.     mul    cl            ; ax = bytes to start of char
  8944.     mov    word ptr emubuf+1,ax    ; save string distance
  8945.     mov    ax,10            ; assume D470
  8946.     cmp    flags.vtflg,ttd470    ; D470?
  8947.     je    dgdefc1a        ; e = yes, uses 10 byte pairs
  8948.     mov    ax,12            ; D463 uses 12 byte pairs
  8949. dgdefc1a:mov    word ptr emubuf+3,ax    ; save string length
  8950.     jmp    dgdefc3            ; setup to get data
  8951.  
  8952. dgdefc2:mov    ax,word ptr emubuf+1    ; get char being defined
  8953.     add    ax,emubufc        ; plus byte into string
  8954.     inc    emubufc            ; count a <nn> pair
  8955. ifndef    no_graphics
  8956.     mov    bx,softptr        ; seg of soft font
  8957. else
  8958.     xor    bx,bx
  8959. endif    ; no_graphics
  8960.     or    bx,bx            ; segment of soft font, defined?
  8961.     jz    dgdefc3            ; z = no, do not store
  8962.     push    es
  8963.     mov    es,bx
  8964.     mov    bx,ax            ; offset to byte
  8965.     mov    ax,dgnum        ; get value
  8966.     cmp    emubuf+3,10        ; for D470 (8 bits wide)?
  8967.     je    dgdefc2a        ; e = yes
  8968.     shr    ax,1            ; D463, 10 bits, chop right most too
  8969. dgdefc2a:mov    es:[bx],al        ; store byte
  8970.     pop    es
  8971.  
  8972. dgdefc3:mov    ax,word ptr emubuf+3    ; wanted string count
  8973.     cmp    emubufc,ax        ; done all?
  8974.     jae    dgdefc6            ; ae = yes
  8975.     mov    bx,offset dgdefc2    ; get char byte pairs
  8976.     cmp    flags.vtflg,ttd470    ; D470?
  8977.     je    dgdefc5            ; e = yes, use get2nn
  8978.     jmp    getdd            ; for D463, 5 bit values
  8979. dgdefc5:jmp    get2n            ; for D470, 4 bit values
  8980.  
  8981. dgdefc6:
  8982. ifndef    no_graphics
  8983.     mov    bx,softptr        ; segment of soft font, defined?
  8984.     or    bx,bx
  8985.     jz    dgdefc7            ; z = no, do not store
  8986. ;JMP DGDEFC7
  8987.     push    es            ; repeat last row of dots
  8988.     push    di
  8989.     mov    es,bx
  8990.     mov    di,word ptr emubuf+1    ; start plus char offset
  8991.     mov    cx,emubufc        ; get current count
  8992.     add    di,cx            ; point to last stored char+1
  8993.     sub    cx,14-1            ; 14-1 dots high (omit last line)
  8994.     neg    cx            ; positive number
  8995.     mov    al,es:[di-1]        ; last stored char
  8996.     cmp    al,es:[di-2]        ; same as previous (line drawing)?
  8997.     jne    dgdefc6a        ; ne = no, do not extend cell
  8998.     cld
  8999.     rep    stosb
  9000. dgdefc6a:pop    di
  9001.     pop    es
  9002. endif    ; no_graphics
  9003. dgdefc7:mov    emubufc,0        ; clear counter
  9004.     jmp    atnorm            ; reset state
  9005. dgdefch    endp
  9006.  
  9007. dgrchr    proc    near            ; RS F d  DG Read Chars Remaining
  9008.     mov    al,dgescape        ; response string
  9009.     call    prtbout
  9010.     mov    al,'o'
  9011.     call    prtbout
  9012.     mov    al,'9'
  9013.     call    prtbout
  9014.     mov    al,'0'            ; high part of 10 bit count
  9015. ;graphics
  9016. mov al,'_'
  9017.     call    prtbout
  9018.     mov    al,'0'            ; low part of 10 bit count
  9019. ;graphics
  9020. mov al,'_'
  9021.     call    prtbout
  9022.     ret
  9023. dgrchr    endp
  9024.  
  9025. dgresch    proc    near            ; RS F e <n><n>  DG Reserve Character
  9026.     mov    bx,offset atnorm    ; discard
  9027.     jmp    get2n
  9028. dgresch    endp
  9029.  
  9030. dgskl    proc    near            ; RS F f <n>  DG Set Kbd Language
  9031.     mov    bx,offset dgskl1
  9032.     jmp    get1n            ; get parameter
  9033. dgskl1:    mov    ax,dgnum        ; 0=setup, 1=DG Int, 2=Latin1
  9034.     cmp    ax,2            ; in range?
  9035.     ja    dgskl4            ; a = no
  9036.     cmp    ax,1            ; DG International?
  9037.     je    dgskl2            ; e = yes
  9038.     ja    dgskl3            ; a = no, Latin1
  9039.     mov    al,vtemu.vtchset    ; get setup char set
  9040.     mov    dgkbl,al        ; store keyboard language ident
  9041.     ret
  9042. dgskl2:    mov    dgkbl,20        ; DG International
  9043.     ret
  9044. dgskl3:    mov    dgkbl,16        ; Latin1
  9045. dgskl4:    ret
  9046. dgskl    endp
  9047.  
  9048. dgsdo    proc    near            ; RS R B <n><n><n> Set Device Options
  9049.     mov    bx,offset dgsdo1    ; get first <n>
  9050.     jmp    get1n
  9051. dgsdo1:    mov    bx,offset atnrm        ; get second and third <n>'s
  9052.     jmp    get2n            ; discard all
  9053. dgsdo    endp
  9054.  
  9055. dgsfield:mov    bx,offset dgsfie1    ; RS F C <ss><rr>  Field attributes
  9056.     jmp    get2n            ; get first <nn>
  9057. dgsfie1:mov    bx,offset atnrm        ; discard proc
  9058.     jmp    get2n            ; get second <nn>
  9059.  
  9060. dgspage:mov    bx,offset dgspag1    ; RS F D <ss><rr>  Page attributes
  9061.     jmp    get2n            ; get first <nn>
  9062. dgspag1:mov    bx,offset atnrm        ; discard proc
  9063.     jmp    get2n            ; get second <nn>
  9064.  
  9065. dgsetw    proc    near            ; RS F B <nn><n>.. Set windows
  9066.     mov    dgwindcnt,0        ; count of windows entries
  9067.     mov    emubuf+4,0        ; normal(0)/compressed (!0) flag
  9068. dgsetw1:mov    bx,offset dgsetw2    ; next processor
  9069.     jmp    get2n            ; get a <nn> window length
  9070. dgsetw2:mov    ax,dgnum
  9071.     mov    word ptr emubuf,ax    ; save around get1n work
  9072.     mov    bx,offset dgsetw2a    ; get <n> 0/1, compressed mode
  9073.     jmp    get1n
  9074. dgsetw2a:mov    ax,dgnum
  9075.     mov    emubuf+4,al        ; save copy for just this window
  9076.     mov    ax,word ptr emubuf    ; <nn> length, 0 (end) to 24
  9077.     or    ax,ax            ; end of set indicator?
  9078.     jnz    dgsetw2b        ; nz = no
  9079.     mov    ax,24            ; pseudo end
  9080. dgsetw2b:xchg    al,ah            ; put row in ah
  9081.     mov    bx,dgwindcnt        ; get subscript
  9082.     cmp    bx,24            ; too many windows? (24 == DG limit)
  9083.     ja    dgsetw7            ; a = yes, else accept data
  9084.     inc    bx
  9085.     mov    dgwindcnt,bx        ; update counter (1 == one window)
  9086.     dec    bx
  9087.     shl    bx,1            ; index words
  9088.     or    bx,bx            ; initial window?
  9089.     jnz    dgsetw3            ; nz = no
  9090.     xor    al,al            ; start at 0,0
  9091.     jmp    short dgsetw4
  9092. dgsetw3:mov    al,byte ptr dgwindow[bx-1] ; previous ending line
  9093.     inc    al            ; start this window down one line
  9094. dgsetw4:add    ah,al            ; new mar_bot = new mar_top + skip
  9095.     dec    ah            ; count lines from zero
  9096.     cmp    ah,byte ptr low_rgt+1    ; bottom of displayable screen?
  9097.     jb    dgsetw5            ; b = no
  9098.     mov    ah,byte ptr low_rgt+1    ; clamp to that bottom
  9099. dgsetw5:mov    dgwindow[bx],ax        ; save [al=mar_top,ah=mar_bot] pair
  9100.     mov    al,ah            ; get current bottom
  9101.     mov    ah,byte ptr low_rgt+1    ; last text line
  9102.     mov    dgwindow[bx+2],ax    ; fill remaining space with next wind
  9103.  
  9104.     push    bx            ; setup new margins, keep window ptr
  9105.     mov    dghscrdis,0        ; horz scroll disable is disabled
  9106.     mov    cx,slen            ; max screen length
  9107.     mov    al,mar_left
  9108.     xor    bx,bx
  9109. dgsetw6:mov    linescroll[bx],al    ; horiz scroll left margin to edge
  9110.     inc    bx
  9111.     loop    dgsetw6
  9112.     pop    bx            ; recover current line count in bx
  9113.  
  9114.     mov    al,emubuf+4        ; get compressed/normal for this wind
  9115.     mov    dh,byte ptr dgwindow[bx+1]; set cursor to bottom row of window
  9116.     or    al,al            ; to regular width?
  9117.     jnz    dgsetw7            ; nz = no, to compressed
  9118.     call    dgnarrow        ; to normal width
  9119.     jmp    short dgsetw8
  9120. dgsetw7:call    dgwide            ; compress things
  9121.  
  9122. dgsetw8:mov    bx,dgwindcnt        ; get window count
  9123.     or    bx,bx            ; any windows (0 = no)
  9124.     jz    dgsetw9
  9125.     dec    bx            ; count from 0
  9126.     shl    bx,1            ; count words
  9127.     mov    al,byte ptr low_rgt+1    ; last text line on screen (typ 23)
  9128.     cmp    byte ptr dgwindow[bx+1],al ; DG limit of 24 lines?
  9129.     jb    dgsetw1            ; b = not reached yet, keep going
  9130.  
  9131. dgsetw9:call    dgshome            ; do necessary DG Screen Home
  9132.     ret
  9133. dgsetw    endp
  9134.  
  9135. dgwwa    proc    near            ; Control-P col row
  9136.     mov    ttstate,offset dgwwa1    ; DG Write window address (win rel)
  9137.     ret                ; get raw binary col
  9138. dgwwa1:    mov    emubuf,al        ; save col
  9139.     mov    ttstate,offset dgwwa2    ; get raw binary row
  9140.     ret
  9141. dgwwa2:    mov    ttstate,offset atnrm    ; reset state
  9142.     cmp    al,127            ; 127 means use current row
  9143.     je    dgwwa3            ; e = yes
  9144.     add    al,mar_top        ; relative to window top
  9145.     mov    dh,al            ; set cursor row
  9146. dgwwa3:    xor    al,al            ; get a zero
  9147.     xchg    al,emubuf        ; get raw column, clear temp word
  9148.     cmp    al,127            ; 127 means use current column
  9149.     je    dgwwa4            ; e = yes
  9150.     add    al,mar_left        ; add left margin
  9151.     mov    dl,al            ; new cursor position
  9152. dgwwa4:    cmp    dh,mar_bot        ; below bottom of window?
  9153.     jbe    dgwwa5            ; be = no, in bounds
  9154.     mov    dh,mar_bot        ; peg at bottom
  9155. dgwwa5:    cmp    dl,mar_right        ; beyond right margin?
  9156.     jbe    dgwwa6            ; be = no, in bounds
  9157.     mov    dl,mar_right        ; peg at right
  9158. dgwwa6:    jmp    dgsetcur        ; set cursor within window
  9159. dgwwa    endp
  9160.  
  9161. dgwsa    proc    near            ; RS F P <nn><nn> Write screen address
  9162.     mov    bx,offset dgwsa1    ; get <nn> col
  9163.     jmp    get2n
  9164. dgwsa1:    mov    ax,dgnum        ; absolute column
  9165.     mov    ah,mar_right        ; right most virtual column
  9166.     cmp    al,-1            ; means same screen column?
  9167.     je    dgwsa2a            ; e = yes
  9168.     cmp    al,ah            ; beyond right screen limit?
  9169.     jbe    dgwsa2            ; be = no
  9170.     mov    al,ah            ; peg at the right
  9171. dgwsa2:    mov    byte ptr cursor,al    ; column of cursor
  9172. dgwsa2a:mov    bx,offset dgwsa3    ; get <nn> row
  9173.     jmp    get2n
  9174. dgwsa3:    mov    ax,dgnum        ; get absolute row
  9175.     mov    ah,byte ptr low_rgt+1    ; last text row
  9176.     cmp    al,-1            ; means same screen row?
  9177.     je    dgwsa5            ; e = yes
  9178.     cmp    al,ah            ; below text screen?
  9179.     jbe    dgwsa4            ; be = no
  9180.     mov    al,ah            ; peg at the bottom
  9181. dgwsa4:    mov    byte ptr cursor+1,al    ; new row
  9182. dgwsa5:    mov    dx,cursor
  9183.     call    dggetmar        ; get margins for this dx
  9184.     add    dl,mar_left        ; add left margin
  9185.     jmp    dgsetcur        ; set cursor, protection included
  9186. dgwsa    endp
  9187.  
  9188. dgshome    proc    near            ; RS F G  DG Screen Home
  9189.     xor    dh,dh            ; absolute screen top
  9190.     call    dggetmar        ; get margins for this dx
  9191.     mov    dl,mar_left        ; go to left margin
  9192.     jmp    dgsetcur        ; set the cursor
  9193. dgshome    endp
  9194.  
  9195. dgsetmar proc    near            ; RS F X <nn> <nn> Set margins
  9196.     call    dggetmar        ; get margins for this window row
  9197.     mov    bx,offset dgsetm1    ; get <nn> left margin
  9198.     jmp    get2n
  9199. dgsetm1:mov    al,mar_left        ; current left margin
  9200.     mov    emubuf,al
  9201.     mov    ax,dgnum        ; get left margin info
  9202.     cmp    al,-1            ; use current margin?
  9203.     je    dgsetm2            ; e = yes
  9204.     mov    emubuf,al        ; set left margin
  9205. dgsetm2:mov    bx,offset dgsetm3    ; get right margin
  9206.     jmp    get2n
  9207. dgsetm3:mov    ax,dgnum        ; get right margin info
  9208.     cmp    al,-1            ; use current margin?
  9209.     jne    dgsetm4            ; ne = no
  9210.     mov    al,vswidth-1        ; use full screen
  9211. dgsetm4:cmp    al,vswidth-1        ; check sanity
  9212.     ja    dgsetmx            ; a = too large a right margin
  9213.     cmp    al,emubuf        ; getting things on the wrong side?
  9214.     jb    dgsetmx            ; b = yes (ok for left=right)
  9215. dgsetm5:cmp    emubuf,vswidth-1    ; this side too
  9216.     jae    dgsetmx            ; ae = too large
  9217.     mov    mar_right,al        ; set right margin
  9218.     mov    al,emubuf        ; new left
  9219.     mov    mar_left,al        ; new left
  9220.     mov    byte ptr cursor,al    ; set cursor to left margin
  9221.     mov    dx,cursor
  9222.     mov    emubuf,al        ; preset args for dgschw1
  9223.     mov    al,mar_right
  9224.     mov    emubuf+1,al
  9225.     jmp    dgschw1            ; try to show both margins, set cursor
  9226. dgsetmx:ret                ; ignore command
  9227. dgsetmar endp
  9228.  
  9229. dgsetamar proc    near            ; DG RS F Y <nn><nn><nn>
  9230.     cmp    savdgmar,0        ; have we saved l/r margins?
  9231.     jne    dgsetam0        ; ne = yes, don't save current
  9232.     mov    ah,mar_right        ; save originals
  9233.     mov    al,mar_left
  9234.     mov    savdgmar,ax        ; saved
  9235. dgsetam0:mov    bx,offset dgsetam1    ; Set Alternate Margins
  9236.     jmp    get2n            ; get cursor row
  9237. dgsetam1:mov    ax,dgnum        ; cursor row wrt top margin
  9238.     mov    bl,dh            ; row of cursor
  9239.     cmp    al,-1            ; use current row?
  9240.     je    dgsetam2        ; e = yes
  9241.     mov    bl,mar_top        ; get row at top of this window
  9242.     add    bl,al            ; new cursor row is mar_top + new
  9243. dgsetam2:cmp    bl,mar_bot        ; below window?
  9244.     jbe    dgsetam3        ; be = no
  9245.     mov    bl,mar_bot        ; clamp to window bottom
  9246. dgsetam3:mov    emubuf,bl        ; save cursor row
  9247.     mov    bx,offset dgsetam4    ; get <nn> col of new left margin
  9248.     jmp    get2n
  9249. dgsetam4:mov    ax,dgnum
  9250.     mov    bl,byte ptr savdgmar    ; get permanent left margin
  9251.     cmp    al,-1            ; use current left margin?
  9252.     je    dgsetam5        ; e = yes
  9253.     add    bl,al            ; new left, wrt old left
  9254. dgsetam5:mov    word ptr emubuf+2,bx    ; save left margin
  9255.     mov    bx,offset dgsetam6    ; get <nn> right margin
  9256.     jmp    get2n
  9257. dgsetam6:mov    ax,dgnum
  9258.     mov    bl,byte ptr savdgmar+1    ; current right margin
  9259.     cmp    al,-1            ; use current right margin?
  9260.     je    dgsetam7        ; e = yes
  9261.     mov    bl,al            ; new relative right margin
  9262.     add    bl,mar_left        ; relative to old left margin
  9263.     cmp    bl,byte ptr savdgmar+1    ; exceeds old right_margin?
  9264.     jbe    dgsetam7        ; be = no
  9265.     mov    bl,byte ptr savdgmar+1    ; yes, use old right_margin
  9266. dgsetam7:cmp    bl,vswidth-1        ; too far right?
  9267.     ja    dgsetam9        ; a = yes, abandon the command
  9268.     mov    mar_right,bl        ; alt right margin
  9269.     mov    al,emubuf+2        ; get alt left margin
  9270.     mov    mar_left,al
  9271.     mov    dl,al            ; cursor to left margin
  9272.     mov    dh,emubuf        ; get row for cursor
  9273.     mov    dghscrdis,1        ; horz scroll disabled (if 1)
  9274.     call    dgsetcur        ; set cursor
  9275. dgsetam9:ret
  9276. dgsetamar endp
  9277.  
  9278. dgrnmar    proc    near            ; RS F Z  DG Restore normal margins
  9279.     cmp    savdgmar,0        ; anything saved?
  9280.     jz    dgrnma1            ; z = no, do nothing
  9281.     xor    ax,ax            ; get a null
  9282.     xchg    ax,savdgmar        ; recover saved margins, clear saved
  9283.     mov    mar_left,al
  9284.     mov    mar_right,ah
  9285. dgrnma1:ret
  9286. dgrnmar    endp
  9287.  
  9288. ; Worker. Given cursor in dx, set mar_top, mar_bot based on finding the 
  9289. ; DG window for that cursor row.
  9290. dggetmar proc    near
  9291.     mov    cx,dgwindcnt        ; number of windows
  9292.     xor    bx,bx
  9293.     jcxz    dggetma2        ; z = none
  9294.     inc    cx            ; let implied last window be seen
  9295. dggetma1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  9296.     jbe    dggetma3        ; be = cursor is in this window
  9297.     add    bx,2            ; skip two margin bytes
  9298.     loop    dggetma1        ; next window
  9299. dggetma2:ret
  9300.  
  9301. dggetma3:mov    ax,dgwindow[bx]        ; DG Window structure
  9302.     mov    mar_top,al
  9303.     mov    mar_bot,ah
  9304.     ret
  9305. dggetmar endp
  9306.  
  9307. ; Worker. Given cursor in dx, and al=mar_top, ah=mar_bot
  9308. ; store these margins in the window structure for that row, based on
  9309. ; finding the DG window for that cursor row.
  9310. dgstoremar proc    near
  9311.     push    cx
  9312.     mov    cx,dgwindcnt        ; number of windows
  9313.     xor    bx,bx
  9314.     jcxz    dgstore2        ; z = none
  9315. dgstore1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  9316.     jbe    dgstore2        ; be = cursor is in this window
  9317.     add    bx,2            ; skip two margin bytes
  9318.     loop    dgstore1        ; next window
  9319.     xor    bx,bx            ; fail, use first window slot
  9320. dgstore2:pop    cx
  9321.     mov    dgwindow[bx],ax
  9322.     ret
  9323. dgstoremar endp
  9324.  
  9325. dgsmid    proc    near            ; RS F { <nn><n> DG Set Model ID
  9326.     mov    bx,offset dgsmid1    ; setup for <nn>
  9327.     jmp    get2n
  9328. dgsmid1:mov    ax,dgnum        ; get new model id
  9329.     mov    byte ptr dgaltid,al    ; save
  9330.     mov    bx,dgsmid2        ; get graphics possible (1) bit
  9331.     jmp    get1n
  9332. dgsmid2:mov    ax,dgnum
  9333.     mov    byte ptr dgaltid+1,al
  9334.     ret
  9335. dgsmid    endp
  9336.  
  9337. dgscrup    proc    near            ; DG  RS H
  9338.     mov    scroll,1
  9339.     call    atscru            ; scroll up one line
  9340.     jmp    dgsetcur        ; place according to protected mode
  9341. dgscrup endp
  9342.  
  9343. dgscrdn    proc    near            ; DG  RS I
  9344.     mov    scroll,1
  9345.     call    atscrd            ; scroll down one line
  9346.     jmp    dgsetcur        ; place according to protected mode
  9347. dgscrdn    endp
  9348.  
  9349. dgcuu    proc    near            ; Control-W  DG cursor up
  9350. dgcuu1:    cmp    dh,mar_top        ; above the top margin?
  9351.     ja    dgcuu2            ; a = not on top margin
  9352.     mov    dh,mar_bot        ; roll to bottom margin
  9353.     inc    dh
  9354. dgcuu2:    dec    dh            ; go up one row
  9355.     call    dgcurpchk        ; do proteced mode check
  9356.     jc    dgcub1            ; c = protected, do cursor back
  9357.     jmp    atsetcur        ; set the cursor
  9358. dgcuu    endp
  9359.  
  9360. dgcud    proc    near            ; Control-Z  DG cursor down
  9361. dgcud1:    cmp    dh,mar_bot        ; below the bottom text line?
  9362.     jb    dgcud2            ; b = no
  9363.     mov    dh,mar_top        ; roll to top margin
  9364.     dec    dh
  9365. dgcud2:    inc    dh            ; go down one row
  9366.     call    dgcurpchk        ; check for protected cell
  9367.     jc    dgcuf1            ; c = on protected cell, go forward
  9368.     jmp    dgsetcur        ; set cursor
  9369. dgcud    endp
  9370.  
  9371. dgcuf    proc    near            ; Control-X  DG cursor forward
  9372.     cmp    dl,mar_right        ; test for about to wrap
  9373.     jb    dgcuf1            ; b = not wrapping
  9374.     test    anspflg,vtautop        ; printing desired?
  9375.     jz    dgcuf1            ; e = no
  9376.     push    dx            ; save cursor value
  9377.     call    pntlin            ; print line current line
  9378.     mov    al,LF            ; terminate in LF
  9379.     call    fpntchr
  9380.     call    fpntflsh        ; flush printer buffer
  9381.     mov    atwrap,0
  9382.     pop    dx
  9383.  
  9384. dgcuf1:    cmp    dl,mar_right        ; to right of right margin?
  9385.     jb    dgcuf5            ; b = not on right margin
  9386.     mov    dl,mar_left        ; go to left margin
  9387.     inc    dh            ; and down one
  9388.     cmp    dh,mar_bot        ; below bottom line now?
  9389.     jbe    dgcuf6            ; be = no
  9390.     mov    dh,mar_bot        ; stay on bottom line
  9391.     cmp    dgroll,0        ; is roll mode disabled?
  9392.     jne    dgcuf3            ; ne = no, do the scroll
  9393.     mov    dh,mar_top        ; yes, wrap to top
  9394.     jmp    short dgcuf6
  9395. dgcuf3:    mov    scroll,1
  9396.     call    atsetcur        ; set cursor before the scroll
  9397.     call    atscru            ; scroll up one line
  9398.     ret
  9399. dgcuf5:    inc    dl            ; go right one column
  9400. dgcuf6:    cmp    dx,cursor        ; is this the same place?
  9401.     je    dgcuf7            ; e = yes, stop here
  9402.     call    dgcurpchk        ; check protection
  9403.     jc    dgcuf1            ; c = stepped on protected cell
  9404. dgcuf7:    jmp    atsetcur        ; set cursor
  9405. dgcuf    endp
  9406.  
  9407. dgcub    proc    near            ; Control-Y  DG cursor left
  9408. dgcub1:    cmp    dl,mar_left        ; to left of left margin?
  9409.     ja    dgcub2            ; a = no
  9410.     mov    dl,mar_right        ; go to right margin 
  9411.     jmp    dgcuu1            ; and do a cursor up
  9412. dgcub2:    dec    dl            ; go left one column
  9413.     call    dgcurpchk        ; check protection
  9414.     jc    dgcub1            ; c = stepped on protected cell
  9415.     jmp    atsetcur        ; set real cursor and exit
  9416. dgcub    endp
  9417.  
  9418. dgcurpchk proc    near
  9419.     cmp    protectena,0        ; protected mode enabled?
  9420.     je    dgcurpc1        ; e = no
  9421.     push    dx
  9422.     push    bx
  9423.     mov    bl,dh            ; row
  9424.     xor    bh,bh
  9425.     cmp    linetype[bx],0        ; single width?
  9426.     pop    bx
  9427.     je    dgcurpc2        ; e = yes
  9428.     shl    dl,1            ; double cursor position
  9429. dgcurpc2:call    getatch            ; read char under new cursor position
  9430.     pop    dx
  9431.     test    cl,att_protect        ; protected?
  9432.     jz    dgcurpc1        ; z = no, accept this position
  9433.     stc                ; say stepping on protected char cell
  9434.     ret
  9435. dgcurpc1:clc                ; say no other action needed
  9436.     ret
  9437. dgcurpchk endp
  9438.  
  9439. ; Worker for cursor cmds. Skips protected fields, but remembers if we have
  9440. ; come full circle and then does a cursor right from there. Enter with
  9441. ; pre-motion cursor in "cursor", new desired position in dx.
  9442. dgsetcur proc    near
  9443.     call    dgcurpchk        ; call protected cell checker
  9444.     jnc    dgsetcu1        ; nc = ok, accept this position
  9445.     jmp    dgcuf1            ; do cursor forward
  9446. dgsetcu1:mov    bl,dh            ; get row
  9447.     xor    bh,bh
  9448.     cmp    dl,linescroll[bx]    ; to left of visible screen?
  9449.     jae    dgsetcu2        ; ae = no
  9450.     mov    emubuf,dl        ; set desired left margin
  9451.     mov    cl,mar_right
  9452.     mov    emubuf+2,cl        ; set desired right margin
  9453.     mov    cursor,dx        ; preset for dgschw1
  9454.     jmp    dgschw1            ; do Show Window to track cursor
  9455.  
  9456. dgsetcu2:jmp    atsetcur        ; set real cursor and exit
  9457. dgsetcur endp
  9458.  
  9459. dglf    proc    near            ; Control-J  DG New Line
  9460.     test    anspflg,vtautop        ; printing desired?
  9461.     jz    dglf1            ; e = no
  9462.     push    dx            ; save cursor
  9463.     call    pntlin            ; print line
  9464.     mov    al,LF            ; terminate in LF
  9465.     call    fpntchr
  9466.     call    fpntflsh        ; flush printer buffer
  9467.     mov    atwrap,0
  9468.     pop    dx
  9469. dglf1:    mov    dl,mar_left        ; to left margin
  9470.     cmp    dh,mar_bot        ; on bottom margin?
  9471.     jb    dglf3            ; b = no
  9472.     cmp    dgroll,0        ; is roll disabled
  9473.     je    dglf2            ; e = yes, do home
  9474.     mov    bl,dh            ; row
  9475.     xor    bh,bh
  9476.     mov    al,linescroll[bx]    ; save current line scroll
  9477.     push    dx
  9478.     push    bx
  9479.     push    ax
  9480.     mov    scroll,1
  9481.     call    atscru            ; do a scroll up by one line
  9482.     pop    ax
  9483.     pop    bx
  9484.     pop    dx
  9485.     mov    linescroll[bx],al    ; set line scroll for new line
  9486.     jmp    dgsetcur        ; set cursor, does show columns too
  9487.  
  9488. dglf2:    mov    dh,mar_top        ; do window Home
  9489.     jmp    short dglf4
  9490. dglf3:    inc    dh            ; down one row
  9491. dglf4:    jmp    dgsetcur        ; set cursor wrt protected mode
  9492. dglf    endp
  9493.  
  9494. dgcr    proc    near            ; DG Control-M
  9495.     mov    dl,mar_left        ; go to left margin, same row
  9496.     jmp    dgsetcur        ; set cursor, with protected mode
  9497. dgcr    endp
  9498.  
  9499. dgrmid    proc    near            ; RS C  DG Read Model ID
  9500.     mov    al,dgescape        ; resp RS o # <mm> <x> <y>
  9501.     call    prtbout
  9502.     mov    al,'o'
  9503.     call    prtbout
  9504.     mov    al,'#'
  9505.     call    prtbout
  9506.     mov    al,'5'            ; 5 is DG D217
  9507.     test    flags.vtflg,ttd217    ; D217?
  9508.     jnz    dgrmid6            ; nz = yes
  9509.     mov    al,'6'            ; 6 is DG D413/D463
  9510.     test    flags.vtflg,ttd470    ; D470?
  9511.     jz    dgrmid6            ; z = no
  9512.     mov    al,44            ; 44 is DG D470
  9513. dgrmid6:cmp    byte ptr dgaltid,0    ; alternate ID given?
  9514.     je    dgrmid1            ; e = no
  9515.     mov    al,byte ptr dgaltid    ; use alternate
  9516. dgrmid1:call    prtbout
  9517.     xor    al,al            ; <x> byte, clear it
  9518.     test    flags.remflg,d8bit    ; using 8 bits?
  9519.     jz    dgrmid2            ; z = no
  9520.     or    al,10h            ; say 8-bit mode
  9521. dgrmid2:push    ax
  9522.     mov    ah,ioctl        ; get printer status, via DOS
  9523.     mov    al,7            ; status for output
  9524.     push    bx
  9525.     mov    bx,4            ; std handle for system printer
  9526.     int    dos
  9527.     pop    bx
  9528.     jnc    dgrmid3            ; nc = call succeeded
  9529.     mov    al,0ffh
  9530. dgrmid3:cmp    al,0ffh            ; code for Ready
  9531.     pop    ax
  9532.     jne    dgrmid4            ; ne = not ready
  9533.     or    al,8            ; say printer present
  9534. dgrmid4:or    al,40h
  9535.     call    prtbout            ; send composite byte
  9536.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  9537.     xor    bh,bh
  9538.     mov    al,nrcdgkbd[bx]        ; <y>, get DG keyboard code from table
  9539.     or    al,50h            ; 01+kbd installed (no graphics)
  9540.     or    al,20h            ; say have graphics
  9541.     cmp    byte ptr dgaltid,0    ; alternate id given?
  9542.     je    dgrmid5            ; e = no
  9543.     cmp    byte ptr dgaltid+1,0    ; host wants to say no graphics?
  9544.     jne    dgrmid5            ; ne = no, let things stand
  9545.     and    al,not 20h        ; remove graphics bit
  9546. dgrmid5:call    prtbout
  9547.     ret
  9548. dgrmid    endp
  9549.                     ; D470 command, absent from D463's
  9550. dgscmap    proc    near            ; RS F c <n><n><n><n> DG set color map
  9551.     mov    bx,offset dgscmap1    ; get language ident
  9552.     jmp    get3n            ; get three of the <n>'s
  9553. dgscmap1:mov    bx,offset dgscmap2    ; get the fourth
  9554.     jmp    get1n
  9555. dgscmap2:ret
  9556. dgscmap    endp
  9557.  
  9558. dgshcol    proc    near            ; RS F _ <nn><nn>  DG Show Columns
  9559.     mov    bx,offset dgshco1    ; get left col to show
  9560.     jmp    get2n
  9561. dgshco1:mov    ax,dgnum        ; left column to show, is dominant
  9562.     mov    cx,vswidth        ; max columns in vscreen
  9563.     dec    cx            ; max column ident
  9564.     sub    cl,byte ptr low_rgt    ; visible display width - 1
  9565.     sbb    ch,0            ; max left column showable
  9566.     cmp    ax,cx            ; want further right than this?
  9567.     jbe    dgshco2            ; be = no
  9568.     mov    ax,cx            ; limit to max
  9569. dgshco2:mov    emubuf,al        ; save max left col to show
  9570.     mov    bx,offset dgshco3    ; get right col to show
  9571.     jmp    get2n
  9572. dgshco3:mov    ax,dgnum        ; right col
  9573.     cmp    al,emubuf        ; right less than left?
  9574.     jae    dgshco4            ; ae = no
  9575.     ret                ; else ignore command
  9576. dgshco4:mov    emubuf+1,al
  9577.     cmp    dghscrdis,0        ; is horizontal scrolling disabled?
  9578.     je    dgschw1            ; e = no
  9579.     ret                ; disabled, ignore this command
  9580.  
  9581. ; worker. emubuf=wanted visible left, emubuf+1=wanted visible right margin
  9582. dgschw1:mov    bl,mar_top        ; get window top
  9583.     xor    bh,bh
  9584.     mov    cl,mar_bot
  9585.     sub    cl,bl
  9586.     inc    cl
  9587.     xor    ch,ch            ; lines in window
  9588.     mov    al,emubuf+1        ; desired right margin
  9589.     sub    al,emubuf        ; minus desired left
  9590.     cmp    al,byte ptr low_rgt    ; more than a screen's width?
  9591.     jbe    dgschw2            ; be = no
  9592.     mov    al,emubuf        ; desired left
  9593.     add    al,byte ptr low_rgt    ; plus screen width
  9594.     mov    emubuf+1,al        ; chop desired rm to give one screen
  9595.  
  9596. dgschw2:mov    al,linescroll[bx]    ; get scroll now in effect
  9597.     cmp    emubuf,al        ; is left margin to left of screen?
  9598.     jb    dgshw4            ; b = yes, put it on screen
  9599.     je    dgshw8            ; e = there now, do nothing
  9600.     mov    ah,emubuf+1        ; right margin to use
  9601.     add    al,byte ptr low_rgt    ; visible right edge
  9602.     cmp    al,ah            ; visible vs wanted right edge
  9603.     jae    dgshw8            ; ae = rm visible now, do nothing
  9604.     sub    ah,al            ; distance right margin is invisible
  9605.     xchg    ah,al
  9606.     add    al,linescroll[bx]    ; new shift plus current shift
  9607.     jmp    short dgshw5
  9608.  
  9609. dgshw4:    mov    al,emubuf        ; new scroll
  9610. dgshw5:    mov    linescroll[bx],al    ; horiz scroll for this line (window)
  9611.     inc    bx
  9612.     loop    dgshw5            ; do all lines in this window
  9613.     mov    dx,cursor
  9614.     cmp    dl,al            ; is cursor off to the left?
  9615.     jae    dgshw6            ; ae = no
  9616.     mov    dl,al            ; offset cursor too
  9617. dgshw6:    add    al,byte ptr low_rgt    ; visible right edge
  9618.     cmp    dl,al            ; cursor is on screen?
  9619.     jbe    dgshw7            ; be = yes
  9620.     mov    dl,al            ; move cursor to right edge
  9621. dgshw7:    push    dx
  9622.     mov    dl,mar_top        ; region affected
  9623.     mov    dh,mar_bot
  9624.     call    touchup            ; repaint based on new linescroll
  9625.     pop    dx
  9626. dgshw8:    jmp    dgsetcur        ; set cursor, updates screen
  9627. dgshcol    endp
  9628.  
  9629. dgrnmod    proc    near            ; RS F w  DG Read New Model ID
  9630.     mov    al,dgescape        ; resp RS o w <c><s><r><n><res>
  9631.     call    prtbout
  9632.     mov    al,'o'
  9633.     call    prtbout
  9634.     mov    al,'w'
  9635.     call    prtbout
  9636.     mov    al,'1'            ; <c> D217 terminal
  9637.     test    flags.vtflg,ttd217 ; DG D217?
  9638.     je    dgrnmod3        ; e = yes
  9639. ;    mov    al,'3'            ; <c> D413 level graphics terminal
  9640.     mov    al,'8'            ; <c> D470/D463 graphics terminal
  9641. dgrnmod3:call    prtbout
  9642.     mov    al,'0'            ; <s> pair, 01 is D470/D463
  9643.     call    prtbout
  9644.     mov    al,'1'
  9645.     call    prtbout
  9646.     mov    al,'0'            ; <r> rev level as <nn>
  9647.     call    prtbout            ; report 00
  9648.     mov    al,'0'
  9649.     call    prtbout
  9650.     mov    cx,4
  9651. ;;    mov    si,offset d413model    ; 8 char name, all printables
  9652.     mov    si,offset d463model    ; graphics term name, 8 printables
  9653.     test    flags.vtflg,ttd470    ; D470?
  9654.     jz    dgrnmo1            ; z = no
  9655.     mov    si,offset d470model
  9656. dgrnmo1:lodsb
  9657.     push    cx
  9658.     call    prtbout
  9659.     pop    cx
  9660.     loop    dgrnmo1
  9661.     mov    cx,4+4            ; <reserved> four spaces
  9662. dgrnmo2:mov    al,' '
  9663.     push    cx
  9664.     call    prtbout
  9665.     pop    cx
  9666.     loop    dgrnmo2
  9667.     ret
  9668. dgrnmod    endp
  9669.  
  9670. dgunix    proc    near            ; RS P @ <n>  DG Unix mode
  9671.     mov    ttstate,offset dgunix1    ; setup to ignore @
  9672.     ret
  9673. dgunix1:mov    bx,offset atnrm        ; consume the <n>
  9674.     jmp    get1n
  9675. dgunix    endp
  9676.  
  9677. dgsct    proc    near            ; RS F Q <n>  DG Set Cursor Type
  9678.     mov    bx,offset dgsct1
  9679.     jmp    get1n            ; get the <n> arg
  9680. dgsct1:    mov    ax,dgnum        ; get cursor type
  9681.     or    al,al            ; case 0, invisible/off?
  9682.     jnz    dgsct2            ; nz = no
  9683.     call    csrtype            ; set text cursor bits, keep kind
  9684.     or    atctype,4        ; remember, is off
  9685.     jmp    short dgsct5
  9686.  
  9687. dgsct2:    cmp    al,2            ; standard 1,2? (underline, block)
  9688.     jbe    dgsct4            ; be = yes
  9689.     sub    al,5
  9690.     neg    al            ; 5 - AL
  9691.     js    dgsct6            ; s = out of range, ignore
  9692.     jnz    dgsct4            ; nz = cases 3 and 4 (block, uline)
  9693.     mov    al,atctype        ; case 5, use saved cursor type
  9694.     and    al,not 4        ; remove invisible bit
  9695. dgsct4:    mov    atctype,al        ; save text cursor type here
  9696.     push    ax
  9697.     or    vtemu.vtflgop,vscursor ; set to underlined
  9698.     test    al,2            ; setting to block?
  9699.     jz    dgsct4a            ; z = no, underline
  9700.     and    vtemu.vtflgop,not vscursor ; say block in status word
  9701. dgsct4a:call    csrtype            ; set the cursor bits
  9702.     pop    ax
  9703. dgsct5:    test    tekflg,tek_active+tek_sg ; special graphics mode active?
  9704.     jz    dgsct6            ; z = no
  9705.     mov    dx,cursor
  9706. ifndef    no_graphics
  9707.     call    teksetcursor        ; set new cursor
  9708. endif    ; no_graphics
  9709. dgsct6:    ret
  9710. dgsct    endp
  9711.  
  9712. dgchatr    proc    near            ; RS F N <nnn><n><n> DG change attrib
  9713.     mov    bx,offset dgchat1    ; get <nnn> qty chars to change
  9714.     jmp    get3n
  9715. dgchat1:mov    ax,dgnum        ; qty chars to change
  9716.     mov    word ptr emubuf,ax    ; save
  9717.     mov    bx,offset dgchat2    ; get <n> set list
  9718.     jmp    get1n
  9719. dgchat2:mov    ax,dgnum        ; bitfield for characteristics
  9720.     mov    emubuf+2,al        ; save set list
  9721.     mov    bx,offset dgchat3    ; get final <n> reset list
  9722.     jmp    get1n
  9723. dgchat3:mov    bl,byte ptr dgnum    ; get reset list to BL
  9724.     mov    emubuf+3,bl        ; save reset list
  9725.     mov    bh,emubuf+2        ; set list
  9726.     and    bh,bl            ; get toggle bits
  9727.     mov    emubuf+4,bh        ; save toggle list here
  9728.     not    bh            ; clear out bits processed here
  9729.     and    emubuf+2,bh        ; update set list
  9730.     and    emubuf+3,bh        ; update reset list
  9731.     mov    cursor,dx        ; save cursor location
  9732.  
  9733.     mov    cx,word ptr emubuf    ; qty of bytes to change, max
  9734.     or    cx,cx            ; some count?
  9735.     jnz    dgchag4            ; nz = something to do
  9736.     ret
  9737. dgchag4:mov    al,extattr        ; preserve settable attributes
  9738.     mov    ah,scbattr
  9739.     push    ax
  9740. dgchag4a:push    cx            ; save loop counter
  9741.     call    getatch            ; get video in ah, extended att in cl
  9742.     mov    extattr,cl        ; place extended where procs can see
  9743.     mov    emubuf+5,al        ; save char
  9744.     call    dgchag10        ; process this char
  9745.     mov    al,emubuf+5        ; restore char
  9746.     call    qsetatch        ; quietly update the char
  9747.     pop    cx
  9748.     inc    dl            ; next column
  9749.     cmp    dl,mar_right        ; at the right margin?
  9750.     jbe    dgchag5            ; be = no, not yet
  9751.     mov    dl,mar_left        ; wrap to left and next line
  9752.     inc    dh            ; next line down
  9753.     cmp    dh,mar_bot        ; below the window bottom?
  9754.     ja    dgchag6            ; a = yes, all done
  9755. dgchag5:loop    dgchag4a        ; do more chars
  9756. dgchag6:pop    ax
  9757.     mov    extattr,al        ; restore setables
  9758.     mov    scbattr,ah
  9759.     mov    dl,byte ptr cursor+1    ; dl = starting row, dh = ending row
  9760.     mov    dh,mar_bot
  9761.     call    touchup            ; repaint part of screen
  9762.     mov    dx,cursor        ; reset cursor location
  9763.     ret
  9764.  
  9765. ; worker for dgchag            ; do toggle mode
  9766. dgchag10:mov    bh,emubuf+4        ; toggle list
  9767.     or    bh,bh            ; any work?
  9768.     jz    dgchag20        ; z = no
  9769.     test    bh,1            ; blink?
  9770.     jz    dgchag11        ; z = no
  9771.     xor    ah,att_blink        ; xor blink
  9772. dgchag11:test    bh,2            ; underscore?
  9773.     jz    dgchag13        ; z = no
  9774.     test    cl,att_uline        ; is it set now?
  9775.     jz    dgchag12        ; z = no
  9776.     call    clrunder        ; reset it
  9777.     jmp    short dgchag13
  9778. dgchag12:call    setunder        ; set it
  9779. dgchag13:test    bh,4            ; reverse video
  9780.     jz    dgchag15        ; z = no
  9781.     test    cl,att_rev        ; reversed now?
  9782.     jz    dgchag14        ; z = no
  9783.     call    clrrev            ; unreverse it
  9784.     jmp    short dgchag15
  9785. dgchag14:call    setrev            ; reverse it
  9786. dgchag15:test    bh,8            ; Dim
  9787.     jz    dgchag20
  9788.     xor    ah,att_bold
  9789.                     ; do set list from emubuf+2
  9790. dgchag20:mov    bh,emubuf+2        ; get set list
  9791.     or    bh,bh            ; any work?
  9792.     jz    dgchag30        ; z = no
  9793.     test    bh,1            ; blink?
  9794.     jz    dgchag21        ; z = no
  9795.     call    setblink        ; set blink
  9796. dgchag21:test    bh,2            ; underscore?
  9797.     jz    dgchag22        ; z = no
  9798.     call    setunder        ; set underline
  9799. dgchag22:test    bh,4            ; reverse video?
  9800.     jz    dgchag23        ; z = no
  9801.     call    setrev            ; set reverse video
  9802. dgchag23:test    bh,8            ; dim?
  9803.     jz    dgchag30        ; z = no
  9804.     call    clrbold            ; set Dim
  9805.                     ; do reset list from emubuf+3
  9806. dgchag30:mov    bh,emubuf+3        ; get reset list
  9807.     or    bh,bh            ; any work?
  9808.     jz    dgchag34        ; z = no
  9809.     test    bh,1            ; blink?
  9810.     jz    dgchag31        ; z = no
  9811.     call    clrblink        ; clear blink
  9812. dgchag31:test    bh,2            ; underscore?
  9813.     jz    dgchag32        ; z = no
  9814.     call    clrunder        ; clear underscore
  9815. dgchag32:test    bh,4            ; reverse video?
  9816.     jz    dgchag33        ; z = no
  9817.     call    clrrev
  9818. dgchag33:test    bh,8            ; Dim?
  9819.     jz    dgchag34        ; z = no
  9820.     call    setbold            ; reset dim
  9821. dgchag34:ret                ; end of callable worker
  9822. dgchatr    endp
  9823.  
  9824. dgsclk    proc    near            ; RS r <n> <pos> <time> DG Set Clock
  9825.     mov    bx,offset dgsclk1    ; set up to get <n><0000>
  9826.     jmp    get3n
  9827. dgsclk1:mov    bx,offset dgsclk2    ; setup to get HH
  9828.     jmp    get1n
  9829. dgsclk2:mov    ttstate,offset dgsclk3    ; setup to get ":"
  9830.     ret
  9831. dgsclk3:mov    bx,offset atnrm        ; absorb final MM
  9832.     jmp    get1n
  9833. dgsclk    endp
  9834.  
  9835. dgrss    proc    near            ; RS F t  DG Report Screen Size
  9836.     mov    al,dgescape        ; resp RS o < <5 more items>
  9837.     call    prtbout
  9838.     mov    al,'o'
  9839.     call    prtbout
  9840.     mov    al,'<'
  9841.     call    prtbout
  9842.     mov    al,byte ptr low_rgt+1    ; number of screen rows -1
  9843.     inc    al
  9844.     call    out2n            ; first item
  9845.     mov    al,207            ; number of screen cols (DG hard #)
  9846.     call    out2n            ; second item
  9847.     mov    al,mar_bot
  9848.     sub    al,mar_top
  9849.     inc    al            ; third item, num rows in window
  9850.     call    out2n
  9851.     mov    al,mar_right
  9852.     sub    al,mar_left
  9853.     inc    al            ; fourth item, num cols in window
  9854.     call    out2n
  9855.     mov    al,01110000b        ; fifth item, status
  9856.     call    prtbout
  9857.     ret
  9858. dgrss    endp
  9859.  
  9860. dgrhso    proc    near            ; RS F O  DG Read Horz Scroll Offset
  9861.     mov    al,dgescape        ; resp RS o : <nn>
  9862.     call    prtbout
  9863.     mov    al,'o'
  9864.     call    prtbout
  9865.     mov    al,':'
  9866.     call    prtbout
  9867.     mov    bl,dh            ; get current row
  9868.     xor    bh,bh
  9869.     mov    al,linescroll[bx]    ; get scroll value
  9870.     call    out2na
  9871.     ret
  9872. dgrhso    endp
  9873.  
  9874. dgrwa    proc    near            ; Control-E  DG Read Window Address
  9875.     mov    al,1fh            ; Response string Control-_ col row
  9876.     call    prtbout
  9877.     mov    al,dl            ; col, raw binary
  9878.     call    prtbout
  9879.     mov    al,dh            ; row, raw binary
  9880.     call    prtbout
  9881.     ret
  9882. dgrwa    endp
  9883.  
  9884. dgrsa    proc    near            ; RS F b  DG Read Screen Address
  9885.     mov    al,dgescape        ; resp RS o 8 <nn> <nn>
  9886.     call    prtbout
  9887.     mov    al,'o'
  9888.     call    prtbout
  9889.     mov    al,'8'
  9890.     call    prtbout
  9891.     mov    al,byte ptr cursor    ; column
  9892.     call    out2na
  9893.     mov    al,byte ptr cursor+1    ; row
  9894.     call    out2na
  9895.     ret
  9896. dgrsa    endp
  9897.  
  9898. dgrwc    proc    near            ; RS F v <r1> <c1> <r2> <c2>
  9899.     mov    emubufc,0        ; counter. DG Read Window Contents
  9900. dgrwc1:    mov    bx,offset dgrwc2
  9901.     jmp    get2n            ; read <nn>
  9902. dgrwc2:    mov    bx,emubufc        ; get counter
  9903.     inc    emubufc
  9904.     mov    ax,dgnum        ; r1, c1, r2, or c2
  9905.     mov    emubuf[bx],al        ; save here
  9906.     cmp    bx,3            ; done all four?
  9907.     jb    dgrwc1            ; b = no, get more
  9908.     mov    dh,emubuf        ; starting row
  9909.     cmp    dh,emubuf+2        ; versus ending row
  9910.     ja    dgrwc8            ; a = fail if wrong order
  9911. dgrwc3:    mov    dl,emubuf+3        ; ending column
  9912.     mov    cl,dl
  9913.     sub    cl,emubuf+1        ; minus starting column
  9914.     jl    dgrwc8            ; fail if wrong order
  9915.     inc    cl            ; number of cells to examine
  9916.     xor    ch,ch
  9917.  
  9918. dgrwc4:    push    cx
  9919.     push    dx
  9920.     call    direction
  9921.     call    getatch            ; read char into AL at cursor dx
  9922.     pop    dx
  9923.     pop    cx
  9924.     cmp    al,' '            ; space?
  9925.     jne    dgrwc5            ; found non-space
  9926.     dec    dl
  9927.     loop    dgrwc4
  9928. dgrwc5:    jcxz    dgrwc7            ; z = only spaces on the line
  9929.     mov    dl,emubuf+1        ; staring column
  9930. dgrwc6:    push    cx
  9931.     push    dx
  9932.     call    direction
  9933.     call    getatch            ; get char and attribute
  9934.     call    prtbout            ; send char in al
  9935.     pop    dx
  9936.     pop    cx
  9937.     inc    dl            ; across the row
  9938.     loop    dgrwc6            ; do all interesting cols
  9939. dgrwc7:    push    dx
  9940.     mov    al,CR            ; send line terminators
  9941.     call    prtbout
  9942.     mov    al,LF
  9943.     call    prtbout
  9944.     pop    dx
  9945.     inc    dh            ; next row down
  9946.     cmp    dh,emubuf+2        ; beyond last row?
  9947.     jbe    dgrwc3            ; be = no
  9948.     mov    dx,cursor
  9949.     mov    emubufc,0        ; clear counter
  9950. dgrwc8:    ret
  9951. dgrwc    endp
  9952.         ; Data General D463/D470 graphics commands
  9953.  
  9954. dggline    proc    near            ; RS L and RS G 8  DG line drawing
  9955.     call    dgsettek        ; setup special graphics mode
  9956. dggline1:mov    bx,offset dggline2    ; get <NNN> x coord
  9957.     jmp    get3loc
  9958. dggline2:jc    dggline9        ; c = read null terminator
  9959.     mov    ax,dgnum        ; start x coord
  9960.     mov    word ptr emubuf+0,ax    ; save here
  9961.     mov    word ptr emubuf+4,ax    ; and here
  9962.     mov    bx,offset dggline3    ; get <NNN> y coord
  9963.     jmp    get3loc
  9964. dggline3:jc    dggline9
  9965.     mov    ax,dgnum
  9966.     mov    word ptr emubuf+2,ax    ; start y
  9967.     mov    word ptr emubuf+6,ax    ; and here
  9968. dggline4:mov    bx,offset dggline5    ; get <NNN> end x coord
  9969.     jmp    get3loc
  9970. dggline5:jc    dggline8        ; c = ending on single coord, do a dot
  9971.     mov    ax,dgnum
  9972.     mov    word ptr emubuf+4,ax    ; end x
  9973.     mov    bx,offset dggline6    ; get <NNN> end y coord
  9974.     jmp    get3loc
  9975. dggline6:jc    dggline9        ; c = null char
  9976.     mov    ax,dgnum        ; end y
  9977.     mov    word ptr emubuf+6,ax
  9978.     call    dggline8        ; plot line
  9979.     jmp    short dggline4        ; continue gathering coord pairs
  9980.  
  9981. dggline8:                ; worker called above
  9982. ifndef    no_graphics
  9983.     push    word ptr mar_top    ; mar_top in low byte
  9984.     push    dglinepat        ; line pattern
  9985.     push    word ptr emubuf+6    ; end y
  9986.     push    word ptr emubuf+4    ; end x
  9987.     push    word ptr emubuf+2    ; start y
  9988.     push    word ptr emubuf+0    ; start x
  9989.     call    dgline            ; do the line
  9990.     add    sp,12            ; clear the argument stack
  9991.     mov    ax,word ptr emubuf+4    ; old end is new beginning
  9992.     mov    word ptr emubuf,ax
  9993.     mov    ax,word ptr emubuf+6
  9994.     mov    word ptr emubuf+2,ax
  9995. endif    ; no_graphics
  9996. dggline9:ret
  9997. dggline    endp
  9998.  
  9999. dggarc    proc    near            ; RS G 0  DG arc drawing
  10000.     mov    bx,offset dggarc1    ; get <NNN> x coord
  10001.     jmp    get3loc
  10002. dggarc1:jc    dggarc9            ; unexpected terminator
  10003.     mov    ax,dgnum        ; x coord
  10004.     mov    word ptr emubuf,ax    ; save here
  10005.     mov    bx,offset dggarc2    ; get <NNN> y coord
  10006.     jmp    get3loc
  10007. dggarc2:jc    dggarc9
  10008.     mov    ax,dgnum
  10009.     mov    word ptr emubuf+2,ax
  10010.     mov    bx,offset dggarc3    ; get <NNN> radius
  10011.     jmp    get3loc
  10012. dggarc3:jc    dggarc9
  10013.     mov    ax,dgnum
  10014.     mov    word ptr emubuf+4,ax
  10015.     mov    bx,offset dggarc4    ; get <NNN> start angle
  10016.     jmp    get3loc
  10017. dggarc4:jc    dggarc9
  10018.     mov    ax,dgnum
  10019.     mov    word ptr emubuf+6,ax
  10020.     mov    bx,offset dggarc5    ; get <NNN> end angle
  10021.     jmp    get3loc
  10022. dggarc5:
  10023. ifndef    no_graphics
  10024.     call    dgsettek        ; setup graphics mode
  10025.     mov    al,mar_bot        ; bottom margin in PC text lines
  10026.     xor    ah,ah
  10027.     push    ax
  10028.     mov    al,mar_top        ; top margin in PC text lines
  10029.     push    ax
  10030.     push    dgnum            ; end angle
  10031.     push    word ptr emubuf+6    ; start angle
  10032.     push    word ptr emubuf+4    ; radius
  10033.     push    word ptr emubuf+2    ; start y
  10034.     push    word ptr emubuf+0    ; start x
  10035.     call    dgarc            ; draw the arc in msgibm
  10036.     add    sp,14            ; clean stack
  10037. endif    ; no_graphics
  10038. dggarc9:ret
  10039. dggarc    endp
  10040.  
  10041. dggbar    proc    near            ; RS G 1  DG bar drawing
  10042.     call    dgsettek        ; setup special graphics mode
  10043.     mov    bx,offset dggbar1    ; get <NNN> x coord, lower left
  10044.     jmp    get3loc
  10045. dggbar1:jc    dggbar9            ; c = unexpected terminator
  10046.     mov    ax,dgnum        ; x coord
  10047.     mov    word ptr emubuf,ax    ; save here
  10048.     mov    bx,offset dggbar2    ; get <NNN> y coord
  10049.     jmp    get3loc
  10050. dggbar2:jc    dggbar9
  10051.     mov    ax,dgnum
  10052.     mov    word ptr emubuf+2,ax
  10053.     mov    bx,offset dggbar3    ; get <NNN> width
  10054.     jmp    get3loc
  10055. dggbar3:jc    dggbar9
  10056.     mov    ax,dgnum
  10057.     mov    word ptr emubuf+4,ax
  10058.     mov    bx,offset dggbar4    ; get <NNN> height
  10059.     jmp    get3loc
  10060. dggbar4:jc    dggbar9
  10061.     mov    ax,dgnum
  10062.     mov    word ptr emubuf+6,ax
  10063.     mov    bx,offset dggbar5    ; get <n> foreground/background
  10064.     jmp    get1n
  10065. dggbar5:jc    dggbar9
  10066. ifndef    no_graphics
  10067.     xor    ah,ah
  10068.     mov    al,mar_bot
  10069.     push    ax
  10070.     mov    al,mar_top
  10071.     push    ax
  10072.     push    dgnum            ; fore(1) or background (0) color
  10073.     push    word ptr emubuf+6    ; height
  10074.     push    word ptr emubuf+4    ; width
  10075.     push    word ptr emubuf+2    ; start y lower left corner
  10076.     push    word ptr emubuf+0    ; start x
  10077.     call    dgbar            ; msgibm bar drawer
  10078.     add    sp,14            ; clean stack
  10079. endif    ; no_graphics
  10080. dggbar9:ret
  10081. dggbar    endp
  10082.  
  10083. dggpoly    proc    near            ; RS G :  DG polygon fill drawing
  10084.     mov    word ptr rdbuf,0    ; count argument pairs
  10085. dggpol1:mov    bx,offset dggpol2    ; get <NNN> x coord
  10086.     jmp    get3loc
  10087. dggpol2:jc    dggpol4            ; c = got null terminator
  10088.     mov    ax,dgnum        ; x coord
  10089.     mov    word ptr emubuf,ax    ; save here
  10090.     mov    bx,offset dggpol3    ; get <NNN> y coord
  10091.     jmp    get3loc
  10092. dggpol3:jc    dggpol4
  10093.     mov    bx,word ptr rdbuf    ; vertex index
  10094.     shl    bx,1            ; count words
  10095.     shl    bx,1            ; count pairs
  10096.     mov    cx,word ptr emubuf    ; x coord
  10097.     mov    ax,dgnum        ; y coord
  10098.     mov    word ptr rdbuf+2[bx],cx    ; stuff x
  10099.     mov    word ptr rdbuf+2[bx+2],ax ; stuff y
  10100.     inc    word ptr rdbuf        ; another vertex in list
  10101.     jmp    short dggpol1        ; get another vertex
  10102. dggpol4:cmp    word ptr rdbuf,3    ; minimum viable point count
  10103.     jb    dggpol6            ; b = insufficient qty
  10104.     mov    bx,word ptr rdbuf    ; vertex index
  10105.     shl    bx,1            ; count words
  10106.     shl    bx,1            ; count pairs
  10107.     mov    al,mar_top
  10108.     xor    ah,ah
  10109.     mov    word ptr rdbuf+2[bx],ax    ; top margin, PC text lines
  10110.     mov    al,mar_bot
  10111.     mov    word ptr rdbuf+2[bx+2],ax ; bottom margin, PC text lines
  10112.     call    dgsettek        ; setup special graphics mode
  10113.     mov    al,curattr        ; save current coloring
  10114.     push    ax
  10115.     test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  10116.     jz    dgpoly5            ; z = no
  10117.     and    al,0f0h            ; remove foreground
  10118.     or    al,dg463fore        ; OR in D463 foreground color
  10119.     mov    curattr,al        ; set drawing coloring
  10120. dgpoly5:
  10121. ifndef    no_graphics
  10122.     call    dgpoly            ; call worker in msgibm
  10123. endif    ; no_graphics
  10124.     pop    ax
  10125.     mov    curattr,al        ; restore coloring
  10126. dggpol6:ret
  10127. dggpoly    endp
  10128.  
  10129. dggsetp    proc    near            ; RS G p 1  DG Set Pattern
  10130.     mov    ttstate,offset dggset1    ; setup to read the 1
  10131.     ret
  10132. dggset1:cmp    al,'1'            ; correct?
  10133.     je    dggset2            ; e = yes
  10134. dggsetx:jmp    atnorm            ; fail and reset state
  10135. dggset2:mov    ttstate,offset dggset3    ; setup to read <offset>
  10136.     mov    dglinepat,0        ; init line pattern to all zeros
  10137.     call    dgsettek        ; setup special graphics mode
  10138.     ret
  10139. dggset3:sub    al,'@'            ; remove ASCII bias
  10140.     jc    dggset9            ; c = failure
  10141.     and    al,1fh            ; keep lower five bits
  10142.     xor    ah,ah
  10143.     mov    word ptr emubuf,ax    ; save initial bit position
  10144.     mov    cl,al
  10145.     rcl    dglinepat,cl        ; rotate initial pattern
  10146.     mov    ttstate,offset dggset4    ; setup to read <n> 0/1 bit
  10147.     ret
  10148. dggset4:or    al,al            ; null terminator?
  10149.     jz    dggset6            ; z = yes
  10150.     and    al,0fh            ; keep lower four bits of <n>
  10151.     cmp    al,1            ; legal values are 0, 1, and other
  10152.     jbe    dggset5            ; be = 0 or 1
  10153.     xor    al,al            ; above 1 is made to be zero
  10154. dggset5:rcr    al,1
  10155.     rcr    dglinepat,1        ; put into line pattern high bit
  10156.     inc    word ptr emubuf        ; count bit added to pattern
  10157.     ret                ; continue in state dggset4
  10158.  
  10159. dggset6:mov    cx,16            ; bits in pattern
  10160.     sub    cx,word ptr emubuf    ; get pattern bit count
  10161.     jle    dggset9            ; le = rotated enough
  10162.     mov    ax,dglinepat        ; pattern
  10163.     mov    bx,ax            ; a copy
  10164.     mov    cx,word ptr emubuf    ; pattern bit count
  10165.     mov    dx,16            ; overall bits
  10166. dggset6a:sub    dx,cx            ; minus original pattern
  10167.     jg    dggset7            ; g = still have room to copy
  10168.     je    dggset8            ; e = all done
  10169.     neg    dx
  10170.     mov    cx,dx            ; else tag end
  10171. dggset7:ror    ax,cl            ; rotate pattern to starting position
  10172.     or    ax,bx            ; move in a copy
  10173.     jmp    short dggset6a
  10174.  
  10175. dggset8:mov    dglinepat,ax        ; store line pattern
  10176. dggset9:jmp    atnorm
  10177. dggsetp    endp
  10178.  
  10179. dggrcl    proc    near            ; RS G ? |  DG Read Cursor Location
  10180.     mov    ttstate,offset dggrcl1
  10181.     ret
  10182. dggrcl1:mov    ttstate,atnrm        ; reset state
  10183.     cmp    al,'|'            ; correct terminator?
  10184.     jne    dggrcl3            ; ne = no
  10185. dggrcl2:
  10186. ifndef    no_graphics
  10187.     call    dgcrossrpt        ; generate report in msgibm
  10188. endif    ; no_graphics
  10189. dggrcl3:ret
  10190. dggrcl    endp
  10191.  
  10192. dggcon    proc    near            ; RS G B  DG Cursor on
  10193. ifndef    no_graphics
  10194.     call    dgsettek        ; setup special graphics mode
  10195.     call    dgcrosson        ; turn on crosshair
  10196. endif    ; no_grpahics
  10197.     ret
  10198. dggcon    endp
  10199.  
  10200. dggcoff    proc    near            ; RS G C  DG Cursor off
  10201. ifndef    no_graphics
  10202.     call    dgcrossoff        ; turn off crosshair
  10203. endif    ; no_graphics
  10204.     ret
  10205. dggcoff    endp
  10206.  
  10207. dggcloc    proc    near            ; RS G > | <NNN> <NNN> DG Cursor loc
  10208.     mov    ttstate,offset dggclo1    ; get vertical bar
  10209.     ret
  10210. dggclo1:mov    ttstate,offset atnrm    ; reset state
  10211.     cmp    al,'|'            ; correct character?
  10212.     je    dggclo2            ; e = yes
  10213.     ret
  10214. dggclo2:mov    bx,offset dggclo3    ; get <nnn> x ordinate
  10215.     jmp    get3loc            ; as 15 bit location argument
  10216. dggclo3:mov    ax,dgnum
  10217.     mov    word ptr emubuf,ax    ; got x ordinate
  10218.     mov    bx,offset dggclo4    ; get <nnn> y ordinate
  10219.     jmp    get3loc            ; as 15 bit location argument
  10220. dggclo4:mov    bx,dgnum        ; setup registers for call
  10221.     mov    ax,word ptr emubuf
  10222. ifndef    no_graphics
  10223.     call    dgsetcrloc        ; setup crosshair location
  10224. endif    ; no_graphics
  10225.     ret
  10226. dggcloc    endp
  10227.  
  10228. dggctrk    proc    near            ; RS G H <n>  DG Cursor track
  10229.     mov    bx,offset dggctr1
  10230.     jmp    get1n
  10231. dggctr1:and    al,2+4            ; pick out our trackables
  10232.     and    dgcross,not (2+4)    ; preserve on/of bit (1)
  10233.     or    dgcross,al        ; track keypad (2) and/or mouse (4)
  10234.     ret
  10235. dggctrk    endp
  10236.  
  10237. dggcatt    proc    near            ; RS G @  DG graphics cursor attribute
  10238.     mov    al,dgescape
  10239.     call    prtbout
  10240.     mov    al,'o'
  10241.     call    prtbout
  10242.     mov    al,','
  10243.     call    prtbout
  10244.     mov    al,'0'            ; say crosshair is off
  10245.     test    dgcross,1        ; is it on?
  10246.     jz    dggcatt1        ; z = no
  10247.     inc    al            ; say '1' for on
  10248. dggcatt1:call    prtbout            ; output <v1>
  10249.     mov    al,'0'            ; <v2> is always 0 for not blinking
  10250.     call    prtbout
  10251.     mov    al,'1'            ; <v3> is 1 for long crosshair, D463
  10252.     test    flags.vtflg,ttd470    ; D470?
  10253.     jz    dggcatt2        ; z = no
  10254.     dec    al            ; <v3> is 0 for short crosshair, D470
  10255. dggcatt2:call    prtbout
  10256.     mov    al,dgcross        ; get tracked devices
  10257.     and    al,2+4            ; pick out just devices
  10258.     add    al,'0'            ; bias
  10259.     call    prtbout            ; output <v4>
  10260.     mov    al,CR            ; terminal character
  10261.     call    prtbout
  10262.     ret
  10263. dggcatt    endp
  10264.  
  10265. dggcrst    proc    near            ; RS G A  DG Cursor reset
  10266. ifndef    no_graphics
  10267.     call    dgcrossoff        ; turn off crosshair
  10268. endif    ; no_graphics
  10269.     mov    dgcross,0        ; and no kind of tracking
  10270.     ret
  10271. dggcrst    endp
  10272.  
  10273. ; D470 ANSI mode support routines
  10274.  
  10275. dgesc_ch proc    near            ; ESC <Gn> <set> Select character set
  10276.     cmp    ninter,1        ; just one intermediate?
  10277.     je    dgesc_ch2        ; e = yes, designator
  10278.     cmp    inter+1,' '        ; DRCB 1..16?
  10279.     je    dgesc_ch1        ; e = yes
  10280.     cmp    inter+1,'!'        ; DRCB 17..22?
  10281.     je    dgesc_ch1        ; e = yes
  10282.     ret                ; else ignore
  10283. dgesc_ch1:mov    bx,20h            ; identify one soft set
  10284.     jmp    short dgesc_ch4
  10285.  
  10286. dgesc_ch2:cmp    al,'0'            ; final char, use keyboard language?
  10287.     jne    dgesc_ch3        ; ne = no, look it up
  10288.     xor    bh,bh
  10289.     mov    bl,vtemu.vtchset    ; get setup char set
  10290.     cmp    bl,13            ; top of the NRCs
  10291.     jbe    short dgesc_ch4        ;  as keyboard language
  10292.     xor    bx,bx            ; default to ASCII
  10293.     jmp    short dgesc_ch4
  10294. dgesc_ch3:xor    bx,bx            ; look up set in table
  10295.     push    es
  10296.     mov    di,seg d470chr        ; get translation table address
  10297.     mov    es,di
  10298.     mov    di,offset d470chr
  10299.     mov    cx,d470chrlen        ; get table length
  10300.     cld
  10301.     repne    scasb            ; look for match
  10302.     pop    es
  10303.     dec    di            ; backup on match
  10304.     jne    dgesc_ch5        ; ne = no match, ignore
  10305.     sub    di,offset d470chr    ; compute index
  10306.     mov    bl,mskchr[di]        ; get Kermit equivalent code
  10307.     xor    bh,bh
  10308. dgesc_ch4:                ; bx holds Kermit set ident
  10309.     mov    al,inter        ; get set designator
  10310.     sub    al,'('            ; minus bias
  10311.     xor    ah,ah
  10312.     cmp    al,3            ; range check 0..3
  10313.     ja    dgesc_ch5        ; a = out of range
  10314.     mov    si,ax            ; point at set id
  10315.     mov    Gsetid[si],bl        ; indentify new set
  10316.     mov    bx,offset Gsetid    ; tell chrset where to get info
  10317.     jmp    chrsetup        ; create new set
  10318. dgesc_ch5:ret
  10319. dgesc_ch endp
  10320.  
  10321. dgesc_c    proc    near            ; DG ESC c  reset terminal
  10322.     cmp    ninter,0        ; any intermediates?
  10323.     jne    dgesc_c1        ; ne = yes, not this command
  10324.     cmp    nparam,0        ; no params too?
  10325.     jne    dgesc_c1        ; ne = no, ignore
  10326.     jmp    atreset            ; reset
  10327. dgesc_c1:ret
  10328. dgesc_c endp
  10329.  
  10330. dgesc_D    proc    near            ; DG ESC D index
  10331.     cmp    ninter,0        ; any intermediates?
  10332.     jne    dgesc_D5        ; ne = yes, not this command
  10333.     test    anspflg,vtautop        ; printing desired?
  10334.     jz    dgesc_D1        ; e = no
  10335.     push    dx            ; save cursor
  10336.     call    pntlin            ; print line
  10337.     mov    al,LF            ; terminate in LF
  10338.     call    fpntchr
  10339.     call    fpntflsh        ; flush printer buffer
  10340.     mov    atwrap,0
  10341.     pop    dx
  10342. dgesc_D1:cmp    dh,mar_bot        ; on bottom margin?
  10343.     jb    dgesc_D3        ; b = no
  10344.     cmp    dgroll,0        ; is roll disabled
  10345.     je    dgesc_D2        ; e = yes, do home
  10346.     push    dx
  10347.     mov    scroll,1
  10348.     call    atscru            ; do a scroll up by one line
  10349.     pop    dx
  10350.     jmp    dgsetcur        ; set cursor, does show columns too
  10351.  
  10352. dgesc_D2:mov    dh,mar_top        ; do window Home
  10353.     jmp    short dgesc_D4
  10354. dgesc_D3:inc    dh            ; down one row
  10355. dgesc_D4:jmp    dgsetcur        ; set cursor wrt protected mode
  10356. dgesc_D5:ret
  10357. dgesc_D endp
  10358.  
  10359. dgesc_E    proc    near            ; DG ESC E next line
  10360.     cmp    ninter,0        ; any intermediates?
  10361.     jne    dgesc_E1        ; ne = yes, not this command
  10362.     jmp    dglf            ; do line feed
  10363. dgesc_E1:ret
  10364. dgesc_E    endp
  10365.  
  10366. dgesc_M    proc    near            ; DG ESC M reverse index
  10367.     cmp    ninter,0        ; any intermediates?
  10368.     jne    dgesc_M3        ; ne = yes, not this command
  10369.     test    anspflg,vtautop        ; printing desired?
  10370.     jz    dgesc_M1        ; e = no
  10371.     push    dx            ; save cursor
  10372.     call    pntlin            ; print line
  10373.     mov    al,LF            ; terminate in LF
  10374.     call    fpntchr
  10375.     call    fpntflsh        ; flush printer buffer
  10376.     mov    atwrap,0
  10377.     pop    dx
  10378. dgesc_M1:cmp    dh,mar_top        ; on top margin?
  10379.     ja    dgesc_M2        ; a = no
  10380.     cmp    dgroll,0        ; is roll disabled
  10381.     je    dgesc_M3        ; e = yes, do nothing
  10382.     push    dx
  10383.     mov    scroll,1
  10384.     call    atscrd            ; do a scroll down by one line
  10385.     pop    dx
  10386.     jmp    dgsetcur        ; set cursor, does show columns too
  10387.     
  10388. dgesc_M2:jmp    dgcuu            ; do cursor up
  10389. dgesc_M3:ret
  10390. dgesc_M    endp
  10391.  
  10392.  
  10393. dgesc_V    proc    near            ; DG ESC V start protected area
  10394.     cmp    ninter,0        ; any intermediates?
  10395.     jne    dgesc_V1        ; ne = yes, not this command
  10396.     call    setprot            ; protect on
  10397. dgesc_V1:ret
  10398. dgesc_V endp
  10399.  
  10400. dgesc_W    proc    near            ; DG ESC W end protected area
  10401.     cmp    ninter,0        ; any intermediates?
  10402.     jne    dgesc_W1        ; ne = yes, not this command
  10403.     call    clrprot            ; protect off
  10404. dgesc_W1:ret
  10405. dgesc_W endp
  10406.  
  10407. dgcsi_@    proc    near            ; DG CSI Pc @  ins chars, scroll left
  10408.     cmp    inter,' '        ; see if ends in space
  10409.     je    dgcsi_@1        ; e = yes
  10410.     mov    cx,param        ; do cx chars
  10411.     or    cx,cx            ; zero?
  10412.     jnz    dgcsi_@2        ; nz = no
  10413.     inc    cx            ; zero means one
  10414. dgcsi_@2:mov    bh,1            ; insert operation
  10415.     jmp    insdel            ; insert space
  10416. dgcsi_@1:mov    bx,offset dgsleft    ; scroll left
  10417.     jmp    dec2getn        ; convert param
  10418. dgcsi_@ endp
  10419.  
  10420. dgcsi_A    proc    near            ; DC CSI Pc A cursor up, scroll right
  10421.     cmp    inter,' '        ; see if ends in space
  10422.     je    dgcsi_A2        ; e = yes
  10423.     mov    cx,param        ; do cx chars
  10424.     or    cx,cx            ; zero?
  10425.     jnz    dgcsi_A1        ; nz = no
  10426.     inc    cx            ; do once
  10427. dgcsi_A1:push    cx
  10428.     call    dgcuu            ; cursor up
  10429.     pop    cx
  10430.     loop    dgcsi_A1
  10431.     ret
  10432. dgcsi_A2:mov    bx,offset dgsright    ; scroll left
  10433.     jmp    dec2getn        ; convert param
  10434. dgcsi_A endp
  10435.  
  10436. dgcsi_B    proc    near            ; DC CSI Pc B cursor down
  10437.     mov    cx,param        ; do cx chars
  10438.     or    cx,cx            ; zero?
  10439.     jnz    dgcsi_B1        ; nz = no
  10440.     inc    cx            ; do once
  10441. dgcsi_B1:push    cx
  10442.     call    dgcud            ; cursor down
  10443.     pop    cx
  10444.     loop    dgcsi_B1
  10445.     ret
  10446. dgcsi_B endp
  10447.  
  10448. dgcsi_C    proc    near            ; DC CSI Pc C cursor forward
  10449.     mov    cx,param        ; do cx chars
  10450.     or    cx,cx            ; zero?
  10451.     jnz    dgcsi_C1        ; nz = no
  10452.     inc    cx            ; do once
  10453. dgcsi_C1:push    cx
  10454.     call    dgcuf            ; cursor forward
  10455.     pop    cx
  10456.     loop    dgcsi_C1
  10457.     ret
  10458. dgcsi_C endp
  10459.  
  10460. dgcsi_D    proc    near            ; DC CSI Pc D cursor back
  10461.     mov    cx,param        ; do cx chars
  10462.     or    cx,cx            ; zero?
  10463.     jnz    dgcsi_D1        ; nz = no
  10464.     inc    cx            ; do once
  10465. dgcsi_D1:push    cx
  10466.     call    dgcub            ; cursor back
  10467.     pop    cx
  10468.     loop    dgcsi_D1
  10469.     ret
  10470. dgcsi_D endp
  10471.  
  10472. dgcsi_L    proc    near            ; DG CSI Pc L  insert Pc lines
  10473.     push    dx            ; save cursor
  10474.     call    inslin            ; do insert line, can scroll
  10475.     pop    dx            ; recover cursor
  10476.     jmp    atsetcur        ; reset cursor
  10477. dgcsi_L endp
  10478.  
  10479. dgcsi_M    proc    near            ; DG CSI Pc M  delete Pc lines
  10480.     push    dx            ; save cursor
  10481.     call    dellin            ; delete lines
  10482.     pop    dx
  10483.     jmp    atsetcur        ; reset cursor
  10484. dgcsi_M    endp
  10485.  
  10486. dgcsi_S    proc    near            ; DC CSI Pc S  scroll up
  10487.     mov    ax,param        ; scroll count
  10488.     or    al,al            ; zero?
  10489.     jnz    dgcsi_S1        ; nz = no
  10490.     inc    al
  10491. dgcsi_S1:mov    scroll,al        ; scroll amount
  10492.     call    atscru            ; scroll up
  10493.     ret
  10494. dgcsi_S    endp
  10495.  
  10496. dgcsi_T    proc    near            ; DC CSI Pc T  scroll down
  10497.     mov    ax,param        ; scroll count
  10498.     or    al,al            ; zero?
  10499.     jnz    dgcsi_T1        ; nz = no
  10500.     inc    al
  10501. dgcsi_T1:mov    scroll,al        ; scroll amount
  10502.     call    atscrd            ; scroll down
  10503.     ret
  10504. dgcsi_T    endp
  10505.  
  10506. dgcsi_f    proc    near            ; DG CSI row; col f
  10507.     mov    ax,param+2        ; get column
  10508.     or    al,al            ; zero now?
  10509.     jz    dgcsi_f1        ; z = yes
  10510.     dec    al            ; count from 0
  10511. dgcsi_f1:mov    emubuf,al        ; column
  10512.     mov    ax,param        ; get row
  10513.     or    al,al            ; zero now?
  10514.     jz    dgcsi_f2        ; z = yes
  10515.     dec    al            ; count from 0
  10516. dgcsi_f2:jmp    dgwwa2            ; do Control-P col row
  10517. dgcsi_f endp
  10518.  
  10519. dgcsi_h    proc    near            ; DG CSI Pc; Pc h  set mode
  10520.     mov    modeset,1        ; say setting modes
  10521.     cmp    lparam,'<'
  10522.     jne    dgcsi_h1
  10523.     mov    di,offset dgcsi_rsm    ; set/reset routine
  10524.     call    atreps            ; repeat for all parameters
  10525. dgcsi_h1:ret
  10526. dgcsi_h endp
  10527.  
  10528. dgcsi_i    proc    near            ; DG CSI Pc i  media copy
  10529.     cmp    lparam,'<'        ; CSI < 0 ?
  10530.     jne    dgcsi_i1        ; ne = no
  10531.     ret                ; ignore CSI <0
  10532. dgcsi_i1:mov    ax,param        ; get parameter
  10533.     cmp    ax,4            ; stop media copy?
  10534.     je    dgcsi_i2        ; e = yes
  10535.     cmp    ax,5            ; start media copy?
  10536.     je    dgcsi_i2        ; e = yes
  10537.     or    ax,ax            ; print window?
  10538.     je    dgcsi_i3        ; e = yes
  10539.     ret                ; ignore others
  10540. dgcsi_i2:jmp    ansmc            ; do 4, 5 as ANSI transparent print
  10541. dgcsi_i3:mov    al,':'            ; setup for window print
  10542.     jmp    dgprt6            ; print window
  10543. dgcsi_i    endp
  10544.  
  10545. dgcsi_sl proc    near            ; DG CSI Pc; Pc l  reset mode
  10546.     mov    modeset,0        ; say resetting modes
  10547.     cmp    lparam,'<'        ; this letter parameter?
  10548.     jne    dgcsi_sl1        ; ne = no
  10549.     mov    di,offset dgcsi_rsm    ; set/reset routine
  10550.     call    atreps            ; repeat for all parameters
  10551. dgcsi_sl1:
  10552.     ret
  10553. dgcsi_sl endp
  10554.  
  10555. ; Worker for set/reset routines. Invoke via atreps with modeset for set/reset
  10556. dgcsi_rsm proc    near
  10557.     mov    ax,param[si]        ; get parameter
  10558.     mov    ah,modeset        ; get set (1), reset (0) mode
  10559.     cmp    al,0            ; roll mode?
  10560.     jne    dgcsi_rsm1        ; ne = no
  10561.     mov    dgroll,ah        ; roll mode
  10562.     ret
  10563. dgcsi_rsm1:cmp    al,1            ; blink mode
  10564.     jne    dgcsi_rsm2        ; ne = no
  10565.     neg    ah            ; invert sense
  10566.     mov    blinkdis,ah        ; blink disable
  10567.     ret
  10568. dgcsi_rsm2:cmp    al,2            ; horizontal scroll?
  10569.     jne    dgcsi_rsm3        ; ne = no
  10570.     neg    ah            ; invert sense
  10571.     mov    dghscrdis,ah        ; horizontal scroll disable
  10572.     ret
  10573. dgcsi_rsm3:cmp    al,3            ; DG D470 ANSI mode?
  10574.     jne    dgcsi_rsm4        ; ne = no
  10575.     mov    dgd470mode,ah        ; set ANSI mode
  10576.     ret
  10577. dgcsi_rsm4:cmp    al,4            ; forms mode?
  10578.     jne    dgcsi_rsm5        ; ne = no
  10579.     ret
  10580. dgcsi_rsm5:cmp    al,5            ; margins mode?
  10581.     jne    dgcsi_rsm6
  10582.     ret
  10583. dgcsi_rsm6:ret
  10584. dgcsi_rsm endp
  10585.  
  10586. dgcsi_n    proc    near            ; DC CSI Pc n  device status report
  10587.     cmp    param,5            ; send ready report?
  10588.     jne    dgcsi_n1        ; ne = no
  10589.     mov    al,ESCAPE        ; response is Esc [ 0 n
  10590.     call    prtbout            ; meaning "ready"
  10591.     mov    al,'['
  10592.     call    prtbout
  10593.     mov    al,'0'
  10594.     call    prtbout
  10595.     mov    al,'n'
  10596.     call    prtbout
  10597.     ret
  10598. dgcsi_n1:cmp    param,6            ; cursor position report?
  10599.     jne    dgcsi_n2        ; ne = no
  10600.     mov    al,ESCAPE        ; response is ESC [ row; col R
  10601.     call    prtbout
  10602.     mov    al,'['
  10603.     call    prtbout
  10604.     mov    al,byte ptr cursor+1    ; get current row
  10605.     call    prtnout            ; output number as decimal ASCII
  10606.     mov    al,';'
  10607.     call    prtbout
  10608.     mov    al,byte ptr cursor    ; column
  10609.     call    prtnout
  10610.     mov    al,'R'
  10611.     call    prtbout
  10612. dgcsi_n2:ret
  10613. dgcsi_n    endp
  10614.  
  10615. dgcsi_sp proc    near            ; DG CSI..p  draw bar or arc
  10616.     cmp    inter,' '        ; ends on space?
  10617.     je    dgcsi_sp1        ; e = yes, do draw arc
  10618.     mov    bx,offset dggbar    ; draw bar
  10619.     jmp    dec2getn        ; convert params to <loc> form
  10620. dgcsi_sp1:mov    bx,offset dggarc    ; draw arc
  10621.     jmp    dec2getn        ; convert params to <loc> form
  10622. dgcsi_sp endp
  10623.  
  10624. dgcsi_q    proc    near            ; DG CSI Pc q  change attributes
  10625.     cmp    inter,' '        ; read graphics cursor signature?
  10626.     je    dgcsi_q1        ; e = yes
  10627.     mov    bx,offset dgchatr    ; change attributes routine
  10628.     jmp    dec2getn        ; convert args to DG <n> form
  10629. dgcsi_q1:                ; similar to RS G ? |
  10630. ifndef    no_graphics
  10631.     call    dgcrossrpt        ; do report via MSGIBM
  10632. endif    ; no_graphics
  10633.     ret
  10634. dgcsi_q    endp
  10635.  
  10636. dgcsi_r    proc    near            ; DG CSI <space> r  read cursor att
  10637.     mov    al,Escape        ; response similar to RS G @
  10638.     call    prtbout
  10639.     mov    al,'['
  10640.     call    prtbout
  10641.     mov    al,'0'            ; say crosshair is off
  10642.     test    dgcross,1        ; is it on?
  10643.     jz    dgcsi_r1        ; z = no
  10644.     inc    al            ; say '1' for on
  10645. dgcsi_r1:call    prtbout            ; output <v1>
  10646.     mov    al,';'
  10647.     call    prtbout
  10648.     mov    al,'0'            ; <v2> is always 0 for not blinking
  10649.     call    prtbout
  10650.     mov    al,';'
  10651.     call    prtbout
  10652.     mov    al,'0'            ; <v3> is 0 for short crosshair, D470
  10653.     call    prtbout
  10654.     mov    al,';'
  10655.     call    prtbout
  10656.     mov    al,dgcross        ; get tracked devices
  10657.     and    al,2+4            ; pick out just devices
  10658.     add    al,'0'            ; bias
  10659.     call    prtbout            ; output <v4>
  10660.     mov    al,'r'            ; terminal character
  10661.     call    prtbout
  10662.     ret
  10663. dgcsi_r    endp
  10664.  
  10665. dgcsi_ss proc    near            ; DG CSI Pc s read/reserve characters
  10666.     mov    ax,param        ; get parameter
  10667.     or    ax,ax            ; do report?
  10668.     jnz    dgcsi_ss2        ; nz = no, reserve (do nothing here)
  10669.     mov    al,ESCAPE        ; report is ESC [ <qty> s
  10670.     call    prtbout
  10671.     mov    al,'['
  10672.     call    prtbout
  10673.     mov    al,'2'            ; say <qty> is 2000
  10674.     call    prtbout
  10675.     mov    cx,3
  10676. dgcsi_ss1:push    cx
  10677.     mov    al,'0'
  10678.     call    prtbout
  10679.     pop    cx
  10680.     loop    dgcsi_ss1
  10681.     mov    al,'s'            ; terminator
  10682.     call    prtbout
  10683. dgcsi_ss2:ret
  10684. dgcsi_ss endp
  10685.  
  10686. dgcsi_st proc    near            ; DG CSI Pc t  read offset/show cols
  10687.     cmp    inter,' '        ; Write graphics cursor command?
  10688.     je    dgcsi_st3        ; e = yes
  10689.     cmp    param,0            ; read offset?
  10690.     jne    dgcsi_st1        ; ne = no
  10691.     mov    al,ESCAPE        ; response is Esc [ col t
  10692.     call    prtbout
  10693.     mov    al,'['
  10694.     call    prtbout
  10695.     mov    bl,dh            ; get current row
  10696.     xor    bh,bh
  10697.     mov    al,linescroll[bx]    ; get scroll value
  10698.     call    prtnout            ; output number as decimal ASCII
  10699.     mov    al,'t'
  10700.     call    prtbout
  10701.     ret
  10702. dgcsi_st1:cmp    param,1            ; show columns?
  10703.     jne    dgcsi_st2        ; ne = no
  10704.     mov    ax,param+2        ; remove initial param
  10705.     mov    param,ax
  10706.     mov    ax,param+4
  10707.     mov    param+2,ax
  10708.     mov    nparam,2        ; setup for call
  10709.     mov    bx,offset dgshcol    ; show columns, RS F _
  10710.     jmp    dec2getn        ; perform the routine
  10711. dgcsi_st2:ret
  10712.  
  10713. dgcsi_st3:mov    ax,param        ; x graphics coord
  10714.     mov    bx,param+2        ; y graphics coord
  10715. ifndef    no_graphics
  10716.     call    dgsetcrloc        ; set crosshairs to x,y
  10717. endif    ; no_graphics
  10718.     ret
  10719. dgcsi_st endp
  10720.  
  10721. dgcsi_u    proc    near            ; DG CSI Pc <space> u
  10722.     cmp    inter,' '        ; ends on space
  10723.     je    dgcsi_u1        ; e = yes, cursor off
  10724.     mov    inter,0
  10725.     mov    ninter,0        ; best to clear these
  10726.     jmp    dgcsi_f            ; it's cursor row, col
  10727. dgcsi_u1:jmp    dggcoff            ; do RS G C  graphics cursor off
  10728. dgcsi_u    endp
  10729.  
  10730. dgcsi_v    proc    near            ; DG CSI <space> v cursor on
  10731.     cmp    inter,' '        ; proper form?
  10732.     jne    dgcsi_v1        ; ne = no
  10733.     jmp    dggcon            ; do RS G B  graphics cursor on
  10734. dgcsi_v1:ret
  10735. dgcsi_v    endp
  10736.  
  10737. dgcsi_w    proc    near            ; DG CSI Pn; Pc w  set margins
  10738.     cmp    inter,' '        ; graphics cursor reset indicator?
  10739.     jne    dgcsi_w4        ; ne = no, must be margins
  10740. ifndef    no_graphics
  10741.     call    dgcrossoff        ; turn off crosshair
  10742. endif    ; no_graphics
  10743.     mov    dgcross,0        ; and no kind of tracking
  10744.     ret
  10745. dgcsi_w4:mov    bx,param        ; set margins
  10746.     mov    ax,param+2
  10747.     mov    param,ax
  10748.     mov    ax,param+4
  10749.     mov    param+2,ax        ; remove leading param
  10750.     mov    ax,param+6
  10751.     mov    param+4,ax
  10752.     dec    nparam            ; one less parameter
  10753.     cmp    bx,1            ; set margins?
  10754.     je    dgcsi_w1        ; e = 1 = yes, do draw arc
  10755.     ja    dgcsi_w2        ; a = 2 = set alt margins
  10756.     jmp    dgrnmar            ; 0 = restore normal margins
  10757. dgcsi_w1:mov    bx,offset dgsetmar    ; set margins
  10758.     jmp    dec2getn        ; convert params to <nn> form
  10759. dgcsi_w2:mov    bx,offset dgsetamar    ; set alt margins
  10760.     jmp    dec2getn        ; convert params to <nn> form
  10761. dgcsi_w endp
  10762.  
  10763. dgcsi_x    proc    near            ; DG CSI Pc x   cursor track
  10764.     cmp    inter,' '        ; proper form for cursor track?
  10765.     jne    dgcsi_x1        ; ne = no
  10766.     mov    ax,param        ; get arg
  10767.     and    al,2+4            ; pick out our trackables
  10768.     and    dgcross,not (2+4)    ; preserve on/of bit (1)
  10769.     or    dgcross,al        ; track keypad (2) and/or mouse (4)
  10770. dgcsi_x1:                ; like RS C  DG Read Model ID
  10771.     mov    al,escape        ; resp ESC [ <mm> <x> <y>
  10772.     call    prtbout
  10773.     mov    al,'['
  10774.     call    prtbout
  10775.     mov    al,'5'            ; 5 is DG D470 in ANSI mode
  10776.     call    prtbout
  10777.     mov    al,'4'            ; 4 is DG D470
  10778.     call    prtbout
  10779.     mov    al,';'
  10780.     call    prtbout
  10781.     mov    al,'0'            ; two bytes here
  10782.     call    prtbout
  10783.     mov    al,'0'
  10784.     test    flags.remflg,d8bit    ; using 8 bits?
  10785.     jz    dgcsi_x2        ; z = no
  10786.     or    al,2            ; say 8-bit mode
  10787. dgcsi_x2:push    ax
  10788.     mov    ah,ioctl        ; get printer status, via DOS
  10789.     mov    al,7            ; status for output
  10790.     push    bx
  10791.     mov    bx,4            ; std handle for system printer
  10792.     int    dos
  10793.     pop    bx
  10794.     jnc    dgcsi_x3        ; nc = call succeeded
  10795.     mov    al,0ffh
  10796. dgcsi_x3:cmp    al,0ffh            ; code for Ready
  10797.     pop    ax
  10798.     jne    dgcsi_x4        ; ne = not ready
  10799.     or    al,1            ; say printer present
  10800. dgcsi_x4:call    prtbout            ; send composite byte
  10801.     mov    al,';'
  10802.     call    prtbout
  10803.     mov    al,'0'            ; revision 0
  10804.     call    prtbout
  10805.     mov    al,';'
  10806.     call    prtbout
  10807.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  10808.     xor    bh,bh
  10809.     mov    al,nrcdgkbd[bx]        ; get DG keyboard code from table
  10810.     call    prtnout
  10811.     mov    al,'x'
  10812.     call    prtbout
  10813.     ret
  10814. dgcsi_x    endp
  10815.  
  10816. dgdcs_F    proc    near            ; DC DCS F ST  failure report
  10817.     mov    al,Escape        ; report DCS F ST for no failure
  10818.     call    prtbout
  10819.     mov    al,'P'
  10820.     call    prtbout
  10821.     mov    al,'F'
  10822.     call    prtbout
  10823.     mov    al,Escape
  10824.     call    prtbout
  10825.     mov    al,'\'
  10826.     call    prtbout
  10827.     jmp    atnorm
  10828. dgdcs_F    endp
  10829.  
  10830.         ; End of Data General specific routines
  10831.  
  10832.         ; Start Wyse-50 specific routines
  10833.  
  10834. wyenq    proc    near            ; Control E, ESC sp  inquire
  10835.     mov    al,'5'
  10836.     call    prtbout            ; send 5 0 CR
  10837.     mov    al,'0'
  10838.     call    prtbout
  10839.     mov    al,CR
  10840.     call    prtbout
  10841.     ret
  10842. wyenq    endp
  10843.  
  10844. wycub    proc    near            ; Control H  cursor left (back)
  10845.     sub    dl,1            ; column, one to the left
  10846.     jns    wycub1            ; ns = no wrap
  10847.     mov    dl,mar_right        ; wrap left to right
  10848.     sub    dh,1            ; up one row
  10849.     jns    wycub1            ; ns = no wrap
  10850.     mov    dh,mar_bot        ; wrap top to bottom
  10851. wycub1:    jmp    atsetcur        ; set cursor
  10852. wycub    endp
  10853.  
  10854. wycup    proc    near            ; Control K (VT) cursor up
  10855.     mov    dx,cursor
  10856.     sub    dh,1            ; compute new cursor position
  10857.     jnc    wycu1            ; nc = ok
  10858.     mov    dh,mar_bot        ; overflow, wrap to last line
  10859. wycu1:    jmp    atscur            ; set the cursor at its new position
  10860. wycup    endp
  10861.  
  10862. wysub    proc    near            ; Control Z  erase all unprotected
  10863.                     ; also ESC ; and ESC :
  10864.     mov    dl,mar_left        ; upper left corner
  10865.     mov    dh,mar_top
  10866.     call    erprot            ; do protected erasure
  10867.     jmp    short wyhome        ; home the cursor
  10868. wysub    endp
  10869.  
  10870. wyhome    proc    near            ; Control ^  cursor home
  10871.     mov    dl,mar_left        ; upper left corner
  10872.     mov    dh,mar_top
  10873.     jmp    atscur            ; set cursor
  10874. wyhome    endp
  10875.  
  10876. wyprtoff proc    near            ; Autoprint off
  10877.     test    anspflg,vtautop        ; check state of print flag
  10878.     jz    wyprtof1        ; z = off already
  10879.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  10880.     call    ftrnprs            ; toggle mode line PRN indicator
  10881.     and    anspflg,not (vtautop + vtcntp) ; clear all printing kinds
  10882. wyprtof1:ret
  10883. wyprtoff endp
  10884.  
  10885. wyprton    proc    near            ; Autoprint on
  10886.     test    anspflg,vtautop        ; is print already enabled?
  10887.     jnz    wyprton1        ; nz = yes, leave trnprs intact
  10888.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  10889.     call    ftrnprs            ; toggle on mode line PRN indicator
  10890. wyprton1:ret
  10891. wyprton    endp
  10892.  
  10893. wyesc    proc    near            ; ESC processor, enter when ESC seen
  10894.     mov    ttstate,offset wyesc1    ; come here for next char
  10895.     ret
  10896. wyesc1:    mov    param,0
  10897.     mov    param+2,0
  10898.     mov    lparam,0
  10899.     mov    bx,offset wyescf    ; dispatch table
  10900.     mov    ttstate,offset atnrm    ; reset state
  10901.     jmp    atdispat        ; dispatch on char in AL
  10902. wyesc    endp
  10903.  
  10904. wytab0    proc    near            ; ESC 0
  10905.     mov    param,3            ; clear all tab stops
  10906.     jmp    attbc            ; do it
  10907. wytab0    endp
  10908.  
  10909. wytab2    proc    near            ; ESC 2
  10910.     mov    param,0            ; clear this tab stop
  10911.     jmp    attbc            ; do it
  10912. wytab2    endp
  10913.  
  10914. wy_bang    proc    near            ; ESC ! attrib, set attribute on all
  10915.     mov    ttstate,offset wy_ban1    ;  unprotected chars, clear chars
  10916.     mov    emubuf,0        ; say ESC ! rather than ESC A 0
  10917.     ret
  10918. wy_ban1:xor    dx,dx            ; home position
  10919.     mov    ttstate,offset atnrm    ; reset state
  10920.     mov    bl,al            ; save argument
  10921.     mov    ah,scbattr        ; normal background
  10922.     mov    curattr,ah        ; current attributes, update
  10923.     mov    extattr,0        ; clear extended attributes
  10924.     test    bl,2            ; set blink?
  10925.     jz    wy_ban2            ; z = no
  10926.     test    bl,1            ; and blank?
  10927.     jnz    wy_ban2            ; nz = yes, ignore blink
  10928.     call    setblink
  10929. wy_ban2:test    bl,4            ; set reverse video bit?
  10930.     jz    wy_ban3            ; z = no
  10931.     call    setrev
  10932. wy_ban3:test    bl,8            ; set underscore?
  10933.     jz    wy_ban4            ; z = no
  10934.     call    setunder
  10935. wy_ban4:test    bl,40h            ; dim?
  10936.     jz    wy_ban5            ; z = no
  10937.     call    setbold
  10938. wy_ban5:mov    curattr,ah        ; new attributes
  10939.     mov    extattr,cl
  10940.     mov    al,mar_right
  10941.     sub    al,mar_left
  10942.     inc    al            ; width
  10943.     mov    cl,mar_bot
  10944.     sub    cl,mar_top
  10945.     inc    cl            ; rows
  10946.     mul    cl
  10947.     mov    cx,ax            ; number of character cells to do
  10948.     xor    dx,dx            ; home position
  10949. wy_ban6:push    cx            ; save loop counter
  10950.     call    getatch            ; get video in ah, extended att in cl
  10951.     test    cl,att_protect        ; protected?
  10952.     jnz    wy_ban7            ; nz = yes, skip it
  10953.     mov    cl,extattr
  10954.     mov    ah,curattr
  10955.     cmp    emubuf,0        ; erase char?
  10956.     jne    wy_ban6a        ; ne = no
  10957.     mov    al,' '            ; cleared character
  10958. wy_ban6a:call    qsetatch        ; quietly update the char
  10959. wy_ban7:pop    cx
  10960.     inc    dl            ; next column
  10961.     cmp    dl,mar_right        ; at the right margin?
  10962.     jbe    wy_ban8            ; be = no, not yet
  10963.     mov    dl,mar_left        ; wrap to left and next line
  10964.     inc    dh            ; next line down
  10965.     cmp    dh,mar_bot        ; below the window bottom?
  10966.     ja    wy_ban9            ; a = yes, all done
  10967. wy_ban8:loop    wy_ban6            ; do more chars
  10968. wy_ban9:call    frepaint        ; repaint screen
  10969.     xor    dx,dx            ; home cursor
  10970.     cmp    emubuf,0        ; erase char?
  10971.     je    wy_ban10        ; e = yes
  10972.     mov    dx,cursor        ; else replace cursor
  10973. wy_ban10:jmp    atsetcur        ; restore cursor
  10974. wy_bang    endp
  10975.  
  10976. wy_dot    proc    near            ; ESC . CODE   clr unprotected chars
  10977.     mov    ttstate,offset wy_dot1    ;  of value code
  10978.     ret
  10979. wy_dot1:mov    ttstate,offset atnrm    ; reset state
  10980.     mov    emubuf,al        ; save char code
  10981.     mov    al,mar_right
  10982.     sub    al,mar_left
  10983.     inc    al            ; width
  10984.     mov    cl,mar_bot
  10985.     sub    cl,mar_top
  10986.     inc    cl            ; rows
  10987.     mul    cl
  10988.     mov    cx,ax            ; number of character cells to do
  10989. wy_dot2:push    cx            ; save loop counter
  10990.     call    getatch            ; get video in ah, extended att in cl
  10991.     test    cl,att_protect        ; protected?
  10992.     jnz    wy_dot3            ; nz = yes, skip it
  10993.     cmp    al,emubuf        ; same as code?
  10994.     jne    wy_dot3            ; ne = no
  10995.     mov    al,' '            ; char
  10996.     mov    ah,scbattr        ; normal background
  10997.     xor    cl,cl            ; clear extended attributes
  10998.     call    qsetatch        ; quietly update the char
  10999. wy_dot3:pop    cx
  11000.     inc    dl            ; next column
  11001.     cmp    dl,mar_right        ; at the right margin?
  11002.     jbe    wy_dot4            ; be = no, not yet
  11003.     mov    dl,mar_left        ; wrap to left and next line
  11004.     inc    dh            ; next line down
  11005.     cmp    dh,mar_bot        ; below the window bottom?
  11006.     ja    wy_dot5            ; a = yes, all done
  11007. wy_dot4:loop    wy_dot2            ; do more chars
  11008. wy_dot5:call    frepaint        ; repaint screen
  11009.     mov    dx,cursor        ; reset cursor location
  11010.     ret
  11011. wy_dot    endp
  11012.  
  11013. wy_8    proc    near            ; ESC 8 enter STX (2) code
  11014.     mov    al,2
  11015.     jmp    atnrm
  11016. wy_8    endp
  11017.  
  11018. wy_9    proc    near            ; ESC 9 enter ETX (3) code
  11019.     mov    al,3
  11020.     jmp    atnrm
  11021. wy_9    endp
  11022.  
  11023. wy_slash proc    near            ; ESC /  send txt seg and cursor
  11024.     mov    al,'0'            ; text segment 0
  11025.     call    prtbout            ; send
  11026.     jmp    wy_query        ; send cursor position
  11027. wy_slash endp
  11028.  
  11029. wy_query proc    near            ; ESC ?  send rc CR cursor report
  11030.     mov    al,byte ptr cursor+1    ; row
  11031.     add    al,20h            ; plus bias
  11032.     call    prtbout
  11033.     mov    al,byte ptr cursor    ; column
  11034.     add    al,20h
  11035.     call    prtbout
  11036.     mov    al,CR            ; terminator
  11037.     call    prtbout
  11038.     ret
  11039. wy_query endp
  11040.  
  11041. wy_sa    proc    near            ; ESC a rr R ccc C  cursor to row,col
  11042.     mov    ttstate,offset wy_sa1    ; get first row char
  11043.     ret
  11044. wy_sa1:    cmp    al,'R'            ; field termination?
  11045.     je    wy_sa2            ; yes
  11046.     push    ax
  11047.     mov    ax,param        ; ASCII decimal to binary
  11048.     mov    cx,10
  11049.     imul    cx
  11050.     mov    param,ax
  11051.     pop    ax
  11052.     sub    al,'0'            ; ccc, decimal col
  11053.     cbw
  11054.     add    param,ax
  11055.     ret                ; stay in this state
  11056. wy_sa2:    mov    lparam,al        ; save it
  11057.     mov    ttstate,offset wy_sa3    ; get column
  11058.     ret
  11059. wy_sa3:    cmp    al,'C'            ; field termination?
  11060.     je    wy_sa4            ; e = yes
  11061.     push    ax
  11062.     mov    ax,param+2        ; ASCII decimal to binary
  11063.     mov    cx,10
  11064.     imul    cx
  11065.     mov    param+2,ax
  11066.     pop    ax
  11067.     sub    al,'0'            ; ccc, decimal col
  11068.     cbw
  11069.     add    param+2,ax
  11070.      ret                ; stay in this state
  11071. wy_sa4:    mov    ttstate,offset atnrm
  11072.     xor    ah,ah
  11073.     xchg    ah,lparam        ; get the 'R', clear lparam
  11074.     cmp    ax,'RC'            ; proper terminators?
  11075.     jne    wy_sax            ; ne = no
  11076.     xor    ax,ax
  11077.     xor    bx,bx
  11078.     xchg    ax,param        ; row
  11079.     xchg    bx,param+2        ; column
  11080.     or    ax,ax            ; zero now?
  11081.     jz    wy_sa5            ; z = yes
  11082.     dec    ax            ; count row from zero
  11083. wy_sa5:    or    bx,bx            ; zero now?
  11084.     jz    wy_sa6            ; z = yes
  11085.     dec    bx            ; count column from zero
  11086. wy_sa6:    cmp    ax,24            ; row, in bounds?
  11087.     ja    wy_sax            ; a = no
  11088.     cmp    bx,132            ; column, in bounds?
  11089.     ja    wy_sax            ; a = no
  11090.     mov    dh,al            ; row
  11091.     mov    dl,bl            ; column
  11092.     jmp    atscur            ; set cursor
  11093. wy_sax:    mov    param,0
  11094.     mov    param+2,0        ; clear temps
  11095.     ret                ; ignore command
  11096. wy_sa    endp
  11097.  
  11098. wy_equ    proc    near            ; ESC = r c  cursor to row, col
  11099.     mov    ttstate,offset wy_equ1    ; get row char
  11100.     ret
  11101. wy_equ1:sub    al,' '-1        ; remove ASCII bias
  11102.     cbw                ; grab sign
  11103.     mov    param,ax        ; save as row
  11104.     mov    ttstate,offset wy_equ2
  11105.     ret
  11106. wy_equ2:sub    al,' '-1        ; remove ASCII bias
  11107.     cbw
  11108.     mov    param+2,ax        ; save as column
  11109.     mov    lparam,'R'        ; setup R..C form
  11110.     mov    al,'C'
  11111.     jmp    wy_sa4            ; parse completion as ESC a rr R ccc C
  11112. wy_equ    endp
  11113.  
  11114. wy_minus proc    near            ; ESC - nrc  cursor to txt seg row col
  11115.     and    al,1            ; n can be anything (despite manual)
  11116.     mov    ttstate,offset wy_equ    ; parse rest as if ESC = r c
  11117.     ret
  11118. wy_minus endp
  11119.  
  11120. wy_star    proc    near            ; ESC *   ESC + 
  11121.                     ; protect mode off, clear screen
  11122.     mov    protectena,0        ; disable protect mode
  11123.     xor    dx,dx            ; set cursor to home
  11124.     mov    cursor,dx
  11125.     jmp    ereos            ; clear entire screen
  11126. wy_star    endp
  11127.  
  11128. wy_comma proc    near            ; ESC ,  screen clear to prot'd spaces
  11129.     mov    protectena,0        ; disable protect mode
  11130.     xor    dx,dx            ; set cursor to home
  11131.     mov    cursor,dx
  11132.     mov    ah,scbattr        ; normal background
  11133.     mov    al,' '            ; space
  11134.     mov    cl,att_protect        ; set protection bit
  11135. wy_comm1:call    setatch            ; write cell
  11136.     inc    dl            ; next column
  11137.     cmp    dl,mar_right        ; beyond right edge?
  11138.     jbe    wy_comm1        ; be = no
  11139.     xor    dl,dl            ; left edge
  11140.     inc    dh            ; next row
  11141.     cmp    dh,mar_bot        ; below bottom?
  11142.     jbe    wy_comm1        ; be = no
  11143.     xor    dx,dx            ; top left corner
  11144.     jmp    atsetcur        ; set cursor
  11145. wy_comma endp
  11146.  
  11147. wy_A    proc    near            ; ESC A n attrib  set video attribs
  11148.     mov    ttstate,offset wy_A1    ; get field code n
  11149.     ret
  11150. wy_A1:    cmp    al,'0'            ; entire text display?
  11151.     jne    wy_A2            ; ne = no, ignore after getting attrib
  11152.     mov    emubuf,1        ; flag to wy_bang to not erase chars
  11153.     mov    ttstate,offset wy_ban1    ; process attrib in ESC ! procedure
  11154.     ret
  11155. wy_A2:    mov    ttstate,offset atnorm    ; ignore next byte, exit command
  11156.     ret
  11157. wy_A    endp
  11158.  
  11159. wy_F    proc    near            ; ESC F text CR, to message area
  11160.     mov    ttstate,offset wy_F1
  11161.     ret
  11162. wy_F1:    cmp    al,CR            ; end of string?
  11163.     jne    wy_F2            ; ne = no, continue discarding bytes
  11164.     mov    ttstate,offset atnrm    ; reset state
  11165. wy_F2:    ret
  11166. wy_F    endp
  11167.  
  11168. wy_G    proc    near            ; ESC G n  set char attributes
  11169.     mov    ttstate,offset wy_G1    ; get attribute code
  11170.     ret
  11171. wy_G1:    mov    ttstate,offset atnrm    ; reset state
  11172.     mov    ah,curattr        ; current attributes
  11173.     mov    bl,al            ; get code
  11174.     cmp    bl,' '            ; space code?
  11175.     je    wy_Gx            ; e = yes, just ignore it
  11176.     cmp    bl,'0'            ; range check for '0' et seq
  11177.     jb    wy_Gx            ; b = out of range
  11178.     ja    wy_G2            ; a = in range
  11179.     call    clrbold            ; clear bold attribute
  11180.     call    clrblink        ; clear blink attribute
  11181.     call    clrrev            ; clear reverse video attribute
  11182.     call    clrunder        ; clear underline attribute
  11183.     mov    atinvisible,0        ; clear invisible attribute
  11184.     mov    extattr,0        ; clear extended attributes
  11185.     jmp    short wy_Gx
  11186.  
  11187. wy_G2:    test    bl,2            ; set blink?
  11188.     jz    wy_G3            ; z = no
  11189.     test    bl,1            ; and blank?
  11190.     jnz    wy_G3            ; nz = yes, ignore blink
  11191.     push    bx
  11192.     call    setblink        ; set blink
  11193.     pop    bx
  11194. wy_G3:    test    bl,4            ; set reverse video bit?
  11195.     jz    wy_G4            ; z = no
  11196.     push    bx
  11197.     call    setrev            ; set reverse video
  11198.     pop    bx
  11199. wy_G4:    test    bl,8            ; set underscore?
  11200.     jz    wy_G5            ; z = no
  11201.     push    bx
  11202.     call    setunder        ; set underline
  11203.     pop    bx
  11204. wy_G5:    cmp    bl,'p'            ; dim?
  11205.     jb    wy_Gx            ; b = no
  11206.     call    clrbold            ; set dim
  11207. wy_Gx:    mov    curattr,ah        ; store new attribute byte
  11208. ;;;;;    mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attributes
  11209. ;;;;;    mov    byte ptr wyse_protattr+1,att_protect
  11210.     mov    dx,cursor        ; moves cursor left one column
  11211.     inc    dl
  11212.     jmp    atscur
  11213. wy_G    endp
  11214.  
  11215. wy_H    proc    near            ; ESC H x  show graphics char
  11216.     mov    ttstate,offset wy_H1    ; setup to read x
  11217.     ret
  11218. wy_H1:    mov    ttstate,offset atnrm    ; reset state
  11219.     cmp    al,2            ; STX (^B) enter graphics mode?
  11220.     jne    wy_H2            ; ne = no
  11221.     jmp    atls1            ; do LS1 to get graphics set
  11222.  
  11223. wy_H2:    cmp    al,3            ; ETX (^C) exit graphics mode?
  11224.     jne    wy_H3            ; ne = no
  11225.     jmp    atls0            ; do LS0 to exit graphics mode
  11226.  
  11227. wy_H3:    mov    SSptr,offset G1set    ; set Single Shift to G1 for graphics
  11228.     jmp    atnrm            ; show code
  11229. wy_Hx:    ret
  11230. wy_H    endp
  11231.  
  11232. wy_I    proc    near            ; ESC I  cursor back to previous tab
  11233.     xor    ch,ch
  11234.     cmp    cl,dl            ; cursor column
  11235.     jcxz    wy_I3            ; z = at left margin
  11236. wy_I1:    dec    dl            ; tab always moves at least one column
  11237.     push    si
  11238.     mov    si,vtemu.vttbst        ; active buffer
  11239.     call    istabs            ; returns carry set if at a tabstop
  11240.     pop    si
  11241.     jc    wy_I2            ; c = at a tabstop
  11242.     loop    wy_i1
  11243. wy_I2:    call    dgsetcur        ; set cursor and return
  11244. wy_I3:    ret
  11245. wy_I    endp
  11246.  
  11247. wy_N    proc    near            ; ESC N  turn on no-scroll mode
  11248.     mov    wyse_scroll,1
  11249.     ret
  11250. wy_N    endp
  11251.  
  11252. wy_O    proc    near            ; ESC O  turn off no-scroll mode
  11253.     mov    wyse_scroll,0
  11254.     ret
  11255. wy_O    endp
  11256.  
  11257. wy_R    proc    near            ; ESC R  delete line
  11258.     call    dellin
  11259.     xor    dl,dl            ; cursor to left margin
  11260.     jmp    atsetcur        ; set cursor
  11261. wy_R    endp
  11262.  
  11263. wy_V    proc    near            ; ESC V  mark column as protected
  11264.     push    cursor            ; remember starting cursor
  11265.     mov    dh,mar_top        ; start with this row
  11266.     mov    cl,mar_bot
  11267.     sub    cl,mar_top
  11268.     inc    cl
  11269.     xor    ch,ch            ; count of rows to touch
  11270.     call    direction        ; set column in dl
  11271. wy_V1:    push    cx
  11272.     call    getatch            ; get char to al, attrib to ah,cl
  11273.     or    cl,att_protect        ; set protected attribute
  11274.     call    qsetatch        ; quite writeback
  11275.     pop    cx
  11276.     inc    dh            ; next row
  11277.     loop    wy_V1
  11278.     pop    cursor
  11279.     mov    dx,cursor
  11280.     jmp    atsetcur        ; set cursor, just in case
  11281. wy_V    endp
  11282.  
  11283. wy_acc    proc    near            ; ESC ` n  set screen features
  11284.     mov    ttstate,offset wy_acc1    ; setup to read "n"
  11285.     ret
  11286. wy_acc1:mov    ttstate,offset atnrm    ; reset state
  11287.     cmp    al,'0'            ; 0, cursor off?
  11288.     jne    wy_acc2            ; ne = no
  11289.     mov    al,4            ; set cursor off code
  11290.     jmp    wy_acc7
  11291. wy_acc2:cmp    al,'1'            ; 1, cursor on?
  11292.     jne    wy_acc3            ; ne = no
  11293.     mov    al,atctype        ; get cursor type
  11294.     jmp    wy_acc7
  11295.     ret
  11296. wy_acc3:cmp    al,'2'            ; 2, block cursor?
  11297.     je    wy_acc4            ; e = yes
  11298.     cmp    al,'5'            ; blinking block?
  11299.     jne    wy_acc5            ; ne = no
  11300. wy_acc4:mov    al,2            ; block cursor code
  11301.     jmp    wy_acc7
  11302. wy_acc5:cmp    al,'3'            ; 3, blinking line?
  11303.     je    wy_acc6            ; e = yes
  11304.     cmp    al,'4'            ; 4, steady line?
  11305.     jne    wy_acc8            ; ne = no
  11306. wy_acc6:mov    al,1            ; line code
  11307. wy_acc7:call    atsctyp            ; set cursor type, remember it
  11308.     ret
  11309.  
  11310. wy_acc8:cmp    al,'A'            ; normal protected char?
  11311.     jne    wy_acc9            ; ne = no
  11312.     mov    cl,extattr        ; running extended attribute
  11313.     push    cx
  11314.     mov    ah,curattr        ; current attribute
  11315.     call    getblink        ; save blinking attribute
  11316.     mov    al,ah            ;  to al
  11317.     mov    ah,scbattr        ; normal attribute
  11318.     or    ah,al            ;  include blinking
  11319.     or    cl,att_protect        ; set protected extended attrib
  11320.     and    cl,not att_uline+att_rev
  11321.     mov    extattr,cl
  11322.     call    setbold            ; set bold
  11323.     mov    byte ptr wyse_protattr,ah ; store attribute to write
  11324.     mov    byte ptr wyse_protattr+1,cl
  11325.     call    wy_setp            ; set attributes on protected chars
  11326.     pop    cx
  11327.     mov    extattr,cl        ; restore extended attribute
  11328.     ret
  11329.  
  11330. wy_acc9:cmp    al,'6'            ; reverse protected char?
  11331.     jne    wy_acc10        ; ne = no
  11332.     mov    cl,extattr        ; running extended attribute
  11333.     push    cx
  11334.     mov    ah,curattr        ; current attribute
  11335.     call    getblink        ; save blinking attribute
  11336.     mov    al,ah            ;  to al
  11337.     mov    ah,scbattr        ; normal attribute
  11338.     or    ah,al            ;  include blinking
  11339.     or    cl,att_protect        ; set protected extended attrib
  11340.     and    cl,not att_uline+att_rev
  11341.     mov    extattr,cl
  11342.     call    clrbold            ; clear bold (set dim)
  11343.     call    setrev            ; set reverse
  11344.     mov    byte ptr wyse_protattr,ah ; store attribute to write
  11345.     mov    byte ptr wyse_protattr+1,cl
  11346.     call    wy_setp            ; set attributes on protected chars
  11347.     pop    cx
  11348.     mov    extattr,cl        ; restore extended attribute
  11349.     ret
  11350.  
  11351. wy_acc10:cmp    al,'7'            ; dim protected char?
  11352.     jne    wy_acc11        ; ne = no
  11353.     mov    cl,extattr        ; running extended attribute
  11354.     push    cx
  11355.     mov    ah,curattr        ; current attribute
  11356.     call    getblink        ; save blinking attribute
  11357.     mov    al,ah            ;  to al
  11358.     mov    ah,scbattr        ; normal attribute
  11359.     or    ah,al            ;  include blinking
  11360.     or    cl,att_protect        ; set protected extended attrib
  11361.     and    cl,not att_uline+att_rev
  11362.     mov    extattr,cl
  11363.     call    clrbold            ; set dim
  11364.     mov    byte ptr wyse_protattr,ah ; store attribute to write
  11365.     mov    byte ptr wyse_protattr+1,cl
  11366.     call    wy_setp            ; set attributes on protected chars
  11367.     pop    cx
  11368.     mov    extattr,cl        ; restore extended attribute
  11369.     ret
  11370.  
  11371. wy_acc11:cmp    al,':'            ; set 80 columns?
  11372.     jne    wy_acc12
  11373.     mov    al,3            ; arg for columns set/reset
  11374.     mov    modeset,0        ; reset condition
  11375.     jmp    atrsm6
  11376.  
  11377. wy_acc12:cmp    al,';'            ; set 132 columns?
  11378.     jne    wy_acc14        ; ne = no
  11379.     mov    al,3            ; arg for columns
  11380.     mov    modeset,1        ; set condition
  11381.     jmp    atrsm6            ; do set/reset operation
  11382. wy_acc14:ret
  11383. wy_acc    endp
  11384.  
  11385. ; worker for wy_acc. Set attributes of all protected characters. New
  11386. ; attributes are in word wyse_protattr.
  11387. wy_setp    proc    near            ; set protected char attributes
  11388.     push    cursor            ; remember starting cursor
  11389.     mov    dh,mar_top        ; start with this row
  11390.     mov    cl,mar_bot
  11391.     sub    cl,mar_top
  11392.     inc    cl
  11393.     xor    ch,ch            ; count of rows to touch
  11394.     xor    dl,dl            ; left physical column
  11395. wy_setp1:push    cx
  11396.     call    getatch            ; get char to al, attrib to ah,cl
  11397.     test    cl,ATT_PROTECT        ; protected?
  11398.     jz    wy_setp2        ; z = no, do nothing
  11399.     mov    ah,byte ptr wyse_protattr ; "normal" attributes
  11400.     mov    cl,byte ptr wyse_protattr+1 ; extended, set protected
  11401.     call    setatch            ; visible writeback
  11402. wy_setp2:pop    cx
  11403.     inc    dl
  11404.     cmp    dl,mar_right        ; at right margin?
  11405.     jb    wy_setp1        ; b = no, more on this row
  11406.     xor    dl,dl            ; left column
  11407.     inc    dh            ; next row
  11408.     loop    wy_setp1
  11409.     pop    cursor
  11410.     mov    dx,cursor
  11411.     jmp    atsetcur        ; set cursor, just in case
  11412. wy_setp    endp
  11413.  
  11414.  
  11415. wy_M    proc    near            ; ESC M  send to host char at cursor
  11416.     call    getatch            ; get char to al
  11417.     call    prtbout            ; send, no echo
  11418.     ret
  11419. wy_M    endp
  11420.  
  11421. wy_b    proc    near            ; ESC b send cursor address to host
  11422.     mov    al,'0'            ; three digits
  11423.     call    prtbout
  11424.     mov    al,byte ptr cursor+1    ; get row
  11425.     inc    al            ; count from 1
  11426.     cmp    al,10
  11427.     jae    wy_b1            ; ae = have two digits
  11428.     push    ax
  11429.     mov    al,'0'            ; second leadin
  11430.     call    prtbout
  11431.     pop    ax
  11432. wy_b1:    call    prtnout            ; decimal ASCII
  11433.     mov    al,'R'            ; report rr R ccc C
  11434.     call    prtbout
  11435.     mov    al,byte ptr cursor    ; column
  11436.     inc    al            ; count from 1
  11437.     cmp    al,100            ; three digits again
  11438.     jae    wy_b2
  11439.     push    ax
  11440.     mov    al,'0'
  11441.     call    prtbout
  11442.     pop    ax
  11443.     cmp    al,10
  11444.     jae    wy_b2
  11445.     push    ax
  11446.     mov    al,'0'
  11447.     call    prtbout
  11448.     pop    ax
  11449. wy_b2:    call    prtnout
  11450.     mov    al,'C'            ; terminator
  11451.     call    prtbout
  11452.     ret
  11453. wy_b    endp
  11454.  
  11455. wy_d    proc    near            ; ESC d #, transparent print on
  11456.     mov    ttstate,offset wy_d1    ; get sharp sign
  11457.     ret
  11458. wy_d1:    cmp    al,'#'            ; proper terminator?
  11459.     je    wy_d2            ; e = yes
  11460.     jmp    atnorm            ; reset state
  11461.  
  11462. wy_d2:    mov    ttstate,offset wy_d3    ; do transparent printing (Control-X)
  11463.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  11464.     call    ftrnprs            ; toggle mode line PRN indicator
  11465.     jc    wy_d2a            ; c = printer failure
  11466.     or    anspflg,vtcntp        ; controller printing is on
  11467. wy_d2a:    ret
  11468.  
  11469. wy_d3:    cmp    al,'T'-40h        ; Control-T to end printing?
  11470.     je    wy_d4            ; e = yes
  11471.     call    fpntchr            ; print char in al, ignore errors
  11472.     ret
  11473.  
  11474. wy_d4:    mov    ttstate,offset atnrm    ; return to normal state
  11475.     call    fpntflsh        ; flush printer buffer
  11476.     test    anspflg,vtcntp        ; was printing active?
  11477.     jz    wy_d5            ; z = no
  11478.     and    anspflg,not vtcntp    ; yes, disable print controller
  11479.     call    ftrnprs            ; toggle mode line PRN indicator
  11480.     and    anspflg,not (vtautop + vtcntp) ; clear all printing kinds
  11481. wy_d5:    ret
  11482. wy_d    endp
  11483.  
  11484. wy_q    proc    near            ; ESC q   turn on insert mode
  11485.     mov    insmod,1
  11486.     ret
  11487. wy_q    endp
  11488.  
  11489. wy_sr    proc    near            ; ESC r  turn off insert mode
  11490.     mov    insmod,0
  11491.     ret
  11492. wy_sr    endp
  11493.  
  11494. wy_x    proc    near            ; ESC x n HSR  change display format
  11495.     mov    ttstate,offset wy_x1    ; get argument n (0, 1)
  11496.     ret
  11497. wy_x1:    cmp    al,'1'            ; 1, split screen?
  11498.     jne    wy_x2            ; ne = no
  11499.     mov    ttstate,offset wy_x2    ; get HSR screen split code
  11500.     ret
  11501. wy_x2:    
  11502.     mov    ttstate,offset atnrm    ; reset state
  11503.     ret
  11504. wy_x    endp
  11505.  
  11506. wy_z    proc    near            ; ESC z n aaaa CR  set msg to place
  11507.     mov    ttstate,offset wy_z1    ; get argument n
  11508.     ret
  11509. wy_z1:    cmp    al,CR            ; terminator?
  11510.     je    wy_z2            ; e = yes
  11511.     cmp    al,DEL            ; or shift terminator?
  11512.     je    wy_z2            ; e = yes
  11513.     ret                ; continue to consume bytes
  11514. wy_z2:    jmp    atnorm            ; reset state, return
  11515. wy_z    endp
  11516.  
  11517.     ; Wyse-50 end
  11518.  
  11519. ; Display "LEDs" routine. yflags from MSYIBM is needed to know if the mode
  11520. ; line is enabled. Display current state of "LEDs" on line 25.
  11521. ansdsl    proc    near            ; display "LEDs"
  11522.     test    yflags,modoff        ; mode line off?
  11523.     jnz    ansdsl2            ; nz = yes, just return
  11524.     cmp    flags.modflg,1        ; mode line on and owned by us?
  11525.     jne    ansdsl2            ; ne = no, leave it intact
  11526.     mov    cx,10            ; length of the array
  11527.     call    getled            ; set si to string, c set if no leds
  11528.     push    es
  11529.     mov    di,ds
  11530.     mov    es,di
  11531.     mov    di,led_col+offset modbuf ; mode line buffer, our position
  11532.     cld
  11533.     rep    movsb
  11534.     pop    es
  11535. ansdsl2:ret
  11536. ansdsl    endp
  11537.  
  11538. ; Return pointer to "led" display in si, set carry if terminal type does
  11539. ; not have leds 1..4.
  11540. getled    proc    near
  11541.     mov    ax,flags.vtflg        ; terminal type
  11542.     mov    si,offset v320leds    ; VT320 ident
  11543.     cmp    ax,ttvt320        ; VT320?
  11544.     je    getled2            ; e = yes
  11545.     mov    si,offset v220leds    ; VT220 ident
  11546.     cmp    ax,ttvt220        ; VT220?
  11547.     je    getled2            ; e = yes
  11548.     mov    si,offset v102leds    ; VT102 ident
  11549.     cmp    ax,ttvt102        ; VT102 mode?
  11550.     je    getled2            ; e = yes
  11551.     mov    si,offset v100leds
  11552.     cmp    ax,ttvt100        ; VT100?
  11553.     je    getled2            ; e = yes
  11554.     mov    si,offset honeyleds
  11555.     cmp    ax,tthoney        ; Honeywell?
  11556.     je    getled2            ; e = yes
  11557.     mov    si,offset ansileds
  11558.     cmp    ax,ttansi        ; ANSI-BBS?
  11559.     je    getled2            ; e = yes
  11560.     mov    si,offset v52leds    ; VT52 ident
  11561.     cmp    ax,ttvt52        ; VT52?
  11562.     je    getled1            ; e = yes, no leds
  11563.     mov    si,offset pt20leds
  11564.     cmp    ax,ttpt200        ; Prime PT200?
  11565.     je    getled2            ; e = yes
  11566.     mov    si,offset d217leds
  11567.     cmp    ax,ttd217        ; DG D217?
  11568.     je    getled1            ; e = yes, but no led dots
  11569.     mov    si,offset d463leds
  11570.     cmp    ax,ttd463        ; DG D463?
  11571.     je    getled1            ; e = yes, but no led dots
  11572.     mov    si,offset d470leds
  11573.     cmp    ax,ttd470        ; DG D470?
  11574.     je    getled1            ; e = yes, but no led dots
  11575.     mov    si,offset wyseleds
  11576.     cmp    ax,ttwyse        ; Wyse-50?
  11577.     je    getled1            ; e = yes
  11578.     mov    si,offset h19leds    ; Heath-19 ident
  11579. getled1:stc                ; c = set, does not have leds 1..4
  11580.     ret
  11581. getled2:clc                ; c = clear, has leds 1..4
  11582.     ret
  11583. getled    endp
  11584.  
  11585. ; This routine is called to adjust the cursor for the "indexing" like commands
  11586. ; (e.g., index, reverse index, newline, etc.).    It contrains the cursor, and
  11587. ; indicates if scrolling is necessary, and if so, in which direction.
  11588. ;
  11589. ; Call: cursor = "old" cursor position
  11590. ;    dx =     "new" cursor position
  11591. ;
  11592. ; Return: ax = pointer to scrolling routine to call (or to a ret)
  11593. ;      bx = "old" cursor position
  11594. ;      dx = "new" cursor position adjusted for screen limits or
  11595. ;               scrolling region, depending on whether the original
  11596. ;               cursor position was inside or outside the scrolling region.
  11597. ;
  11598. ; On the VT100, a scroll does not occur unless the original cursor position
  11599. ; was on the top or bottom margin. This routine assumes that when decom is
  11600. ; set the cursor position is set to the new origin, and that no other routine
  11601. ; allows the cursor to be positioned outside the scrolling region as long
  11602. ; as decom is set (which is the way a real VT100 works).  Note that for the
  11603. ; normal case (no limited scrolling region defined) the margins are the same
  11604. ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
  11605. ; an attempt is made to index off the screen. Preserves cx.
  11606.  
  11607. atccic    proc    near
  11608.     push    cx
  11609.     mov    cl,byte ptr low_rgt    ; get right margin
  11610.     mov    bl,dh            ; get row
  11611.     xor    bh,bh
  11612.     cmp    bl,crt_lins        ; below screen?
  11613.     jae    atcci0            ; ae = yes, use single width line
  11614.     cmp    linetype[bx],0        ; single width chars?
  11615.     je    atcci0            ; e = yes, single width
  11616.     shr    cl,1            ; halve margin for double wides
  11617. atcci0:    mov    ax,offset atign        ; assume no scrolling necessary
  11618.     mov    bx,cursor        ; get old cursor
  11619.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG terminal?
  11620.     jz    atcci0a            ; z = no
  11621.     mov    cl,mar_right
  11622.     cmp    dl,mar_left        ; left of left margin?
  11623.     jae    atcci1            ; ae = no
  11624.     mov    dl,mar_right        ; fold to right
  11625.     dec    dh            ; and go up
  11626.     jmp    short atcci1
  11627. atcci0a:cmp    dl,250            ; left of left margin? (wide screen)
  11628.     jb    atcci1            ; b = no, go check right
  11629.     xor    dl,dl            ; set to left margin
  11630. atcci1:    cmp    dl,cl            ; left of right margin
  11631.     jbe    atcci2            ; be = yes, go check top
  11632.     mov    dl,cl            ; set to right margin
  11633.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG terminal?
  11634.     jz    atcci2            ; z = no
  11635.     mov    dl,mar_left        ; to left margin
  11636.     inc    dh            ; and down one
  11637. atcci2:    pop    cx
  11638.     cmp    bh,mar_top        ; was old pos above scroll top margin?
  11639.     jb    atcci7            ; b = yes
  11640.     cmp    dh,mar_top        ; want to go above top margin?
  11641.     jge    atcci5            ; ge = no
  11642.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11643.     jz    atcci3            ; z = no
  11644.     mov    dh,mar_bot        ; roll over to bottom margin
  11645.     ret
  11646. atcci3:    mov    scroll,1
  11647.     mov    ax,offset atscrd    ; indicate scroll down required
  11648.     mov    dh,mar_top        ; set to top margin
  11649.     ret
  11650.  
  11651. atcci5:    cmp    bh,mar_bot        ; old position below bottom margin?
  11652.     ja    atcci7            ; a = yes
  11653.     cmp    dh,mar_bot        ; want to go below?
  11654.     jbe    atcci6            ; be = no, nothing to worry about
  11655.     mov    scroll,1        ; 1 line
  11656.     mov    ax,offset atscru    ; indicate scroll up required
  11657.     mov    dh,mar_bot        ; set to bottom margin
  11658. atcci6:    ret
  11659. atcci7:    jmp    short atccpc        ; old pos was outside scrolling region
  11660. atccic    endp
  11661.  
  11662. ; This routine is called to check the cursor position after any kind of cursor
  11663. ; positioning command.    Note that cursor positioning does NOT cause scrolling
  11664. ; on a VT100 (hence the need for a routine separate from this for "indexing".
  11665. ; Call:    dx = "new" cursor position (modified cursor)
  11666. ; Return: dx = "new" cursor position adjusted for screen limits (if
  11667. ;        decom is reset), or scrolling region (if decom is set).
  11668. ; Preserves ax, bx, and cx.
  11669.  
  11670. atccpc    proc    near
  11671.     push    bx            ; save bx and cx
  11672.     push    cx
  11673.     mov    cx,low_rgt        ; margins, cl = right margin
  11674.     mov    bl,dh            ; get row
  11675.     xor    bh,bh
  11676.     cmp    linetype [bx],0        ; single width line?
  11677.     je    atccp0            ; e = yes, single width
  11678.     shr    cl,1            ; halve right margin for double wides
  11679. atccp0:    test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11680.     jz    atccp0a            ; z = no
  11681.     mov    cl,mar_right
  11682.     cmp    dl,mar_left        ; left of margin?
  11683.     jae    atccp1            ; ae = no
  11684.     mov    dl,mar_right        ; go to right margin
  11685.     dec    dh            ; do a cursor up
  11686.     jmp    short atccp1        ; do a cursor up
  11687.  
  11688. atccp0a:cmp    dl,250            ; to left of left margin?(wide screen)
  11689.     jb    atccp1            ; b = no, go check right
  11690.     xor    dl,dl            ; set to left margin
  11691. atccp1: cmp    dl,cl            ; to right of right margin?
  11692.     jbe    atccp2            ; be = yes, go check top
  11693.     mov    dl,cl            ; set to right margin
  11694.  
  11695.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11696.     jz    atccp2            ; z = no
  11697.     mov    dl,mar_left        ; to left margin
  11698.     jmp    atlf            ; do a LF operation now
  11699.  
  11700. atccp2:    pop    cx
  11701.     pop    bx
  11702.     test    vtemu.vtflgop,decom    ; Origin mode set?
  11703.     jnz    atccp5            ; nz = yes, stay in scrolling region
  11704.     or    dh,dh            ; above top of screen?
  11705.     jns    atccp3            ; ns = no, check bottom
  11706.     xor    dh,dh            ; stop here
  11707. atccp3: cmp    dh,byte ptr low_rgt+1    ; below bottom of screen?
  11708.     jbe    atccp4            ; be = no, stay in margins
  11709.     mov    dh,byte ptr low_rgt+1    ; stop at end of text screen
  11710.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  11711.     jne    atccp4            ; ne = no
  11712.     test    h19stat,h19l25        ; 25th line enabled?
  11713.     jnz    atccp4            ; nz = yes
  11714.     inc    dh            ; allow 25th line
  11715. atccp4:    ret
  11716.  
  11717. atccp5: cmp    dh,mar_top        ; above top of scrolling region?
  11718.     jae    atccp6            ; ae = no, check bottom
  11719.     mov    dh,mar_top        ; yes, stop there
  11720.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11721.     jz    atccp6            ; z = no
  11722.     mov    dh,mar_bot        ; roll to bottom
  11723.     ret
  11724. atccp6: cmp    dh,mar_bot        ; below bottom perhaps?
  11725.     jbe    atccp4            ; be = no, return
  11726.     mov    dh,mar_bot        ; yes, stop at the bottom margin
  11727.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11728.     jz    atccp7            ; z = no
  11729.     mov    dh,mar_top        ; roll to top
  11730. atccp7:    ret
  11731. atccpc    endp
  11732.  
  11733.  
  11734. ; Routine to set cursor type (off, block, underline).
  11735. ; 4 = do not show, but keep block/underline attributes.
  11736. ; 2 = block, 1 = underline
  11737. atsctyp:cmp    flags.vtflg,ttheath    ; Heath-19?
  11738.     jne    atsct1            ; ne = no
  11739.     mov    al,h19ctyp        ; get cursor kind and on/off bit
  11740.     test    al,4            ; is cursor to be off?
  11741.     jz    atsct4            ; z = no, al has kind
  11742.     xor    al,al            ; turn off cursor
  11743.     jmp    short atsct4        ; do it
  11744. atsct1:    test    atctype,4        ; VTxxx cursor type, off?
  11745.     jnz    atsct3            ; z = no
  11746. atsct2:    mov    al,1            ; assume underline
  11747.     test    vtemu.vtflgop,vscursor    ; block?
  11748.     jnz    atsct3            ; nz = no, underline
  11749.     inc    al
  11750. atsct3:    mov    atctype,al        ; save VTxxx cursor type here
  11751. atsct4:    call    csrtype            ; set the cursor type
  11752.     ret
  11753.  
  11754. atdeb    proc    near            ; Debug, display all chars in tty style
  11755.     test    yflags,capt        ; capturing output?
  11756.     jz    atdeb3            ; z = no, forget this part
  11757.     call    fcptchr            ; give it captured character
  11758. atdeb3:    mov    bl,curattr        ; save attribute
  11759.     push    bx
  11760.     push    word ptr mar_top    ; save limited scrolling region
  11761.     push    ax            ; save character for a second
  11762.     mov    ah,curattr        ; get attribute
  11763.     call    clrblink        ; clear blink attribute
  11764.     call    clrunder        ; clear underline attribute
  11765.     mov    atinvisible,0        ; clear invisible attribute
  11766.     mov    extattr,0        ; extended attribute
  11767.     mov    curattr,ah        ; store
  11768.     or    vtemu.vtflgop,decawm    ; set autowrap temporarily
  11769.     mov    mar_top,0        ; set scrolling region to entire page
  11770.     mov    al,byte ptr low_rgt+1
  11771.     mov    mar_bot,al
  11772.     pop    ax            ; restore character
  11773.     mov    ah,al
  11774.     test    al,80h            ; high bit set?
  11775.     jz    atdeb0            ; z = not set
  11776.     push    ax            ; save the character for a second
  11777.     mov    al,7eh            ; output a tilde
  11778.     call    atnrm2
  11779.     pop    ax            ; restore character
  11780.     and    al,7fh            ; and remove high bit
  11781. atdeb0:    cmp    al,del            ; DEL?
  11782.     je    atdeb1            ; e = yes, output "^?"
  11783.     cmp    al,20h            ; control character?
  11784.     jnb    atdeb2            ; nb = no, just output char in al
  11785. atdeb1: push    ax            ; save the character for a second
  11786.     mov    al,5eh            ; output a caret
  11787.     call    atnrm2
  11788.     pop    ax            ; restore character
  11789.     add    al,40h            ; make ^letter (or ^? for DEL)
  11790.     and    al,7fh            ; clear bit 7 (for DEL)
  11791. atdeb2:    push    ax
  11792.     call    atnrm2            ; output translated character
  11793.     pop    ax
  11794.     cmp    ah,LF            ; natural line break?
  11795.     jne    atdeb4            ; ne = no
  11796.     call    atcr
  11797.     call    atlf
  11798. atdeb4:    pop    word ptr mar_top    ; restore scrolling region,
  11799.     pop    bx            ;  flags, and cursor attribute
  11800.     mov    curattr,bl
  11801.     ret
  11802. atdeb    endp
  11803. code1    ends
  11804.     end
  11805.