home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msr313src.zip / mszibm.asm < prev    next >
Assembly Source File  |  1993-07-12  |  294KB  |  9,030 lines

  1.     NAME    mszibm
  2. ; File MSZIBM.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1993, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ;
  9. ; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
  10. ; VT52, VT102, and VT320, Honeywell VIP7809, Prime PT200, DG D463, and D470.
  11. ; Original version for VT100 done by James Harvey, Indiana Purdue Univ, for 
  12. ; MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ for 
  13. ; MS Kermit 2.29 et seq.
  14. ; Edit history
  15. ; 8 July 1993 version 3.13
  16. ; 6 Sept 1991 version 3.11
  17. ; Last edit 7 July 1993
  18. ; 6 Feb 1993 Add DG 470 color terminal.
  19. ; 6 Jan 1993. Add CSI ? 35 h/l as DEC macro to shift keyboard maps. In Kermit
  20. ; these invoke new macro names KEYBOARDS and KEYBOARDR, respectively. From
  21. ;  Shalom Mitz, shmitz@coma.huji.ac.il.
  22. ; April 1992 Add Data General D463 terminal emulation.
  23. ; 7 Sept 1992 Add small extra code from htb to more fully emulate Prime PT200
  24. ; 20 July 1990 Include terminal type of VT100 as the same as VT102 but with
  25. ;  a different ident response. Also include terminal type of HONEYWELL VIP7809
  26. ;  as a VT100 with a VT100 ident response, with a canned response to ENQ, and
  27. ;  another to ESC y. Honeywell material is from Frank Dreano,
  28. ;  dreano@trout.nosc.mil.
  29. ; 29 May 1989 Rewrite and expand to DEC VT320 level.
  30. ; 5 Oct 1988 Add controls to write from right to left, using bit vswdir in
  31. ;  the setup bytes vtemu.vtflgst and vtemu.vtflgop. The concept was invented
  32. ;  by Baruch Cochavy, IIT, Haifa, Israel; the current code is by [jrd].
  33. ;  If vswdir is non-zero writing is done starting on the visual right side.
  34. ;  Procedure direction accomdates most directional details. The
  35. ;  implementation here retains DX and CURSOR as logical values while the
  36. ;  physical screen coordinates are conditioned via proc direction and
  37. ;  several sections of special code. Screen printing is done full width if
  38. ;  writing right to left. Outside mszibm the logical cursor = physical.
  39. ; 1 Jan 1988 version 2.30
  40. ;    [Joe R. Doupnik, Utah State Univ]
  41.  
  42.     public    anstty, ansini, ansrei, ansdsl, anskbi ; Entry points
  43.     public    ans52t, vsinit, tabset, tabclr, tekflg
  44.     public    mar_top, mar_bot, anspflg, scroll, cursor, curattr
  45.     public    dnparam, dparam, dlparam, dninter, dinter, emubufc, emubuf
  46.     public    emubufl, dcsstrf, upss, MNlatin
  47.     public    GRptr, G0set, G1set, G2set, G3set
  48.     public    savezlen, savezoff, blinkdis, protectena, dghscrdis
  49.     public    linescroll, xltkey, dgkbl, dgwindcomp, atctype, dgcross
  50.     public    dgnctoggle, apcstring
  51. ;
  52. ; DEC and VT are trademarks of Digital Equipment Corporation.
  53. ;
  54. ; Description of the global entry points and calls on external routines
  55. ; needed by this emulator.
  56. ;
  57. ; vsinit - start up routine called as Kermit initializes. Takes no arguments.
  58. ;       Sets up address pointers to tabs, reads default terminal parameters
  59. ;       reads current screen coloring. Examines and updates structure
  60. ;       "vtemu." which is how mssset communicates changed information
  61. ;       about many Set Term parameters; "flags." is a Kermit structure
  62. ;       carrying the other Set Term parameters.
  63. ; anstty - starting point for displaying a character, delivered in AL.
  64. ;       Returns when the display operation is completed and that may
  65. ;       take many many instructions. All normal "characters received by
  66. ;       the terminal" are provided by calling anstty with the char in AL.
  67. ; ansini - entry point to initialize the emulator. It requires information
  68. ;       from msy in four registers: the Kermit terminal routine flags
  69. ;       "yflags" (used mainly to sense debug mode and the mode line toggle)
  70. ;       "low_rgt" (bh = row, bl = column of the lower right display corner)
  71. ;       "lbaudtab" (index into baud rate table, for status reporting)
  72. ;       "lpartab" (index into parity table, for status reporting)
  73. ;       Ansini causes a full reset of the emulator, including screen 
  74. ;       clearing and a beep. Ansini is also called by msy in response to
  75. ;       sensing the Alt = key combination to fully reset the emulator.
  76. ; ansrei - entry point to reinitialize the emulator. Nearly the same as
  77. ;       ansini except operating flags, tabs, etc are retained from the
  78. ;       previous emulator session. Items which can be changed by Set Term
  79. ;       are examined and updated. The msy flags "yflags" are needed.
  80. ;       This is the warm-restart entry point used when connect mode
  81. ;       is reentered gracefully. The screen is cleared only if the coloring
  82. ;       has changed. The starting cursor location is whereever msy puts it.
  83. ; ansdsl - display "led" (status line) information. Invoked by msy when
  84. ;       the mode line is constructed so the emulator can write the 
  85. ;       terminal type and the VT100 led status lights when Connect mode
  86. ;       is started. Requires "yflags" from msy to sense whether the mode
  87. ;       line is to be shown.
  88. ; anskbi - a routine called by msy to notify the emulator that a character
  89. ;       is available from the keyboard. No character is read, just flag
  90. ;       ttkbi is set. This is actually used only to beep when the cursor
  91. ;       goes beyond column 72 and the margin bell flag is on.
  92. ; ans52t - called by msy to change terminal types "on the fly" without
  93. ;       fully updating all operating parameters and without losing setup
  94. ;       information. Msy senses the Alt minus key and calls ans52t with
  95. ;       no arguments. Ans52t cycles among terminal types.
  96. ; other modules in msy are called by this file to handle screen scrolling
  97. ;       mode line on/off, output to the serial port (reports), screen
  98. ;       particulars (location, cursor shape, blanking). The list is
  99. ;       the set of code extrn procedures below; all are in file msy.
  100. ;
  101. ; data exchange is directly with msy to assist in scrolling (varaibles
  102. ;       "mar_top", "mar_bot") and in sensing the non-connect
  103. ;       mode screen coloring ("scbattr"). Screen coloring controlled by
  104. ;       the emulator is not permitted to influence the non-connect mode
  105. ;       screens whereas the emulator attempts to use the regular Kermit
  106. ;       screen colors as defaults. The kind of terminal to emulate is
  107. ;       held in word "flags.vtflg" which is set by Set Term and by this
  108. ;       module for global information within Kermit.
  109. ;
  110. ; Many things have been added or modified since James Harvey donated this
  111. ;       code to Columbia University for use in Kermit.              [jrd]
  112. ; Character sets in VT320 and VT102 modes:
  113. ;  ASCII ("B"/94)
  114. ;  ISO Latin-1 ("A"/96)
  115. ;  DEC UK-ASCII ("A"/94, available only in VT102 mode)
  116. ;  DEC Supplemental Graphics ("%5"/94),
  117. ;  DEC Technical Graphics (">"/94), an extension taken from the VT340,
  118. ;  DEC Special Graphics ("0"/94 and "2"/94)
  119. ;  ALT-ROM (Kermit specific, "1"/94/96)
  120. ;  DEC National Replacement Chars (all 12 sets)
  121. ;  Startup:
  122. ;   GL = G0 = G1 = ASCII (or ALT-ROM if selected by SET TERM CHAR ALT-ROM),
  123. ;   GR = G2 = G3 = ISO Latin-1.
  124. ;   When an NRC is selected by SET TERM CHAR <country> and enabled by
  125. ;   CSI ? 42 h the NRC table replaces G0..G3 at the time of selection. When
  126. ;   thus designated and selected incoming characters are forced to 7 bits and
  127. ;   8-bit Controls (outgoing) is turned off. No designation means no selection.
  128. ;  Selecting a character set with the wrong sized designator yields no action.
  129. ;
  130. ;  Startup in D463/D470 mode:
  131. ;   GL = G0 = ASCII
  132. ;   GR = G1 = Data General International if using 8-bit characters, else
  133. ;   GR = G1 = Data General Word Processing.
  134. ;
  135. ; References:
  136. ;  "PT200 Programmers Reference Guide", 1984, Prime Computer # DOC 8621-001P
  137. ;  "Video Terminal Model H19, Operation", 1979, Heath Company # 595-2284-05
  138. ;  "VT100 User's Guide", 2nd ed., Jan 1979, DEC # EK-VT100-UG
  139. ;  "Rainbow 100+/100B Terminal Emulation Manual", June 1984, DEC # QV069-GZ
  140. ;  "Installing and Using The VT320 Video Terminal", June 1987,
  141. ;    DEC # EK-VT320-UU-001
  142. ;  "VT320 Programmer Reference Manual", July 1987, DEC # EK-VT320-RM-001
  143. ;  "VT330/340 Programmer Ref Manual", 2nd ed, May 1988,
  144. ;    Vol 1: Text programming DEC # EK-VT3XX-TP-002
  145. ;    Vol 2: Graphics programming DEC # EK-VT3XX-GP-002
  146. ;  "Programming the Display Terminal: Models D217, D413, and D463", Data
  147. ;    General Corp, 014-00211-00, 1991.
  148. ;  "Installing and Operating Your D216E+, D217, D413, and D463 Display
  149. ;    Terminals", Data General Corp, 014-002057-01, 1991.
  150. ;  "Dasher D470C Color Display Terminal, Programmer's Reference Manual",
  151. ;    Data General Corp, 014-001015, 1984.
  152. ; ---------------------------------------------------------------------------
  153.  
  154. vswidth    equ    207            ; cross correlate with msyibm
  155. swidth  equ     207            ; assumed max screen width
  156. slen    equ    60            ; assumed max screen length 
  157. maxparam equ    10            ; number of ESC and DCS Parameters
  158. maxinter equ    10            ; number of ESC and DCS Intermediates
  159. gsize    equ    128            ; character set storage size
  160.                     ; anspflg bit field definitions:
  161. ; prtscr equ    1            ; used in msyibm print screen toggle
  162. vtautop    equ    1            ; autoprint enabled (1)
  163. vtcntp    equ    2            ; controller print enabled (1)
  164. vtextp    equ    4            ; printer extent set (1)
  165. vtffp    equ    10h            ; form feed wanted at end of print (1)
  166.  
  167. h19l25    equ    1            ; h19stat, line 25 enabled
  168. h19alf    equ    2            ; h19stat, auto cr/lf when cr seen
  169.                     ; display save-info for dspstate
  170. dsptype    equ    1            ; main (0) or status line (1) flag
  171. dspdecom equ    2            ; remembered origin mode (1=on)
  172.  
  173. att_bold    equ    08h        ; bold        in main video word
  174. att_blink    equ    80h        ; blinking    in main video word
  175. att_protect    equ    01h        ; protected    in vsatt
  176. att_uline    equ    02h        ; underscored    in vsatt
  177. att_rev        equ    04h        ; reversed video  in vsatt
  178.  
  179. braceop    equ    7bh            ; opening curly brace
  180. bracecl    equ    7dh            ; closing curly brace
  181.  
  182. ; DEC emulator status flags (bits in words vtemu.vtflgst and vtemu.vtflgop)
  183. ;anslnm  equ    1H            ; ANSI line feed/new line mode
  184. ;decawm  equ    2H            ; DEC autowrap mode
  185. ;decscnm equ    80H            ; DEC screen mode
  186. ;decckm  equ    200H            ; DEC cursor keys mode
  187. ;deckpam equ    400H            ; DEC keypad application mode
  188. ;decom   equ    800H            ; DEC origin mode
  189. ;deccol     equ    1000H            ; DEC column mode (0=80 col)
  190. ;decanm  equ    2000H            ; ANSI mode
  191. ;;dececho equ    4000H            ; ANSI local echo on (1 = on)
  192.      
  193. ; Terminal SETUP mode flags (joint with bits above, some name dups)
  194. ;vsnewline    equ    1H        ; ANSI new line (0 = off)
  195. ;vswrap        equ    2H        ; Line wrap around (0 = no wrap)
  196. ;vsnrcm        equ    4H        ; National Rep Char set (0=none)
  197. ;vswdir        equ    8H        ; Writing direction (0=left, 1 right)
  198. ;vskeyclick    equ    10H        ; Keyclick (0 = off)
  199. ;vsmarginbell    equ    20H        ; Margin bell (0 = off)
  200. ;vscursor    equ    40H        ; Cursor (0 = block, 1 = underline)
  201. ;vsscreen    equ    80H        ; Screen (0 = normal, 1 = rev. video)
  202. ;vscntl        equ    100h        ; 8 or 7 bit controls (1 = 8-bit)
  203. ;vshscroll    equ    4000h        ; horiz scroll (0=auto, 1=manual)
  204. ;vscompress    equ    8000h        ; compressed text(0=graphics,1=132col)
  205.  
  206. ;vsdefaults    equ    0+vscursor
  207.  
  208. ; Kinds of terminals available
  209. ;ttgenrc    equ    0        ; no emulation done by Kermit
  210. ;ttheath    equ    1        ; Heath-19
  211. ;ttvt52        equ    2        ; VT52
  212. ;ttvt100    equ    4        ; VT100
  213. ;ttvt102    equ    8        ; VT102
  214. ;ttvt220    equ    10h        ; VT220
  215. ;ttvt320    equ    20h        ; VT320
  216. ;tttek        equ    40h        ; Tektronix 4010
  217. ;tthoney    equ    80h        ; Honeywell VIP7809
  218. ;ttpt200    equ    100h        ; Prime PT200
  219. ;ttd463        equ    200h        ; Data General D463
  220. ;ttd470        equ    400h        ; Data General D440
  221. ;TTTYPES    equ    12        ; Number of terminal types defined
  222. ;; tekflg bits in byte
  223. ;tek_active equ    1            ; actively in graphics mode
  224. ;tek_tek equ    2            ; Tek terminal
  225. ;tek_dec equ    4            ; Tek submode of DEC terminals
  226. ;tek_sg    equ    8            ; special graphics mode
  227.  
  228. ;emulst    struc        ; structure of vtemu.xxx for VTxxx emulator
  229. ;vtflgst dw    0    ; DEC setup flags (from SET)
  230. ;vtflgop dw    0    ; DEC runtime flags, like setup flags (here & STAT)
  231. ;vttbs    dw    0    ; pointer to default tab stops, for SET
  232. ;vttbst    dw    0    ; pointer to active tab stops, for STATUS
  233. ;vtchset db    1    ; value of default character set (1=US-ascii)
  234. ;att_ptr dw    0    ; pointer to normal & reverse video attributes
  235. ;emulst    ends
  236. ;;;;;;;;;;;;;;;;  end references ;;;;;;;;;;;;;;;;;;;;
  237.  
  238. data    segment
  239.     extrn    vtemu:byte, scbattr:byte, flags:byte, yflags:byte
  240.     extrn    crt_lins:byte, rxtable:byte, denyflg:word, low_rgt:word
  241.     extrn    vtclear:byte, dosnum:word, chcontrol:byte, apcenable:byte
  242.     extrn    parstate:word, pardone:word, parfail:word, nparam:word
  243.     extrn    param:word, lparam:byte, ninter:word, inter:byte, ttyact:byte
  244.     extrn    L1cp437:byte, L1cp850:byte, L1cp860:byte, L1cp863:byte
  245.     extrn    L1cp865:byte, modbuf:byte, extattr:byte, rdbuf:byte
  246.     extrn    vtenqenable:byte, vtcpage:word
  247.  
  248.     even                    ; C0 7-bit control code table
  249. ansc0    dw    5 dup (atign)            ; NUL, SOH, STX, ETX, EOT
  250.     dw    atenq,atign,vtbell,atbs,atht     ; ENQ, ACK, BEL, BS,  HT
  251.     dw    atlf, atlf, atff, atcr,atls1    ; LF,  VT,  FF,  CR,  SO
  252.     dw    atls0, 4 dup (atign)        ; SI,  DLE, DC1, DC2, DC3
  253.     dw    4 dup (atign), atcan        ; DC4, NAK, SYN, ETB, CAN
  254.     dw    atign, atnrm, atesc,atign,atign    ; EM,  SUB, ESC, FS,  GS
  255.     dw    2 dup (atign)            ; RS,  US
  256.  
  257.                         ; C1 8-bit control code table
  258. ansc1    dw    4 dup (atign), atind        ; ignore 4, IND
  259.     dw    atnel,atign,atign,athts,atign    ; NEL, SSA, ESA, HTS, HTJ
  260.     dw    atign,atign,atign,atri, atign    ; VTS, PLD, PLU, RI,  SS2
  261.     dw    atign,atdcs,3 dup (atign)    ; SS3, DCS, PU1, PU2, STS
  262.     dw    atign,atign,protena,protdis,atign ; CCH, MW, SPA, EPA,ignore
  263.     dw    atign,atign,atcsi,atgotst,atdcsnul; ignore 2, CSI, ST, OSC
  264.     dw    atdcsnul, atapc            ; PM,  APC
  265.  
  266. ; Heath-19 mode escape follower table
  267. h19esc    db    36            ; number of entries
  268.     dw    h19ejt            ; address of action routines
  269.     db    '<=>@A','BCDEF','GHIJK','LMNOY','Z[bjk','lnopq','rvwxy','z'
  270.  
  271. ; Dispatch table for Heath-19 escape sequence table h19esc
  272.     even
  273. h19ejt    dw    h19sans, atkpam,  atkpnm,  entins,  atcuu    ; '<=>@A'
  274.     dw    atcud,   atcuf,   atcub,   h19clrs, v52sgm    ; 'BCDEF'
  275.     dw    chrdef,  atcup,   atri0,   ated,    atel    ; 'GHIJK'
  276.     dw    inslin,  dellin,  atdelc,  noins,   v52pos    ; 'LMNOY'
  277.     dw    decid,   h19csi,  h19esos, h19sc,   h19rc    ; 'Z[bjk'
  278.     dw    h19erl,  hrcup,   h19ero,  h19herv, h19hxrv    ; 'lnopq'
  279.     dw    atnorm,  h19wrap, h19nowrp,h19smod, h19cmod    ; 'rvwxy'
  280.     dw    atxreset                    ; 'z'
  281.  
  282. h19ans    db    21            ; Heath-19 ANSI style escape sequences
  283.     dw    h19jmp            ; address of action routine table
  284.     db    'ABCDH','JKLMP','fhlmn','pqrsu','z'
  285.  
  286. ; Heath-19 action table for h19ans
  287.     even
  288. h19jmp    dw    atcuu, atcud, atcuf,  atcub,  atcup        ; 'ABCDH'
  289.     dw    h19ed, atel,  inslin, dellin, atdelc        ; 'JKLMP'
  290.     dw    atcup, atsm,  atrm,   atsgr,  rpcup        ; 'fhlmn'
  291.     dw    atign, atign, atign,  h19sc,  h19rc        ; 'pqrsu'
  292.     dw    atxreset                    ; 'z'
  293.  
  294. ; VT52 compatibility mode escape follower table
  295. v52esc    db    23            ; number of entries
  296.     dw    v52ejt            ; address of action routines
  297.     db    '78<=>', 'ABCDF', 'GHIJK', 'VWXYZ'
  298.     db    ']',5eh,5fh        ; 5eh = caret, 5fh = underscore
  299.  
  300. ; Dispatch for v52esc table
  301.     even
  302. v52ejt    dw    atsc,   atrc,   v52ans, atkpam, atkpnm        ; '78<=>'
  303.     dw    atcuu,  atcud,  atcuf,  atcub,  v52sgm        ; 'ABCDF'
  304.     dw    chrdef, atcup,  atri0,  ated,   atel        ; 'GHIJK'
  305.     dw    v52pl,  v52pcb, v52pce, v52pos, decid        ; 'VWXYZ'
  306.     dw    v52ps,  v52pcb, v52pce                ; ']^_'
  307.  
  308. ; Prime PT200 escape follower table
  309. pt200esc db    38            ; number of entries
  310.     dw    p20ejt            ; address of action routines
  311.     db    '01234','5678<', '=>?AB', 'DEFGH', 'JMNOP'
  312.     db    'Z[\]',5eh        ; 5eh = caret
  313.     db    5fh,'cno',7bh        ; 5fh=underscore, 7bh=left curly brace
  314.     db    7ch,7dh,7eh   ; 7ch=vert bar, 7dh=right curly brace, 7eh=tilde
  315.  
  316. ; Dispatch for p20esc
  317.     even
  318. p20ejt    dw    atdgf0, atdgf1, atdgf0, atsdhl, atsdhl         ; '01234'
  319.     dw    4 dup (atsdhl), atdgfu                ; '5678<'
  320.     dw    atkpam, atnorm, p20ed, atdgfA, atdgfB         ; '=>?AB'
  321.     dw    atind,  atnel,  ats7c, ats8c,  athts        ; 'DEFGH'
  322.     dw    ated,   atri,   atss2, atss3,  atdcs        ; 'JMNOP'
  323.     dw    decid,  atcsi,  atgotst, 2 dup(atdcsnul)    ; 'Z[\]^'
  324.     dw    atdcsnul, atxreset,atls2, atls3, atpriv        ; '_cno{'
  325.     dw    atls3r, atls2r, atls1r                ; '|}~'
  326.  
  327. ; VT320/VT102/VT100/Honewell ANSI mode escape follower table
  328. ansesc    db    49            ; number of entries
  329.     dw    ansejt            ; address of action routines
  330.     db    '01234','56789','<=>?A','BCDEF','GHKLMN','OPQRV'
  331.     db    'WYZ[\',']',5eh,5fh    ; 5eh = caret, 5fh=underscore
  332.     db    60h,'c','fgno',7bh    ; 7bh=left curly brace,  7ch=vert bar
  333.     db    7ch,7dh,7eh        ; 7dh=right curly brace, 7eh=tilde
  334.  
  335. ; Dispatch for ansesc table
  336.     even
  337. ansejt    dw    atdgf0, atdgf1, atdgf0, atsdhl, atsdhl         ; '01234'
  338.     dw    4 dup (atsdhl), atdgnrc                ; '56789'
  339.     dw    atdgfu,atkpam, atdgft, atdgfq, atdgfA         ; '<=>?A'
  340.     dw    atdgfB,atdgnrc, atind0, atnel0,ats7c        ; 'BCDEF'
  341.     dw    ats8c, athts0, atdgnrc, atdgnrc,atri0, atss2    ; 'GHKLMN'
  342.     dw    atss3, atdcs0, atdgnrc, atdgnrc,protena        ; 'OPQRV'
  343.     dw    protdis,decid, atdgnrc, atcsi0, atgotst0    ; 'WYZ[\'
  344.     dw    2 dup (atdcsnul0),atapc, athoncls, atxreset    ; ']^_`c'
  345.     dw    atdgnrc,atdgnrc,atls2,atls3, atpriv        ; 'fgno{'
  346.     dw    atls3r, atls2r, atls1r                ; '|}~'
  347.  
  348. ; Final char table for VT320/VT102/VT100/Honeywell ANSI control sequences
  349. anstab    db    38            ; number of entries
  350.     dw    ansjmp            ; address of action routines
  351.     db    '@ABCD','EFGHI','JKLMP', 'Xacde','fghil','mnpqr','uwxyz'
  352.     db    7ch,7dh,7eh        ; 7dh=right curly brace, 7eh=tilde
  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.  
  365. ; Final character table for Device Control Strings (DCS, ESC P)
  366. dcstab    db    5            ; number of entries
  367.     dw    dcsjmp            ; address of action routines
  368.     db    'pqu',7bh,7ch        ; 7bh = left curly brace
  369.  
  370. ; Dispatch for dcstab table
  371.     even
  372. dcsjmp    dw    atcrqq, atcrq, atupss, atdcsnul, atudk        ; 'pqu{|'
  373. ;;; DCS Ps $ p string ST   page 209 restore color palette
  374.  
  375. ; Data General D463/D470 terminal section
  376. dgescape equ    1eh                ; DG escape char (RS)
  377.  
  378.     even                ; DG C0 7-bit control code table
  379. dgc0    dw    atign,dgprtfm,dgrevidoff,dgblkena,dgblkdis;NUL,SOH,STX,ETX,EOT
  380.     dw    dgrwa,atign,vtbell,dgwinhome,atign  ; ENQ, ACK, BEL, BS,  HT
  381.     dw    dglf, dgeol, dgewin, dgcr,dgblkon   ; LF,  VT,  FF,  CR,  SO
  382.     dw    dgblkoff,dgwwa,dgprtwn,dgrollena,dgrolldis ;SI,DLE,DC1,DC2,DC3
  383.     dw    dguson,dgusoff,dgrevidon,dgcuu,dgcuf ; DC4, NAK, SYN, ETB, CAN
  384.     dw    dgcub, dgcud,dgansi,dgdimon,dgdimoff ; EM, SUB, ESC, FS, GS
  385.     dw    dgesc, atign                ; RS, US
  386.  
  387. ; DG D463/D470 DG-escape (RS) follower table
  388. dgesctab db    17            ; number of entries
  389.     dw    dgejt            ; address of action routines
  390.     db    'ABCDE','FGHIJ','KLMNO','PR'
  391.  
  392. ; Dispatch for dgesctab table
  393.     even
  394. dgejt    dw    dgsfc, dgsbc, dgrmid, dgrevidon, dgrevidoff     ; 'ABCDE'
  395.     dw    dgFSERIES, dgGSERIES, dgscrup, dgscrdn, inschr    ; 'FGHIJ'
  396.     dw    dgdelc, dggline, atign, atls1, atls0        ; 'KLMNO'
  397.     dw    dgunix, dgRSERIES                ; 'PR'
  398.  
  399. fltable    db    60                ; RS F letter dispatch table
  400.     dw    faction                ; table of action routines
  401.     db    '789;<', '>?ABC', 'DEFGH', 'IJKLM', 'NOPQR'
  402.     db    'STUVW', 'XYZ[\', ']^_`a', 'bcdef', 'hikmq'
  403.     db    'rstvw', 'xz{}~'
  404.  
  405. ; Dispatch for fltable table
  406.     even
  407. faction    dw    dgign2n, atign, dggrid, atign, atign        ; '789;<'
  408.     dw    dgalign, dgprt, atreset, dgsetw, dgsleft    ; '>?ABC'
  409.     dw    dgsright, dgescn, dgeeos, dgshome, dginsl    ; 'DEFGH'
  410.     dw    dgdell, dgnarrow, dgwide, dgpton, dgptoff    ; 'IJKLM'
  411.     dw    dgchatr, dgrhso, dgwsa, dgsct, dgdefch        ; 'NOPQR'
  412.     dw    dgscs, dgign1n, dg78bit, protena, protdis    ; 'STUVW'
  413.     dw    dgsetmar, dgsetamar, dgrnmar, dgilbm, dgdlbm    ; 'XYZ[\'
  414.     dw    dghsdis, dghsena, dgshcol, dgprt3a, atign    ; ']^_`a'
  415.     dw    dgrsa, dgscmap, dgrchr, dgresch, dgskl        ; 'bcdef'
  416.     dw    atign, atign, atnorm, atnorm, dgdcs         ; 'hikmq'
  417.     dw    dgsclk, dgign1n, dgrss, dgrwc, dgrnmod        ; 'rstvw'
  418.     dw    dgppb, dgs25l, dgsmid, dgnscur, dgign2n        ; 'xz{}~'
  419.  
  420. gltable    db    14                ; RS G letter dispatch table
  421.     dw    gaction                ; table of action routines
  422.     db    '018:>','?@ABC','HInp'
  423.  
  424. ; Dispatch for gltable table
  425.     even
  426. gaction    dw    dggarc, dggbar, dggline, dggpoly, dggcloc    ; '018:>'
  427.     dw    dggrcl, dggcatt, dggcrst, dggcon, dggcoff    ; '?@ABC'
  428.     dw    dggctrk, atnorm, atnorm, dggsetp        ; 'HInp'
  429.  
  430. rltable    db    6            ; Data General D463/D470 RS R series
  431.     dw    raction
  432.     db    '@ABCD','E'
  433.  
  434. ; Dispatch for rltable table
  435. raction    dw    dgign2n, dgsps, dgsfield, dgspage, dgsdo    ; '@ABCD'
  436.     dw    dgdhdw                        ; 'E'
  437.  
  438. ;; Notes on char set idents
  439. ; Kermit ident         size    ident    comment            designator
  440. ;    0        94    'B',0    ASCII             "B"
  441. ;    1        94    'A',0    British NRC         "A"
  442. ;    2        94    '4',0    Dutch NRC         "4"
  443. ;    3        94    '5',0    Finnish    NRC (also "C")    "5"
  444. ;    4        94    'R',0    French NRC (also "f")    "R"
  445. ;    5        94    '9',0    French Canadian NRC     "9"
  446. ;    6        94    'K',0    German NRC        "K"
  447. ;    7        94    'Y',0    Italian    NRC        "Y"
  448. ;    8        94    '`',0    Norwegian/Danish NRC    "`"
  449. ;    9        94    '%','6'    Portugese NRC ("L","g") "%6"
  450. ;    10        94    'Z',0    Spanish    NRC        "Z"
  451. ;    11        94    '7',0    Swedish    NRC        "7"
  452. ;    12        94    '=',0    Swiss NRC        "="
  453. ;    13        94    '=','%' DEC Hebrew NRC        "=%'
  454. ;    14        94    '1',0    Alt-ROM            "1"
  455. ;    15        96    '?',0    Transparent        "?"
  456. ;    16        96    'A',0    Latin1            "A"
  457. ;    17        94    '%','5'    DEC Multinat (Sup Gr)     "%5"
  458. ;    18        94    '>',0    DEC Technical        ">"
  459. ;    19        94    '0',0    DEC-Special          "0","2"
  460. ;    20        94    'D','I' DG International    "DI"
  461. ;     21        94    'D','L'    DG Line Drawing        "DL"
  462. ;    22        94    'D','W' DG Word Processing    "DW"
  463. ;    23        96    'B',0   Latin2            "B"
  464. ;    24        96    'H',0   Hebrew-ISO        "H"
  465. ;    25        94    '"','4' DEC Hebrew        ""4"
  466. ;      100        94    'D','U' DG soft set filler    "DU"
  467. ;; End of notes
  468.  
  469. ; Heath-19 special graphics characters to CP437. Use as offsets from caret
  470. ; (94D)
  471. hgrtab    db    249, 17,179,196,197    ; caret,underscore,accent grave,a,b
  472.     db    191,217,192,218,241    ; c,d,e,f,g
  473.     db     26,177,219, 25,220    ; h,i,j,k,l
  474.     db    220,223,223,223,222    ; m,n,o,p,q
  475.     db     16,194,180,193,195    ; r,s,t,u,v
  476.     db    'X','/','\',223,220    ; w,x,y,z,left curly brace
  477.     db    221,222, 20        ; vertical bar,right curly brace,tilde
  478. hgrtabl    equ ($-hgrtab)
  479.  
  480. ; Data General Line Drawing Character Set, based on CP437, starting in 10/0
  481. dgldc    db    20h,0dah,0bfh,0c0h,0d9h,0c2h,0b4h,0c3h        ; 2/0
  482.     db    0c1h,0c5h,0b3h,0c4h,0c2h,0b4h,0c3h,0c1h
  483.     db    0b3h,0c9h,0bbh,0c8h,0bch,0cbh,0b9h,0cch        ; 3/0
  484.     db    0cah,0ceh,0bah,0cdh,0c4h,0f6h,9bh,3fh
  485.     db    3fh,3fh,3fh                    ; 4/0
  486. dgldclen equ    ($-dgldc)
  487.  
  488. ; VT320/VT102 "Special graphics" set translation table for characters 95..126d
  489. ; when the special graphics set is selected. Some characters (98, 99, 100,
  490. ; 101, 104, 105, 111, 112, 114, 115, and 116) do not have exact equivalents
  491. ; in the available set on the IBM, so a close substitution is made.
  492. ; Table is indexed by ASCII char value minus 95 for chars 95..126d.
  493. sgrtab    db     32,  4,177, 26, 23,  27, 25,248,241, 21
  494.     db     18,217,191,218,192, 197,196,196,196,196
  495.     db    196,195,180,193,194, 179,243,242,227,157
  496.     db    156,250
  497. sgrtabl    equ    $-sgrtab
  498.  
  499.  
  500.     ; DEC National Replacement Char sets, referenced to Latin1
  501. nrclat    db    23h,40h,5bh,5ch,5dh,5eh        ; 0, ASCII, "B", dispatch ref
  502.     db    5fh,60h,7bh,7ch,7dh,7eh
  503.     db    94,'B',0            ; 94 byte set, letter pair
  504.     db    0a3h,40h,5bh,5ch,5dh,5eh    ; 1, British, "A"
  505.     db    5fh,60h,7bh,7ch,7dh,7eh
  506.     db    94,'A',0
  507.     db    0a3h,0beh,0ffh,0bdh,7ch,5eh    ; 2, Dutch, "4"
  508.     db    5fh,60h,0a8h,66h,0bch,0b4h
  509.     db    94,'4',0
  510.     db    23h,40h,0c4h,0d6h,0c5h,0dch    ; 3, Finnish, "5"
  511.     db    5fh,0e9h,0e4h,0f6h,0e5h,0fch
  512.     db    94,'5',0
  513.     db    0a3h,0e0h,0b0h,0e7h,0a7h,5eh    ; 4, French, "R"
  514.     db    5fh,60h,0e9h,0f9h,0e8h,0fbh
  515.     db    94,'R',0
  516.     db    23h,0e0h,0e2h,0e7h,0eah,0eeh    ; 5, French Canadian, "9"
  517.     db    5fh,0f4h,0e9h,0f9h,0e8h,0f8h
  518.     db    94,'9',0
  519.     db    23h,0a7h,0c4h,0d6h,0dch,5eh    ; 6, German, "K"
  520.     db    5fh,60h,0e4h,0f6h,0fch,0dfh
  521.     db    94,'K',0
  522.     db    0a3h,0a7h,0b0h,0e7h,0e9h,5eh    ; 7, Italian, "Y"
  523.     db    5fh,97h,0e0h,0f2h,0e8h,0ech
  524.     db    94,'Y',0
  525.     db    23h,40h,0c6h,0d8h,0c5h,5eh    ; 8, Norwegian/Danish, "`"
  526.     db    5fh,60h,0e6h,0f8h,0e5h,7eh
  527.     db    94,60h,0
  528.     db    23h,60h,0c3h,0c7h,0d5h,5eh    ; 9, Portugese, "%6"
  529.     db    5fh,60h,0e3h,0e7h,0f5h,7eh
  530.     db    94,'%','6'
  531.     db    0a3h,0a7h,0a1h,0d1h,0bfh,5eh    ; 10, Spanish, "Z"
  532.     db    5fh,60h,0b0h,0f1h,0e7h,7eh
  533.     db    94,'Z',0
  534.     db    23h,0c9h,0c4h,0d6h,0c5h,0dch    ; 11, Swedish, "7"
  535.     db    5fh,0e9h,0e4h,0f6h,0e5h,0fch
  536.     db    94,'7',0
  537.     db    0f9h,0e0h,0e9h,0e7h,0eah,0eeh    ; 12, Swiss, "="
  538.     db    0e8h,0f4h,0e4h,0f6h,0fch,0fbh
  539.     db    94,'=',0
  540.  
  541. nrcfinal db    'A45CRf9QKY`E6Z7H=Lg'        ; NRC country letters
  542. nrcflen    equ    $-nrcfinal            ; "%6" "%=" done separately
  543. nrcnum    db    1,2,3,3,4,4,5,5,6,7,8,8,8,10,11,11,12,9,9 
  544.                         ; country numbers matching
  545.                         ; nrcfinal letters
  546.  
  547. ;NRC to DEC keyboard codes, North American (ASCII is nrckbd 1),+ALT-ROM+transp
  548. nrckbd    db    1,2,8,6,14,4,7,9,13,16,15,12,11,1, 1,1,1,1,1,1,1
  549. ;NRC to DG keyboard codes, North American + ALT-ROM+transparent
  550. nrcdgkbd db    19h,1ah,0,1dh,1bh,18h,1ch,17h,1fh,0,1eh,1dh,14h,19h, 19h,18h
  551.     db    19h,19h,19h,19h,19h
  552. ; DG char set idents to Kermit set idents
  553. ; DG set values 0 1 2 3 4  5  6    7     8   9  0a  0b  0c  0d 0e  0f  hex
  554. dgchtab    db    0,0,1,4,6,11,10,8,   12,100,100,100,100,100,20,100 ; decimal
  555. ;        10 11  12 13 14 15  16   17  18  19  1a  1b  1c 1d 1e 1f
  556.     db    22,21,100,15,17,19,100, 100,100,100,100,100,100, 0,15,16
  557. ;        20h and above map to soft set filler 100
  558.     db    100                        ; filler set
  559.  
  560. ; Translation tables for byte codes 0a0h..0ffh to map DEC Multinational
  561. ; Character Set (DEC Supplemental Graphic) to Code Pages.
  562. ; Codes 00h-1fh are 7-bit controls (C0), codes 20h..7eh are ASCII, 7fh DEL is
  563. ; considered to be a control code, 80h..9fh are 8-bit controls (C1).
  564. ; Each table is 128 translatable bytes followed by the table size (94) and the
  565. ; ISO announcer ident '%5'.
  566.  
  567. MNlatin    db    0a4h,0a6h,0a8h,0ach,0adh,0aeh,0afh,0b4h    ; Latin1 code points
  568.     db    0beh,0d0h,0d7h,0deh,0f0h,0fdh,0feh,0ffh
  569.     db    20h,20h,0a4h,20h,20h,20h,20h,20h    ; MN values there
  570.     db    20h,20h,3fh,20h,20h,0ffh,20h,20h
  571.  
  572.  
  573.                ; Dec Technical set to CP437, CP860, CP863, CP865
  574.              ; Note: CP850 lacks the symbols so expect trash
  575. dectech    db    32 dup (0)                ; columns 8 and 9
  576.     db    0h,0fbh,0dah,0c4h, 0f4h,0f5h,0b3h,0dah    ; column 10
  577.     db    0c0h,0bfh,0d9h,28h,28h,29h,29h,0b4h
  578.     db    0c3h,3ch,3eh,5ch,  2fh,0bfh,0d9h,03eh    ; column 11
  579.     db    0a8h,20h,20h,20h,  0f3h,3dh,0f2h,3fh
  580.     db    1eh,0ech,0ech,0f6h,1eh,1fh,0e8h,0e2h    ; column 12
  581.     db    0f7h,0f7h,0e9h,58h,3fh,1dh,1ah,0f0h
  582.     db    0e3h,3fh,20h,0e4h, 20h,20h,0fbh,0eah    ; column 13
  583.     db    3fh,54h,3fh,3fh,   0efh,55h,5eh,76h
  584.     db    0aah,0e0h,0e1h,78h,0ebh,0eeh,0edh,3fh    ; column 14 
  585.     db    6eh,69h,0e9h,6bh,  3fh,20h,76h,3fh
  586.     db    0e3h,3fh,70h,0e5h, 0e7h,0a8h,9fh,77h    ; column 15
  587.     db    45h,76h,3fh,1bh,   18h,1ah,19h,7fh
  588.     db    94,3eh,0            ; 94 byte set, letter ident
  589.  
  590.                 ; Data General Word Processing to CP 437
  591. dgwpcp437 db    20h,0dah,0c0h,0bfh, 0d9h,9fh,'~',8h    ; column 10
  592.     db    0e4h,0e4h,0f4h,0f5h, 0fbh,8h,0ech,8h
  593.     db    '0','1',0fdh,'3', '4','5','6','7'    ; column 11
  594.     db    '8','9',8h,0c9h, 1bh,8h,1ah,0fah
  595.     db    13h,0e0h,0e1h,8h, 0ebh,8h,8h,0fch    ; column 12
  596.     db    0e9h,8h,8h,8h, 0e6h,8h,0eeh,8h
  597.     db    8h,8h,0e5h,0e7h, 8h,0edh,8h,8h        ; column 13
  598.     db    8h,0eah,1eh,14h, 4 dup (8h)
  599.     db    0c3h,04h,010h,010h, 011h,1eh,1fh,9 dup (8h) ; column 14
  600.     db    '0','1','2','3', '4','5','6','7'    ; column 15
  601.     db    '8','9',3fh,18h, 1ah,1bh,19h,20h
  602.     db    94,'D','W'            ; 94 byte set, letter idents
  603. dgwplen    equ    $-dgwpcp437            ; table size
  604.  
  605.             ; Convert Data General International to Latin1.
  606.             ; DGI chars at these code points translate to the
  607.             ; value used as a code point in the Latin1 table.
  608.             ; Thus the second byte, 0ach, DGI not sign, in its
  609.             ; row 2 col 10 translates to Latin1 not sign in row 12
  610.             ; col 10. Columns 8 and 9 are C1 controls.
  611. dgi2lat    db    0a0h,0ach,0bdh,0b5h, 0b2h,0b3h,0a4h,0a2h ; column 10
  612.     db    0a3h,0aah,0bah,0a1h, 0bfh,0a9h,0aeh,3fh
  613.     db    0bbh,0abh,0b6h,3fh,  3fh,0a5h,0b1h,3fh     ; column 11
  614.     db    3fh,0b7h,60h,0a7h,   0b0h,0a8h,0b4h,3fh
  615.     db    0c1h,0c0h,0c2h,0c4h, 0c3h,0c5h,0c6h,0c7h ; column 12
  616.     db    0c9h,0c8h,0cah,0cbh, 0cdh,0cch,0ceh,0cfh
  617.     db    0d1h,0d3h,0d2h,0d4h, 0d6h,0d5h,0d8h,3fh     ; column 13
  618.     db    0dah,0d9h,0dbh,0dch, 0a0h,59h,0a0h,0a0h
  619.     db    0e1h,0e0h,0e2h,0e4h, 0e3h,0e5h,0e6h,0e7h ; column 14
  620.     db    0e9h,0e8h,0eah,0ebh, 0edh,0ech,0eeh,0efh
  621.     db    0f1h,0f3h,0f2h,0f4h, 0f6h,0f5h,0f8h,3fh     ; column 15
  622.     db    0fah,0f9h,0fbh,0fch, 0dfh,0ffh,0a0h,0a0h
  623. dgi2len    equ    $-dgi2lat
  624. ; Device attributes response string. Make strings asciiz.
  625. v32str    db    escape,'[?63;1;2;4;6;8;9;15c',0 ; VT320, level 3, 132 col, 
  626.     ;printer, selective chars, Sixel graphics, UDkeys, NRC, DEC Tech Chars
  627. v32sda    db    escape,'[>24;0;0c',0    ; VT320 secondary DA response
  628. v22str    db    escape,'[?62;1;2;4;6;8;9;15c',0; VT220, level 2, etc as above
  629. v102str    db    escape,'[?6c',0        ; VT102
  630. v100str db    escape,'[?1c',0        ; vanilla VT100
  631. v52str    db    escape,'/Z',0        ; VT100 in VT52 compatibility mode
  632. h19str    db    escape,'/K',0        ; Heath-19 (says plain VT52)
  633. VIPstr    db    escape,'[8p  OT',03h,escape,'[y7813  P GC  A ',03h,0
  634. VIPstrl    equ    $-VIPstr        ; Honeywell MOD400 3.1 id for ESC [ y
  635. ENQhstr    db    '7813  P GC  A',03h    ; Honeywell MOD400 4.0 id string
  636. ENQhstrl equ    $-ENQhstr
  637. pt20str    db    escape,'! ~0 ~..6~C~2 ~$',0 ; Prime PT200
  638. ENQstr    db    'MS-DOS KERMIT'        ; generic enquiry response
  639. ENQstrl    equ    $-ENQstr
  640.                     ; parity code translation table
  641. partab    db    5,3,1,4,2        ; even, mark, none, odd, space
  642. lpartab equ    $-partab
  643. parcode db    0            ; parity code (0-4)
  644.                     ; baud rate code translation table
  645. ; 45.5 - no VT100 code (call it 50),50,75,110,134.5,150,300,600,1200,
  646. ; 1800,2000,2400,4800,9600,19200,38400,57600,115200  extended beyond DEC
  647. baudtab db    0,0,8,16,24,32,48,56,64,72,80,88,104,112,120,128,128,128,64,8
  648. lbaudtab equ    $-baudtab-1    ; last two are 1200/75 for split speeds
  649. baudidx db    0            ; index into baud rate table
  650. datbits db    7            ; number of databits (7 or 8)
  651.  
  652. ;;;;;;;;;;;;;;; start session save area
  653.     even
  654. savezoff label    word
  655. ttstate dw    offset atnrm        ; terminal automata state
  656. ttstateST dw    offset atnorm        ; state for action after ST seen
  657. apcstring dw    0            ; segment of apcmacro memory
  658. bracecount db    0            ; count of curly braces in APC string
  659. att_normal db    07H            ; default normal screen coloring
  660. oldterm    dw    0            ; terminal type from previous entry
  661. tekflg    db    0            ; Tek mode active flag
  662. old8bit    db    -1            ; flags.remflg setting for D463/D470
  663. iniflgs    dw    0            ; status flags at entry time
  664. modeset db    0            ; temp for atsm/atrm
  665. anspflg    db    0            ; printer flag bits and definitions
  666. h19stat    db    0            ; H-19 extra status bits
  667. h19ctyp    db    1            ; H-19 cursor type (1=ul, 2=bk, 4=off)
  668. h19cur    dw    0            ; H-19 saved cursor position
  669. insmod    db    0            ; insert mode on (1) or off (0)
  670. belcol    db    72            ; column at which to ring margin bell
  671. kbicsr    dw    0            ; cursor when keyboard input typed
  672. kbiflg    db    0            ; set/reset for keyboard input
  673. ttkbi    db    0            ; flag for keyboard input seen
  674. atescftab dw    ansesc            ; offset of esc follower table
  675. setptr    dw    0            ; hold offset of designated char set
  676. upss    db    96,'A',0,0        ; User Preferred Supplemental Set
  677.                     ; size, ident (DEC Supplemental Gr)
  678. ; tab stops, stored here
  679. tabs    db    (swidth+7)/8 dup (0)    ; active tab stops, one column per bit
  680. deftabs    db    (swidth+7)/8 dup (0)    ; default (setup) tab stops
  681. ; byte per line, type of line: 0=normal, 1=double wide, 2=double high
  682. linetype db    slen dup (0)        ; single/double width chars for a line
  683. linescroll db    slen dup (0)        ; horizontal scroll for each line
  684. oldscrn    dw    0            ; old screen. hi=rows-1, low=cols-1
  685.  
  686. ; Scrolling region - do not separate or change order of mar_top & mar_bot
  687. mar_top db    0            ; scrolling region top margin
  688. mar_bot db    23            ; scrolling region bottom margin
  689. mar_left db    0            ; left margin
  690. mar_right db    vswidth-1        ; right margin
  691. savdgmar dw    0            ; DG saved right/left margins
  692. dspstate db    0            ; display state (mode)line work byte
  693. dspmsave dw    0            ; saved main dsp scrolling margins
  694. dspcstat dw    0            ; saved cursor pos for status line
  695. dspcmain dw    0            ; saved cursor pos for main display
  696. G0set    db    gsize+3 dup (0),0    ; G0..G3 char set space
  697. G1set    db    gsize+3 dup (0),1    ; last byte is permanent set index
  698. G2set    db    gsize+3 dup (0),2    ;  and should never be changed
  699. G3set    db    gsize+3 dup (0),3
  700.                     ; Start of save cursor material
  701. savelist equ    this byte        ; top of list of things to save
  702. havesaved db    0            ; if have saved anything
  703. cursor    dw    0            ; cursor position
  704. savextattr db    0            ; extended display attributes
  705. curattr db    07h            ; cursor attribute
  706. svattr_index    equ $-savelist        ; offset of saved cursor attribute
  707. savscbattr db    1            ; normal background attributes
  708. atctype    db    1            ; VTxxx cursor type (1=ul,2=bk,0/4=off)
  709. savflgs dw    0            ; saved flags for atsc/atrc
  710. atwrap    db    0            ; autowrap flag
  711. decrlm    db    0            ; host controlled right-left writing
  712. GLptr    dw    0            ; pointer to char set for GL
  713. GRptr    dw    0            ; pointer to char set for GR
  714. SSptr    dw    0            ; pointer to char set for single shift
  715. Gsetid    db    4 dup (0)        ; set numbers 0..24 of char set
  716. lsavecu equ    $-savelist        ; length of stuff to save
  717. savecu    db    lsavecu dup (0)        ; saved cursor, attr., charset, etc
  718.                     ; End of save cursor material
  719.     even                ; Control sequence storage area
  720. dnparam    dw    0            ; number of parameters for DCS
  721. dparam    dw    maxparam dup (0)    ; Parameters for DCS
  722. dlparam    db    0            ; a single letter Parameter for DCS
  723. dninter    dw    0            ; number of DCS intermediates
  724. dinter    db    maxinter dup (0)    ; Intermediates for DCS
  725. dcsstrf    db    0            ; Final char of DCS
  726. emubufc    dw    0            ; count of chars in string buffer
  727. emubuf    db    66 dup (0)        ; emulator string storage buffer
  728.     db    0            ; safety for string overflow
  729. emubufl    dw    $-emubuf        ; length of emulator buffer
  730.                     ; DG windows structure
  731. dgwindcnt dw    1            ; DG count of active windows
  732. dgwindow dw    25 dup (0)        ; DG window [mar_top,mar_bot]
  733. dgwindcomp db    25 dup (0)        ; DG window compress (0=80,1=132 cols)
  734. dgcaller dw    atnorm            ; DG hex proc callback address
  735. numdigits db    0            ; DG hex digits remaining to be done
  736. dgnum    dw    0            ; DG numerical result
  737. protectena db    0            ; DG protected mode enabled
  738. blinkdis db    0            ; DG blink disabled
  739. dgroll    db    1            ; DG roll (0=disabled, 1=enabled)
  740. dghscrdis db    0            ; DG horz scroll disabled (if 1)
  741. dgcursave dw    16 dup (0)        ; DG cursor position named save area
  742. dgctypesave db    16 dup (0)        ; DG cursor type named save area
  743. dgcross    db    0            ; DG crosshair activity: 0=off, 1=on
  744.                     ;   2 = track keypad, 4= track mouse
  745. dg463fore db    0            ; DG D463 Polygon fill foregnd color
  746. dgaltid    dw    0            ; DG alt term id from host (0=none)
  747. dgkbl    db    0            ; DG keyboard language
  748. dglinepat dw    0ffffh            ; DG line drawing pattern
  749. thisline db    0            ; linetype for current line
  750. scroll    db    1            ; lines to scroll, temp worker
  751. savezlen dw    ($-savezoff)        ; length of z save area
  752. ;;;;;;;;;;;;;;;;; end of session save area
  753.  
  754. ;note low_rgt    dw    0        ; text screen dimensions
  755.                     ; byte low_rgt = max column (79)
  756.                     ; byte low_rgt+1 = max row (23)
  757. led_col    equ    65            ; column position for "LEDs" display
  758. led_off equ    '.'            ; "Off" LED
  759. v320leds db    'VT320 ....'        ; VT320 mode (all 10 characters)
  760. v220leds db    'VT220 ....'        ; VT220 mode
  761. v102leds db    'VT102 ....'        ; VT102 mode
  762. v100leds db    'VT100 ....'        ; VT100 mode
  763. v52leds    db    'VT52      '        ; VT52 mode
  764. h19leds    db    'Heath-19  '        ; Heath-19 mode
  765. honeyleds db    'Honey ....'        ; Honeywell VIP 7809
  766. pt20leds db    'PT200 ....'        ; Prime PT200
  767. d470leds db    'D470      '        ; D470 series from Data General
  768. d470model db    'D470'            ; D470 response for Read New Model ID
  769. d463leds db    'D463      '        ; D463 series from Data General
  770. d463model db    'D463'            ; D463 response for Read New Model ID
  771. ;;d413model db    'D413'            ; D413 response for Read New Model ID
  772. data    ends
  773.  
  774. code2    segment
  775.     extrn    tekini:far, tekemu:far, tekend:far, teksetcursor:far
  776.     extrn    dgline:far, dgbar:far, dgcrosson:far, dgcrossoff:far
  777.     extrn    dgcrossrpt:far, dgsetcrloc:far, dgarc:far, dgpoly:far
  778. code2    ends
  779.  
  780. code    segment
  781.     extrn    cptchr:near, pntchr:near, pntchk:near, pntflsh:near
  782.     extrn    modlin:near, latin1:near
  783.     extrn    clrmod:near, dec2di:near, latininv:near, trnprs:near
  784.     extrn    dgsettek:far, vtksmac:near, vtkrmac:near, product:near
  785.  
  786.     assume    ds:data, es:nothing
  787.  
  788. fmodlin    proc    far
  789.     call    modlin
  790.     ret
  791. fmodlin    endp
  792.  
  793. fclrmod    proc    far
  794.     call    clrmod
  795.     ret
  796. fclrmod    endp
  797.  
  798. fcptchr    proc    far
  799.     call    cptchr
  800.     ret
  801. fcptchr    endp
  802.  
  803. fdec2di    proc    far
  804.     call    dec2di
  805.     ret
  806. fdec2di    endp
  807.  
  808. fpntchr    proc    far
  809.     call    pntchr
  810.     ret
  811. fpntchr    endp
  812.  
  813. fpntchk    proc    far
  814.     call    pntchk
  815.     ret
  816. fpntchk    endp
  817.  
  818. fpntflsh proc    far
  819.     call    pntflsh
  820.     ret
  821. fpntflsh endp
  822.  
  823. ftrnprs    proc    far
  824.     call    trnprs
  825.     ret
  826. ftrnprs    endp
  827.  
  828. fvtksmac proc    far
  829.     call    vtksmac
  830.     ret
  831. fvtksmac endp
  832.  
  833. fvtkrmac proc    far
  834.     call    vtkrmac
  835.     ret
  836. fvtkrmac endp
  837.  
  838. fproduct proc    far
  839.     call    product
  840.     ret
  841. fproduct endp
  842.  
  843. flatin1    proc    far
  844.     push    flags.chrset
  845.     mov    ax,vtcpage        ; get current terminal Code Page
  846.     mov    flags.chrset,ax        ; tell file transfer part
  847.     call    latin1
  848.     call    latininv
  849.     pop    flags.chrset
  850.     ret
  851. flatin1    endp
  852. code    ends
  853.  
  854. code1    segment
  855.     extrn    prtbout:near, prtnout:near, csrtype:near, atsclr:near
  856.     extrn    vtscru:near, vtscrd:near, chgdsp:near
  857.     extrn    setpos:near, setudk:near, udkclear:near, vtbell:near
  858.     extrn    setatch:near, qsetatch:near, getatch:near
  859.     extrn    revideo:near, getbold:near, setbold:near, clrbold:near
  860.     extrn    getblink:near, setblink:near, clrblink:near, getunder:near
  861.     extrn    setunder:near, clrunder:near, revscn:near, setcolor:near
  862.     extrn    setrev:near, clrrev:near, tekrpal:near
  863.     extrn    tekinq:near, tekpal:near, tekrpal:near
  864.     extrn    atparse:near, atpclr:near, atdispat:near, apcmacro:near
  865.     extrn    setprot:near, clrprot:near, frepaint:far, touchup:near
  866.  
  867.     assume    cs:code1, ds:data, es:nothing
  868.  
  869. ; Terminal display routine. Call with character incoming character in AL
  870.  
  871. anstty    proc    near
  872.     mov    dx,cursor        ; some routines need cursor in dx
  873.     mov    kbiflg,0        ; clear old flag value
  874.     test    yflags,trnctl        ; Debug mode?
  875.     jz    anstt1            ; z = no
  876.     jmp    atdeb            ; yes, just translate control chars
  877. anstt1:    cmp    ttkbi,0            ; new keyboard input?
  878.     je    anstt2            ; e = no, just continue
  879.     mov    kbiflg,1        ; yes, set flag
  880.     mov    kbicsr,dx        ; save old cursor
  881.     mov    ttkbi,0            ; clear this flag
  882.  
  883. anstt2:    test    anspflg,vtcntp        ; print controller on?
  884.     jz    anstt4            ; z = no
  885.     test    flags.capflg,logses    ; capturing output?
  886.     jz    anstt3            ; z = no, forget this part
  887.     push    ax            ; save char
  888.     call    fcptchr            ; give it captured character
  889.     pop    ax            ; restore character
  890. anstt3:    jmp    ttstate            ; print transparently
  891.  
  892. anstt4:    test    flags.vtflg,ttd463+ttd470 ; DG D463/D470 mode?
  893.     jnz    anstt4a            ; nz = yes, must pass nulls
  894.     or    al,al            ; NUL char?
  895.     jz    atign            ; z = yes, ignore it before logging
  896. anstt4a:test    yflags,capt        ; capturing output?
  897.     jz    anstt8            ; z = no, forget this part
  898.     call    fcptchr            ; give it captured character
  899.                     ; Direct char to processor module
  900. anstt8:    test    flags.vtflg,ttd463+ttd470 ; DG D463/D470 mode?
  901.     jnz    anstt10            ; nz = yes
  902.     cmp    vtemu.vtchset,13    ; ASCII (0) or NRC's (1-13) active?
  903.     ja    anstt8b            ; a = no
  904.     cmp    vtemu.vtchset,0        ; ASCII?
  905.     je    anstt8b            ; e = yes
  906.     and    al,7fh            ; yes, NRCs force chars to 7-bits
  907. anstt8b:test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  908.     jnz    anstt9            ; nz = no
  909.     cmp    al,20h            ; C0 control code?
  910.     jb    anstt8c            ; b = yes
  911.     cmp    vtemu.vtchset,15    ; TRANSPARENT?
  912.     je    anstt9            ; e = yes, pass all others
  913. anstt8c:jmp    atctrl            ; dispatch on control code
  914. anstt9:    jmp    ttstate            ; dispatch according to state
  915.  
  916.                     ; DG D463/D470 terminal
  917. anstt10:test    flags.remflg,d8bit    ; use high bit?
  918.     jnz    anstt11            ; nz = yes
  919.     and    al,7fh            ; 7 bit terminal only
  920. anstt11:test    anspflg,vtcntp        ; controller (transparent) printing?
  921.     jnz    anstt12            ; nz = yes, go through filter routine
  922.     cmp    al,20h            ; C0 control code?
  923.     jae    anstt12            ; ae = no, do according to ttstate
  924.     cmp    ttstate,offset atnrm    ; normal text processing?
  925.     jne    anstt12            ; ne = no, pass controls to state
  926.     jmp    dgctrl            ; do DG controls
  927. anstt12:jmp    ttstate            ; process regularly
  928. anstty    endp
  929.  
  930. atign:    ret                ; something to be ignored
  931.  
  932. atnorm: mov    ttstate,offset atnrm    ; reset state to "normal"
  933.     mov    ttstateST,offset atnorm    ; reset state for ST seen
  934.     ret
  935.             
  936. atnrm    proc    near            ; Normal character (in AL) processor
  937.     cmp    SSptr,0            ; single shift needed?
  938.     je    atnrm10            ; e = no
  939.     and    al,not 80h        ; strip high bit
  940.     mov    bx,SSptr        ; pointer to desired char set
  941.     mov    SSptr,0            ; clear single shift indicator
  942.     jmp    short atnrm12        ; process
  943.  
  944. atnrm10:test    al,80h            ; high bit set for GRight?
  945.     jnz    atnrm11            ; nz = yes
  946.     mov    bx,GLptr        ; GL char set
  947.     jmp    short atnrm12        ; process
  948.  
  949. atnrm11:and    al,not 80h        ; strip high bit
  950.     mov    bx,GRptr        ; GR char set
  951.  
  952. atnrm12:xlatb                ; translate al to new char in al
  953. atnrm13:cmp    rxtable+256,0        ; TRANSLATION INPUT turned off?
  954.     je    atnrm14            ; e = yes, use ISO mechanisms
  955.     mov    bx,offset rxtable    ; address of translate table
  956.     mov    ah,al            ; copy char
  957.     xlatb                ; new char is in al
  958. atnrm14:cmp    al,DEL            ; ANSI Delete char?
  959.     jne    atnrm2            ; ne = no
  960.     ret                ; ignore DEL
  961.                     ; use atdeb for debug simple tty dsp
  962. atnrm2:    mov    dx,cursor        ; get cursor virtual position
  963.     push    bx
  964.     mov    bl,dh            ; get row
  965.     xor    bh,bh
  966.     mov    bl,linetype[bx]        ; line width
  967.     mov    thisline,bl        ; save for current reference
  968.     pop    bx
  969.     test    vtemu.vtflgop,decawm    ; Autowrap active?
  970.     jz    atnrm2a            ; z = no
  971.     mov    cl,mar_right        ; logical right margin
  972.     cmp    thisline,0        ; single width line?
  973.     je    atnrm2c            ; e = yes, single
  974.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  975.     jnz    atnrm2c            ; nz = yes, these double the margins
  976.     shr    cl,1            ; halve right column # for wide chars
  977. atnrm2c:cmp    dl,cl            ; want to write beyond right margin?
  978.     jb    atnrm2a            ; b = no
  979.     cmp    atwrap,0        ; autowrap pending?
  980.     je    atnrm2a            ; e = no
  981.     test    anspflg,vtautop        ; printing desired?
  982.     jz    atnrm2a            ; e = no
  983.     push    dx
  984.     push    ax            ; save char
  985.     mov    dh,atwrap        ; get 1+last display line's row
  986.     dec    dh            ; up one line
  987.     call    pntlin            ; print line
  988.     mov    al,LF            ; terminate in LF
  989.     call    fpntchr
  990.     call    fpntflsh        ; flush printer buffer
  991.     pop    ax            ; recover char in AL
  992.     pop    dx
  993. atnrm2a:push    ax            ; save character
  994.     call    getatch            ; check for protected field
  995.     test    cl,att_protect        ; protected?
  996.     jz    atnrm2d            ; z = no
  997.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  998.     jz    atnrm2d            ; z = no
  999.     call    dgcuf            ; do DG cursor right
  1000.     mov    dx,cursor
  1001. atnrm2d:cmp    decrlm,0        ; host right-left mode active?
  1002.     je    atnrm2e            ; e = no
  1003.     cmp    atwrap,0        ; wrap pending?
  1004.     je    atnrm2e            ; e = no
  1005.     mov    dl,mar_right
  1006.     inc    dl            ; set to wrap in normal sense
  1007.  
  1008. atnrm2e:call    atscur            ; set cursor physical position
  1009.     pop    ax
  1010.     cmp    insmod,0        ; insert mode off?
  1011.     je    atnrm3            ; e = yes
  1012.     push    ax
  1013.     call    inschr            ; open a char space in this line
  1014.     cmp    thisline,0        ; single width line?
  1015.     je    atnrm2b            ; e = yes
  1016.     call    inschr            ; open second space for double width
  1017. atnrm2b:pop    ax            ; restore char
  1018.                     ; set cursor before writing char
  1019. atnrm3:    cmp    thisline,0        ; check for double characteristic
  1020.     je    atnrm3a            ; e = normal, not doubles
  1021.     shl    dl,1            ; double the column number
  1022. atnrm3a:    
  1023.     push    dx
  1024.     call    direction        ; set dx to desired position
  1025.     mov    ah,curattr        ; current attribute
  1026.     mov    cl,extattr        ; extended attribute
  1027.     call    setatch            ; write char (al) and attribute (ah)
  1028.     pop    dx
  1029.     cmp    thisline,0        ; check for double characteristic
  1030.     je    atnrm4            ; e = normal, not doubles
  1031.     cmp    decrlm,0        ; host writing direction active?
  1032.     je    atnrm3b            ; e = no
  1033.     dec    dl            ; next col
  1034.     jmp    short atnrm3c
  1035. atnrm3b:inc    dl            ; next column
  1036. atnrm3c:push    dx
  1037.     call    direction        ; set dx to desired position
  1038.     mov    al,' '            ; use a space for doubling
  1039.     mov    ah,curattr        ; current attribute
  1040.     mov    cl,extattr        ; extended attribute
  1041.     call    setatch            ; write char (al) and attribute (ah)
  1042.     pop    dx
  1043.     shr    dl,1            ; keep "cursor" in single units
  1044.  
  1045. atnrm4:    test    flags.vtflg,ttd463+ttd470+ttheath ; D463, D470 or H-19?
  1046.     jz    atnrm4d            ; z = no
  1047.     jmp    dgcuf            ; do DG cursor forward
  1048.  
  1049. atnrm4d:test    vtemu.vtflgop,decawm    ; Autowrap active?
  1050.     jz    atnrm5            ; z = no
  1051.     cmp    decrlm,0        ; host writing left to right?
  1052.     je    atnrm4e            ; e = no
  1053.     or    dl,dl            ; wrote in left most col?
  1054.     jnz    atnrm5            ; nz = no
  1055.     mov    dl,mar_right        ; set next column to the right
  1056.     jmp    short atnrm4b        ; do not move cursor now
  1057.  
  1058. atnrm4e:mov    cl,mar_right        ; logical right margin
  1059.     cmp    thisline,0        ; single width line?
  1060.     je    atnrm4a            ; e = yes, single
  1061.     shr    cl,1            ; halve right column # for wide chars
  1062. atnrm4a:cmp    dl,cl            ; wrote in right-most column?
  1063.     jb    atnrm5            ; b = no
  1064.     inc    dl            ; say want to use next column
  1065. atnrm4b:mov    atwrap,dh        ; turn on wrap flag with 1 + this row
  1066.     inc    atwrap            ;  so 0 means no wrap pending
  1067.     test    flags.vtflg,ttheath    ; H-19?
  1068.     jnz    atscur            ; nz = yes, show wrap now
  1069.     mov    cursor,dx        ; virtual cursor position
  1070.     ret                ; exit without moving cursor from eol
  1071.  
  1072. atnrm5:    mov    dx,cursor        ; restore cursor position
  1073.     cmp    decrlm,0        ; host writing direction active?
  1074.     je    atnrm5a            ; e = no
  1075.     or    dl,dl
  1076.     jz    atnrm5b
  1077.     dec    dl            ; next column
  1078.     jmp    short atnrm5b
  1079. atnrm5a:inc    dl            ; next column
  1080. atnrm5b:mov    atwrap,0        ; say not about to wrap
  1081. ;;    jmp    short atscur
  1082. atnrm    endp
  1083.  
  1084. atscur:    cmp    dl,mar_left        ; left of left margin?
  1085.     jae    atscu1            ; ae = no, continue
  1086.     mov    dl,mar_left        ; set at left margin
  1087. atscu1:    mov    cl,mar_right        ; copy logical margin; cl = right col
  1088.     push    bx
  1089.     mov    bl,dh            ; get row
  1090.     xor     bh,bh
  1091.     cmp    linetype [bx],0        ; single width lines?
  1092.     pop    bx
  1093.     je    atscu1a            ; e = yes, single width
  1094.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  1095.     jnz    atscu1a            ; nz = yes, these double the margins
  1096.     shr    cl,1            ; halve column # for double wides
  1097. atscu1a:cmp    dl,cl            ; right of right margin?
  1098.     jbe    atscu3            ; be = no, continue
  1099.     mov    dl,cl            ; assume no autowrap
  1100.     test    vtemu.vtflgop,decawm    ; Autowrap?
  1101.     jz    atscu3            ; z = no
  1102.     mov    dl,mar_left        ; set to left margin
  1103.     cmp    decrlm,0        ; host right-left mode active?
  1104.     je    atscu1e            ; e = no
  1105.     mov    dl,mar_right
  1106. atscu1e:cmp    dh,byte ptr low_rgt+1    ; at bottom of screen?
  1107.     je    atscu1b            ; e = yes
  1108.     cmp    dh,mar_bot        ; at bottom of scrolling region?
  1109.     jl    atscu2            ; l = no, bump cursor and continue
  1110. atscu1b:test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  1111.     jz    atscu1d            ; z = no
  1112.     cmp    dgroll,0        ; is DG roll enabled?
  1113.     jne    atscu1d            ; ne = yes, do the scroll
  1114.     mov    dh,mar_top        ; move to top of window
  1115.     jmp    short atscu3
  1116. atscu1d:mov    scroll,1        ; scroll count = 1 line
  1117.     call    atscru            ; scroll up
  1118.     dec    dh            ; offset inc dh below
  1119. atscu2: inc    dh            ; just bump it
  1120. atscu3: or    dh,dh            ; constrain row to valid range
  1121.     jge    atscu4            ; ge = non-negative row, ok
  1122.     xor    dh,dh
  1123. atscu4: cmp    dh,byte ptr low_rgt+1    ; 25th line?
  1124.     jle    atsetcur        ; le = no
  1125.     mov    dh,byte ptr low_rgt+1    ; set to 24th line
  1126.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  1127.     jne    atscu4a            ; ne = no [hlk]
  1128.     test    h19stat,h19l25        ; Heath 25th line enabled?
  1129.     jz    atsetcur        ; z = no
  1130. atscu4a:inc    dh            ; go to line 25 [hlk]
  1131.     test    yflags,modoff        ; is mode line off?
  1132.     jnz    atscu4b            ; nz = yes
  1133.     push    dx            ; save cursor position
  1134.     call    fclrmod            ; clear the line
  1135.     or    yflags,modoff        ; now say it's off (owned by host)
  1136.     pop    dx
  1137. atscu4b:mov    flags.modflg,2        ; say mode line is owned by host
  1138.  
  1139. atsetcur:mov    cursor,dx        ; set cursor and return
  1140.     push    dx
  1141.     mov    bl,dh            ; get row
  1142.     xor    bh,bh            ; clear high byte
  1143.     cmp    linetype[bx],0        ; single width line?
  1144.     je    atsetcu1        ; e = yes
  1145.     shl    dl,1            ; double the column number
  1146. atsetcu1:call    direction        ; set dx to desired position
  1147.     call    setpos            ; set cursor physical position
  1148.     pop    dx
  1149.     test    vtemu.vtflgop,vsmarginbell; do we care about margin bell?
  1150.     jz    atsetcu2        ; z = no, return if no margin bell
  1151.     cmp    kbiflg,0        ; is keyboard input flag set?
  1152.     je    atsetcu2        ; e = no, just return
  1153.     mov    bx,kbicsr        ; cursor at previous keyboard input
  1154.     cmp    bh,dh            ; same row as now?
  1155.     jne    atsetcu2        ; ne = no, just return
  1156.     cmp    bl,belcol        ; old cursor at or left of bell column?
  1157.     ja    atsetcu2        ; a = no, just return
  1158.     cmp    dl,belcol        ; new cursor past bell column?
  1159.     jbe    atsetcu2        ; be = no, just return
  1160.     call    vtbell            ; ring the bell
  1161. atsetcu2:ret
  1162.  
  1163. ; Control-character dispatcher
  1164. atctrl:    cmp    al,escape        ; an escape sequence starting?
  1165.     je    atctrl1            ; e = yes, don't print it
  1166.     cmp    al,CSI            ; this kind of escape?
  1167.     je    atctrl1            ; e = yes
  1168.     cmp    al,18h            ; CAN (cancel)?
  1169.     je    atctrl6            ; e = yes
  1170.     cmp    al,1ah            ; SUB (treated as CAN)?
  1171.     je    atctrl6            ; e = yes
  1172.     cmp    ttstate,offset atdcsnul    ; consuming a DCS?
  1173.     jne    atctrl5            ; ne = no
  1174.     ret                ; consume
  1175. atctrl5:cmp    ttstate,offset atesc1    ; state is second char of ST?
  1176.     jne    atctrl6            ; ne = no
  1177.     jmp    ttstate            ; go process second char
  1178. atctrl6:test    anspflg,vtcntp        ; printing desired?
  1179.     jz    atctrl1            ; z = no
  1180.     call    fpntchr            ; print char in al
  1181. atctrl1:xor    ah,ah            ; clear for word use below
  1182.     test    al,80h            ; high bit set?
  1183.     jnz    atctrl2            ; nz = yes
  1184.     mov    di,ax            ; use AL as a word index
  1185.     shl    di,1
  1186. atctrl3:jmp    ansc0[di]        ; dispatch on C0 control codes
  1187. atctrl2:and    al,not 80h        ; strip high bit
  1188.     mov    di,ax            ; use AL as a word index
  1189.     shl    di,1
  1190.     test    flags.vtflg,ttvt320+ttvt220 ; doing VT320/VT220?
  1191.     jz    atctrl3            ; z = no, trim back to C0
  1192. atctrl4:jmp    ansc1[di]        ; dispatch on C1 control codes
  1193.  
  1194. ; Control code routines
  1195. atbs:    cmp    decrlm,0        ; host writing direction active?
  1196.     jne    atbs2            ; ne = yes
  1197.     or    dl,dl            ; Backspace, too far?
  1198.     jz    atbs1            ; z = at column 0 already
  1199.     dec    dl            ; backup cursor
  1200. atbs1:    call    atccpc            ; check range
  1201.     mov    atwrap,0        ; cancel wrap pending
  1202.     jmp    atsetcur        ; set cursor and return
  1203.  
  1204. atbs2:    cmp    dl,mar_right        ; at right margin now?
  1205.     je    atbs1            ; e = yes, stop
  1206.     inc    dl
  1207.     jmp    short atbs1
  1208.  
  1209. atht:    cmp    flags.vtflg,ttheath    ; Horizontal Tab, Heath-19 mode?
  1210.     je    atht2            ; e = yes, handle specially
  1211.     xor    ch,ch
  1212.     mov    cl,mar_right
  1213.     cmp    dl,cl            ; at or beyond last column?
  1214.     jae    atht1a            ; ae = yes check range, set cursor
  1215. atht1:    inc    dl            ; tab always moves at least one column
  1216.     push    si
  1217.     mov    si,vtemu.vttbst        ; active buffer
  1218.     call    istabs            ; returns carry set if at a tabstop
  1219.     pop    si
  1220.     jc    atht1a            ; c = at a tabstop
  1221.     loopz    atht1
  1222. atht1a:    call    atccpc            ; check range
  1223. atht1b:    call    atsetcur        ; set cursor and return
  1224.     ret
  1225.  
  1226. atht2:    mov    dx,cursor        ; Heath-19. get cursor position
  1227.     add    dl,8            ; tabs are every 8 columns
  1228.     and    dl,not 7        ; do modulo 8
  1229.     cmp    dl,mar_right        ; check against right edge
  1230.     jbe    atht3            ; be = in range
  1231.     mov    dl,mar_right        ; else go to right margin
  1232. atht3:    jmp    atht1b            ; set cursor and return
  1233.  
  1234. atlf:    test    vtemu.vtflgop,anslnm    ; Line Feed, New-line mode?
  1235.     jz    atlf2            ; z = no, just move to next line down
  1236. atlf1:    mov    dl,mar_left        ; move to left margin also
  1237.     cmp    decrlm,0        ; host writing direction active?
  1238.     je    atlf2            ; e = no
  1239.     mov    dl,mar_right
  1240. atlf2:    test    anspflg,vtautop        ; printing desired?
  1241.     jz    atlf3            ; e = no
  1242.     push    dx
  1243.     push    ax            ; save char
  1244.     call    pntlin            ; print current line
  1245.     pop    ax            ; recover char in AL, print it too
  1246.     call    fpntchr
  1247.     call    fpntflsh        ; flush printer buffer
  1248.     pop    dx
  1249. atlf3:    inc    dh            ; index line down
  1250.     call    atccic            ; check indexing
  1251.     call    ax            ; call scrolling routine
  1252.     jmp    atsetcur        ; set cursor
  1253.  
  1254. atcr:     mov    dl,mar_left        ; Carriage Return, go to left margin
  1255.     mov    atwrap,0        ; cancel wrap pending
  1256.     cmp    decrlm,0        ; host writing direction active?
  1257.     je    atcr2            ; e = no
  1258.     mov    dl,mar_right
  1259. atcr2:    cmp    flags.vtflg,ttheath    ; Heath-19?
  1260.     jne    atcr1            ; ne = no
  1261.     test    h19stat,h19alf        ; auto line feed on?
  1262.     jnz    atlf2            ; nz = yes, do the LF part above
  1263. atcr1:    jmp    atsetcur        ; set cursor and return
  1264.  
  1265. atff:    cmp    ttstate,offset atescf    ; Form Feed, parsing escape sequence?
  1266.     jne    atlf            ; ne = no, do as line feed
  1267. atff1:    test    denyflg,tekxflg        ; is auto Tek mode disabled?
  1268.     jnz    atlf            ; nz = yes, treat as line feed
  1269.     call    atsc            ; save cursor and associated data
  1270.     mov    al,escape
  1271.     call    TEKEMU
  1272.     mov    al,FF
  1273.     call    TEKEMU            ; feed to Tektronix Emulator, al=FF
  1274.     jmp    atnorm
  1275.  
  1276. atcan:    mov    parstate,0        ; CAN, clear esc seq parser
  1277.     jmp    atnorm
  1278.  
  1279. atenq:    mov    cx,ENQhstrl        ; length of Honeywell string
  1280.     mov    si,offset ENQhstr    ; ptr to string
  1281.     mov    ttyact,0        ; start grouping for networks
  1282.     cmp    flags.vtflg,tthoney    ; ENQ, Honeywell terminal?
  1283.     je    atenq1            ; e = yes
  1284.     cmp    vtenqenable,0        ; VTxxx response enabled?
  1285.     je    atenq2            ; e = no
  1286.     mov    cx,ENQstrl        ; length of string
  1287.     mov    si,offset ENQstr    ; ptr to string
  1288. atenq1:    cld    
  1289.     lodsb                ; get a byte
  1290.     push    cx            ; save regs
  1291.     push    si
  1292.     call    prtbout            ; send to port WITHOUT echo
  1293.     pop     si
  1294.     pop    cx
  1295.     loop    atenq1            ; loop for all characters
  1296.     mov    ttstate, offset atnrm    ; reset to normal and return
  1297.     mov    ttyact,1        ; end group output for networks
  1298. atenq2:    ret
  1299.  
  1300. atesc:    cmp    ttstate,offset atdcsnul    ; consuming a DCS?
  1301.     jne    atesc3            ; ne = no
  1302.     mov    ttstate,offset atesc1    ; stay here
  1303.     ret
  1304. atesc1:    cmp    al,'\'            ; end of ST?
  1305.     je    atesc2            ; e = yes
  1306.     jmp    atdcsnul        ; continue to consume DCS
  1307. atesc2:    jmp    atgotst            ; reset DCS processing
  1308.  
  1309. atesc3:    mov    ttstate,offset atescf    ; ESC, next state is escape follower
  1310.     ret
  1311.  
  1312. ; Respond to character following Escape, dispatch on that char
  1313. atescf:    call    atpclr            ; clear parser argument list
  1314.     mov    atescftab,offset ansesc; ANSI escape table, for atdispat
  1315.     mov    cx,flags.vtflg
  1316.     test    cx,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; VT320 etc?
  1317.     jnz    atescf2            ; nz = yes
  1318.     mov    atescftab,offset v52esc ; VT52 escape table
  1319.     cmp    cx,ttvt52        ; VT52?
  1320.     je    atescf1            ; e = yes
  1321.     mov    atescftab,offset h19esc ; use Heath-19 table
  1322.     cmp    cx,ttheath        ; Heath-19?
  1323.     je    atescf1            ; e = yes
  1324.     mov    atescftab,offset pt200esc
  1325.     cmp    cx,ttpt200        ; Prime PT200?
  1326.     je    atescf2            ; e = yes
  1327.     ret                ; return on error
  1328. atescf1:mov    ttstate,offset atnrm    ; reset state to "normal"
  1329.     mov    bx,atescftab        ; get offset of escape follower table
  1330.     jmp    atdispat        ; perform dispatch via table in BX
  1331.  
  1332. atescf2:test    al,not (2fh)        ; in intermediates (column 2)?
  1333.     jnz    atescf1            ; nz = no, dispatch on this char
  1334.     mov    ttstate,offset atescf2    ; stay in this state til col 3 or more
  1335.     mov    bx,ninter        ; number of intermediates
  1336.     cmp    bx,maxinter        ; done enough already?
  1337.     jae    atescf3            ; ae = yes, ignore the excess
  1338.     mov    inter[bx],al        ; store this one
  1339.     inc    ninter            ; one more
  1340. atescf3:ret                ; get more input
  1341.  
  1342.                     ; CSI, char 9bh (ANSI CSI == ESC [)
  1343. atcsi0:    cmp    ninter,0        ; any intermediates from ESC..[?
  1344.     je    atcsi            ; e = no, else not this item
  1345.     jmp    atnorm            ; reset state to "normal"
  1346.                     ; enter here with real CSI char
  1347. atcsi:    mov    ttstate,offset atparse    ; next state is parse control seq
  1348.     mov    pardone,offset atcsi1    ; where to jmp when done
  1349.     mov    parfail,offset atnorm    ; where to jmp if failure
  1350.     jmp    atpclr            ; clear parser parameters and return
  1351.  
  1352. atcsi1:    mov    bx,offset anstab    ; ANSI Final character table
  1353.     mov    ttstate,offset atnrm    ; reset state to "normal"
  1354.     jmp    atdispat        ; dispatch on character
  1355.  
  1356. h19csi:    test    vtemu.vtflgop,decanm    ; Heath-19 "ESC [", is ANSI mode on?
  1357.     jnz    h19csi1            ; nz = yes
  1358.     mov    ttstate,offset atnrm    ; else ignore the "[" (kbd lock)
  1359.     ret
  1360. h19csi1:mov    ttstate,offset atparse    ; H-19, ESC [ parser
  1361.     mov    pardone,offset h19csi2     ; where to jmp when done
  1362.     mov    parfail,offset atnorm    ; where to jmp if failure
  1363.     ret                ; get next char
  1364. h19csi2:mov    bx,offset h19ans    ; H-19 ANSI Final character table
  1365.     mov    ttstate,offset atnrm    ; reset state to "normal"
  1366.     jmp    atdispat        ; dispatch on character
  1367.  
  1368. ; Process Device Control Strings (DCS or ESC P lead-in chars, already read).
  1369. atdcs0:    cmp    ninter,0        ; any intermediates?
  1370.     je    atdcs            ; e = no, else not this item
  1371.     jmp    atnorm            ; reset state to normal
  1372.                     ; enter here with real DCS char
  1373. atdcs:    mov    ttstate,offset atparse    ; next state is parse control seq
  1374.     mov    pardone,offset atdcs1    ; where to jmp when done
  1375.     mov    parfail,offset atnorm    ; where to jmp if failure
  1376.     ret
  1377. atdcs1:    mov    dcsstrf,al        ; record Final char
  1378.     mov    emubufc,0        ; clear string count
  1379.     mov    cx,maxparam        ; number of DCS parameters
  1380.     push    si            ; copy these to the DCS area so that
  1381.     push    di            ;  they are not lost when an ST is
  1382.     push    es            ;  parsed (parser clears ESC items)
  1383.     push    ds
  1384.     pop    es
  1385.     mov    si,offset param        ; ESC paramater storage area, numeric
  1386.     mov    di,offset dparam    ; DCS parameter storage area, numeric
  1387.     cld
  1388.     rep    movsw            ; copy set to DCS storage area
  1389.     mov    cl,lparam         ; copy letter Paramter
  1390.     mov    dlparam,cl
  1391.     mov    cx,maxinter        ; number of intermediate characters
  1392.     mov    si,offset inter        ; source
  1393.     mov    di,offset dinter    ; destination
  1394.     rep    movsb
  1395.     mov    si,nparam        ; number of parameters
  1396.     mov    dnparam,si
  1397.     mov    si,ninter
  1398.     mov    dninter,si        ; number of intermediates
  1399.     pop    es
  1400.     pop    di
  1401.     pop    si
  1402.     mov    ttstateST,offset atnorm ; default ST completion state
  1403.     mov    emubufc,0        ; clear processed string length
  1404.     mov    al,dcsstrf        ; get DCS Final char
  1405.     mov    bx,offset dcstab    ; DCS dispatch table
  1406.     call    atdispat        ; go to DCS handler
  1407.     ret
  1408.  
  1409. ; Process ST or ESC \  String Terminator.
  1410. atgotst0:cmp    ninter,0        ; any intermediates in ESC..\?
  1411.     je    atgotst            ; e = no, else not this item
  1412.     jmp    atnorm            ; reset state to normal
  1413.                     ; enter here with real ST char
  1414. atgotst:jmp    ttstateST        ; go to state for ST arrival
  1415.  
  1416. ; Read and discard OSC (ESC ]), PM (ESC ^) control sequences
  1417. ; through final ST (ESC \) terminator.
  1418. atdcsnul0:cmp    ninter,0        ; any intermediates in ESC..\?
  1419.     je    atdcsnul        ; e = no, else not this item
  1420.     ret
  1421.                     ; enter here with real ST char
  1422. atdcsnul:mov    dcsstrf,0        ; simulate a null (dummy) Final char
  1423.     mov    emubufc,0        ; clear string count
  1424.     mov    ttstate,offset atdcsnul    ; keep coming here
  1425.     mov    ttstateST,offset atnorm    ; where to go when ST has been seen
  1426.     ret                ; consume chars
  1427.  
  1428. ; Process Application Process Control string (APC or ESC _ lead-in chars,
  1429. ; already read). Mallocs 1KB buffer, passes buffer to apcmacro for execution
  1430. ; as a Take file. Curly braces protect comma command separators.
  1431. atapc:    cmp    ninter,0        ; any intermediates?
  1432.     je    atapc0            ; e = no, else not this item
  1433.     jmp    atnorm            ; reset state to normal
  1434.                     ; enter here with real DCS char
  1435. atapc0:    mov    ax,apcstring        ; old string buffer segment
  1436.     or    ax,ax            ; used?
  1437.     jz    atapc1            ; z = no
  1438.     push    es
  1439.     mov    es,ax
  1440.     mov    ah,freemem        ; free that string memory
  1441.     int    dos
  1442.     pop    es
  1443.     mov    apcstring,0        ; clear pointer
  1444. atapc1:    mov    bx,(1024+3+15)/16    ; 1K buffer
  1445.     mov    cx,bx            ; remember desired paragraphs
  1446.     mov    ah,alloc        ; allocate a memory block
  1447.     int    dos
  1448.     jc    atapc2            ; c = error, not enough memory
  1449.      cmp    bx,cx            ; obtained vs wanted
  1450.     jae    atapc3            ; ae = enough
  1451.     push    es
  1452.     mov    es,ax            ; allocated segment
  1453.     mov    ah,freemem        ; free it again
  1454.     int    dos
  1455.     pop    es
  1456. atapc2:    jmp    atnorm            ; fail
  1457.  
  1458. atapc3:    mov    apcstring,ax        ; remember segment
  1459.     mov    bracecount,0        ; count of curly braces in string
  1460.     mov    emubufc,0        ; preset string buffer count
  1461.     mov    ttstate,offset atapc4    ; next state is read string
  1462.     mov    ttstateST,offset atapc5    ; where to go when ST has been seen
  1463.     ret
  1464.                     ; read bytes of APC string
  1465. atapc4:    mov    bx,emubufc        ; count of buffer chars
  1466.     cmp    bx,1024            ; too many?
  1467.     ja    atapc6            ; a = yes, ignore string
  1468.     push    es
  1469.     mov    cx,apcstring        ; segment of string buffer
  1470.     mov    es,cx
  1471.     cmp    al,braceop        ; opening brace?
  1472.     jne    atapc4a            ; ne = no
  1473.     inc    bracecount        ; count up braces
  1474. atapc4a:cmp    al,bracecl        ; closing brace?
  1475.     jne    atapc4b            ; ne = no
  1476.     sub    bracecount,1        ; count down braces
  1477.     jnc    atapc4b            ; nc = not below zero
  1478.     mov    bracecount,0        ; clamp to zero
  1479. atapc4b:cmp    al,','            ; comma command separator?
  1480.     jne    atapc4c            ; ne = no
  1481.     cmp    bracecount,0        ; in curly braces?
  1482.     jne    atapc4c            ; ne = yes, leave comma as comma
  1483.     mov    al,CR            ; replace bare comma as CR
  1484. atapc4c:xor    ah,ah
  1485.     mov    es:[bx],ax        ; store incoming byte + null
  1486.     pop    es
  1487.     inc    emubufc            ; count bytes in buffer
  1488.     ret                ; accumulate more bytes
  1489.  
  1490. atapc5:    mov    ax,apcstring        ; get here upon ST for APC
  1491.     or    ax,ax            ; string buffer in use?
  1492.     jz    atapc6            ; z = no, quit
  1493.     mov    ttstate,offset atnrm    ; reinit state before leaving
  1494.     mov    ttstateST,offset atnorm
  1495.     mov    bracecount,0        ; count of curly braces in string
  1496.     cmp    apcenable,0        ; is APCMACRO enabled?
  1497.     je    atapc6            ; e = no, quit
  1498.     push    es
  1499.     mov    es,ax
  1500.     mov    bx,emubufc        ; count of bytes in string
  1501.     mov    byte ptr es:[bx],CR    ; append CR C to renter Connect mode
  1502.     mov    byte ptr es:[bx+1],'C'
  1503.     add    bx,2            ; two more bytes in buffer
  1504.     pop    es
  1505.     mov    cx,bx            ; CX used to pass string length
  1506.     call    APCMACRO        ; create and execute Take file
  1507.                     ; does not return if success
  1508. atapc6:    mov    ax,apcstring        ; segment of string buffer
  1509.     or    ax,ax            ; in use?
  1510.     jz    atapc7            ; z = no
  1511.     mov    es,ax
  1512.     mov    ah,freemem        ; free buffer
  1513.     int    dos
  1514. atapc7:    mov    apcstring,0        ; clear buffer
  1515.     mov    emubufc,0        ; clear string count
  1516.     mov    bracecount,0        ; count of curly braces in string
  1517.     jmp    atnorm            ; exit this sequence
  1518.  
  1519.  
  1520. ; User Definable Key processor of DCS strings.
  1521. atudk:    cmp    dinter,0        ; no intermediates?
  1522.     je    atudk1            ; e = correct
  1523.     mov    ninter,0        ; setup atdcsnul for proper form
  1524.     jmp    atdcsnul        ; bad, consume the rest
  1525.  
  1526. atudk1:    cmp    dparam,1        ; is initial Parameter Pc a 1?
  1527.     jae    atudk2            ; ae = yes, clear only this key
  1528.     call    udkclear        ; clear all UDKeys
  1529.     mov    dparam,1        ; and turn off Parameter
  1530. atudk2:    mov    ttstate,offset atudk3    ; next state is get a substring
  1531.     mov    ttstateST, offset atudk6 ; for when ST has been seen
  1532.     ret
  1533.  
  1534. atudk3:    cmp    al,';'            ; string separator?
  1535.     je    atudk5            ; e = yes, process string to-date
  1536.     mov    bx,emubufc        ; count of chars in string buffer
  1537.     cmp    bx,emubufl        ; too many?
  1538.     jae    atudk4            ; ae = too many, ignore extras
  1539.     mov    emubuf[bx],al        ; store the char
  1540.     inc    emubufc            ; count it
  1541. atudk4:    ret
  1542. atudk5:    mov    si,offset emubuf    ; address of string buffer is DS:SI
  1543.     mov    cx,emubufc        ; count of buffer contents
  1544.     call    setudk            ; insert string definition
  1545.     mov    emubufc,0        ; clear string buffer
  1546.     ret
  1547. atudk6:    call    atudk5            ; ST seen, process last string
  1548.     jmp    atnorm            ; reset state to normal
  1549.  
  1550. ; Call this routine to deliver Parameters in succession. Each call points to
  1551. ; a Parameter as param[si], where si is maintained here. If there are no
  1552. ; Parameters the effect is the same as one Parameter with a value of zero.
  1553. ; Enter with di = offset of action routine to be called for each Parameter.
  1554. ; cx, si, and di are preserved over the call to the action routine.
  1555.  
  1556. atreps    proc    near
  1557.     xor    si,si            ; initialize parm index
  1558.     mov    cx,nparam        ; number of Parameters
  1559.     or    cx,cx            ; zero?
  1560.     jnz    atrep1            ; nz = no
  1561.     inc    cx            ; zero parms is same as 1
  1562. atrep1: push    cx            ; save loop counter
  1563.     push    si            ; save parameter index
  1564.     push    di            ; save call vector
  1565.     call    DI            ; call indicated routine
  1566.     pop    di            ; restore registers
  1567.     pop    si
  1568.     pop    cx
  1569.     add    si,2            ; advance to next parameter
  1570.     loop    atrep1            ; loop for all
  1571.     ret
  1572. atreps    endp
  1573.  
  1574.                     ; Action routines
  1575. atind0:    cmp    ninter,0        ; any intermediates?
  1576.     je    atind            ; e = no, else not this item
  1577.     ret
  1578. atind:    inc    dh            ; IND (index), move cursor down one
  1579. atind1: call    atccic            ; check cursor position
  1580.     call    ax            ; scroll if necessary
  1581.     jmp    atsetcur        ; set cursor, etc. and return
  1582.  
  1583. atnel0:    cmp    ninter,0        ; any intermediates from ESC..E?
  1584.     je    atnel            ; e = no, else not this item
  1585.     jmp    atdgnrc            ; try Nowegian/Danish NRC designator
  1586.                     ; enter here with real NEL char
  1587. atnel:    mov    dl,mar_left        ; NEL, next line - sort of like CRLF
  1588.     inc    dh            ; ... all in one command
  1589.     jmp    short atind1        ; check cursor, etc., and return
  1590.  
  1591. atri0:    cmp    ninter,0        ; any intermediates?
  1592.     je    atri            ; e = no, else not this item
  1593.     ret
  1594. atri:    cmp    flags.vtflg,ttheath    ; Heath-19?
  1595.     jne    atri1            ; ne = no
  1596.     cmp    dh,byte ptr low_rgt+1    ; on 25th line?
  1597.     jbe    atri1            ; be = no
  1598.     ret                ; no vertical for Heath on 25th line
  1599. atri1:    dec    dh            ; RI, reverse index
  1600.     jmp    short atind1        ; check cursor, etc., and return
  1601.  
  1602.                     ; HTS, horizontal tab set in this col
  1603. athts0:    cmp    ninter,0        ; any intermediates from ESC..H?
  1604.     je    athts            ; e = no, else not this item
  1605.     jmp    atdgnrc            ; try Swedish NRC designator
  1606. athts:    call    atccpc            ; make column number valid
  1607.     mov    si,vtemu.vttbst        ; active buffer
  1608.     jmp    tabset            ; say set tab in this column (DL)
  1609.  
  1610.                     ; DECSC
  1611. atsc:    mov    si,offset savelist    ; save cursor, attribute, char set etc
  1612.     mov    di,offset savecu    ; place to save the stuff
  1613.     mov    cl,extattr        ; extended attributes
  1614.     mov    savextattr,cl        ; it's real storage is in msyibm
  1615.     mov    cl,scbattr
  1616.     mov    savscbattr,cl
  1617.     mov    havesaved,1        ; say have saved something
  1618.     mov    cx,lsavecu        ; length of save area
  1619.     push    es            ; save es
  1620.     mov    ax,data            ; seg of save area
  1621.     mov    es,ax            ; set es to data segment
  1622.     cld
  1623.     shr    cx,1            ; divide by two for word moves
  1624.     jnc    atsc1            ; nc = even number of bytes
  1625.     movsb                ; do the odd byte
  1626. atsc1:    rep    movsw            ; save it
  1627.     pop    es
  1628.     mov    cx,vtemu.vtflgop    ; save a copy of the flags
  1629.     mov    savflgs,cx
  1630.     ret
  1631.                     ; DECRC
  1632. atrc:    cmp    havesaved,0        ; saved anything yet?
  1633.     jne    atrc1            ; ne = yes
  1634.     ret
  1635. atrc1:    mov    si,offset savecu    ; restore cursor, attributes, etc
  1636.     mov    di,offset savelist    ; where stuff goes
  1637.     mov    cx,lsavecu        ; length of save area
  1638.     push    es            ; save es
  1639.     push    ds
  1640.     mov    ax,seg savecu        ; seg of savecu storage
  1641.     mov    ds,ax
  1642.     mov    ax,seg savelist        ; seg of regular storage
  1643.     mov    es,ax
  1644.     cld
  1645.     shr    cx,1            ; divide by two for word moves
  1646.     jnc    atrc2            ; nc = even number of bytes
  1647.     movsb                ; do the odd byte
  1648. atrc2:    rep    movsw            ; put the stuff back
  1649.     pop    ds
  1650.     pop    es
  1651.     mov    al,savextattr        ; extended attributes
  1652.     mov    extattr,al
  1653.     mov    al,savscbattr
  1654.     mov    scbattr,al
  1655.     mov    ax,savflgs        ; get saved flags
  1656.     xor    ax,vtemu.vtflgop    ; exclusive-or with current flags
  1657.     mov    al,atctype        ; get cursor shape
  1658.     call    csrtype            ; restore it
  1659. atrc3:    mov    ax,vtemu.vtflgop    ; reset flags in case called again
  1660.     and    ax, not(decckm+deckpam+decom)  ; remove old bits [dlk]
  1661.     and    savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
  1662.     or    ax,savflgs        ; restore saved bits [dlk]
  1663.     or    vtemu.vtflgop,ax    ; update these flags
  1664.     mov    savflgs,ax
  1665.     mov    bx,offset Gsetid    ; restore character sets
  1666.     call    chrsetup        ; go remake G0..G3
  1667.     mov    dx,cursor        ; get cursor
  1668.     mov    kbiflg,0        ; don't bother them with beeps here
  1669.     jmp    atsetcur        ; set cursor
  1670.  
  1671. atkpam:    cmp    ninter,0        ; any intermediates?
  1672.     jne    atkpam1            ; ne = yes, not this item
  1673.     or    vtemu.vtflgop,deckpam    ; turn on keypad applications mode
  1674.     ret
  1675. atkpam1:jmp    atdgnrc            ; try Swiss NRC designator
  1676.  
  1677. atkpnm: and    vtemu.vtflgop,not deckpam ; turn off keypad applications mode
  1678.     ret                ; (to numeric mode)
  1679.  
  1680.                     ; Privileged sequence, ignore it
  1681. atpriv:    cmp    ninter,0        ; any intermediates?
  1682.     jne    atpriv1            ; ne = yes, not this item
  1683.     mov    ttstate,offset atnorm    ; ignore next char
  1684. atpriv1:ret                ; and return to normal afterward
  1685.  
  1686. ; ISO 2022 three byte Announcer Summary    <ESC> <space> <final char>
  1687. ;Esc Sequence  7-Bit Environment          8-Bit Environment
  1688. ;----------    ------------------------   ----------------------------------
  1689. ;<ESC><SP>A    G0->GL                     G0->GL
  1690. ;<ESC><SP>B    G0-(SI)->GL, G1-(SO)->GL   G0-(LS0)->GL, G1-(LS1)->GL
  1691. ;<ESC><SP>C    (not used)                 G0->GL, G1->GR
  1692. ;<ESC><SP>D    G0-(SI)->GL, G1-(SO)->GL   G0->GL, G1->GR
  1693. ;<ESC><SP>E    Full preservation of shift functions in 7 & 8 bit environments
  1694. ;<ESC><SP>F    C1 represented as <ESC>F   C1 represented as <ESC>F
  1695. ;<ESC><SP>G    C1 represented as <ESC>F   C1 represented as 8-bit quantity
  1696. ;<ESC><SP>H    All graphic character sets have 94 characters
  1697. ;<ESC><SP>I    All graphic character sets have 94 or 96 characters
  1698. ;<ESC><SP>J    In a 7 or 8 bit environment, a 7 bit code is used
  1699. ;<ESC><SP>K    In an 8 bit environment, an 8 bit code is used
  1700. ;<ESC><SP>L    Level 1 of ISO 4873 is used
  1701. ;<ESC><SP>M    Level 2 of ISO 4873 is used
  1702. ;<ESC><SP>N    Level 3 of ISO 4873 is used
  1703. ;<ESC><SP>P    G0 is used in addition to any other sets:
  1704. ;              G0 -(SI)-> GL              G0 -(LS0)-> GL
  1705. ;<ESC><SP>R    G1 is used in addition to any other sets:
  1706. ;              G1 -(SO)-> GL              G1 -(LS1)-> GL
  1707. ;<ESC><SP>S    G1 is used in addition to any other sets:
  1708. ;              G1 -(SO)-> GL              G1 -(LS1R)-> GR
  1709. ;<ESC><SP>T    G2 is used in addition to any other sets:
  1710. ;              G2 -(LS2)-> GL             G2 -(LS2)-> GL
  1711. ;<ESC><SP>U    G2 is used in addition to any other sets:
  1712. ;              G2 -(LS2)-> GL             G2 -(LS2R)-> GR
  1713. ;<ESC><SP>V    G3 is used in addition to any other sets:
  1714. ;              G3 -(LS2)-> GL             G3 -(LS3)-> GL
  1715. ;<ESC><SP>W    G3 is used in addition to any other sets:
  1716. ;              G3 -(LS2)-> GL             G3 -(LS3R)-> GR
  1717. ;<ESC><SP>Z    G2 is used in addition to any other sets:
  1718. ;              SS2 invokes a single character from G2
  1719. ;<ESC><SP>[    G3 is used in addition to any other sets:
  1720. ;              SS3 invokes a single character from G3
  1721. ;
  1722. ; ISO Escape Sequences for Alphabet Designation ("F" = Final char)
  1723. ; Sequence     Function                                         Invoked By
  1724. ;  <ESC>(F     assigns 94-character graphics set "F" to G0.     SI  or LS0
  1725. ;  <ESC>)F     assigns 94-character graphics set "F" to G1.     SO  or LS1
  1726. ;  <ESC>*F     assigns 94-character graphics set "F" to G2.     SS2 or LS2
  1727. ;  <ESC>+F     assigns 94-character graphics set "F" to G3.     SS3 or LS3
  1728. ;  <ESC>-F     assigns 96-character graphics set "F" to G1.     SO  or LS1
  1729. ;  <ESC>.F     assigns 96-character graphics set "F" to G2.     SS2 or LS2
  1730. ;  <ESC>/F     assigns 96-character graphics set "F" to G3.     SS3 or LS3
  1731. ;  <ESC>$(F    assigns multibyte character set "F" to G0.       SI  or LS0
  1732. ;  <ESC>$)F    assigns multibyte character set "F" to G1.       SO  or LS1
  1733. ;  <ESC>$*F    assigns multibyte character set "F" to G2.       SS2 or LS2
  1734. ;  <ESC>$+F    assigns multibyte character set "F" to G3.       SS3 or LS3
  1735. ;     
  1736. ; Designate character sets, AL has final character, inter has all preceeding.
  1737.  
  1738. atdgfA:    call    atdgset            ; 'A' ISO Latin-1, UK-ASCII
  1739.     jc    atdgfA1            ; c = no matching pointer
  1740.     cmp    inter,'+'        ; in the 94 byte set?
  1741.     ja    atdgfA2            ; a = no, 96 'A' is Latin1
  1742.     mov    ax,flags.vtflg        ; terminal type
  1743.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; VTxxx?
  1744.     jz    atdgfA1            ; z = no
  1745.     jmp    mkukascii        ; make UK ASCII table
  1746. atdgfA1:ret
  1747.  
  1748. atdgfA2:jmp    mklatin1        ; make Latin1 char set
  1749.  
  1750. atdgfA3:jmp    atdgnrc            ; try British NRC
  1751.  
  1752. atdgfB:    call    atdgset            ; 'B' ASCII, get setptr from inter
  1753.     jc    atdgfA1            ; c = no matching pointer
  1754.     cmp    inter,'+'        ; in the 94 byte set?
  1755.     ja    atdgfB1            ; a = no, do Latin2
  1756.     jmp    mkascii            ; make US ASCII set
  1757. atdgfB1:jmp    mklatin2        ; make Latin2 ("B"/96)
  1758.  
  1759. atdgf0:    call    atdgset            ; '0', '2', DEC Special Graphics
  1760.     jc    atdgfA1            ; c = no matching pointer
  1761.     cmp    inter,'+'        ; in the 94 byte set?
  1762.     ja    atdgfA1            ; a = no, ignore
  1763.     jmp    mkdecspec        ; init set to DEC Special Graphics
  1764.  
  1765. atdgf1:    call    atdgset            ; '1' ALT-ROM
  1766.     jc    atdgf1b            ; c = no matching pointer
  1767.     jmp    mkaltrom        ; make ALT-ROM set
  1768.  
  1769. atdgf1b:
  1770. ;    cmp    ninter,0        ; ESC 1? (Special enter Tek mode)
  1771. ;    jne    atdgf1c            ; ne = some, not ESC 1
  1772. ;    cmp    nparam,0
  1773. ;    jne    atdgf1c            ; ne = some, not ESC 1
  1774. ;    jmp    atff1            ; treat the same as ESC ^L
  1775. atdgf1c:ret
  1776.  
  1777. atdgft:    call    atdgset            ; '>' Dec Technical Set
  1778.     jc    atdgft1            ; c = no matching pointer
  1779.     cmp    inter,'+'        ; in the 94 byte set?
  1780.     ja    atdgft1            ; a = no
  1781.     jmp    mkdectech        ; make DEC Tech set
  1782.  
  1783. atdgft1:cmp    ninter,0        ; ESC > DECKNPNM set numeric keypad?
  1784.     jne    atdgft2            ; ne = no
  1785.     and    vtemu.vtflgop,not deckpam ; turn off application keypad bit
  1786. atdgft2:ret                ;  (to numeric)
  1787.                     ; '<' User Preferred Supplemental Set
  1788. atdgfu:    call    atdgset            ; get set pointer
  1789.     jc    atdgfu2            ; c = no matching pointer
  1790.     cmp    inter,','        ; designating the 96 char set?
  1791.     jb    atdgfu1            ; b = no, want 94
  1792.     cmp    word ptr upss+1,0+'A'    ; is ISO Latin-1 the preferred set?
  1793.     jne    atdgfu0a        ; ne = no
  1794.     jmp    mklatin1        ; make Latin1 set
  1795. atdgfu0a:cmp    word ptr upss+1,0+'H'    ; is Hebrew-ISO preferred?
  1796.     jne    atdgfu2            ; ne = no
  1797.     jmp    mklatin_Hebrew        ; make Hebrew-ISO
  1798.  
  1799. atdgfu1:cmp    word ptr upss+1,'5%'    ; DEC Supplemental Graphics?
  1800.     jne    atdgfu1a        ; ne = no
  1801.     jmp    mkdecmn            ; make DEC Multinat/Supp Gr
  1802. atdgfu1a:cmp    word ptr upss+1,'4"'    ; DEC Hebrew?
  1803.     jne    atdgfu2
  1804.     jmp    mkdec_Hebrew        ; make DEC Hebrew 
  1805. atdgfu2:ret
  1806.  
  1807. atdgfq:    call    atdgset            ; '?' Transparent
  1808.     jc    atdgfu2            ; c = no matching pointer
  1809.     jmp    mkxparent        ; make transparent table
  1810.  
  1811.                     ; ESC <...> <1-8>  series
  1812. atsdhl:    cmp    ninter,1        ; just one intermediate?
  1813.     jne    atsdh0            ; ne = no
  1814.     cmp    inter,'#'        ; this intermediate?
  1815.     jne    atdgnrc            ; ne = no, try NRC char set designator
  1816.     cmp    al,'3'            ; Double high lines. Top half?
  1817.     je    atsdh2            ; e = yes
  1818.     cmp    al,'4'            ; bottom half?
  1819.     je    atsdh2            ; e = yes
  1820.     cmp    al,'5'            ; restore line to single width?
  1821.     je    atsdh1            ; e = yes
  1822.     cmp    al,'6'            ; double width single height?
  1823.     je    atsdh2            ; e = yes
  1824.     cmp    al,'8'            ; screen alignment?
  1825.     je    atsdh8            ; e = yes
  1826. atsdhx:    ret                ; else ignore
  1827.  
  1828. atsdh1:    jmp    linesgl            ; set line to single width
  1829. atsdh2:    jmp    linedbl            ; expand the line to double width
  1830. atsdh8:    jmp    atalign            ; do screen alignment
  1831.  
  1832. atsdh0:    cmp    ninter,0        ; zero intermediates?
  1833.     jne    atdgf5            ; ne = no, try for more
  1834.     cmp    al,'7'            ; save cursor?
  1835.     jne    atsdh0a            ; ne = no
  1836.     jmp    atsc            ; do save cursor, ESC 7
  1837. atsdh0a:cmp    al,'8'            ; restore cursor?
  1838.     jne    atsdh0b            ; ne = no
  1839.     jmp    atrc            ; do restore cursor, ESC 8
  1840. atsdh0b:ret
  1841.  
  1842. atdgf5:    cmp    ninter,2        ; two intermediates?
  1843.     jne    atdgf5a            ; ne = no, ignore remainder
  1844.     cmp    al,'6'            ; '%6' NRC designator?
  1845.     je    atdgnrc            ; e = yes, do that above
  1846.     cmp    al,'5'            ; '%5' DEC Supplemental Graphic?
  1847.     jne    atdgf5a            ; ne = no
  1848.     cmp    inter,'+'        ; in the 94 byte set?
  1849.     ja    atdgf5a            ; a = no, ignore
  1850.     cmp    inter[1],'%'        ; '%5'?
  1851.     jne    atdgf5a            ; ne = no
  1852.     mov    ninter,1        ; help atdgset find our set
  1853.     call    atdgset            ; get set pointer
  1854.     jc    atdgf5a            ; c = no matching pointer
  1855.     jmp    mkdecmn            ; make DEC Multinat/Supp Gr
  1856. atdgf5a:ret
  1857.  
  1858. ; Enter with Final esc char in al, others in array inter. Setup Gn if success.
  1859. atdgnrc    proc    near            ; check for NRC set designator
  1860.     cmp    ninter,0        ; ESC Z?
  1861.     jne    atdgnr1            ; ne = no
  1862.     cmp    al,'Z'            ; the Z?
  1863.     jne    atdgnrx            ; ne = not ESC Z
  1864.     jmp    atda            ; process ident request
  1865. atdgnr1:cmp    inter,'+'        ; in the 94 byte set?
  1866.     ja    atdgnrx            ; a = no, ignore
  1867.     call    findctry        ; find NRC country number in CX
  1868.     jc    atdgnrx            ; c = not found, ignore
  1869.     mov    ninter,1        ; help atdgset find our set
  1870.     call    atdgset            ; check for Gn designator
  1871.     jc    atdgnrx            ; c = not found
  1872.     jmp    mknrc            ; make NRC set
  1873. atdgnrx:ret                ; ignore
  1874. atdgnrc    endp
  1875.  
  1876. ; Find NRC country number, putting it into CX, given Final char in AL and
  1877. ; intermediates in array inter. Return carry set if not found.
  1878. findctry proc    near
  1879.     cmp    ninter,2        ; second intermediate (%)?
  1880.     jb    findct1            ; b = no
  1881.     ja    findct3            ; a = three or more, no match
  1882.     mov    ah,inter+1        ; get NRC intermediate
  1883.     cmp    ax,'%6'            ; Portugese NRC?
  1884.     jne    findct4            ; ne = no, try Hebrew
  1885.     mov    cx,9            ; Portuguese NRC is number 9
  1886.     clc
  1887.     ret
  1888. findct4:cmp    ax,'%='            ; Hebrew NRC?
  1889.     jne    findct3            ; ne = no, fail
  1890.     mov    cx,13            ; Hebrew NRC is number 13
  1891.     clc
  1892.     ret
  1893. findct1:cmp    ninter,0        ; no intermediate?
  1894.     je    findct3            ; e = yes, no designator, fail
  1895.     mov    cx,nrcflen        ; number of NRC letters to consider
  1896.     cld
  1897.     push    di            ; save regs
  1898.     push    es
  1899.     push    ds
  1900.     pop    es
  1901.     mov    di,offset nrcfinal    ; list of NRC final chars
  1902.     repne    scasb            ; look for a match
  1903.     pop    es            ; recover reg
  1904.     jne    findct2            ; ne = failed
  1905.     dec    di            ; compenstate for auto-inc
  1906.     sub    di,offset nrcfinal    ; get distance covered
  1907.     mov    cl,nrcnum[di]        ; country number from parallel list
  1908.     xor    ch,ch            ; return number in CX
  1909.     pop    di
  1910.     clc                ; success
  1911.     ret
  1912. findct2:pop    di            ; carry set = failure
  1913. findct3:stc
  1914.     ret
  1915. findctry endp
  1916.  
  1917. ; Worker for atdgf routines. Return setptr looking at Gnset (n=0..3) and
  1918. ; carry clear, based on ninter=1, inter = Gn designator. Carry set if fail.
  1919. ; Modifies AL
  1920. atdgset    proc    near
  1921.     cmp    ninter,1        ; one intermediate?
  1922.     jne    atdgsex            ; ne = no, ignore
  1923.     mov    al,inter        ; inter, from parser
  1924.     cmp    al,'('            ; 94 char sets, designate G0?
  1925.     je    atdgse0            ; e = yes
  1926.     cmp    al,')'            ; G1?
  1927.     je    atdgse1
  1928.     cmp    al,'*'            ; G2?
  1929.     je    atdgse2
  1930.     cmp    al,'+'            ; G3?
  1931.     je    atdgse3
  1932.     cmp    al,'-'            ; 96 char sets, designate G1?
  1933.     je    atdgse1
  1934.     cmp    al,'.'            ; G2?
  1935.     je    atdgse2
  1936.     cmp    al,'/'            ; G3?
  1937.     je    atdgse3
  1938. atdgsex:stc                ; carry set for failure
  1939.     ret
  1940. atdgse0:mov    setptr,offset G0set    ; designate G0 set
  1941.     clc
  1942.     ret
  1943. atdgse1:mov    setptr,offset G1set    ; designate G1 set
  1944.     clc
  1945.     ret
  1946. atdgse2:mov    setptr,offset G2set    ; designate G2 set
  1947.     clc
  1948.     ret
  1949. atdgse3:mov    setptr,offset G3set    ; designate G3 set
  1950.     clc
  1951.     ret
  1952. atdgset endp
  1953.                     ; S7C1T/S8C1T select 7/8-bit controls
  1954. ats7c:    test    flags.vtflg,ttvt320+ttvt220 ; in VT320/VT220 mode?
  1955.     jz    atdgsex            ; z = no, ignore command
  1956.     cmp    ninter,1        ; one intermediate?
  1957.     jne    ats7ca            ; ne = no
  1958.     cmp    inter,' '        ; proper intermediate?
  1959.     jne    ats7ca            ; ne = no
  1960.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls bit
  1961. ats7ca:ret                ; done
  1962.  
  1963. ats8c:    cmp    inter,' '        ; proper intermediate?
  1964.     jne    ats8ca            ; ne = no
  1965.     cmp    ninter,1        ; just one?
  1966.     jne    ats8ca            ; ne = no
  1967.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls bit
  1968. ats8ca:    ret
  1969.  
  1970. ; Designate User Preferred Supplemental Set as
  1971. ;  'A' ISO Latin-1  or '%','5' DEC Supplemental Graphics, or
  1972. ;  'H' Hebrew-ISO,  or '"','4' DEC-Hebrew
  1973. ; Store the selection letters in array upss for later use by ESC <char> '<'
  1974. atupss:    cmp    word ptr dinter,0+'!'    ; "!u" proper intermediate?
  1975.     je    atupss0            ; e = yes
  1976.     mov    ninter,0        ; set up atdcsnul for proper form
  1977.     jmp    atdcsnul        ; consume unknown command
  1978. atupss0:mov    ah,94            ; assume 94 byte set
  1979.     cmp    dparam,1        ; 96 byte char size indicator?
  1980.     jb    atupss1            ; b = no, 94
  1981.     ja    atupss2            ; a = illegal Parameter
  1982.     mov    ah,96            ; say 96
  1983. atupss1:mov    upss,ah            ; store char set size
  1984.     mov    ttstateST,offset atupss4; where to go when ST has been seen
  1985.     mov    emubufc,0        ; clear buffer count
  1986.     mov    ttstate,offset atupss2    ; next state is get string
  1987.     ret
  1988. atupss2:mov    bx,emubufc        ; count of chars in string buffer
  1989.     cmp    bx,emubufl        ; too many?
  1990.     jae    atupss3            ; ae = too many, ignore extras
  1991.     mov    emubuf[bx],al        ; store the char
  1992.     inc    emubufc            ; count it
  1993. atupss3:ret
  1994. atupss4:mov    si,emubufc        ; count of chars in string
  1995.     mov    emubuf[si],0        ; terminate string in null
  1996.     mov    ax,word ptr emubuf    ; copy two chars from string to
  1997.     mov    word ptr upss+1,ax    ;  upss char set ident storage area
  1998.     mov    emubufc,0        ; clear the string count
  1999.     ret
  2000.  
  2001. ; Select/map character sets
  2002. atls0:    mov    GLptr,offset G0set    ; LS0,  map G0 char set into GLeft
  2003.     ret                ; Control-O
  2004. atls1:    mov    GLptr,offset G1set    ; LS1,  map G1 char set into GLeft
  2005.     ret                ; Control-N
  2006. atls1r:    cmp    ninter,0        ; any intermediate chars?
  2007.     jne    atlsx            ; ne = yes, not a Locking Shift
  2008.     mov    GRptr,offset G1set    ; LS1R, map G1 char set into GRight
  2009.     ret
  2010. atss2:    cmp    ninter,0        ; any intermediate chars?
  2011.     jne    atlsx            ; ne = yes, not a Single Shift
  2012.     mov    SSptr,offset G2set    ; SS2,  use G2 for next graphics only
  2013.     ret
  2014. atls2:    cmp    ninter,0        ; any intermediate chars?
  2015.     jne    atlsx            ; ne = yes, not a Locking Shift
  2016.     mov    GLptr,offset G2set    ; LS2,  map G2 char set into GLeft
  2017.     ret
  2018. atls2r:    cmp    ninter,0        ; any intermediate chars?
  2019.     jne    atlsx            ; ne = yes, not a Locking Shift
  2020.     mov    GRptr,offset G2set    ; LS2R, map G2 char set into GRight
  2021.     ret
  2022. atss3:    cmp    ninter,0        ; any intermediate chars?
  2023.     jne    atlsx            ; ne = yes, not a Single Shift
  2024.     mov    SSptr,offset G3set    ; SS3,  use G3 for next graphics only
  2025.     ret
  2026. atls3:    cmp    ninter,0        ; any intermediate chars?
  2027.     jne    atlsx            ; ne = yes, not a Locking Shift
  2028.     mov    GLptr,offset G3set    ; LS3,  map G3 char set into GLeft
  2029.     ret
  2030. atls3r:    cmp    ninter,0        ; any intermediate chars?
  2031.     jne    atlsx            ; ne = yes, not a Locking Shift
  2032.     mov    GRptr,offset G3set    ; LS3R, map G3 char set into GRight
  2033. atlsx:    ret
  2034.  
  2035.  
  2036. ; Routine to set default character set.
  2037. chrdef    proc    near
  2038.       mov    GLptr,offset G0set    ; map G0 set to GLeft
  2039.     mov    GRptr,offset G2set    ; map G2 set to GRight
  2040.     mov    SSptr,0            ; clear single shift
  2041.     mov    bx,offset emubuf    ; temp table of char set idents
  2042.     mov    word ptr [bx],0        ; G0 and G1 to ASCII
  2043.     mov    al,vtemu.vtchset    ; user specifed char set for GL
  2044.     mov    byte ptr [bx+2],al    ; set G2 and G3 to user selected set
  2045.     mov    byte ptr [bx+3],al
  2046.     test    flags.vtflg,ttvt320+ttvt220
  2047.     jnz    chrdef1            ; nz = yes, 8-bit terminals
  2048.     mov    GRptr,offset G1set    ; map G1 set to GRight
  2049.     mov    byte ptr [bx+1],18    ; assume Dec Special Graphics in G1
  2050.  
  2051. chrdef1:test    vtemu.vtflgop,vsnrcm    ; doing National Replacement Chars?
  2052.     jz    chrdef2            ; z = no
  2053.     mov    al,vtemu.vtchset    ; get country number
  2054.     mov    dgkbl,al        ; keyboard language
  2055.     cmp    al,13            ; max NRC country
  2056.     ja    chrdef2            ; a = out of bounds, ignore
  2057.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  2058.     mov    ah,al            ; country number 1..12
  2059.     mov    [bx],al            ; set G0
  2060.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  2061.     jnz    chrdef2            ; nz = yes, don't touch G1..G3 here
  2062.     mov    [bx+1],ah
  2063.     mov    word ptr [bx],ax    ; same char set in G0..G3
  2064.     mov    word ptr [bx+2],ax
  2065.  
  2066. chrdef2:test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  2067.     jz    chrdef5            ; z = no (should have all cases now)
  2068.     mov    al,20            ; D463/D470 DG International to G1
  2069.     test    flags.remflg,d8bit    ; 8 bit mode?
  2070.     jnz    chrdef4            ; nz = yes
  2071. chrdef3:mov    al,22            ; D463/D470 DG Word Processing to G1
  2072. chrdef4:mov    [bx+1],al        ; D463/D470 G1 default
  2073.     mov    dgkbl,al        ; DG keyboard language
  2074.     mov    ah,[bx]            ; G0
  2075.     or    ah,ah            ; using NRCs?
  2076.     jz    chrdef5            ; z = no
  2077.     mov    dgkbl,ah        ; yes, state NRC in use for kbd
  2078.  
  2079. chrdef5:call    chrsetup        ; worker to setup G0..G3
  2080.                     ; do table of Gn overrides
  2081.     mov    bx,offset vtemu.vttable    ; table of char set overrides
  2082.     call    chrsetup        ; worker to setup G0..G3
  2083.     ret
  2084. chrdef    endp
  2085.  
  2086. ; Load G0..G3 with character sets whose idents (0..24) are in byte array 
  2087. ; pointed to by BX. Update Gsetid with those byte idents enroute.
  2088. chrsetup proc    near
  2089.     push    ninter            ; preserve these
  2090.     mov    ch,inter
  2091.     push    cx            ; save them
  2092.     mov    ninter,1        ; one intermediate
  2093.     mov    inter,'('        ; init inter for atdgset
  2094.     xor    cx,cx            ; count sets from 0
  2095. chrset1:push    cx            ; save loop counter
  2096.     push    bx
  2097.     call    atdgset            ; get setptr = offset Gnset (n=0..3)
  2098.     mov    al,[bx]            ; get char set ident from 4 byte list
  2099.     cmp    al,0ffh            ; none?
  2100.     je    chrset90        ; e = none
  2101.     mov    bx,cx            ; update Gsetid table with set ident
  2102.     mov    Gsetid[bx],al
  2103.     or    al,al            ; ASCII (0)?
  2104.     jnz    chrset13        ; nz = no
  2105.     call    mkascii            ; make ASCII
  2106.     jmp    chrset90
  2107.  
  2108. chrset13:cmp    al,13            ; in NRC's?
  2109.     ja    chrset14              ; a = no
  2110.     mov    cl,al            ; put country number in cx
  2111.     xor    ch,ch
  2112.     call    mknrc            ; setup an NRC, using cx and setptr
  2113.     jmp    short chrset90
  2114.  
  2115. chrset14:cmp    al,14            ; want ALT-ROM?
  2116.     jne    chrset15        ; ne = no
  2117.     call    mkaltrom        ; do ALT-ROM setup
  2118.     jmp    short chrset90
  2119.  
  2120. chrset15:cmp    al,15            ; Transparent (15)?
  2121.     jne    chrset16        ; ne = no
  2122.     call    mkxparent        ; do Transparent setup
  2123.     jmp    short chrset90
  2124.  
  2125. chrset16:cmp    al,16            ; Latin1 (16)?
  2126.     jne    chrset17
  2127.     cmp    setptr,offset G0set    ; want 96 byte set in G0?
  2128.     je    chrset90        ; e = yes, can not do this
  2129.     call    mklatin1        ; make Latin1
  2130.     jmp    short chrset90
  2131.  
  2132. chrset17:cmp    al,17            ; DEC-MCS (17)?
  2133.     jne    chrset18        ; ne = no
  2134.     call    mkdecmn            ; make DEC Supplement Graph (DEC-MCS)
  2135.     jmp    short chrset90
  2136.  
  2137. chrset18:cmp    al,18            ; DEC-Technical (18)?
  2138.     jne    chrset19        ; ne = no
  2139.     call    mkdectech        ; make DEC Technical
  2140.     jmp    short chrset90
  2141.  
  2142. chrset19:cmp    al,19            ; DEC-Special-Graphics?
  2143.     jne    chrset20        ; ne = no
  2144.     call    mkdecspec        ; make DEC Special Graphics
  2145.     jmp    short chrset90
  2146.  
  2147. chrset20:cmp    al,20            ; DG International?
  2148.     jne    chrset21        ; ne = no
  2149.     call    mkdgint            ; make DG International
  2150.     jmp    short chrset90
  2151.  
  2152. chrset21:cmp    al,21            ; DG Line Drawing?
  2153.     jne    chrset22        ; ne = no
  2154.     call    mkdgld            ; make DG line drawing
  2155.     jmp    short chrset90
  2156.  
  2157. chrset22:cmp    al,22            ; DG Word Processing?
  2158.     jne    chrset23        ; ne = no
  2159.     call    mkdgwp            ; make DG Word Procssing
  2160.     jmp    short chrset90
  2161.     
  2162. chrset23:cmp    al,23            ; Latin1/CP852?
  2163.     jne    chrset24        ; ne = no
  2164.     call    mklatin2
  2165.     jmp    short chrset90
  2166.  
  2167. chrset24:cmp    al,24            ; Hebrew-ISO (CP862)?
  2168.     jne    chrset100        ; ne = no
  2169.     call    mklatin_hebrew
  2170.     jmp    short chrset90
  2171.  
  2172. chrset100:cmp    al,100            ; possible DG soft set?
  2173.     jne    chrset90        ; ne = no
  2174.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  2175.     jz    chrset90        ; z = no
  2176.     call    mkdgtr            ; do it
  2177.  
  2178. chrset90:pop    bx
  2179.     pop    cx
  2180.     inc    bx            ; next byte of table
  2181.     inc    inter            ; next set pointer
  2182.     inc    cx
  2183.     cmp    cx,4            ; done all sets?
  2184.     jae    chrset92        ; ae = yes
  2185.     jmp    chrset1            ; b = no (counting sets as 0..3)
  2186. chrset92:pop    cx            ; recover saved parsing items
  2187.     mov    inter,cl        ; restore
  2188.     pop    ninter            ; this too
  2189.     ret
  2190. chrsetup endp
  2191.  
  2192. ; copy gsize+3 bytes from (si) to (setptr)
  2193. cpyset    proc    near
  2194.     push    di
  2195.     push    es
  2196.     push    ds
  2197.     pop    es
  2198.     cld
  2199.     mov    cx,gsize+3        ; gsize chars plus three ident bytes
  2200.     mov    di,setptr        ; destination
  2201.     rep    movsb
  2202.     pop    es
  2203.     pop    di
  2204.     ret
  2205. cpyset    endp
  2206.  
  2207. ; Make Data General International to Gn table. 
  2208. ; Enter with destination in setptr
  2209. mkdgint    proc    near
  2210.     push    si
  2211.     push    di
  2212.     call    flatin1            ; get BX to Code Page dependent Latin1
  2213.     call    cpyset            ; copy in Latin1
  2214.     mov    di,setptr
  2215.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2216.     xor    ah,ah
  2217.     mov    si,ax
  2218.     mov    Gsetid[si],20        ; store our char set ident
  2219.     add    di,20h            ; where new chars start
  2220.     mov    si,offset dgi2lat    ; source = code points in Latin1
  2221.     mov    cx,dgi2len        ; number of new chars
  2222.     push    es
  2223.     push    ds
  2224.     pop    es
  2225.     cld
  2226. mkdgin1:lodsb                ; read Latin1 code point from dgi2lat
  2227.     cmp    al,80h            ; "?" unknown indicator or ASCII?
  2228.     jb    mkdgin2            ; b = yes, reproduce it literally
  2229.     sub    al,80h            ; map down to indexable value
  2230.     xlatb                ; translate through Latin1 table
  2231. mkdgin2:stosb                ; store in active table
  2232.     loop    mkdgin1            ; do all necessary
  2233.     mov    di,setptr
  2234.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2235.     mov    word ptr[di+gsize+1],'ID' ; set ident code
  2236.     pop    es
  2237.     pop    di
  2238.     pop    si
  2239.     ret
  2240. mkdgint    endp
  2241.  
  2242. ; Make Data General line drawing graphics to Gn table. 
  2243. ; Enter with destination in setptr
  2244. mkdgld    proc    near
  2245.     push    si
  2246.     push    di
  2247.     mov    di,setptr
  2248.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2249.     xor    ah,ah
  2250.     mov    si,ax
  2251.     mov    Gsetid[si],21        ; store our char set ident
  2252.     mov    cx,gsize        ; first fill with spaces
  2253.     mov    al,20h
  2254.     push    es
  2255.     push    ds
  2256.     pop    es
  2257.     push    di            ; save starting location
  2258.     cld
  2259.     rep    stosb            ; spaces
  2260.     pop    di
  2261.     add    di,20h            ; where new chars start
  2262.     mov    si,offset dgldc        ; replacement chars
  2263.     mov    cx,dgldclen        ; number of new chars
  2264.     rep    movsb            ; copy them to the table
  2265.     mov    di,setptr
  2266.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2267.     mov    word ptr[di+gsize+1],'LD' ; set ident code
  2268.     pop    es
  2269.     pop    di
  2270.     pop    si
  2271.     ret
  2272. mkdgld    endp
  2273.  
  2274. ; Make Data General word processing to Gn table. 
  2275. ; Enter with destination in setptr
  2276. mkdgwp    proc    near
  2277.     push    si
  2278.     push    di
  2279.     mov    di,setptr
  2280.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2281.     xor    ah,ah
  2282.     mov    si,ax
  2283.     mov    Gsetid[si],22        ; store our char set ident
  2284.     mov    cx,gsize        ; first fill with spaces
  2285.     mov    al,20h
  2286.     push    es
  2287.     push    ds
  2288.     pop    es
  2289.     push    di            ; save starting location
  2290.     cld
  2291.     rep    stosb            ; spaces
  2292.     pop    di
  2293.     add    di,20h            ; where new chars start
  2294.     mov    si,offset dgwpcp437    ; replacement chars
  2295.     mov    cx,dgwplen        ; number of new chars
  2296.     rep    movsb            ; copy them to the table
  2297.     mov    di,setptr
  2298.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2299.     mov    word ptr[di+gsize+1],'WD' ; set ident code
  2300.     pop    es
  2301.     pop    di
  2302.     pop    si
  2303.     ret
  2304. mkdgwp    endp
  2305.  
  2306. ; Make Data General soft set filler to Gn table. 
  2307. ; Enter with destination in setptr
  2308. mkdgtr    proc    near
  2309.     push    si
  2310.     push    di
  2311.     mov    di,setptr
  2312.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2313.     xor    ah,ah
  2314.     mov    si,ax
  2315.     mov    Gsetid[si],100        ; store our char set ident
  2316.     mov    cx,gsize        ; fill with "?"
  2317.     mov    al,'?'
  2318.     push    es
  2319.     push    ds
  2320.     pop    es
  2321.     cld
  2322.     rep    stosb            ; fill with "?"
  2323.     mov    di,setptr
  2324.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2325.     mov    word ptr[di+gsize+1],'UD' ; set ident code
  2326.     pop    es
  2327.     pop    di
  2328.     pop    si
  2329.     ret
  2330. mkdgtr    endp
  2331.  
  2332. ; Make DEC Alt-ROM to Gn table.
  2333. ; Enter with destination in setptr
  2334. mkaltrom proc    near
  2335.     call    mkascii            ; init set to ASCII
  2336.     push    si
  2337.     push    di
  2338.     push    es
  2339.     push    ds
  2340.     pop    es            ; point es at data segment
  2341.     mov    di,setptr
  2342.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2343.     xor    ah,ah
  2344.     mov    si,ax
  2345.     mov    Gsetid[si],14        ; store our char set ident
  2346.     add    di,60h            ; replace a..z with 20h + (a..z)
  2347.     mov    si,di            ; special graphics table
  2348.     mov    cx,27            ; number of chars to do (a..z)
  2349.     cld
  2350. decalt1:lodsb                ; get a char
  2351.     add    al,20h            ; map up by 20h
  2352.     stosb
  2353.     loop    decalt1
  2354.     mov    di,setptr
  2355.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2356.     mov    word ptr[di+gsize+1],0+'1' ; set ident code
  2357.     pop    es
  2358.     pop    di
  2359.     pop    si
  2360.     ret
  2361. mkaltrom endp
  2362.  
  2363. ; Make DEC special graphics to Gn table.
  2364. ; Enter with destination in setptr
  2365. mkdecspec proc    near
  2366.     call    mkascii            ; init set to ASCII
  2367.     push    si
  2368.     push    di
  2369.     mov    di,setptr
  2370.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2371.     xor    ah,ah
  2372.     mov    si,ax
  2373.     mov    Gsetid[si],19        ; store our char set ident
  2374.     add    di,95            ; replace chars 95-126
  2375.     mov    si,offset sgrtab    ; use DEC special graphics table
  2376.     mov    cx,sgrtabl        ; table length
  2377.     test    flags.vtflg,ttheath    ; Heath rather than VT?
  2378.     jz    mkdecsp1        ; z = no
  2379.     mov    si,offset hgrtab    ; use Heath table
  2380.     mov    cx,hgrtabl
  2381.     dec    di            ; work from 94 rather than 95
  2382. mkdecsp1:push    es
  2383.     push    ds
  2384.     pop    es
  2385.     cld
  2386.     rep    movsb            ; replace chars with sgrtab items
  2387.     mov    di,setptr
  2388.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2389.     mov    word ptr[di+gsize+1],0+'0' ; set ident code
  2390.     pop    es
  2391.     pop    di
  2392.     pop    si
  2393.     clc
  2394.     ret
  2395. mkdecspec endp
  2396.  
  2397. ; Make Dec Technical to Gn table
  2398. ; Enter with destination in setptr
  2399. mkdectech proc    near
  2400.     push    si
  2401.     push    di
  2402.     mov    di,setptr
  2403.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2404.     xor    ah,ah
  2405.     mov    si,ax
  2406.     mov    Gsetid[si],18        ; store our char set ident
  2407.     mov    si,offset dectech    ; source data
  2408.     call    cpyset            ; copy the set to setptr's place
  2409.     mov    di,setptr
  2410.     mov    byte ptr[di+gsize],94    ; say this is a 96 byte set
  2411.     mov    word ptr[di+gsize+1],0+'>' ; set ident code
  2412.     pop    di
  2413.     pop    si
  2414.     clc
  2415.     ret
  2416. mkdectech endp
  2417.  
  2418. ; Make Heath-19 special graphics to Gn table. Enter with dest of setptr.
  2419.  
  2420. ; Initialize a char set to ASCII values 0..127 and ident of 94/B
  2421. ; Enter with setptr holding offset of G0set, G1set, G2set, or G3set char set
  2422. mkascii    proc    near
  2423.     push    ax
  2424.     push    cx
  2425.     push    di
  2426.     push    es
  2427.     mov    di,setptr        ; char set to init (G0..G3)
  2428.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2429.     xor    ah,ah
  2430.     mov    si,ax
  2431.     mov    Gsetid[si],0        ; store our char set ident
  2432.     mov    cx,gsize        ; number of bytes to do
  2433.     xor    al,al            ; initial value
  2434.     push    ds
  2435.     pop    es            ; set es to data segment
  2436.     cld
  2437. mkascii1:stosb                ; copy value to char set table
  2438.     inc    al
  2439.     loop    mkascii1
  2440.     mov    di,setptr
  2441.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2442.     mov    word ptr[di+gsize+1],0+'B' ; set ident code to ASCII "B"
  2443.     pop    es
  2444.     pop    di
  2445.     pop    cx
  2446.     pop    ax
  2447.     ret
  2448. mkascii    endp
  2449.  
  2450. ; Make UK ASCII to table Gn
  2451. ; Enter with destination in setptr
  2452. mkukascii proc    near
  2453.     call    mkascii            ; make US ASCII table
  2454.     push    di
  2455.     mov    di,setptr        ; get set pointer
  2456.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2457.     xor    ah,ah
  2458.     mov    si,ax
  2459.     mov    Gsetid[si],1        ; store our char set ident
  2460.     mov    byte ptr[di+23h],156    ; replace sharp 2/3 with Sterling sign
  2461.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2462.     mov    word ptr[di+gsize+1],0+'A' ; set ident code
  2463.     pop    di
  2464.     ret
  2465. mkukascii endp
  2466.  
  2467. ; Make DEC Multinational Char Set (DEC-MCS/DEC Supplemental Graphics)
  2468. ; and put into Gn table indicated by AL = 0..3
  2469. ; Enter with destination in setptr
  2470. mkdecmn    proc    near
  2471.     push    si
  2472.     push    di
  2473.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2474.     xor    ah,ah
  2475.     mov    si,ax
  2476.     mov    Gsetid[si],17        ; store our char set ident
  2477.     call    flatin1            ; get Latin1 to BX
  2478.     mov    si,bx
  2479.     call    cpyset            ; copy the set, gsize+3 bytes
  2480.     mov    si,offset MNlatin    ; get update table
  2481.     mov    di,setptr
  2482.     mov    cx,16            ; number of updates
  2483.     xor    bh,bh
  2484. mkdecmn1:mov    bl,[si]            ; get Latin1 code point to be changed
  2485.     and    bl,not 80h        ; map down to 0..127 range
  2486.     mov    al,[si+16]        ; get new value
  2487.     mov    [di+bx],al        ; store new value
  2488.     inc    si
  2489.     loop    mkdecmn1
  2490.     mov    di,setptr
  2491.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2492.     mov    word ptr[di+gsize+1],'5%' ; set ident code
  2493.     pop    di
  2494.     pop    si
  2495.     ret
  2496. mkdecmn    endp
  2497.  
  2498. ; Put transparent char set (128..255) into Gn table.
  2499. ; Enter with destination in setptr
  2500. mkxparent proc    near
  2501.     call    mkascii            ; init set to ASCII
  2502.     push    si
  2503.     push    di
  2504.     mov    di,setptr        ; point at character set
  2505.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2506.     xor    ah,ah
  2507.     mov    si,ax
  2508.     mov    Gsetid[si],1        ; store our char set ident
  2509.     mov    cx,gsize        ; number of chars to do, 128
  2510.     cld
  2511.     mov    al,cl            ; start with 128 char value
  2512.     push    es
  2513.     push    ds
  2514.     pop    es            ; point es at data segment
  2515. mkxpar2:stosb                ; store codes 128..255
  2516.     inc    al
  2517.     loop    mkxpar2
  2518.     mov    di,setptr
  2519.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2520.     mov    word ptr[di+gsize+1],0+'?' ; set ident code
  2521.     pop    es
  2522.     pop    di
  2523.     pop    si
  2524.     ret
  2525. mkxparent endp
  2526.  
  2527. ; Construct NRC table.
  2528. ; Enter with destination in setptr
  2529. ; and CX holding the desired country code (1..13).
  2530. mknrc    proc near
  2531.     call    mkascii            ; init set to ASCII
  2532.     push    bx
  2533.     push    cx
  2534.     push    si
  2535.     push    di
  2536.     push    word ptr emubuf
  2537.     push    word ptr emubuf+2
  2538.     push    es
  2539.     mov    di,setptr
  2540.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2541.     xor    ah,ah
  2542.     mov    si,ax
  2543.     mov    Gsetid[si],cl        ; store our char set ident
  2544.     mov    emubuf+2,cl        ; local copy
  2545.     cmp    cl,13            ; DEC Hebrew case?
  2546.     je    mknrc10            ; e = yes
  2547.         ; copy from NRC table (si) to set pointed at by di, cx chars
  2548.                     ;  plus 3 ident bytes at table end
  2549.     mov    word ptr emubuf,offset nrclat ; start of NRC to Latin1 table
  2550.     mov    ax,cx            ; country code 1..12
  2551.     mov    bl,15            ; 15 bytes per entry
  2552.     mul    bl            ; distance down the table to country
  2553.     add    word ptr emubuf,ax    ; point at country line
  2554.     mov    cx,12            ; do 12 bytes of new chars
  2555.     push    ds
  2556.     pop    es
  2557.     cld
  2558.     call    flatin1            ; returns BX = Latin1 to CPnnn table
  2559.     xor    si,si
  2560. mknrc2:    mov    al,nrclat[si]        ; get code point to change
  2561.     xor    ah,ah
  2562.     mov    di,setptr        ; start of destination table
  2563.     add    di,ax            ; destination of new char
  2564.     push    bx
  2565.     mov    bx,word ptr emubuf    ; ptr to country entries
  2566.     mov    al,[bx+si]        ; read char from NRC table
  2567.     pop    bx
  2568.     inc    si
  2569.     test    al,80h            ; in GR Latin1 area?
  2570.     jz    mknrc3            ; z = no, in ASCII GL area
  2571.     and    al,not 80h        ; trim high bit for xlat
  2572.     xlatb                  ; translate through Latin1 Code Page
  2573. mknrc3:    stosb                ; move replacement char from nrc list
  2574.     loop    mknrc2
  2575.  
  2576.     mov    di,setptr
  2577.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  2578.     jz    mknrc8            ; z = no
  2579.     mov    cl,emubuf+2        ; country code again
  2580.     cmp    cl,3            ; French NRC?
  2581.     jne    mknrc4            ; ne = no
  2582.     mov    al,07fh            ; apply DG French NRC patch
  2583.     jmp    short mknrc7
  2584. mknrc4:    cmp    cl,6            ; Spanish NRC?
  2585.     jne    mknrc5            ; ne = no
  2586.     mov    al,07fh            ; apply DG Spanish NRC patch
  2587.     jmp    short mknrc7
  2588. mknrc5:    cmp    cl,7            ; DG Danish/Norweigen NRC?
  2589.     jne    mknrc6            ; ne = no
  2590.     mov    al,0fch            ; apply DG Danish/Norweigen NRC patch
  2591.     jmp    short mknrc7
  2592. mknrc6:    cmp    cl,8            ; Swiss NRC?
  2593.     jne    mknrc7            ; ne = no
  2594.     mov    al,0e9h            ; apply DG Swiss NRC patch
  2595. mknrc7:    and    al,not 80h
  2596.     xlatb                ; push through Latin1 translation
  2597.     mov    [di+7fh],al        ; new value
  2598. mknrc8:    add    di,gsize        ; look at end of set, to id bytes
  2599.     movsb                ; copy set size and two ident chars
  2600.     movsw
  2601.     jmp    short mknrc11
  2602.  
  2603. mknrc10:mov    vtcpage,862        ; Hebrew NRC CP862
  2604.     call    flatin1            ; get SI appropriate for Code Page
  2605.     mov    si,bx            ; point to Latin 1 for this code page
  2606.     add    si,6*16            ; get Hebrew part of CP862
  2607.     mov    di,ds
  2608.     mov    es,di
  2609.     mov    di,setptr
  2610.     add    di,6*16
  2611.     mov    cx,27            ; number of characters
  2612.     cld
  2613.     rep    movsb
  2614. mknrc11:pop    es
  2615.     pop    word ptr emubuf+2
  2616.     pop    word ptr emubuf
  2617.     pop    di
  2618.     pop    si
  2619.     pop    cx
  2620.     pop    bx
  2621.     ret
  2622. mknrc    endp
  2623.     
  2624. ; Construct Latin1 table to Gn table.
  2625. ; Enter with destination in setptr
  2626. mklatin1 proc    near
  2627.     push    si
  2628.     push    di
  2629.     mov    di,setptr        ; destination
  2630.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2631.     xor    ah,ah
  2632.     mov    si,ax
  2633.     mov    Gsetid[si],16        ; store our char set ident
  2634.     call    flatin1            ; get BX appropriate for Code Page
  2635.     mov    si,bx
  2636.     mov    cx,gsize        ; bytes
  2637.     push    es
  2638.     push    ds
  2639.     pop    es
  2640.     cld
  2641.     rep    movsb            ; copy bytes
  2642.     mov    di,setptr
  2643.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2644.     mov    word ptr[di+gsize+1],0+'A' ; set ident code
  2645.     pop    es
  2646.     pop    di
  2647.     pop    si
  2648.     ret
  2649. mklatin1 endp
  2650.  
  2651. ; Construct Latin2 table to Gn table.
  2652. ; Enter with destination in setptr
  2653. mklatin2 proc    near
  2654.     push    si
  2655.     push    di
  2656.     mov    di,setptr        ; destination
  2657.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2658.     xor    ah,ah
  2659.     mov    si,ax
  2660.     mov    Gsetid[si],16        ; store our char set ident
  2661.     mov    vtcpage,852        ; set emulator's CP to CP852
  2662.     call    flatin1            ; get BX appropriate for Code Page
  2663.     mov    si,bx
  2664.     mov    cx,gsize        ; bytes
  2665.     push    es
  2666.     push    ds
  2667.     pop    es
  2668.     cld
  2669.     rep    movsb            ; copy bytes
  2670.     mov    di,setptr
  2671.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2672.     mov    word ptr[di+gsize+1],0+'B' ; set ident code
  2673.     pop    es
  2674.     pop    di
  2675.     pop    si
  2676.     ret
  2677. mklatin2 endp
  2678.  
  2679. ; Make DEC Hebrew (94) 8-bit Supplemental
  2680. ; Same code points as Hebrew-ISO at this time
  2681. mkdec_Hebrew    proc    near
  2682.     call    mklatin_hebrew
  2683.     push    es
  2684.     push    ds
  2685.     pop    es
  2686.     mov    di,setptr
  2687.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2688.     mov    word ptr[di+gsize+1],'4"' ; set ident code
  2689.     pop    es
  2690.     ret
  2691. mkdec_Hebrew    endp
  2692.  
  2693. ; Make Hebrew-ISO (96) 8-bit Supplemental to Gn pointer
  2694. ; Enter with destination in setptr
  2695. ; Presumes CP 862 is loaded
  2696. mklatin_Hebrew    proc    near
  2697.     push    si
  2698.     push    di
  2699.     mov    di,setptr        ; destination
  2700.     mov    al,[di+gsize+3]        ; get Gn number (0..3)
  2701.     xor    ah,ah
  2702.     mov    si,ax
  2703.     mov    Gsetid[si],24        ; store our char set ident
  2704.     mov    cx,gsize        ; bytes
  2705.     mov    vtcpage,862        ; set emulator's CP to CP862
  2706.     call    flatin1            ; get BX appropriate for Code Page
  2707.     mov    si,bx
  2708.     push    es
  2709.     push    ds
  2710.     pop    es
  2711.     cld
  2712.     rep    movsb            ; copy bytes
  2713.     mov    di,setptr
  2714.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2715.     mov    word ptr[di+gsize+1],0+'H' ; set ident code
  2716.     pop    es
  2717.     pop    di
  2718.     pop    si
  2719.     ret
  2720. mklatin_Hebrew    endp
  2721.  
  2722. ; Get output byte in AL from keyboard raw reader and convert through active
  2723. ; Code Page translations. Return final output byte in AL
  2724. ; Return modified char code, depending on SET TERM CHAR-SET and active
  2725. ; Code Page. Enter and exit with char in AL.
  2726. xltkey    proc    FAR
  2727.     cmp    al,80h            ; regular ASCII key?
  2728.     jb    xltkey1            ; b = yes, do not translate
  2729.     cmp    flags.xltkbd,0        ; keyboard translation is off?
  2730.     jne    xltkey2            ; ne = no
  2731. xltkey1:ret
  2732.  
  2733. xltkey2:push    es
  2734.     push    ds
  2735.     pop    es
  2736.     push    di
  2737.     mov    di,GRptr        ; high bit is where GR points
  2738.     mov    cx,gsize
  2739.     add    di,cx
  2740.     std
  2741.     repne    scasb            ; scan looking for this code
  2742.     cld
  2743.     jne    xltkey3            ; ne = not found
  2744.     inc    di            ; backup to found code
  2745.     sub    di,GRptr        ; minus start
  2746.     or    di,80h            ; put back high bit
  2747.     mov    ax,di            ; AL is the byte value
  2748. xltkey3:pop    di
  2749.     pop    es
  2750.     ret
  2751. xltkey    endp
  2752.  
  2753. ; cursor movements
  2754.  
  2755. atcup:    test    dspstate,dsptype    ; on VT320 status line?
  2756.     jz    atcup0            ; z = no
  2757.     mov    param,0            ; yes, do not change rows
  2758. atcup0:    mov    dh,byte ptr param    ; get row,col parameters
  2759.     mov    dl,byte ptr param+2    ; dh is row, dl is column
  2760.     or    dh,dh            ; zero row number?
  2761.     jz    atcup1            ; z = yes, continue
  2762.     dec    dh            ; normalize to 0,0 system
  2763. atcup1:    or    dl,dl            ; ditto for column
  2764.     jz    atcup2
  2765.     dec    dl
  2766. atcup2:    test    vtemu.vtflgop,decom    ; Origin mode?
  2767.     jz    atcup3            ; z = no, skip this stuff
  2768.     add    dh,mar_top        ; yes, it was relative to top margin
  2769.     jno    atcup3            ; if no overflow, continue
  2770.     mov    dh,byte ptr low_rgt+1    ; otherwise just set to screen bottom
  2771. atcup3:    mov    al,mar_right        ; right margin
  2772.     cmp    dl,al            ; too far to the right?
  2773.     jbe    atcup4            ; ne = no
  2774.     mov    dl,al            ; limit to right margin
  2775. atcup4:    mov    ah,byte ptr low_rgt+1    ; last regular text line
  2776.     cmp    dh,ah            ; going to 25th line?
  2777.     jbe    atcup7            ; be = no
  2778.     inc    ah            ; "25th" status line
  2779.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  2780.     je    atcup5            ; e = yes
  2781.     cmp    dh,ah            ; going too far?
  2782.     je    atcup8            ; e = no
  2783.     dec    ah
  2784.     mov    dh,ah            ; last normal row
  2785. atcup4a:jmp    atsetcur        ; set cursor here
  2786.  
  2787. atcup5:    cmp    dh,ah            ; going too far?
  2788.     ja    atcup6            ; a = yes
  2789.     test    h19stat,h19l25        ; Heath 25th mode line enabled?
  2790.     jnz    atcup8            ; nz = yes
  2791. atcup6:    mov    dh,byte ptr cursor+1    ; do not change rows
  2792. atcup7: call    atccpc            ; check position
  2793. atcup8:    jmp    atsetcur        ; set cursor position and return
  2794.  
  2795. atcuarg:mov    al,byte ptr param    ; worker, get cursor movement argument
  2796.     or    al,al            ; zero?
  2797.     jnz    atcua1            ; nz = no
  2798.     inc    al            ; default to one
  2799. atcua1: ret
  2800.                     ; cursor up
  2801. atcuu:    cmp    dh,byte ptr low_rgt+1    ; on 25th line?
  2802.     jbe    atcuu1            ; be = no
  2803.     ret                ; no vertical for Heath on 25th line
  2804. atcuu1:    call    atcuarg            ; get cursor move up argument into al
  2805.     sub    dh,al            ; compute new cursor position
  2806.     jnc    atcuu2            ; nc = ok [dlk]
  2807.     xor    dh,dh            ; overflow, restrict range. [dlk]
  2808. atcuu2:    call    atccic            ; check indexing, ignore action in ax
  2809.     jmp    atsetcur        ; set the cursor at its new position
  2810.  
  2811. atcud:    call    atcuarg            ; cursor down
  2812.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  2813.     jbe    atcud1            ; be = no
  2814.     ret                ; else leave it on status line
  2815. atcud1:    add    dh,al            ; compute new cursor position
  2816.     jnc    atcud2            ; nc = ok [dlk]
  2817.     mov    dh,byte ptr low_rgt+1    ; default bottom [dlk]
  2818. atcud2:    call    atccic            ; check indexing, ignore action in ax
  2819.     jmp    atsetcur        ; set the cursor at its new position
  2820.  
  2821.                     ; Allow horiz movement on 25th line
  2822. atcuf:    call    atcuarg            ; cursor forward
  2823.     add    dl,al            ; compute new cursor position
  2824.     jnc    atcup3            ; nc = no problem
  2825.     mov    dl,byte ptr low_rgt    ; else set to right margin
  2826.     jmp    atcup3            ; check/set cursor, return
  2827.  
  2828. atcub:    call    atcuarg            ; cursor back
  2829.     sub    dl,al            ; compute new cursor position
  2830.     jnc    atcub1            ; nc = no problem
  2831.     xor    dl,dl            ; else set to left margin
  2832. atcub1:    jmp    atcup3            ; check/set cursor, return
  2833.  
  2834. atcha:    call    atcuarg            ; absolute horizontal address
  2835.     mov    dl,al            ; new column, counted from 1
  2836.     sub    dl,1            ; column, count from 0 internally
  2837.     jns    atcha1            ; ns = no problem
  2838.     xor    dl,dl            ; else set to left margin
  2839. atcha1:    jmp    atcup3            ; check/set cursor, return
  2840.  
  2841. atcht:    call    atcuarg            ; move cursor forward # horiz tabs
  2842.     inc    dl            ; next column
  2843.     mov    cl,al            ; number of tabstops to locate
  2844.     xor    ch,ch
  2845.     mov    si,offset tabs        ; active tabs buffer
  2846. atcht1:    cmp    dl,mar_right        ; at end of line?
  2847.     jae    atcht2            ; ae = yes, stop here
  2848.     call    istabs            ; is dl column a tabstop?
  2849.     inc    dl            ; try next column, preserves carry
  2850.     jnc    atcht1            ; nc = no, find one
  2851.     loop    atcht1            ; do cx tabstops
  2852. atcht2:    jmp    atcup3            ; set cursor
  2853.  
  2854. atcva:    inc    dl            ; count columns from 1 here
  2855.     mov    byte ptr param+2,dl    ; set column in second parameter
  2856.     mov    param+3,0        ; high byte
  2857.     jmp    atcup            ; do absolute vertical positioning
  2858.  
  2859. atcnl:    call    atcuarg            ; do # Next-Lines
  2860.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  2861.     jbe    atcnl1            ; be = no
  2862.     ret                ; else leave it on status line
  2863. atcnl1:    mov    cl,al            ; number to do
  2864.     xor    ch,ch
  2865. atcnl2:    push    cx
  2866.     inc    dh            ; number to do
  2867.     mov    dl,mar_left
  2868.     call    atccic            ; check cursor position
  2869.     call    ax            ; scroll if necessary
  2870.     call    atsetcur        ; set cursor, etc. and return
  2871.     pop    cx
  2872.     loop    atcnl2
  2873.     ret
  2874. atcpl:    call    atcuarg            ; do # Previous-Lines
  2875.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  2876.     jbe    atcpl1            ; be = no
  2877.     ret                ; else leave it on status line
  2878. atcpl1:    mov    cl,al            ; number to do
  2879.     xor    ch,ch
  2880.     mov    dl,mar_left
  2881. atcpl2:    dec    dh            ; do one line
  2882.     push    cx            ; save counter
  2883.     call    atccic            ; check cursor position
  2884.     call    ax            ; scroll if necessary
  2885.     call    atsetcur        ; set cursor
  2886.     pop    cx
  2887.     loop    atcpl2            ; do cx times
  2888.     ret
  2889.  
  2890. ; Screen erasure commands
  2891.                     ; Erase in display
  2892. ated:    cmp    ninter,0        ; zero intermediates?
  2893.     je    ated0            ; e = yes, else try protected mode
  2894.     ret
  2895.  
  2896. ated0:    cmp    lparam,0
  2897.     je    ated0a
  2898.     jmp    atedsel
  2899. ated0a:    cmp    param,0            ; was arg zero?
  2900.     jne    ated1            ; ne = no
  2901.     jmp    ereos            ; do erase cursor to end of screen
  2902.  
  2903. ated1:    cmp    param,1            ; was arg one?
  2904.     jne    ated2            ; ne = no
  2905.     jmp    ersos            ; do erase start of screen to cursor
  2906.  
  2907. ated2:    cmp    param,2            ; was arg two?
  2908.     je    ated2a            ; e = yes, erase entire screen
  2909.     ret                ; else ignore
  2910. ated2a:    push    dx            ; save dynamic cursor
  2911.     push    word ptr mar_top
  2912.     mov    mar_bot,dh
  2913.     mov    mar_top,0        ; row of cursor
  2914.     inc    dh            ; number of lines to scroll
  2915.     mov    scroll,dh
  2916.     call    atscru            ; scroll them up before erasure
  2917.     pop    word ptr mar_top
  2918.     pop    dx
  2919.     call    ersos            ; erase start of screen to cursor
  2920.     call    ereos            ; erase cursor to end of screen
  2921.     ret
  2922.  
  2923.  
  2924. atedsel    proc    near            ; DECSED selective erase in display
  2925.     cmp    lparam,'?'        ; proper intermediate?
  2926.     jne    atedsel3        ; ne = no
  2927.     mov    ax,param        ; get parameter
  2928.     or    ax,ax            ; 0?
  2929.     jnz    atedsel1        ; nz = no
  2930.     mov    al,mar_top        ; 0: erase cursor to end of screen
  2931.     mov    ah,mar_bot        ; save margins
  2932.     push    ax
  2933.     mov    mar_top,dh        ; use current row
  2934.     mov    ah,byte ptr low_rgt+1    ; bottom screen row for text
  2935.     mov    mar_bot,ah
  2936.     call    erprot            ; do protected mode erasure
  2937.     pop    ax
  2938.     mov    mar_top,al        ; restore margins
  2939.     mov    mar_bot,ah
  2940.     jmp    short atedsel3
  2941. atedsel1:cmp    al,1            ; 1? erase start of line to cursor
  2942.     jne    atedsel2        ; ne = no
  2943.     mov    al,mar_top        ; 1: erase start to cursor
  2944.     mov    ah,mar_bot        ; save margins
  2945.     push    ax
  2946.     mov    al,mar_right
  2947.     mov    ah,dl            ; save right margin and cursor col
  2948.     push    ax
  2949.     mov    mar_right,dl        ; stop at current cursor
  2950.     mov    dl,mar_left        ; start at this pseudo cursor
  2951.     mov    mar_top,dh        ; use current row
  2952.     mov    mar_bot,dh
  2953.     call    erprot            ; do protected mode erasure
  2954.     pop    ax
  2955.     mov    mar_right,al        ; restore right margin
  2956.     mov    dl,ah            ; restore cursor row
  2957.     pop    ax
  2958.     mov    mar_top,al        ; restore margins
  2959.     mov    mar_bot,ah
  2960.     jmp    short atedsel3
  2961. atedsel2:cmp    al,2            ; 2? erase whole line
  2962.     jne    atedsel3        ; ne = no
  2963.     mov    al,mar_top        ; 2: erase whole screen
  2964.     mov    ah,mar_bot        ; save margins
  2965.     push    ax
  2966.     mov    ah,mar_right
  2967.     mov    al,mar_left
  2968.     push    ax
  2969.     push    dx            ; save cursor
  2970.     xor    dx,dx            ; set to top left corner
  2971.     mov    mar_right,dl        ; starting point
  2972.     mov    mar_top,dh
  2973.     mov    ax,low_rgt        ; lower right corner of text area
  2974.     mov    mar_left,al        ; start at this pseudo cursor
  2975.     mov    mar_bot,ah
  2976.     call    erprot            ; do protected mode erasure
  2977.     pop    dx            ; restore cursor
  2978.     pop    ax
  2979.     mov    mar_left,al
  2980.     mov    mar_right,ah
  2981.     pop    ax
  2982.     mov    mar_top,al        ; restore margins
  2983.     mov    mar_bot,ah
  2984. atedsel3:ret
  2985. atedsel    endp
  2986.  
  2987.  
  2988. p20ed:    xor    dx,dx            ; Prime PT200, set cursor to 0,0
  2989.     call    ereos            ; erase cursor to end of screen
  2990.     jmp    atsetcur            ; put cursor at 0,0 and return
  2991.  
  2992.                     ; Erase in current line
  2993. atel:    cmp    ninter,0        ; zero intermediates?
  2994.     je    atel0            ; e = yes
  2995.     ret
  2996.  
  2997. atel0:    cmp    lparam,0        ; letter parameter?
  2998.     je    atel0a
  2999.     jmp    atelsel            ; try protected mode erasure
  3000. atel0a:    cmp    param,0            ; was arg zero?
  3001.     jne    atel1            ; ne = no
  3002.     mov    al,dl            ; erase from cursor
  3003.     mov    bl,byte ptr low_rgt    ;  to end of line, inclusive
  3004.     jmp    erinline        ; do the erasure
  3005.  
  3006. atel1:    cmp    param,1            ; was arg one?
  3007.     jne    atel2            ; ne = no
  3008.     xor    al,al            ; erase from start of line
  3009.     mov    bl,dl            ;  to cursor, inclusive
  3010.     jmp    erinline        ; do the erasure
  3011.  
  3012. atel2:    cmp    param,2            ; was arg two?
  3013.     jne    atel3            ; ne = no, ignore
  3014.     xor    al,al            ; erase entire line
  3015.     mov    bl,byte ptr low_rgt
  3016.     jmp    erinline        ; clear it
  3017. atel3:    ret
  3018.  
  3019.  
  3020. atelsel    proc    near            ; DECSEL selective erase in line
  3021.     cmp    lparam,'?'        ; proper intermediate?
  3022.     jne    atelsel3        ; ne = no
  3023.     mov    ax,param        ; get parameter
  3024.     or    ax,ax            ; 0?
  3025.     jnz    atelsel1        ; nz = no
  3026.     mov    al,mar_top        ; 0: erase cursor to end of line
  3027.     mov    ah,mar_bot        ; save margins
  3028.     push    ax
  3029.     mov    mar_top,dh        ; use current row
  3030.     mov    mar_bot,dh
  3031.     call    erprot            ; do protected mode erasure
  3032.     pop    ax
  3033.     mov    mar_top,al        ; restore margins
  3034.     mov    mar_bot,ah
  3035.     ret
  3036. atelsel1:cmp    al,1            ; 1? erase start of line to cursor
  3037.     jne    atelsel2        ; ne = no
  3038.     mov    al,mar_top        ; 1: erase start to cursor
  3039.     mov    ah,mar_bot        ; save margins
  3040.     push    ax
  3041.     mov    al,mar_right
  3042.     mov    ah,dl            ; save right margin and cursor col
  3043.     push    ax
  3044.     mov    mar_right,dl        ; stop at current cursor
  3045.     mov    dl,mar_left        ; start at this pseudo cursor
  3046.     mov    mar_top,dh        ; use current row
  3047.     mov    mar_bot,dh
  3048.     call    erprot            ; do protected mode erasure
  3049.     pop    ax
  3050.     mov    mar_right,al        ; restore right margin
  3051.     mov    dl,ah            ; restore cursor row
  3052.     pop    ax
  3053.     mov    mar_top,al        ; restore margins
  3054.     mov    mar_bot,ah
  3055.     ret
  3056. atelsel2:cmp    al,2            ; 2? erase whole line
  3057.     jne    atelsel3        ; ne = no
  3058.     mov    al,mar_top        ; 2: erase whole line
  3059.     mov    ah,mar_bot        ; save margins
  3060.     push    ax
  3061.     mov    ah,dl            ; save right margin and cursor col
  3062.     push    ax
  3063.     mov    mar_right,dl        ; stop at current cursor
  3064.     mov    dl,mar_left        ; start at this pseudo cursor
  3065.     mov    mar_top,dh        ; use current row
  3066.     mov    mar_bot,dh
  3067.     call    erprot            ; do protected mode erasure
  3068.     pop    ax
  3069.     mov    dl,ah            ; restore cursor row
  3070.     pop    ax
  3071.     mov    mar_top,al        ; restore margins
  3072.     mov    mar_bot,ah
  3073. atelsel3:ret
  3074. atelsel    endp
  3075.  
  3076.                     ; ECH, erase chars in this line
  3077. atech:    mov    ax,dx            ; get cursor position
  3078.     mov    bx,ax            ; erase ax to bx
  3079.     cmp    byte ptr param,0    ; 0 argument
  3080.     je    atech1            ; e = yes
  3081.     dec    bl            ; count from 1
  3082. atech1:    add    bl,byte ptr param    ; number of characters
  3083.     jmp    erinline        ; erase in this line
  3084.  
  3085.  
  3086. ; Set Graphics Rendition commands (video attributes)
  3087.  
  3088. atsgr:    cmp    lparam,0        ; any letter parameter?
  3089.     jne    atsgr0            ; ne = yes, fail
  3090.     mov    ah,curattr        ; get current cursor attribute
  3091.     mov    di,offset atsgr1    ; routine to call
  3092.     call    atreps            ; repeat for all parms
  3093.     mov    curattr,ah        ; store new attribute byte
  3094. atsgr0:    ret
  3095.  
  3096. atsgr1:    mov    bx,param[si]        ; fetch an argument
  3097.     or    bl,bl            ; 0, clear all attributes?
  3098.     jnz    atsgr2            ; nz = no, do selectively below
  3099.     call    clrbold            ; clear bold attribute
  3100.     call    clrblink        ; clear blink attribute
  3101.     call    clrrev            ; clear reverse video attribute
  3102.     call    clrunder        ; clear underline attribute
  3103.     mov    extattr,0        ; clear extended attributes
  3104.     ret
  3105.  
  3106. atsgr2:    cmp    bl,1            ; 1, set bold?
  3107.     jne    atsgr2a            ; ne = no
  3108.     jmp    setbold            ; set bold attribute
  3109.  
  3110. atsgr2a:cmp    flags.vtflg,ttpt200    ; PT200 '2' = half intensity
  3111.     jne    atsgr3              ; ne = no, do next attrib test
  3112.     cmp    bl,2            ; PT200 - 2, set bold?
  3113.     jne    atsgr3            ; ne = no
  3114.     jmp    setbold            ; set half intensity
  3115.  
  3116. atsgr3: cmp    bl,4            ; 4, set underline?
  3117.     jne    atsgr4            ; ne = no
  3118.     jmp    setunder        ; set underline attribute
  3119.  
  3120. atsgr4: cmp    bl,5            ; 5, set blink?
  3121.     jne    atsgr5            ; ne = no
  3122.     jmp    setblink        ; set blink attribute
  3123.  
  3124. atsgr5: cmp    bl,7            ; 7, reverse video for chars?
  3125.     jne    atsgr6            ; ne = no, try coloring
  3126.     jmp    setrev            ; set reversed video attribute (AH)
  3127.  
  3128. atsgr6:    cmp    flags.vtflg,ttheath    ; Heath-19?
  3129.     jne    atsgr9            ; ne = no
  3130.     cmp    bl,10            ; 10, enter graphics mode?
  3131.     jne    atsgr7            ; ne = no
  3132.     push    ax            ; save ah
  3133.     mov    al,'F'            ; simulate final char of 'F'
  3134.     call    v52sgm            ; do character setup like VT52
  3135.     pop    ax
  3136.     ret
  3137. atsgr7:    cmp    bl,11            ; 11, exit graphics mode?
  3138.     jne    atsgr8            ; ne = no, ignore
  3139.     push    ax            ; save ah
  3140.     mov    al,'G'            ; simulate final char of 'G'
  3141.     call    v52sgm            ; do character setup like VT52
  3142.     pop    ax
  3143. atsgr8:    ret
  3144.  
  3145. atsgr9:    test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  3146.     jz    atsgr8            ; z = no, 22-27 are VT220/320 only
  3147.     cmp    bl,22            ; 22, bold off?
  3148.     jne    atsgr10            ; ne = no
  3149.     jmp    clrbold
  3150. atsgr10:cmp    bl,24            ; 24, underline off?
  3151.     jne    atsgr11            ; ne = no
  3152.     jmp    clrunder
  3153. atsgr11:cmp    bl,25            ; 25, blinking off?
  3154.     jne    atsgr12            ; ne = no
  3155.     jmp    clrblink
  3156. atsgr12:cmp    bl,27            ; 27, reverse video off?
  3157.     jne    atsgr13            ; ne = no
  3158.     jmp    clrrev            ; clear reversed video attribute (AH)
  3159. atsgr13:jmp    setcolor        ; BL = color, AH = attribute byte
  3160.  
  3161. ; Tabulation char commands
  3162. attbc:    call    atccpc            ; make sure cursor is kosher
  3163.     cmp    ninter,0        ; zero intermediates?
  3164.     je    attbc0            ; e = yes, else quit
  3165.     ret
  3166.                     ; Tabstop set/clears
  3167. attbc0: cmp    param,0            ; was argument zero?
  3168.     jne    attbc1            ; ne = no
  3169.     push    si
  3170.     mov    si,vtemu.vttbst        ; active buffer
  3171.     call    tabclr            ; clear tabstop in column DL
  3172.     pop    si
  3173.     ret
  3174.  
  3175. attbc1: cmp    param,3            ; was arg 3 (clear all tab stops)?
  3176.     je    attbc2            ; e = yes
  3177.     ret                ; else ignore
  3178. attbc2:    mov    cx,(swidth+7)/8        ; get ready to zap swidth columns
  3179.     mov    di,offset tabs        ; point to the tab stop table
  3180.     xor    al,al            ; zero indicates no tab stop
  3181.     push    es            ; save es
  3182.     push    ds
  3183.     pop    es            ; use data segment for es:di below
  3184.     cld                ; set direction forward
  3185.     rep    stosb            ; clear all bits
  3186.     pop    es
  3187.     ret
  3188.                     ; set scrolling margins
  3189. atstbm:    test    dspstate,dsptype    ; on status line?
  3190.     jnz    atstb3            ; nz = yes, ignore this command
  3191.     mov    al,byte ptr param    ; get the two line number args
  3192.     mov    ah,byte ptr param+2
  3193.     or    al,al            ; was first zero?
  3194.     jnz    atstb1            ; nz = no, continue
  3195.     inc    al            ; default is one
  3196. atstb1: or    ah,ah            ; was second zero?
  3197.     jnz    atstb2            ; nz = no
  3198.     mov    ah,byte ptr low_rgt+1    ; yes, default is last line on screen
  3199.     inc    ah
  3200. atstb2: dec    al            ; normalize to 0,0 coordinate system
  3201.     dec    ah
  3202.     cmp    ah,al            ; size of region at least two lines?
  3203.     jbe    atstb3            ; be = no, indicate an error
  3204.     or    al,al            ; check against screen limits
  3205.     jl    atstb3            ; l = out of range
  3206.     cmp    ah,byte ptr low_rgt+1
  3207.     ja    atstb3            ; a = too far down
  3208.     mov    mar_top,al        ; set the limits
  3209.     mov    mar_bot,ah
  3210.     xor    dx,dx            ; Home cursor
  3211.     call    atccpc
  3212.     jmp    atsetcur        ; set cursor position and return
  3213. atstb3:    ret                ; ignore bad requests
  3214.  
  3215. ; Device attributes commands
  3216. atda:    cmp    param,0            ; was argument zero?
  3217.     je    decid            ; e = send the i.d. string
  3218.     ret                ; no, only an echo
  3219. decid:    cmp    ninter,0        ; any intermediates?
  3220.     je    decid1            ; e = no, else not this item
  3221.     jmp    atdgnrc            ; try Spanish NRC designator
  3222. decid1:    mov    ax,flags.vtflg        ; get terminal ident type
  3223.     mov    cx,30            ; assumed length of asciiz string
  3224.     mov    si,offset v32str    ; VT320 ident string
  3225.     cmp    ax,ttvt320        ; VT320?
  3226.     je    decid2            ; e = yes
  3227.     mov    si,offset v22str
  3228.     cmp    ax,ttvt220        ; VT220?
  3229.     je    decid2            ; e = yes
  3230.     mov    si,offset v102str
  3231.     cmp    ax,ttvt102        ; VT102?
  3232.     je    decid2            ; e = yes
  3233.     mov    si,offset v100str
  3234.     cmp    ax,ttvt100        ; VT100?
  3235.     je    decid2            ; e = yes
  3236.     cmp    ax,tthoney        ; Honeywell?
  3237.     je    decid2            ; e = yes
  3238.     mov    si,offset v52str
  3239.     cmp    ax,ttvt52        ; VT52?
  3240.     je    decid2            ; e = yes
  3241.     mov    si,offset h19str
  3242.     cmp    ax,ttheath        ; Heath-19 mode?
  3243.     je    decid2            ; e = yes
  3244.     mov    si,offset pt20str    ; Prime PT200 string
  3245. decid2:    cmp    lparam,'>'        ; this letter parameter?
  3246.     jne    decid3            ; ne = no
  3247.     test    al,ttvt320+ttvt220    ; VT320/VT220 mode?
  3248.     jz    decid4            ; z = no, ignore
  3249.     mov    si,offset v32sda    ; Secondary DA response string
  3250. decid3:    cld
  3251.     lodsb                ; read string
  3252.     or    al,al            ; end of string?
  3253.     jz    decid4            ; z = yes
  3254.     push    cx
  3255.     push    si
  3256.     call    prtbout            ; send it to port with no local echo
  3257.     pop    si
  3258.     pop    cx
  3259.     loop    decid3            ; do all characters
  3260. decid4:    ret
  3261.                     ; Display LED's
  3262. atll:    mov    di,offset atleds    ; get pointer to routine to call
  3263.     call    atreps            ; repeat for selective parameters
  3264.     ret
  3265.  
  3266. atleds:    push    si            ; set LED indicators
  3267.     call    getled            ; set si to term type (led) string
  3268.     mov    di,si
  3269.     pop    si
  3270.     jc    atled2            ; c = no leds 1..4, ignore
  3271. atled4:    cmp    param[si],0        ; zero argument?
  3272.     jne    atled3            ; ne = no, check further
  3273.     mov    al,led_off        ; set all off
  3274.     mov    ah,al
  3275.     mov    [di+6],ax        ; where dots go after name
  3276.     mov    [di+6+2],ax
  3277. atled1:    test    yflags,modoff        ; mode line supposed to be off?
  3278.     jnz    atled2            ; nz = yes
  3279.     push    dx
  3280.     call    fmodlin            ; update status line
  3281.     pop    dx
  3282. atled2: ret
  3283. atled3: mov    ax,param[si]        ; get the argument
  3284.     cmp    al,1            ; must be 1 to 4
  3285.     jb    atled2            ; b = out of range
  3286.     cmp    al,4
  3287.     ja    atled2            ; a = out of range
  3288.     dec    ax            ; zero base it
  3289.     push    di
  3290.     add    di,ax
  3291.     add    al,'1'            ; add ascii offset for digit
  3292.     mov    [di+6],al         ; turn the "LED" on by storing digit
  3293.     pop    di
  3294.     jmp    short atled1        ; update display and return
  3295.  
  3296. decsca    proc    near            ; DEC Select Character Attributes
  3297.     cmp    ninter,1        ; one intermediate?
  3298.     jne    atll            ; no, try led routine
  3299.     cmp    inter,'"'        ; CSI Pn " q ?
  3300.     jne    decsca2            ; ne = no
  3301.     cmp    param,1            ; 0, 2 mean protected mode goes off
  3302.     jne    decsca1            ; ne = not 1, protected mode goes on
  3303.     call    setprot            ; start protecting
  3304.     ret
  3305. decsca1:call    clrprot            ; end protecting
  3306. decsca2:ret
  3307. decsca    endp
  3308.  
  3309.  
  3310. ; Set/Reset mode commands
  3311.                     ; ESC [ ? xxx h/l Set/Reset series
  3312. atrm:    mov    modeset,0        ; say we are resetting modes
  3313.     mov    di,offset atrsm        ; Reset/Set modes
  3314.     call    atreps            ; repeat for all parms
  3315.     test    vtemu.vtflgop,decanm    ; did ansi mode get reset?
  3316.     jnz    atrm1            ; nz = no, return
  3317.     cmp    flags.vtflg,ttheath    ; were we a Heath-19?
  3318.     je    atrm0            ; e = yes, don't change terminal types
  3319.     cmp    flags.vtflg,ttpt200    ; were we a PT200?
  3320.     je    atrm0            ; e = yes, don't change terminal types
  3321.     mov    flags.vtflg,ttvt52    ; say VT52 now
  3322. atrm0:    call    chrdef            ; set default char sets
  3323.     call    atsc            ; save cursor status
  3324.     test    yflags,modoff        ; mode line supposed to be off?
  3325.     jnz    atrm1            ; nz = yes
  3326.     call    fmodlin            ; update mode line
  3327. atrm1:    ret
  3328.  
  3329. atsm:    mov    modeset,1        ; say we are setting modes
  3330.     mov    di,offset atrsm        ; Reset/Set modes
  3331.     jmp    atreps            ; repeat for all parms
  3332.  
  3333. atrsm:    mov    ax,param[si]        ; pick up the argument
  3334.     cmp    lparam,'?'        ; DEC private mode? ESC [ ?
  3335.     je    atrsm1            ; e = yes, do DEC specific things
  3336.     cmp    lparam,'>'        ; Heath-19 private mode? ESC [ >
  3337.     jne    atrsma            ; ne = no
  3338.     jmp    htrsm1            ; do Heath specific things
  3339.                     ; ANSI level
  3340. atrsma:    cmp    al,20            ; 20, ANSI new-line mode?
  3341.     jne    atrsm0            ; ne = no, try insert mode
  3342.     and    vtemu.vtflgop,not vsnewline ; assume resetting
  3343.     cmp    modeset,0        ; resetting?
  3344.     je    atrsmb            ; e = yes
  3345.     or    vtemu.vtflgop,vsnewline    ; setting
  3346. atrsmb:    mov    ax,anslnm        ; get the flag bit
  3347.     jmp    atrsflg            ; set or reset it
  3348. atrsm0:    cmp    al,4            ; toggle insert mode?
  3349.     jne    atrsmc            ; ne = no
  3350.     mov    al,modeset        ; set/reset insert mode
  3351.     mov    insmod,al        ; store it
  3352.     ret
  3353. atrsmc:    cmp    al,12            ; 12? Control local echo
  3354.     jne    atrsmx            ; ne = no
  3355.     cmp    modeset,0        ; resetting mode (ESC [ 12 l)?
  3356.     jne    atrsmc1            ; ne = no
  3357.     or    yflags,lclecho        ; (l) turn on local echoing
  3358.     jmp    short atrsmc2
  3359. atrsmc1:and    yflags,not lclecho    ; (h) turn off local echoing
  3360. atrsmc2:test    yflags,modoff        ; is mode line off?
  3361.     jnz    atrsmx            ; nz = yes
  3362.     push    dx            ; save cursor position
  3363.     call    fmodlin            ; write mode line
  3364.     pop    dx
  3365. atrsmx:    ret
  3366.                     ; DEC specifics
  3367. atrsm1: cmp    al,1            ; cursor keys mode?
  3368.     jne    atrsm2            ; ne = no
  3369.     mov    ax,decckm        ; get the bit
  3370.     jmp    atrsflg            ; set or reset it and return
  3371.  
  3372. atrsm2: cmp    al,7            ; Auto-wrap?
  3373.     jne    atrsm3            ; ne = no
  3374.     and    vtemu.vtflgop,not vswrap ; assume resetting line wrap
  3375.     cmp    modeset,0        ; resetting?
  3376.     je    atrsm2a            ; e = yes
  3377.     or    vtemu.vtflgop,vswrap    ; set the bit
  3378. atrsm2a:mov    ax,decawm        ; get the bit
  3379.     jmp    atrsflg            ; set or reset it and return
  3380.  
  3381. atrsm3: cmp    al,6            ; Origin mode?
  3382.     jne    atrsm4            ; ne = no
  3383.     jmp    atrsom            ; change decom and return
  3384.  
  3385. atrsm4: cmp    al,5            ; change the video?
  3386.     jne    atrsm5            ; ne = no
  3387.     jmp    atrsscnm        ; yes, change it if necessary
  3388.  
  3389. atrsm5: cmp    al,2            ; Change VT52 compatibility mode?
  3390.     jne    atrsm6            ; ne = no
  3391.     test    dspstate,dsptype    ; on status line?
  3392.     jnz    atrsm5b            ; nz = yes, ignore switch
  3393.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  3394.     jne    atrsm5a            ; ne = no
  3395.     mov    modeset,0        ; Heath  ESC [ ? 2 h  resets ANSI mode
  3396. atrsm5a:mov    ax,decanm        ; get ansi mode flag
  3397.     call    atrsflg            ; set or reset it
  3398.     test    yflags,modoff        ; mode line supposed to be off?
  3399.     jnz    atrsm5b            ; nz = yes
  3400.     push    dx            ; save cursor position
  3401.     call    fmodlin            ; write mode line
  3402.     pop    dx
  3403. atrsm5b:ret
  3404.  
  3405. atrsm6:    cmp    al,3            ; 132/80 column mode change?
  3406.     jne    atrsm7            ; ne = no
  3407.     mov    al,curattr        ; save current video attributes
  3408.     mov    ah,extattr        ; and extended attributes
  3409.     push    ax
  3410.     xor    ah,ah            ; high byte: not exiting Connect mode
  3411.     and    vtemu.vtflgop,not deccol; assume mode is reset
  3412.     mov    al,modeset        ; pass set/reset request to chgdsp
  3413.     or    al,al
  3414.     jz    atrsm6a            ; z = set 80 columns
  3415.     or    vtemu.vtflgop,deccol    ; assume it will work (tell msy)
  3416. atrsm6a:call    chgdsp            ; call Change Display proc in msy
  3417.     and    vtemu.vtflgop,not deccol; assume mode is reset
  3418.     cmp    modeset,0        ; want 80 cols?
  3419.     je    atrsm6n            ; e = yes, else 132 cols
  3420.     cmp    byte ptr low_rgt,79
  3421.     jbe    atrsm6b
  3422.     or    vtemu.vtflgop,deccol    ; set the status bit
  3423.     mov    byte ptr low_rgt,132-1    ; screen capability
  3424.     jmp    short atrsm6e
  3425. atrsm6b:and    vtemu.vtflgst,not deccol; turn off setup 132 col bit too
  3426. atrsm6n:cmp    byte ptr low_rgt,79    ; want 80 cols, is it wider?
  3427.     jbe    atrsm6e            ; be = no
  3428.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  3429. atrsm6e:test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  3430.     jnz    atrsm6f            ; nz = yes, no reset for DG terminals
  3431.     CALL    ATRES2            ; do partial reset of emulator
  3432. atrsm6f:pop    ax
  3433.     mov    curattr,al        ; restore saved items
  3434.     mov    extattr,ah
  3435.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  3436.     jz    atrsm6g            ; z = no
  3437.     call    frepaint        ; repaint new screen
  3438.     ret                ; D463/D470 gets no other changes
  3439. atrsm6g:mov    dx,low_rgt        ; text lines (leave status line intact)
  3440.     mov    mar_top,0
  3441.     mov    mar_bot,dh        ; reset scrolling region
  3442.     mov    dl,byte ptr low_rgt    ; right margin
  3443.     mov    mar_right,dl
  3444.     mov    mar_left,0
  3445.     xor    dx,dx            ; new cursor position is 0,0
  3446.     mov    cursor,dx
  3447.     jmp    atsetcur        ; place it there and return
  3448.  
  3449. atrsm7:    cmp    al,18            ; 18?  18 & 19 = printer support
  3450.     jne    atrsm8            ; ne = no
  3451.     cmp    modeset,0        ; resetting?
  3452.     jne    atrsm7a            ; ne = no, setting
  3453.     and    anspflg,not vtffp    ; no form feed after printing
  3454.     ret
  3455. atrsm7a:or    anspflg,vtffp        ; use form feed after printing
  3456.     ret
  3457.  
  3458. atrsm8:    cmp    al,19            ; 19, print region?
  3459.     jne    atrsm9            ; ne = no
  3460.     cmp    modeset,0        ; resetting?
  3461.     jne    atrsm8a            ; ne = no, setting
  3462.     and    anspflg,not vtextp    ; reset print region to scrolling reg
  3463.     ret
  3464. atrsm8a:or    anspflg,vtextp        ; set print region to whole screen
  3465.     ret
  3466.  
  3467. atrsm9:    cmp    al,25            ; ESC [ ? 25 h/l? cursor on/off
  3468.     jne    atrsm10            ; ne = no
  3469.     mov    al,4            ; assume cursor to be turned off (4)
  3470.     cmp    modeset,0        ; resetting (invisible cursor)?
  3471.     je    atrsm9a            ; e = yes
  3472.     mov    al,1            ; assume underline (1)
  3473.     test    vtemu.vtflgop,vscursor    ; underline?
  3474.     jnz    atrsm9a            ; nz = yes
  3475.     inc    al            ; block (2)
  3476. atrsm9a:mov    atctype,al        ; save VTxxx cursor type here
  3477.     jmp    atsctyp            ; set the cursor type
  3478.  
  3479.                     ; DECRLM (alt VT320 right/left write)
  3480. atrsm10:cmp    al,34            ; ESC [ ? 34 h/l? Invoke special macro
  3481.     jne    atrsm10b        ; ne = no
  3482.     and    vtemu.vtflgop,not vswdir; writing direction to normal
  3483.     and    vtemu.vtflgst,not vswdir; writing direction to normal
  3484.     cmp    modeset,0        ; resetting?
  3485.     jne    atrsm10a        ; ne = no, setting
  3486.     mov    decrlm,0        ; writing direction to left to right
  3487.     ret
  3488. atrsm10a:mov    decrlm,1        ; writing direction to right to left
  3489.     ret
  3490.                     ; DECHEBM (alt VT320 keyboard map)
  3491. atrsm10b:cmp    al,35            ; ESC [ ? 35 h/l? Invoke special macro
  3492.     jne    atrsm10d        ; ne = no
  3493.     cmp    modeset,0        ; resetting?
  3494.     jne    atrsm10c        ; ne = no, setting
  3495.     call    fvtkrmac        ; perform on-line macro
  3496.     ret
  3497.                     ;  code is located in file msy
  3498. atrsm10c:call    fvtksmac        ; do set macro
  3499.     ret
  3500.  
  3501. atrsm10d:cmp    al,36            ; DECHEM Hebrew encoding mode?
  3502.     jne    atrsm11            ; ne = no
  3503.     cmp    modeset,0        ; resetting?
  3504.     jne    atrsm10e        ; ne = no
  3505.     mov    al,13            ; Hebrew NRC
  3506.     mov    ah,al            ; GR = GL = 13
  3507.     or    vtemu.vtflgop,vsnrcm    ; set NRC active bit
  3508.     or    vtemu.vtflgst,vsnrcm
  3509.     and    vtemu.vtflgop,not vscntl ; no 8-bit controls
  3510.     jmp    short atrsm10f
  3511. atrsm10e:mov    al,17            ; DEC Multinational set (17)
  3512.     xor    ah,ah            ; GLeft is ASCII (0)
  3513.     and    vtemu.vtflgop,not vsnrcm ; clear NRC active bit
  3514.     and    vtemu.vtflgst,not vsnrcm
  3515. atrsm10f:mov    vtemu.vtchset,al
  3516.     mov    bx,offset emubuf    ; temp table of char set idents
  3517.     xchg    ah,al            ; order correctly
  3518.     mov    [bx],ax            ; char sets for G0..G3
  3519.     mov    [bx+2],ax
  3520.     call    chrsetup        ; invoke NRC
  3521.     ret
  3522.  
  3523. atrsm11:cmp    al,38            ; 38? Enter Tek sub-mode. VT340 seq
  3524.     jne    atrsm12            ; ne = no
  3525.     cmp    modeset,1        ; setting mode (ESC [ ? 38 h)?
  3526.     jne    atrsm12            ; ne = no, ignore sequence
  3527.     test    denyflg,tekxflg        ; is auto Tek mode disabled?
  3528.     jnz    atrsm12            ; nz = yes, just ignore command
  3529.     call    atsc            ; save cursor and associated data
  3530.     xor    al,al            ; enter with this received character
  3531.     call    TEKEMU            ; go to Tektronix Emulator, al=null
  3532.     jmp    atnorm
  3533.  
  3534. atrsm12:cmp    al,42            ; 42, use NRC 7-bit command?
  3535.     jne    atrsm15            ; ne = no
  3536.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
  3537.     jz    atrsm14            ; z = no
  3538.     cmp    vtemu.vtchset,0        ; ASCII?
  3539.     je    atrsm14            ; e = yes, no NRC
  3540.     cmp    vtemu.vtchset,13    ; highest NRC ident?
  3541.     ja    atrsm14            ; a = not NRC
  3542.     cmp    modeset,0        ; resetting?
  3543.     je    atrsm13            ; e = yes
  3544.     or    vtemu.vtflgop,vsnrcm    ; set NRC flag bit
  3545.     jmp    chrdef            ; and set NRC characters
  3546. atrsm13:mov    ax,vtemu.vtflgop    ; run time flags
  3547.     and    vtemu.vtflgop,not vsnrcm ; turn off NRC flag bit
  3548.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  3549.     jmp    chrdef
  3550. atrsm14:ret
  3551. atrsm15:cmp    al,66            ; 66, keypad to applications mode?
  3552.     jne    atrsm16            ; ne = no
  3553.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
  3554.     jz    atrsm16            ; z = no
  3555.     mov    ax,deckpam        ; bit to control
  3556.     jmp    atrsflg            ; control the flag and return
  3557. atrsm16:ret
  3558.  
  3559. ; VT340  CSI number $ |   number is 0 or 80 for 80 cols, 132 for 132 columns
  3560. ; DECSCPP, set columns per page
  3561. atscpp:    cmp    inter,'$'        ; correct intermediate letter?
  3562.     jne    atscpp2            ; ne = no, ignore
  3563.     cmp    ninter,1        ; one intermediate?
  3564.     jne    atscpp2            ; ne = no, ignore
  3565.     mov    modeset,1        ; assume 132 columns wanted
  3566.     cmp    param,80        ; 80 or 132 columns?
  3567.     ja    atscpp1            ; a = 132 columns
  3568.     mov    modeset,0        ; set to 80 columns
  3569. atscpp1:mov    al,3            ; set up CSI ? 3 h/l command
  3570.     jmp    atrsm6            ; process that command
  3571. atscpp2:ret
  3572.  
  3573.         ; Heath-19  ESC [ > Ps h or l where Ps = 1, 4, 7, or 9
  3574. htrsm1:    cmp    al,1            ; 25th line?
  3575.     jne    htrsm4            ; ne = no
  3576.     and    h19stat,not h19l25    ; clear 25th line bit
  3577.     cmp    modeset,0        ; clearing?
  3578.     je    htrsm1a            ; e = yes
  3579.     or    h19stat,h19l25        ; set bit
  3580.     jmp    htrsmx            ; we are done
  3581. htrsm1a:mov    ah,byte ptr low_rgt+1    ; point to status (25th) line
  3582.     inc    ah            ;  which is here
  3583.     xor    al,al            ; from column 0
  3584.     mov    bh,ah            ; to same line
  3585.     mov    bl,byte ptr low_rgt    ; physical width
  3586.     call    vtsclr            ; disabling status line clears it
  3587.     ret
  3588.  
  3589. htrsm4:    cmp    al,4            ; 4, block/line cursor?
  3590.     jne    htrsm5            ; ne = no
  3591.     and    h19ctyp,4        ; save on/off bit (4)
  3592.     cmp    modeset,0        ; reset?
  3593.     je    htrsm4a            ; e = yes
  3594.     or    h19ctyp,2        ; remember block kind here
  3595.     jmp    atsctyp
  3596. htrsm4a:or    h19ctyp,1        ; remember underline kind here
  3597.     jmp    atsctyp
  3598.      
  3599. htrsm5: cmp     al,5                    ; 5, on/off cursor?
  3600.         jne     htrsm7                  ; ne = no
  3601.         cmp     modeset,0               ; on?
  3602.         je      htrsm5a                 ; e = yes
  3603.     or    h19ctyp,4        ; remember off state in this bit
  3604.         jmp     atsctyp
  3605. htrsm5a:and    h19ctyp,not 4        ; set cursor on
  3606.         jmp     atsctyp
  3607.  
  3608. htrsm7:    cmp    al,7            ; 7, alternate application keypad?
  3609.     jne    htrsm8            ; ne = no
  3610.     mov    ax,deckpam        ; get keypad application mode bit
  3611.     jmp    atrsflg            ; set or reset appl keypad mode
  3612.  
  3613. htrsm8:    cmp    al,8            ; 8, received CR => CR/LF?
  3614.     jne    htrsm9
  3615.     and    h19stat,not h19alf    ; clear autoline feed bit
  3616.     cmp    modeset,0        ; resetting?
  3617.     je    htrsmx            ; yes
  3618.     or    h19stat,h19alf        ; turn on the mode
  3619.     ret
  3620.  
  3621. htrsm9:    cmp    al,9            ; 9, auto newline mode? (add cr to lf)
  3622.     jne    htrsmx            ; ne = no
  3623.     mov    ax,anslnm        ; get the bit
  3624.     jmp    atrsflg            ; set or reset newline mode
  3625. htrsmx:    ret                ; ignore the code
  3626.  
  3627. atrsflg:cmp    modeset,0        ; reset?
  3628.     je    atrsf1            ; e = yes, reset it
  3629.     or    vtemu.vtflgop,ax    ; set, OR in the flag
  3630.     test    ax,decanm        ; changing ansi mode?
  3631.     jz    atrsfx            ; z = no
  3632.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  3633.     je    atrsfx            ; e = yes, don't flip terminal kinds
  3634.     mov    ax,oldterm        ; terminal type at startup
  3635.     mov    flags.vtflg,ax        ; restore it
  3636.     ret
  3637. atrsf1: not    ax            ; reset bit, complement
  3638.     and    vtemu.vtflgop,ax    ; clear the bit
  3639.     not    ax            ; recover the bit
  3640.     test    ax,decanm        ; changing ansi mode?
  3641.     jz    atrsfx            ; z = no
  3642.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  3643.     je    atrsfx            ; e = yes, don't flip terminal kinds
  3644.     mov    flags.vtflg,ttvt52    ; say VT52 now
  3645. atrsfx:    ret
  3646.                     ; Set/Clear Origin mode
  3647. atrsom:    test    dspstate,dsptype    ; on status line?
  3648.     jz    atrsom1            ; z = no
  3649.     ret                ; else ignore this command
  3650. atrsom1:cmp    modeset,0        ; clearing DEC origin mode?
  3651.     jne    atrsom2            ; ne = no, setting
  3652.     and    vtemu.vtflgop,not decom ; reset Origin mode
  3653.     xor    dx,dx            ; go to the home position
  3654.     jmp    atsetcur        ; set cursor and return
  3655. atrsom2:or    vtemu.vtflgop,decom    ; set Origin mode
  3656.     mov    dx,cursor        ; get the cursor
  3657.     xor    dl,dl            ; go to right margin
  3658.     mov    dh,mar_top        ; go to home of scrolling region
  3659.     jmp    atsetcur        ; set the cursor and return
  3660.  
  3661. atrsscnm:cmp    modeset,0        ; resetting?
  3662.     je    atrss1            ; e = yes, reset
  3663.     test    vtemu.vtflgop,vsscreen    ; setting, set already?
  3664.     jnz    atrss3            ; nz = yes, don't do it again
  3665.     or    vtemu.vtflgop,vsscreen    ; set and tell Status display
  3666.     jmp    short atrss2        ; do it
  3667.  
  3668. atrss1: test    vtemu.vtflgop,vsscreen    ; resetting, reset already?
  3669.     jz    atrss3            ; z = yes, don't do it again
  3670.     and    vtemu.vtflgop,not vsscreen ; clear and tell Status
  3671.                     ; fall through to atrss2
  3672.  
  3673. ; Note: This is also called from the stblmds initialization routine.
  3674. ; Reverse video the entire screen, update scbattr and curattr to match.
  3675. atrss2:    push    ax
  3676.     mov    ah,scbattr        ; current screen attributes
  3677.     call    revideo            ; reverse them
  3678.     mov    scbattr,ah        ; set screen background attribute
  3679.     mov    ah,curattr        ; get current cursor attribute
  3680.     call    revideo            ; reverse it
  3681.     mov    curattr,ah        ; store it
  3682.     call    revscn            ; reverse everything on the screen
  3683.     pop    ax
  3684. atrss3:    ret
  3685.  
  3686.                     ; Self tests DECTST
  3687. atctst:    cmp    inter,0            ; any intermediate char?
  3688.     jne    atcts3            ; ne = yes, not a selftest command
  3689.     cmp    param,2            ; VT102 selftest?
  3690.     je    atcts1            ; e = yes
  3691.     cmp    param,4            ; VT320 selftest?
  3692.     jne    atcts6            ; ne = no
  3693. atcts1:    test    dspstate,dsptype    ; cursor is on status line?
  3694.     jz    atcts2            ; z = no
  3695.     push    param            ; save first parameter
  3696.     mov    ah,inter        ;  and first intermediate char
  3697.     push    ax
  3698.     mov    param,0            ; select main display
  3699.     mov    inter,'$'        ; setup proper intermediate
  3700.     call    atssdt            ; select status line of off
  3701.     call    atsasd            ; select main display
  3702.     pop    ax
  3703.     pop    param            ; restore parameter
  3704.     mov    inter,ah        ;  and intermediate char
  3705. atcts2:    xor    al,al            ; init test weight
  3706.     mov    di,offset atcts4    ; routine to call
  3707.     call    atreps            ; repeat for all parms
  3708.     test    al,80H            ; reset?
  3709.     jz    atcts3            ; z = no, return
  3710.     jmp    atreset            ; reset everything
  3711. atcts3: ret
  3712.  
  3713. atcts4:    or    si,si            ; initial arg?
  3714.     jz    atcts5            ; z = yes, skip it (examined above)
  3715.     cmp    param[si],1        ; power up test (0, 1) included?
  3716.     ja    atcts5            ; a = no, ignore printer/comms/repeats
  3717.     or    al,80H            ; say we want reset
  3718. atcts5: ret
  3719.  
  3720. atcts6:    cmp    nparam,0        ; absence of parameters?
  3721.      jne    atcts5            ; ne = no, ignore sequence
  3722.     jmp    athoney            ; try Honeywell ESC [ y  ident response
  3723.  
  3724. atalign    proc    near            ; Align screen, fill screen with 'E's
  3725.     mov    al,'E'            ; char to use as filler
  3726.     test    dspstate,dsptype    ; is cursor on status line?
  3727.     jz    atalig1            ; z = no
  3728.     ret                ; yes, ignore the command
  3729. atalig1:cmp    flags.modflg,0        ; is mode line off?
  3730.     je    atalig2            ; e = yes
  3731.     and    yflags,not modoff    ; say it's on
  3732.     mov    flags.modflg,1        ;  and owned by us
  3733. atalig2:push    ax            ; save displayed char
  3734.     push    vtemu.vtflgst        ; save setup flags
  3735.     mov    ax,vtemu.vtflgop    ; operational flags
  3736.     and    ax,deccol        ; get 80/132 column indicator
  3737.     and    vtemu.vtflgst,not deccol ; clear for set below
  3738.     or    vtemu.vtflgst,ax    ; set it so reset preserves it
  3739.     call    atreset            ; clear system
  3740.     pop    vtemu.vtflgst        ; recover setup flags
  3741.     or    vtemu.vtflgop,decawm    ; set wrap
  3742.     mov    cl,byte ptr low_rgt    ; number of columns-1
  3743.     inc    cl
  3744.     mov    al,byte ptr low_rgt+1    ; number of rows-1
  3745.     inc    al
  3746.     mul    cl            ; ax = number of chars on screen
  3747.     mov    cx,ax
  3748.     pop    ax            ; recover displayed char in AL
  3749.     mov    emubuf,al        ; keep it here while looping
  3750. atalig3:push    cx
  3751.     mov    al,emubuf        ; write screen full of this char
  3752.     call    atnrm            ; write the 'E' or whatever
  3753.     pop    cx
  3754.     loop    atalig3            ; cx times
  3755.     ret
  3756. atalign    endp
  3757.  
  3758.  
  3759. ; Reports
  3760. atreqt: cmp    param,1            ; want report?
  3761.     jbe    atreq1            ; be = yes
  3762. atreq0:    ret                ; Gee, must have been an echo
  3763.  
  3764. atreq1:    test    flags.vtflg,ttvt102+ttvt100+tthoney ; VT102 etc?
  3765.     jz    atreq0            ; z = no, ignore
  3766.     mov    ttyact,0        ; group output for networks
  3767.     mov    al,CSI
  3768.     call    prtbout            ; send CSI or ESC [
  3769.     mov    al,'3'            ; we report only upon request
  3770.     cmp    param,0            ; was argument a zero?
  3771.     jne    atreq1b            ; ne = no
  3772.     mov    al,'2'            ; yes
  3773. atreq1b:call    prtbout
  3774.     mov    al,';'            ; separate
  3775.     call    prtbout
  3776.     mov    bl,parcode        ; get the parity code
  3777.     xor    bh,bh
  3778.     mov    al,partab[bx]        ; get VT100 parity code
  3779.     push    ax            ; save parity code
  3780.     call    prtnout            ; send number to the port
  3781.     mov    al,';'            ; separate
  3782.     call    prtbout
  3783.     mov    al,'2'            ; assume 7 data bits
  3784.     pop    bx            ; get parity code into bl
  3785.     cmp    bl,1            ; is parity none?
  3786.     jne    atreq2            ; ne = no, so 7 data bits
  3787.     test    flags.remflg,d8bit    ; 8 bit display?
  3788.     jz    atreq2            ; z = no
  3789.     mov    al,'1'            ; must be eight
  3790. atreq2: call    prtbout            ; send it to the port
  3791.     mov    al,';'
  3792.     call    prtbout
  3793.     mov    bl,baudidx        ; baud rate index
  3794.     xor    bh,bh
  3795.     mov    al,baudtab[bx]        ; get DEC baud rate code
  3796.     push    ax
  3797.     call    prtnout            ; sending speed index
  3798.     mov    al,';'
  3799.     call    prtbout
  3800.     pop    ax
  3801.     cmp    bl,lbaudtab-1        ; using the split speed entry?
  3802.     jne    atreq2a            ; ne = no
  3803.     mov    al,[bx+1]        ; get trailing receive speed (75 baud)
  3804. atreq2a:call    prtnout            ; receiving speed index
  3805.     mov    al,';'
  3806.     call    prtbout
  3807.     mov    al,'1'            ; clock rate multiplier is always 1
  3808.     call    prtbout
  3809.     mov    al,';'
  3810.     call    prtbout
  3811.     mov    al,'0'            ; Flags are always zero (no STP)
  3812.     call    prtbout
  3813.     mov    ttyact,1        ; end group output for networks
  3814.     mov    al,'x'
  3815.     call    prtbout
  3816.     ret
  3817.  
  3818.                     ; Single Controls
  3819. ; Note DEC manual incorrectly says DECSCL's do a hard rather than soft reset
  3820. decscl:    cmp    inter,'!'        ; "CSI ! p" soft reset?
  3821.     jne    decsc0            ; ne = no
  3822.     jmp    atsres            ; do a soft reset
  3823.  
  3824. decsc0:    cmp    inter,'"'        ; "CSI Psc; Ps1 " p"  operating level?
  3825.     je    decsc1            ; e = yes
  3826.     cmp    inter,'$'        ; "CSI Pn $ p"  DECRQM?
  3827.     jne    decsc0a            ; ne = no, ignore others
  3828.     jmp    decsc5            ; do isolated controls report
  3829. decsc0a:ret                ; else ignore
  3830. decsc1:    cmp    param,61        ; Psc, select VT100?
  3831.     jne    decsc2            ; ne = no
  3832.     mov    flags.vtflg,ttvt102    ; set VT102
  3833.     mov    oldterm,ttvt102        ; and remember it
  3834.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  3835.     mov    al,anspflg        ; preserve screen print flag
  3836.     push    ax
  3837.     call    atsres            ; do soft reset of emulator
  3838.     pop    ax
  3839.     mov    anspflg,al
  3840.     ret
  3841. decsc2:    cmp    param,62        ; go to VT2xx level?
  3842.     jne    decsc3            ; ne = no
  3843.     test    flags.vtflg,ttvt320+ttvt102 ; at VT300/VT102 level now?
  3844.     jnz    decsc3a            ; nz = yes, don't change types
  3845.     mov    flags.vtflg,ttvt220    ; set VT220 mode
  3846.     mov    oldterm,ttvt220
  3847.     jmp    short decsc3b        ; finish up
  3848.     
  3849. decsc3:    cmp    param,63        ; go to VT300 level?
  3850.     jne    decsc4            ; ne = no
  3851. decsc3a:mov    flags.vtflg,ttvt320    ; set VT320 mode
  3852.     mov    oldterm,ttvt320
  3853. decsc3b:cmp    param[2],2        ; Ps1, range here is 0, 1, 2
  3854.     ja    decsc4            ; a = out of range, ignore
  3855.     mov    al,anspflg        ; preserve screen print flag
  3856.     push    ax
  3857.     call    atsres            ; do soft reset of emulator
  3858.     pop    ax
  3859.     mov    anspflg,al
  3860.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  3861.     cmp    param[2],1        ; select 7-bit controls?
  3862.     je    decsc4            ; e = yes, we have done so
  3863.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  3864. decsc4:    ret
  3865.                            ; single controls report request
  3866. decsc5:    cmp    lparam,'?'        ; want DEC Private modes?
  3867.     jne    decsc5a            ; ne = no
  3868.     call    decscpre        ; do standard prefix
  3869.     mov    al,'2'            ; assume mode is reset
  3870.     call    decsc20            ; do DEC Private mode report
  3871.     jmp    decscend        ; do end of sequence
  3872. decsc5a:cmp    inter,0            ; intermediate char?
  3873.     je    decsc5b            ; e = no, ignore
  3874.     call    decscpre        ; do standard prefix
  3875.     mov    al,'2'            ; assume mode is reset
  3876.     call    decsc5c            ; do ANSI report
  3877.     jmp    decscend        ; do end of sequence
  3878. decsc5b:ret                ; else return failure
  3879.                     
  3880. decsc5c:mov    cx,param        ; ANSI report:
  3881.     cmp    cx,2            ; 2, Keyboard action?
  3882.     jne    decsc6            ; ne = no
  3883.     ret
  3884. decsc6:    cmp    cx,3            ; control representation?
  3885.     jne    decsc7            ; ne = no
  3886.     ret                ; say reset(acting on controls)
  3887. decsc7:    cmp    cx,4            ; 4, Insert/Replace mode?
  3888.     jne    decsc8            ; ne = no
  3889.     cmp    insmod,0        ; insert mode off?
  3890.     je    decsc7a            ; e = yes, off
  3891.     dec    al            ; say is on
  3892. decsc7a:ret
  3893. decsc8:    cmp    cx,10            ; 10, Horizontal editing?
  3894.     jne    decsc9            ; ne = no
  3895.     mov    al,'4'            ; permanently reset
  3896.     ret
  3897. decsc9:    cmp    cx,12            ; 12, Send/Receive (local echo)?
  3898.     jne    decsc11            ; ne = no
  3899.     test    yflags,lclecho        ; echoing on?
  3900.     jz    decsc12            ; z = no
  3901.     dec    al            ; say set
  3902.     ret
  3903. decsc11:cmp    cx,20            ; 20, new line mode?
  3904.     jne    decsc13            ; ne = no
  3905.     test    vtemu.vtflgop,anslnm    ; new line set?
  3906.     jz    decsc12            ; z = no, reset
  3907.     dec    al            ; say set
  3908. decsc12:ret
  3909. decsc13:mov    al,'0'            ; say not recognized
  3910.     ret
  3911.  
  3912.                            ; DEC Private mode report
  3913. decsc20:mov    cx,param
  3914.     cmp    cx,1            ; 1, cursor keys?
  3915.     jne    decsc22            ; ne = no
  3916.     test    vtemu.vtflgop,decckm    ; set?
  3917.     jz    decsc31            ; z = no, reset
  3918.     dec    al
  3919.     ret
  3920. decsc22:cmp    cx,2            ; 2, ANSI mode
  3921.     jne    decsc24            ; ne = no
  3922.     test    vtemu.vtflgop,decanm    ; set?
  3923.     jz    decsc31            ; z = no, reset
  3924.     dec    al
  3925.     ret
  3926. decsc24:cmp    cx,3            ; 3, column
  3927.     jne    decsc26            ; ne = no
  3928.     test    vtemu.vtflgop,deccol    ; 132 column mode set?
  3929.     jz    decsc31            ; z = no, reset (80 columns)
  3930.     dec    al
  3931.     ret
  3932. decsc26:cmp    cx,4            ; 4, scrolling mode
  3933.     je    decsc31            ; e = yes always say reset (jump)
  3934.                     ;
  3935.     cmp    cx,5            ; 5, screen
  3936.     jne    decsc28            ; ne = no
  3937.     test    vtemu.vtflgop,decscnm    ; set (light background)?
  3938.     jz    decsc31            ; z = no, reset
  3939.     dec    al
  3940.     ret
  3941. decsc28:cmp    cx,6            ; 6, Origin mode?
  3942.     jne    decsc30            ; ne = no
  3943.     test    dspstate,dsptype    ; on status line?
  3944.     jz    decsc29            ; z = no, main display
  3945.     test    dspstate,dspdecom    ; main display Origin mode set?
  3946.     jz    decsc31            ; z = no, reset
  3947.     dec    al
  3948.     ret
  3949. decsc29:test    vtemu.vtflgop,decom    ; Origin mode set?
  3950.     jz    decsc31            ; z = no, reset
  3951.     dec    al
  3952.     ret
  3953. decsc30:cmp    cx,7            ; 7, autowrap?
  3954.     jne    decsc32            ; ne = no
  3955.     test    vtemu.vtflgop,decawm    ; set?
  3956.     jz    decsc31            ; z = no, reset
  3957.     dec    al
  3958. decsc31:ret                ; common return point
  3959. decsc32:cmp    cx,8            ; 8, autorepeat?
  3960.     jne    decsc34            ; ne = no
  3961.     dec    al
  3962.     ret                ; say set
  3963. decsc34:cmp    cx,18            ; 18, print Form Feed?
  3964.     jne    decsc36            ; ne = no
  3965.     test    anspflg,vtffp        ; set?
  3966.     jz    decsc31            ; z = no, reset
  3967.     dec    al
  3968.     ret
  3969. decsc36:cmp    cx,19            ; 19, printer extent?
  3970.     jne    decsc38            ; ne = no
  3971.     test    anspflg,vtextp        ; set?
  3972.     jz    decsc31            ; z = no, reset
  3973.     dec    al
  3974.     ret
  3975. decsc38:cmp    cx,25            ; 25, text cursor enabled?
  3976.     jne    decsc40            ; ne = no
  3977.     test    atctype,4        ; 4 is off
  3978.     jnz    decsc31            ; nz = off/disabled
  3979.     dec    al            ; say enabled
  3980.     ret
  3981. decsc40:cmp    cx,42            ; 42, NRC's
  3982.     jne    decsc42            ; ne = no
  3983.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  3984.     jz    decsc31            ; z = no
  3985.     test    vtemu.vtflgop,vsnrcm    ; NRC's active?
  3986.     jz    decsc31            ; z = no
  3987.     dec    al            ; say enabled
  3988.     ret
  3989. decsc42:cmp    cx,66            ; 66, numeric keypad?
  3990.     jne    decsc44            ; ne = no
  3991.     test    vtemu.vtflgop,deckpam    ; set?
  3992.     jz    decsc31            ; z = no, reset
  3993.     dec    al            ; say set
  3994.     ret
  3995. decsc44:cmp    cx,68            ; 68, keyboard usage?
  3996.     jne    decsc45            ; ne = no
  3997.     mov    al,'4'            ; say always typewriter mode
  3998.     ret
  3999. decsc45:mov    al,'0'            ; say unknown kind
  4000.     ret
  4001.  
  4002. decscpre:mov    ttyact,0        ; group output for networks
  4003.     mov    al,CSI            ; do standard report beginning
  4004.     call    prtbout
  4005.     mov    al,byte ptr param    ; get parameter
  4006.     call    prtnout            ; send the number
  4007.     mov    al,';'
  4008.     call    prtbout
  4009.     ret
  4010.  
  4011. decscend:call    prtbout            ; do standard rpt end, send char in al
  4012.     mov    al,'$'
  4013.     call    prtbout
  4014.     mov    ttyact,1        ; end group output for networks
  4015.     mov    al,'y'
  4016.     call    prtbout
  4017.     ret
  4018.  
  4019. ; DEC style Soft Reset
  4020. ; Note: graphics rendition is NOT changed by soft reset, DEC manual is wrong.
  4021. atsres    proc    near            ; do soft reset of terminal
  4022.     test    dspstate,dsptype    ; on status line?
  4023.     jz    atsres1            ; z = no, on main display
  4024.     mov    param,0
  4025.     mov    inter,'$'        ; setup entry for atsasd
  4026.     call    atsasd            ; select main display
  4027. atsres1:and    vtemu.vtflgop,not(decawm+decckm+deckpam+decom) ; these go off
  4028.     mov    insmod,0        ; insert mode off
  4029.     mov    mar_top,0        ; reset scrolling margins
  4030.     mov    al,byte ptr low_rgt+1
  4031.     mov    mar_bot,al        ; to full screen
  4032.     mov    anspflg,0        ; clear printer flag
  4033.     mov    al,1            ; restore cursor, assume underline (1)
  4034.     test    vtemu.vtflgop,vscursor    ; underline?
  4035.     jnz    atsres2            ; nz = yes
  4036.     inc    al            ; block (2)
  4037. atsres2:mov    atctype,al        ; save VTxxx cursor type here
  4038.     call    atsctyp            ; set the cursor type
  4039.     push    cursor
  4040.     mov    cursor,0        ; set save cursor to Home
  4041.     call    atsc            ; save attributes
  4042.     pop    cursor            ; restore active cursor
  4043.     call    chrdef            ; set default character set
  4044.     call    fmodlin            ; rewrite mode line
  4045.     ret
  4046. atsres    endp
  4047.                     ; DECRQSS/DECRPSS Control Settings
  4048.  
  4049.                     ; Handle DCS ... q string ST
  4050. atcrq:    cmp    ninter,1        ; one intermediate?
  4051.     je    atcrq1            ; e = yes
  4052.     ja    atcrq0            ; a = too many
  4053.     jmp    atcrqq            ; none, do Sixel DCS params q...ST
  4054. atcrq0:    mov    ninter,0        ; set up atdcsnul for proper form
  4055.     mov    ttstate,offset atdcsnul    ; not understood, consume til ST
  4056.     ret
  4057.  
  4058. atcrq1:    cmp    inter,'$'        ; correct intermediate?
  4059.     jne    atcrq0            ; ne = no
  4060.     cmp    nparam,0        ; and no parameters?
  4061.     jne    atcrq0            ; ne = have some, not ours
  4062.     mov    ttstateST,offset atcrq4    ; set state for ST arrival
  4063.     mov    ttstate,offset atcrq2    ; next state gets string contents
  4064.     mov    emubufc,0        ; clear buffer counter
  4065.     mov    word ptr emubuf,0    ; empty start of buffer
  4066.     ret
  4067. atcrq2:    mov    bx,emubufc        ; count of chars in string buffer
  4068.     cmp    bx,emubufl        ; too many?
  4069.     jae    atcrq3            ; ae = too many, ignore extras
  4070.     mov    emubuf[bx],al        ; store the char
  4071.     inc    emubufc            ; count it
  4072. atcrq3:    ret
  4073.                     ; here after ST has been seen
  4074. atcrq4:    cmp    emubufc,2        ; max string chars we want
  4075.     jbe    atcrq4a            ; be = ok
  4076.     jmp    atnorm            ; a = too many, ignore
  4077. atcrq4a:mov    ax,word ptr emubuf    ; get first two chars
  4078.     cmp    ax,'}$'            ; select active display?
  4079.     jne    atcrq5            ; ne = no
  4080.     jmp    atcrqd            ; do the routine
  4081. atcrq5:    cmp    ax,'p"'            ; set conformance level?
  4082.     jne    atcrq7            ; ne = no
  4083.     jmp    atcrqp
  4084. atcrq7:    cmp    ax,'~$'            ; set status line type
  4085.     jne    atcrq8
  4086.     jmp    atcrqt
  4087. atcrq8:    cmp    ax,'r'            ; set top and bottom margins?
  4088.     jne    atcrq9
  4089.     jmp    atcrqr
  4090. atcrq9:    cmp    ax,'m'            ; set graphic rendition?
  4091.     jne    atcrq10
  4092.     jmp    atcrqm
  4093. atcrq10:jmp    atcrqxx            ; unknown command
  4094.                     ; DCS $ q  response routines
  4095. atcrqr:    call    atcrqbeg        ; 'r', top/bottom margins
  4096.     test    dspstate,dsptype    ; doing status line display?
  4097.     jz    atcrqr2            ; z = no
  4098.     mov    al,byte ptr dspmsave    ; get saved top margin
  4099.     inc    al
  4100.     call    prtnout
  4101.     mov    al,';'
  4102.     call    prtbout
  4103.     mov    al,byte ptr dspmsave+1    ; get saved bottom margin
  4104.     jmp    short atcrqr3        ; finish up
  4105. atcrqr2:mov    al,mar_top        ; top margin
  4106.     inc    al            ; move to 1,1 system
  4107.     call    prtnout
  4108.     mov    al,';'
  4109.     call    prtbout
  4110.     mov    al,mar_bot
  4111. atcrqr3:inc    al            ; move to 1,1 system
  4112.     call    prtnout
  4113.     mov    al,'r'            ; final char
  4114.     jmp    atcrqend        ; do epilogue
  4115.  
  4116. atcrqm:    call    atcrqbeg        ; 'm', graphics rendition
  4117.     mov    al,'0'            ; say start with all attributes off
  4118.     call    prtbout
  4119.     call    getbold            ; returns ah with bold attr or 0
  4120.     or    ah,ah            ; bold set?
  4121.     jz    atcrqm2            ; z = no
  4122.     mov    al,';'
  4123.     call    prtbout
  4124.     mov    al,'1'            ; say bold is on
  4125.     call    prtbout
  4126. atcrqm2:call    getunder        ; underline
  4127.     or    cl,cl            ; underline on?
  4128.     jz    atcrqm3            ; z = no, do next
  4129.     mov    al,';'
  4130.     call    prtbout
  4131.     mov    al,'4'            ; say underlining is on
  4132.     call    prtbout
  4133. atcrqm3:mov    ah,scbattr
  4134.     call    getblink        ; blinking
  4135.     or    ah,ah            ; blinking on?
  4136.     jz    atcrqm4            ; z = no
  4137.     mov    al,';'
  4138.     call    prtbout
  4139.     mov    al,'5'            ; say blinking is on
  4140.     call    prtbout
  4141. atcrqm4:test    extattr,att_rev        ; chars in reversed video?
  4142.     jz    atcrqm5            ; z = no
  4143.     mov    al,';'
  4144.     call    prtbout
  4145.     mov    al,'7'            ; say underlining is on
  4146.     call    prtbout
  4147. atcrqm5:mov    al,'m'            ; final char
  4148.     jmp    atcrqend        ; do epilogue
  4149.  
  4150. atcrqd:    call    atcrqbeg        ; '$}', writing to screen/status line
  4151.     mov    al,'0'            ; assume writing to main display
  4152.     test    dspstate,dsptype    ; get type of display
  4153.     jz    atcrqd2            ; z = main display
  4154.     inc    al            ; say writing to mode line
  4155. atcrqd2:call    prtbout
  4156.     mov    al,'$'            ; final chars
  4157.     call    prtbout
  4158.     mov    al,7dh            ; right curly brace
  4159.     jmp    atcrqend        ; do epilogue
  4160.  
  4161. atcrqt:    call    atcrqbeg        ; '$~', status line
  4162.     mov    al,'0'            ; assume mode line is off
  4163.     test    yflags,modoff        ; is mode line off?
  4164.     jnz    atcrqt2            ; nz = yes
  4165.     mov    al,'2'            ; mode line is on and host writable
  4166. atcrqt2:call    prtbout
  4167.     mov    al,'c'            ; final chars
  4168.     call    prtbout
  4169.     mov    al,7eh            ; tilde
  4170.     jmp    atcrqend        ; do epilogue
  4171.                     ; '"p' set conformance level
  4172. atcrqp:    cmp    oldterm,ttvt100        ; main-mode terminal is VT100?
  4173.     je    atcrqp2            ; e = yes
  4174.     cmp    oldterm,tthoney        ; Honeywell?
  4175.     je    atcrqp2            ; e = yes
  4176.     cmp    oldterm,ttvt102        ; VT102?
  4177.     je    atcrqp2            ; e = yes
  4178.     cmp    oldterm,ttvt320        ; how about VT320?
  4179.     je    atcrqp2            ; e = yes
  4180.     jmp    atcrqxx            ; say invalid request
  4181. atcrqp2:mov    ttyact,0        ; group output for networks
  4182.     mov    al,DCS            ; '"p', conformance level
  4183.     call    prtbout
  4184.     mov    al,'0'            ; valid request
  4185.     call    prtbout
  4186.     mov    al,'$'
  4187.     call    prtbout
  4188.     mov    al,61            ; assume VT102
  4189.     cmp    oldterm,ttvt100        ; VT100?
  4190.     je    atcrqp2a        ; e = yes
  4191.     cmp    oldterm,tthoney        ; Honeywell
  4192.     je    atcrqp2a        ; e = yes
  4193.     cmp    oldterm,ttvt102        ; are we a VT102?
  4194.     jne    atcrqp3            ; ne = no
  4195. atcrqp2a:call    prtnout
  4196.     jmp    short atcrqp5        ; finish the report
  4197.  
  4198. atcrqp3:mov    al,63            ; say VT320
  4199.     call    prtnout
  4200.     mov    al,';'
  4201.     call    prtbout
  4202.     mov    al,'2'            ; assume 8-bit controls are on
  4203.     test    vtemu.vtflgop,vscntl    ; 8-bit controls active?
  4204.     jnz    atcrqp4            ; nz = yes
  4205.     mov    al,'1'            ; else say only 7-bit controls
  4206. atcrqp4:call    prtbout
  4207. atcrqp5:mov    al,'"'            ; final characters
  4208.     call    prtbout
  4209.     mov    al,'p'
  4210.     jmp    atcrqend        ; do epilogue
  4211.  
  4212. atcrqbeg:mov    ttyact,0        ; group output for networks
  4213.     mov    al,DCS            ; report prologue
  4214.     call    prtbout
  4215.     mov    al,'0'            ; valid request
  4216.     call    prtbout
  4217.     mov    al,'$'
  4218.     jmp    prtbout
  4219.  
  4220. atcrqend:call    prtbout            ; report epilogue, al has char
  4221.     mov    ttyact,1        ; end group output for networks
  4222.     mov    al,STCHR        ; string terminator
  4223.     jmp    prtbout
  4224.  
  4225. atcrqxx:mov    ttyact,0        ; group output for networks
  4226.     mov    al,DCS            ; report invalid request
  4227.     call    prtbout
  4228.     mov    al,'1'            ; invalid request
  4229.     call    prtbout
  4230.     mov    al,'$'
  4231.     cmp    emubufc,1        ; any first char?
  4232.     jb    atcrqend        ; b = no
  4233.     call    prtbout
  4234.     mov    al,emubuf        ; first string char
  4235.     cmp    emubufc,2        ; two string chars?
  4236.     jne    atcrqend        ; ne = no
  4237.     call    prtbout
  4238.     mov    al,emubuf+1        ; second string char
  4239.     jmp    atcrqend        ; do epilogue
  4240.  
  4241.                     ; DCS P1; P2; P3 <char> Sixel command
  4242. atcrqq:    cmp    dcsstrf,'q'        ; final char of 'q'? Sixel draw
  4243.     je    atcrqq1            ; e = yes
  4244.     cmp    dcsstrf,'p'        ; 'p', restore palette?
  4245.     jne    atcrqq0            ; ne = no
  4246.     cmp    dinter,'$'        ; DCS 2 $ p?
  4247.     jne    atcrqq0            ; ne = no
  4248.     cmp    param,2            ; this too?
  4249.     jne    atcrqq1            ; ne = no
  4250.     call    tekinq            ; get Tek screen state
  4251.     jmp    tekrcol            ; restore palette
  4252.  
  4253. atcrqq0:mov    ninter,0        ; setup atdcsnul for proper form
  4254.     jmp    atdcsnul        ; consume unknown command
  4255. atcrqq1:test    denyflg,tekxflg        ; is auto Tek mode disabled?
  4256.     jnz    atcrqq0            ; nz = yes, consume
  4257.     mov    di,offset emubuf    ; temp buffer
  4258.     mov    byte ptr [di],escape    ; do ESC ^L to erase screen
  4259.     inc    di
  4260.     mov    byte ptr [di],FF
  4261.     inc    di
  4262.     mov    byte ptr [di],escape    ; start DCS
  4263.     inc    di
  4264.     mov    byte ptr [di],'P'
  4265.     inc    di
  4266.     mov    ax,dparam[0]        ; get first parameter
  4267.     call    fdec2di
  4268.     mov    byte ptr [di],';'
  4269.     inc    di
  4270.     mov    ax,dparam[2]        ; get second parameter
  4271.     call    fdec2di            ; write ascii value
  4272.     mov    byte ptr [di],';'
  4273.     inc    di
  4274.     mov    ax,dparam[4]        ; get third parameter
  4275.     call    fdec2di            ; write ascii value
  4276.     mov    al,dcsstrf
  4277.     mov    byte ptr [di],al    ; final char
  4278.     mov    byte ptr [di+1],0    ; terminator
  4279.     mov    di,offset emubuf
  4280.     mov    al,yflags        ; get yflags
  4281.     and    al,capt            ; save logging bit
  4282.     push    ax
  4283.     and    yflags,not capt        ; turn off logging bit
  4284. atcrqq2:mov    al,[di]
  4285.     inc    di
  4286.     or    al,al            ; at the end?
  4287.     jz    atcrqq3            ; z = yes
  4288.     push    di
  4289.     call    tekemu            ; feed Tek emulator this string
  4290.     pop    di
  4291.     jmp    short atcrqq2        ; do another string member
  4292. atcrqq3:mov    chcontrol,1        ; turn on full cell char writing
  4293.     pop    ax            ; recover logging bit
  4294.     or    yflags,al        ; restate logging bit
  4295.     jmp    atnorm
  4296.  
  4297. ; State machine to process DCS strings of type "p" (restore color palette)
  4298. ; Enter with "p" char in AL.
  4299. tekrcol    proc    near
  4300.     mov    ttstate,offset tekrco1    ; next state is get parameter
  4301.     mov    ttstateST,offset tekrcost ; go here on ST
  4302.     push    es
  4303.     push    ds
  4304.     pop    es
  4305.     mov    cx,5            ; five words
  4306.     xor    ax,ax
  4307.     mov    di,offset param        ; clear parameters Pc,Pu,Px,Py,Pz
  4308.     cld
  4309.     rep    stosw
  4310.     pop    es
  4311.     mov    nparam,0        ; work on initial parameter first
  4312.     ret
  4313. tekrco1:push    bx
  4314.     mov    bx,nparam        ; parameter number
  4315.     shl    bx,1            ; make it a word index
  4316.     mov    cx,param[bx]        ; accumulated parameter
  4317.     call    getdec            ; accumulate decimal value
  4318.     mov    param[bx],cx        ; remember accumulation
  4319.     pop    bx
  4320.     jnc    tekrcos1        ; nc = got a digit char
  4321.     inc    nparam            ; say have another complete parameter
  4322.     cmp    al,'/'            ; this kind of separator?
  4323.     je    tekrco3            ; e = yes, finish
  4324.     cmp    al,';'            ; break char is separator?
  4325.     jne    tekrco4            ; ne = no, decode current sequence
  4326. tekrco3:cmp    nparam,5        ; have 5 params already?
  4327.     jb    tekrcos1        ; n = no, continue reading
  4328. tekrco4:call    tekrpal            ; process parameters in msgibm file
  4329.     jmp    tekrcol            ; start over on next field
  4330.  
  4331. tekrcost:mov    ttstate,offset atnrm    ; get here on ST
  4332.     mov    ttstateST,offset atnorm ; default ST completion state
  4333.     cmp    nparam,5        ; enough parameters to finish cmd?
  4334.     jb    tekrcos1        ; b = no, abandon it
  4335.     call    tekrpal            ; update from last data item
  4336. tekrcos1:ret
  4337. tekrcol    endp
  4338.  
  4339. ; Accumulate decimal value in CX using ascii char in al.
  4340. ; Return with value in CX. Return carry clear if ended on a digit,
  4341. ; return carry set and ascii char in al if ended on a non-digit.
  4342. getdec    proc    near
  4343.     cmp    al,'0'            ; a number?
  4344.     jb    getdecx            ; b = no, quit
  4345.     cmp    al,'9'
  4346.     ja    getdecx            ; a = not a number, quit
  4347.     sub    al,'0'            ; remove ascii bias
  4348.     xchg    cx,ax            ; put char in cx, decimal value in ax
  4349.     push    dx            ; save reg
  4350.     push    bx
  4351.     mov    bx,10
  4352.     mul    bx            ; times ten for a new digit
  4353.     pop    bx
  4354.     pop    dx            ; recover reg, ignore overflow
  4355.     add    al,cl            ; add current digit
  4356.     adc    ah,0            ; 16 bits worth
  4357.     xchg    ax,cx            ; rpt cnt back to cx
  4358.     clc                ; say found a digit
  4359.     ret
  4360. getdecx:stc                ; say non-digit (in al)
  4361.     ret
  4362. getdec    endp
  4363.                     ; Device Status Reports
  4364. atdsr:    mov    di,offset atdsr1    ; routine to call
  4365.     call    atreps            ; do for all parms
  4366.     ret
  4367.                     ; DSR workers
  4368. atdsr1:    mov    ax,param[si]
  4369.     cmp    lparam,0        ; any intermediate?
  4370.     jne    atdsr2            ; ne = yes, an intermediate
  4371.     cmp    ax,5            ; operating status report?
  4372.     je    rpstat            ; e = yes
  4373.     cmp    ax,6            ; cursor position report?
  4374.     je    rpcup            ; e = yes
  4375.     ret
  4376. atdsr2:    cmp    lparam,'?'        ; DEC mode queries for below?
  4377.     jne    atdsr3            ; no, skip them
  4378.     cmp    ax,6            ; VT340 cursor report?
  4379.     je    rpcup            ; e = yes
  4380.     cmp    ax,15            ; printer status report?
  4381.     je    rpstap            ; e = yes
  4382.     cmp    ax,25            ; UDK status?
  4383.     jne    atdsr3            ; ne = no
  4384.     jmp    rpudk            ; do udk status rpt
  4385. atdsr3:    cmp    ax,26            ; keyboard type?
  4386.     jne    atdsr4            ; ne = no
  4387.     jmp    rpkbd            ; do keyboard type report
  4388. atdsr4:    cmp    ax,256            ; WordPerfect Tek screen query?
  4389.     jne    atdsr5            ; ne = no
  4390.     jmp    tekrpt            ; do Tek report
  4391. atdsr5:    ret                ; must have been an echo
  4392.  
  4393. rpstat:    mov    ttyact,0        ; group output for networks
  4394.     mov    al,CSI            ; operating status query
  4395.     call    prtbout
  4396.     mov    al,'0'            ; tell them we think we are OK
  4397.     call    prtbout
  4398.     mov    ttyact,1        ; end group output for networks
  4399.     mov    al,'n'
  4400.     call    prtbout
  4401.     ret
  4402.  
  4403. rpcup:    mov    ttyact,0        ; group output for networks
  4404.     mov    al,CSI            ; cursor position report
  4405.     call    prtbout
  4406.     mov    al,byte ptr cursor+1    ; get row
  4407.     inc    al            ; map to origin at 1,1 system
  4408.     test    vtemu.vtflgop,decom    ; Origin mode set?
  4409.     jz    rpcup1            ; z = no
  4410.     sub    al,mar_top        ; subtract off top margin
  4411. rpcup1: call    prtnout            ; output the number
  4412.     mov    al,';'
  4413.     call    prtbout
  4414.     mov    al,byte ptr cursor    ; column number
  4415.     inc    al            ; map to origin at 1,1 system
  4416.     call    prtnout
  4417.     mov    ttyact,1        ; end group output for networks
  4418.     mov    al,'R'            ; final char
  4419.     call    prtbout
  4420.     ret
  4421.  
  4422. rpstap:    mov    ttyact,0        ; group output for networks
  4423.     mov    al,CSI            ; printer port query
  4424.     call    prtbout            ; send CSI or ESC [ ? 10 or 13 n 
  4425.     mov    al,'?'            ;  10 = printer ready, 13 = not ready
  4426.     call    prtbout
  4427.     mov    al,'1'
  4428.     call    prtbout
  4429.     mov    ah,ioctl        ; get printer status, via DOS
  4430.     mov    al,7            ; status for output
  4431.     push    bx
  4432.     mov    bx,4            ; std handle for system printer
  4433.     int    dos
  4434.     pop    bx
  4435.     jc    rpstap1            ; c = call failed
  4436.     cmp    al,0ffh            ; code for Ready
  4437.     jne    rpstap1            ; ne = not ready
  4438.     mov    al,'0'            ; ready, send final digit
  4439.     jmp    short rpstap2
  4440. rpstap1:mov    al,'3'            ; not ready, say printer disconnected
  4441. rpstap2:call    prtbout
  4442.     mov    ttyact,1        ; end group output for networks
  4443.     mov    al,'n'            ; final char of response
  4444.     call    prtbout
  4445.     ret
  4446.  
  4447. rpudk:    mov    ttyact,0        ; group output for networks
  4448.     mov    al,CSI            ; response to UDK locked query
  4449.     call    prtbout
  4450.     mov    al,'?'
  4451.     call    prtbout
  4452.     mov    al,20            ; say keys are unlocked (locked=21)
  4453.     call    prtnout
  4454.     mov    ttyact,1        ; end group output for networks
  4455.     mov    al,'n'            ; final char
  4456.     call    prtbout
  4457.     ret
  4458.  
  4459. rpkbd:    mov    ttyact,0        ; group output for networks
  4460.     mov    al,CSI            ; response to kbd type query
  4461.     call    prtbout
  4462.     mov    al,'?'
  4463.     call    prtbout
  4464.     mov    al,27            ; keyboard dialect follows
  4465.     call    prtnout
  4466.     mov    al,';'
  4467.     call    prtbout
  4468.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  4469.     xor    bh,bh
  4470.     mov    al,nrckbd[bx]        ; get DEC keyboard code from table
  4471.     call    prtnout
  4472.     mov    ttyact,1        ; end group output for networks
  4473.     mov    al,'n'
  4474.     call    prtbout
  4475.     ret
  4476.  
  4477. tekrpt:    call    tekinq            ; get Tek screen size and num colors
  4478.     push    cx            ; screen colors
  4479.     push    bx            ; screen width
  4480.     push    ax            ; screen height
  4481.     mov    ttyact,0        ; group output for networks
  4482.     mov    al,CSI            ; response to Tek query
  4483.     call    prtbout
  4484.     mov    al,'?'
  4485.     call    prtbout
  4486.     mov    di,offset emubuf    ; working buffer
  4487.     mov    byte ptr [di],0        ; insert terminator
  4488.     mov    ax,256            ; first parameter
  4489.     call    fdec2di            ; write ascii digits
  4490.     mov    byte ptr [di],';'    ; separator
  4491.     inc    di
  4492.     pop    ax            ; get screen height
  4493.     call    fdec2di
  4494.     mov    byte ptr [di],';'    ; separator
  4495.     inc    di
  4496.     pop    ax            ; get screen width
  4497.     call    fdec2di
  4498.     mov    byte ptr [di],';'    ; separator
  4499.     inc    di
  4500.     pop    ax            ; get number screen color (0, 1 or 16)
  4501.     call    fdec2di
  4502.     mov    byte ptr[di],'n'    ; end of sequence
  4503.     inc    di
  4504.     mov    cx,di            ; compute string length
  4505.     mov    di,offset emubuf
  4506.     sub    cx,di
  4507. tekrpt1:mov    al,[di]            ; get a string char
  4508.     inc    di
  4509.     cmp    cx,1            ; last char?
  4510.     ja    tekrpt2            ; a = no
  4511.     mov    ttyact,1        ; end group output for networks
  4512. tekrpt2:call    prtbout            ; send it
  4513.     loop    tekrpt1
  4514.     ret
  4515.  
  4516. atrqtsr:cmp    flags.vtflg,ttheath    ; Heath-19? ESC [ u
  4517.     jne    atrqts1            ; ne = no
  4518.     cmp    nparam,0        ; ought to have no parameters
  4519.     jne    atrqts2            ; ne = oops, not H-19 command, ignore
  4520.     jmp    atrc            ; H19, restore cursor pos and attrib
  4521.     
  4522. atrqts1:cmp    inter,'$'        ; VT320 Terminal State Rpt DECRQTSR?
  4523.     jne    atrqts2            ; ne = no
  4524.     cmp    param,1            ; report required?
  4525.     je    atrqts4            ; e = yes
  4526.     cmp    param,2            ; VT340 color palette report?
  4527.     jne    atrqts1a        ; ne = no
  4528.     call    tekinq            ; get Tek screen state
  4529.     call    tekpal            ; do palette report in Tek emulator
  4530. atrqts1a:ret
  4531. atrqts2:cmp    inter,'&'        ; DECRQUPSS, User preferred Supp Set?
  4532.     je    atrqts5            ; e = yes
  4533.     ret                ; else ignore
  4534. atrqts4:mov    al,DCS            ; Terminal state report
  4535.     call    prtbout            ; output as 7- or 8-bit quantity
  4536.     mov    al,byte ptr param
  4537.     call    prtnout            ; output as ascii digits, no echo
  4538.     mov    al,'$'
  4539.     call    prtbout            ; output char, no echo
  4540.     mov    al,'s'            ; Final char to main DCS part
  4541.     call    prtbout
  4542.     mov    al,STCHR        ; terminator to empty string
  4543.     call    prtbout
  4544.     ret
  4545.  
  4546. atrqts5:mov    al,DCS            ; User Preferred Supplemental Set
  4547.     call    prtbout            ;  report
  4548.     mov    al,'0'            ; assume 94 byte set
  4549.     cmp    upss,94            ; 94 byte set?
  4550.     je    atrqts6            ; e = yes
  4551.     inc    al            ; change to 96 byte size
  4552. atrqts6:call    prtbout
  4553.     mov    al,'!'
  4554.     call    prtbout
  4555.     mov    al,'u'
  4556.     call    prtbout
  4557.     mov    al,upss+1        ; first ident char
  4558.     call    prtbout
  4559.     mov    al,upss+2        ; second char, if any
  4560.     or    al,al
  4561.     jz    atrqts7            ; z = no second char
  4562.     call    prtbout
  4563. atrqts7:mov    al,STCHR
  4564.     call    prtbout
  4565.     ret
  4566.                     ; Request Presentation State Report
  4567. atrqpsr:cmp    inter,'$'        ; proper form?
  4568.     jne    atrqps1            ; ne = no, ignore
  4569.     cmp    param,1            ; cursor report?
  4570.     je    atrqps2            ; e = yes
  4571.     cmp    param,2            ; tabstop report?
  4572.     jne    atrqps1            ; ne = no, ignore
  4573.     jmp    atrqps40        ; do tabstop report
  4574. atrqps1:ret                ; else ignore
  4575.  
  4576. atrqps2:mov    al,DCS            ; cursor report, start
  4577.     call    prtbout
  4578.     mov    al,'1'
  4579.     call    prtbout
  4580.     mov    al,'$'
  4581.     call    prtbout
  4582.     mov    al,'u'
  4583.     call    prtbout
  4584.     mov    al,dh            ; row of cursor
  4585.     inc    al            ; count from 1,1
  4586.     call    prtnout            ; output number
  4587.     mov    al,';'
  4588.     call    prtbout
  4589.     mov    al,dl            ; column of cursor
  4590.     inc    al            ; count from 1,1
  4591.     call    prtnout            ; output number
  4592.     mov    al,';'
  4593.     call    prtbout
  4594.     mov    al,'1'            ; video page, always 1 for VT320
  4595.     call    prtbout
  4596.     mov    al,';'
  4597.     call    prtbout
  4598.     mov    al,40h            ; start bit field template
  4599.     test    extattr,att_rev        ; reverse video char writing on?
  4600.     jz    atrqps3            ; z = no
  4601.     or    al,8            ; set the bit
  4602. atrqps3:call    getblink        ; ah will be non-zero if blinking
  4603.     or    ah,ah            ; blinking?
  4604.     jz    atrqps4            ; z = no
  4605.     or    al,4            ; set the bit
  4606. atrqps4:call    getunder        ; ah will be non-zero if underlining
  4607.     or    cl,cl            ; underlining?
  4608.     jz    atrqps5            ; z = no
  4609.     or    al,2            ; set the bit
  4610. atrqps5:call    getbold            ; ax will be non-zero if bolding
  4611.     or    ah,ah            ; bold?
  4612.     jz    atrqps6            ; z = no
  4613.     or    al,1            ; set the bit
  4614. atrqps6:call    prtbout
  4615.     mov    al,';'
  4616.     call    prtbout
  4617.     mov    al,40h            ; Satt (Selective params)
  4618.     test    extattr,att_protect    ; is char protected?
  4619.     jz    atrqps6a        ; z = no
  4620.     or    al,1            ; say char is protected
  4621. atrqps6a:call    prtbout            ; output required skeleton
  4622.     mov    al,';'
  4623.     call    prtbout
  4624.     mov    al,40h            ; Sflag (shift/wrap/origin mode)
  4625.     cmp    atwrap,0        ; wrap pending?
  4626.     je    atrqps7            ; e = no
  4627.     or    al,8            ; set the bit
  4628. atrqps7:cmp    SSptr,offset G3set    ; SS3: G3 mapped to GL for next char?
  4629.     jne    atrqps8            ; ne = no
  4630.     or    al,4            ; set the bit
  4631. atrqps8:cmp    SSptr,offset G2set    ; SS2: G2 mapped to GL for next char?
  4632.     jne    atrqps9            ; ne = no
  4633.     or    al,2            ; set the bit
  4634. atrqps9:test    vtemu.vtflgop,decom    ; Origin mode set?
  4635.     jz    atrqps10        ; z = no
  4636.     or    al,1            ; set the bit
  4637. atrqps10:call    prtbout
  4638.     mov    al,';'
  4639.     call    prtbout
  4640.     mov    al,'0'            ; Pgl, say which set is in GL
  4641.     mov    si,GLptr        ; setup for worker
  4642.     call    atrqps30        ; worker returns proper al
  4643.     call    prtbout
  4644.     mov    al,';'
  4645.     call    prtbout
  4646.     mov    al,'0'            ; Pgr, say which set is in GR
  4647.     mov    si,GRptr        ; setup for worker
  4648.     call    atrqps30        ; worker returns proper al
  4649.     call    prtbout
  4650.     mov    al,';'
  4651.     call    prtbout
  4652.     mov    al,40h            ; Scss, char set size bit field
  4653.     call    atrqp15            ; call worker to fill in al
  4654.     call    prtbout    
  4655.     mov    al,';'
  4656.     call    prtbout
  4657.     mov    bx,offset G0set        ; Sdesig, get 1-2 letter ident
  4658.     call    atrqps20        ; G0, let worker fill in response
  4659.     mov    bx,offset G1set
  4660.     call    atrqps20        ; G1, let worker fill in response
  4661.     mov    bx,offset G2set
  4662.     call    atrqps20        ; G2, let worker fill in response
  4663.     mov    bx,offset G3set
  4664.     call    atrqps20        ; G3, let worker fill in response
  4665.     mov    al,STCHR        ; String terminator
  4666.     call    prtbout
  4667.     ret
  4668.  
  4669. ; worker for Character set size reporting
  4670. atrqp15:cmp    G0set+gsize,96        ; is G0 a 96 byte set?
  4671.     jne    atrqp16            ; ne = no
  4672.     or    al,1            ; say 96
  4673. atrqp16:cmp    G1set+gsize,96        ; is G1 a 96 byte set?
  4674.     jne    atrqp17            ; ne = no
  4675.     or    al,2            ; say 96
  4676. atrqp17:cmp    G2set+gsize,96        ; G2 set?
  4677.     jne    atrqp18
  4678.     or    al,4            ; say 96
  4679. atrqp18:cmp    G3set+gsize,96        ; G3 set?
  4680.     jne    atrqp19
  4681.     or    al,8            ; say 96
  4682. atrqp19:ret                ; return with al setup
  4683.  
  4684. ; worker for Character set ident reporting at atrqps16: et seq
  4685. atrqps20:mov    al,[bx+gsize+1]        ; Gn set pointer, first letter
  4686.     call    prtbout
  4687.     mov    al,[bx+gsize+2]        ; second letter
  4688.     or    al,al            ; is there one?
  4689.     jz    atrqps21        ; z = no, nothing there
  4690.     call    prtbout
  4691. atrqps21:ret
  4692.  
  4693. ; worker. Enter with SI holding GLptr or GRptr and al = '0'
  4694. ; Returns al = '0' .. '3' to match set pointed at
  4695. atrqps30:cmp    si,offset G0set        ; si points at G0?
  4696.     je    atrqps31        ; e = yes
  4697.     inc    al            ; try next set
  4698.     cmp    si,offset G1set        ; si points at G1?
  4699.     je    atrqps31
  4700.     inc    al
  4701.     cmp    si,offset G2set        ; si points at G2?
  4702.     je    atrqps31
  4703.     inc    al            ; must be G3
  4704. atrqps31:ret
  4705.  
  4706. atrqps40:mov    al,DCS            ; start tabstop report
  4707.     call    prtbout
  4708.     mov    al,'2'            ; tabs
  4709.     call    prtbout
  4710.     mov    al,'$'
  4711.     call    prtbout
  4712.     mov    al,'u'
  4713.     call    prtbout
  4714.     mov    cl,mar_right        ; right most column number
  4715.     inc    cl            ; number of columns
  4716.     xor    ch,ch
  4717.     push    dx            ; save dx
  4718.     xor    dx,dx            ; dh for done one output, dl = column
  4719.     mov    si,offset tabs        ; active tabs buffer
  4720. atrqps41:call    istabs            ; tab inquiry routine, column is in dl
  4721.     jnc    atrqps43        ; nc = no tab
  4722.     or    dh,dh            ; sent one value already?
  4723.     je    atrqps42        ; e = no, so no separator
  4724.     mov    al,';'            ; separator (DEC used '/')
  4725.     call    prtbout
  4726. atrqps42:mov    al,dl            ; get column
  4727.     inc    al            ; count columns from 1 for host
  4728.     call    prtnout            ; output the number
  4729.     inc    dh            ; say sent a number
  4730. atrqps43:inc    dl            ; next column, say sent one output
  4731.     loop    atrqps41        ; do the rest
  4732.     pop    dx            ; recover dx
  4733.     mov    al,STCHR        ; string terminator
  4734.     call    prtbout
  4735.     ret
  4736.     
  4737. ; Process Restore Presentation Reports, for cursor and tab stops
  4738. ; Uses bytes dinter+5 and dinter+6 as internal variables
  4739. atrp:    cmp    dinter,0+'$'        ; correct intermediate?
  4740.     je    atrp1            ; e = yes
  4741.     jmp    atcrqxx            ; send back "illegal restore" response
  4742. atrp1:    cmp    dparam,1        ; cursor info?
  4743.     je    atrp4            ; e = yes
  4744.     mov    modeset,1        ; say setting tabs
  4745.     call    atrpw            ; call worker to do ascii to binary
  4746.     dec    dl            ; count internally from col 0
  4747.     call    tabset            ; set tab in column dl
  4748. atrp3:    mov    emubufc,0        ; clear the string count
  4749.     ret
  4750.                       ; start cursor info report playback
  4751. atrp4:    cmp    dinter+5,0        ; our internal counter in vacant byte
  4752.     jne    atrp5            ; not initial byte
  4753.     inc    dinter+5        ; point to next item next time
  4754.     call    atrpw            ; ascii to binary worker
  4755.     xchg    dh,dl            ; get row to correct byte
  4756.     mov    dl,byte ptr cursor+1    ; get column
  4757.     jmp    atsetcur        ; set the cursor
  4758. atrp5:    cmp    dinter+5,1        ; column?
  4759.     jne    atrp6
  4760.     inc    dinter+5        ; point to next item next time
  4761.     call    atrpw            ; ascii to binary worker
  4762.     mov    dh,byte ptr cursor    ; get row
  4763.     jmp    atsetcur        ; set the cursor
  4764. atrp6:    cmp    dinter+5,2        ; page?
  4765.     jne    atrp7
  4766.     inc    dinter+5        ; omit page byte
  4767.     ret
  4768. atrp7:    cmp    dinter+5,3
  4769.     jne    atrp8
  4770.     inc    dinter+5        ; Srend
  4771.     mov    al,emubuf        ; string byte
  4772.     mov    ah,curattr        ; attributes field
  4773.                     ; ought to clear attributes first
  4774.     test    al,1            ; set bold?
  4775.     jz    atrp7a            ; z = no
  4776.     call    setbold
  4777. atrp7a:    test    al,2            ; set underline?
  4778.     jz    atrp7b            ; z = no
  4779.     call    setunder
  4780. atrp7b:    test    al,4            ; set blink?
  4781.     jz    atrp7c            ; z = no
  4782.     call    setblink
  4783. atrp7c:    mov    curattr,ah        ; attributes so far
  4784.     test    al,8            ; set per char rev video?
  4785.     jz    atrp7d            ; z = no
  4786.     call    setrev            ; set reversed video
  4787.     mov    curattr,ah        ; gather main attributes
  4788. atrp7d:    ret
  4789. atrp8:    cmp    dinter+5,4
  4790.     jne    atrp9
  4791.     inc    dinter+5        ; Satt, skip it
  4792.     ret
  4793. atrp9:    cmp    dinter+5,5
  4794.     jne    atrp10
  4795.     inc    dinter+5
  4796.     mov    al,emubuf        ; string byte
  4797.     mov    ah,al
  4798.     and    ah,8            ; autowrap bit
  4799.     mov    atwrap,ah        ; set it
  4800.     mov    SSptr,0            ; say no single shift needed
  4801.     test    al,4            ; SS3 bit?
  4802.     jz    atrp9a            ; z = no
  4803.     mov    SSptr,offset G3set    ; set the pointer
  4804. atrp9a:    test    al,2            ; SS2 bit?
  4805.     jz    atrp9b            ; z = no
  4806.     mov    SSptr,offset G2set    ; set the pointer
  4807. atrp9b:    and    vtemu.vtflgop,not decom ; clear origin bit
  4808.     test    al,1            ; origin mode?
  4809.     jz    atrp9c            ; z = no
  4810.     or    vtemu.vtflgop,decom    ; set origin mode
  4811. atrp9c:    ret
  4812. atrp10:    cmp    dinter+5,6        ; Pgl
  4813.     jne    atrp11
  4814.     inc    dinter+5
  4815.     mov    al,emubuf        ; string byte
  4816.     call    atrpw5            ; call worker to setup bx with ptr
  4817.     mov    GLptr,bx
  4818.     ret
  4819. atrp11:    cmp    dinter+5,7        ; Pgr
  4820.     jne    atrp12
  4821.     inc    dinter+5
  4822.     mov    al,emubuf        ; string byte
  4823.     call    atrpw5            ; call worker to setup bx with ptr
  4824.     mov    GRptr,bx
  4825.     ret
  4826. atrp12:    cmp    dinter+5,8        ; Scss
  4827.     jne    atrp13            ; ne = no
  4828.     inc    dinter+5
  4829.     mov    al,emubuf        ; string byte
  4830.     and    al,0fh            ; strip ascii bias
  4831.     mov    dinter+6,al        ; save here for Sdesig byte, next
  4832.     ret
  4833. atrp13:    cmp    dinter+5,9        ; Sdesig
  4834.     jne    atrp14
  4835.     inc    dinter+5
  4836.     mov    si,offset emubuf    ; string
  4837.     xor    cx,cx            ; init loop counter to 0
  4838. atrp13a:mov    al,'('            ; assume G0 is 94 byte set
  4839.     add    al,cl            ; plus loop index to get set pointer
  4840.     shr    dinter+6,1        ; get set size bit
  4841.     jnc    atrp13b            ; e = correct
  4842.     add    al,4            ; map to 96 byte indicator
  4843. atrp13b:mov    inter,al        ; store size byte as intermediate
  4844.     mov    ninter,1        ; one char
  4845.     cld
  4846. atrp13c:lodsb                ; next string byte
  4847.     test    al,not 2fh        ; is there a second intermediate byte?
  4848.     jnz    atrp13d            ; nz = no
  4849.     mov    inter+1,al        ; store intermediate
  4850.     inc    ninter            ; count them
  4851.     jmp    short atrp13c        ; try again for a Final char
  4852. atrp13d:push    si
  4853.     push    cx
  4854.     mov    bx,offset ansesc    ; table to use
  4855.     call    atdispat        ; dispatch on final char to set ptr
  4856.     pop    cx
  4857.     pop    si
  4858.     inc    cx
  4859.     cmp    cx,3            ; doing last one?
  4860.     jbe    atrp13a            ; be = no, do all four
  4861.     ret
  4862. atrp14:    jmp    atcrqxx            ; send back "illegal restore" response
  4863.  
  4864.                     ; worker, ascii string to decimal byte
  4865. atrpw:    mov    cx,emubufc        ; length of this string
  4866.     jcxz    atrpw3            ; nothing there
  4867.     mov    si,offset emubuf    ; address of string
  4868.     xor    dl,dl            ; init final value
  4869.     cld
  4870. atrpw2:    lodsb                ; read a digit
  4871.     sub    al,'0'            ; ascii to numeric
  4872.     jc    atrpw3            ; c = trouble
  4873.     shl    dl,1            ; previous contents times 10
  4874.     mov    dh,dl
  4875.     shl    dl,1
  4876.     shl    dl,1
  4877.     add    dl,dh
  4878.     add    dl,al            ; plus new value
  4879.     loop    atrpw2            ; do all digits
  4880. atrpw3:    ret
  4881.                        ; char set selector worker
  4882. atrpw5:    cmp    al,'0'            ; bx gets G0set...G3set, based on AL
  4883.     jne    atrpw5a
  4884.     mov    bx,offset G0set
  4885.     ret
  4886. atrpw5a:cmp    al,'1'
  4887.     jne    atrpw5b
  4888.     mov    bx,offset G1set
  4889.     ret
  4890. atrpw5b:cmp    al,'2'
  4891.     jne    atrpw5c
  4892.     mov    bx,offset G2set
  4893.     ret
  4894. atrpw5c:mov    bx,offset G3set
  4895.     ret
  4896.  
  4897. ; Select Active Display. When selecting the status line make new scrolling
  4898. ; margins be just the status line and force on Origin mode. Save the regular
  4899. ; margins and origin mode for restoration when regular display is re-selected.
  4900. ; Also CSI Pn; Pn; Pn; Pn ~ invokes Lotus macro PRODUCT
  4901. atsasd    proc    near
  4902.     cmp    inter,'$'        ; correct intermediate?
  4903.     jne    atsasd1            ; ne = no
  4904.     cmp    param,1            ; select which display
  4905.     jb    atsasd4            ; b = select main display
  4906.     ja    atsasd1            ; a = illegal value
  4907.     cmp    flags.modflg,2        ; mode line host owned?
  4908.     jne    atsasd1            ; ne = no, ignore command
  4909.     test    dspstate,dsptype    ; was previous display = status line?
  4910.     jz    atsasd2            ; z = no
  4911. atsasd1:ret                ; else do nothing
  4912.  
  4913. atsasd2:push    word ptr mar_top    ; save scrolling margins
  4914.     pop    dspmsave        ; save scrolling margins
  4915.     or    dspstate,dsptype    ; say status line is active
  4916.     mov    al,byte ptr low_rgt+1    ; get last text line
  4917.     inc    al            ; status line
  4918.     mov    mar_top,al
  4919.     mov    mar_bot,al        ; new scrolling margins
  4920.     and    dspstate,not dspdecom    ; clear remembered origin mode
  4921.     test    vtemu.vtflgop,decom    ; was origin mode active?
  4922.     jz    atsasd3            ; z = no
  4923.     or    dspstate,dspdecom    ; remember origin mode was active
  4924. atsasd3:or    vtemu.vtflgop,decom    ; set origin mode
  4925.     push    cursor            ; get current main display cursor
  4926.     pop    dspcmain        ; save it
  4927.     mov    dx,dspcstat        ; get status line cursor
  4928.     mov    dh,mar_top        ; set row
  4929.     jmp    atsetcur        ; set cursor
  4930.  
  4931. atsasd4:test    dspstate,dsptype    ; was previous display = status line?
  4932.     jnz    atsasd5            ; nz = yes
  4933.     ret                ; else do nothing    
  4934. atsasd5:push    dspmsave        ; restore scrolling margins
  4935.     pop    word ptr mar_top
  4936.     and    vtemu.vtflgop,not decom    ; clear origin mode bit
  4937.     test    dspstate,dspdecom    ; was origin mode on for main screen?
  4938.     jz    atsasd6            ; z = no
  4939.     or    vtemu.vtflgop,decom    ; set it now
  4940. atsasd6:push    cursor            ; get status line cursor position
  4941.     pop    dspcstat        ; save it
  4942.     mov    dx,dspcmain        ; get saved cursor position
  4943.     mov    dspstate,0        ; say now doing main screen
  4944.     jmp    atsetcur        ; set cursor
  4945. atsasd    endp
  4946.  
  4947. atssdt    proc    near            ; Select Status Line Type, DECSSDT
  4948.     cmp    inter,'$'        ; correct intermediate char?
  4949.     je    atssdt1            ; e = yes
  4950.     cmp    ninter,0        ; no intermediates?
  4951.     jne    atssdt0            ; ne = no
  4952.     call    fproduct        ; do PRODUCT macro
  4953. atssdt0:ret
  4954. atssdt1:test    dspstate,dsptype    ; on mode line already?
  4955.     jnz    atssdt4            ; nz = yes, cannot reselect now
  4956.     cmp    param,0            ; turn off status line?
  4957.     jne    atssdt2            ; ne = no
  4958.     push    dx            ; save cursor position
  4959.     call    fclrmod            ; clear the line
  4960.     pop    dx
  4961.     or    yflags,modoff        ; now say it's off
  4962.     mov    flags.modflg,1        ; say mode line is owned by us
  4963.     ret
  4964. atssdt2:cmp    param,1            ; regular status line?
  4965.     jne    atssdt3
  4966.     push    dx
  4967.     call    fmodlin            ; turn on regular mode line
  4968.     pop    dx
  4969.     and    yflags,not modoff    ; and say it's on
  4970.     mov    flags.modflg,1        ; say mode line is owned by us
  4971.     ret
  4972. atssdt3:cmp    param,2            ; host writable?
  4973.     jne    atssdt4            ; ne = no
  4974.     mov    flags.modflg,2        ; say mode line is owned by host
  4975. atssdt4:ret
  4976. atssdt    endp
  4977.  
  4978. ; VT52 compatibility mode routines.
  4979.  
  4980. ; Return to ANSI mode.
  4981.  
  4982. v52ans: or    vtemu.vtflgop,decanm    ; turn on ANSI flag
  4983.     mov    ax,oldterm        ; terminal type at startup
  4984.     cmp    ax,ttvt52        ; was VT52 the prev kind?
  4985.     jne    v52ans1            ; ne = no
  4986.     mov    ax,ttvt320        ; use VT320
  4987. v52ans1:mov    oldterm,ax
  4988.     mov    flags.vtflg,ax        ; restore it
  4989.     call    chrdef            ; set default char sets
  4990.     call    atsc            ; save cursor status
  4991.     test    yflags,modoff        ; mode line supposed to be off?
  4992.     jnz    v52ans2            ; nz = yes
  4993.     call    fmodlin            ; rewrite mode line
  4994. v52ans2:ret
  4995.     
  4996. ; VT52 cursor positioning.
  4997.  
  4998. v52pos: mov    ttstate,offset v52pc1    ; next state
  4999.     ret
  5000. v52pc1: sub    al,' '-1        ; minus offset
  5001.     xor    ah,ah
  5002.     mov    param,ax        ; stash it here
  5003.     mov    ttstate,offset v52pc2    ; next state
  5004.     ret
  5005. v52pc2: sub    al,' '-1        ; minus offset
  5006.     xor    ah,ah
  5007.     mov    param+2,ax        ; stash here
  5008.     mov    ttstate,offset atnrm    ; reset state to "normal"
  5009.     jmp    atcup            ; position and return
  5010.  
  5011. ; VT52 print controls
  5012.  
  5013. v52ps:    mov    param,0            ; print screen
  5014.     mov    lparam,0
  5015.     jmp    ansprt            ; simulate ESC [ 0 i
  5016. v52pl:    mov    param,1            ; print line
  5017.     jmp    short v52pcom        ; simulate ESC [ ? 1 i
  5018. v52pcb:    mov    param,5            ; Enter printer controller on
  5019.     jmp    short v52pcom        ; simulate ESC [ ? 5 i
  5020. v52pce:    mov    param,4            ; Exit printer controller on
  5021. ;    jmp    short v52pcom        ; simulate ESC [ ? 4 i
  5022. v52pcom:mov    lparam,'?'        ; simulate ESC [ ? <number> i
  5023.     jmp    ansprt            ; process command
  5024.  
  5025. v52sgm:    mov    setptr,offset G0set    ; enter/exit special graphics mode
  5026.     cmp    al,'F'            ; enter VT52 graphics mode?
  5027.     jne    v52sgm1            ; ne = no, exit and return to ASCII
  5028.     jmp    mkdecspec        ; 'G' make DEC special graphics in G0
  5029. v52sgm1:jmp    mkascii            ; make ASCII in G0
  5030.  
  5031. ; Heath-19 special functions
  5032.  
  5033. h19sans:or    vtemu.vtflgop,decanm    ; Turn on ANSI flag. ESC <
  5034.     jmp    chrdef            ; set default char sets
  5035.                     ; clear screen and go home
  5036.  
  5037. h19ed:    cmp    param,0            ; Erase cursor to end of screen?
  5038.     jne    h19ed2            ; ne = no
  5039.     mov    ax,dx            ; start at cursor
  5040.     mov    bx,low_rgt        ; lower right corner
  5041.     cmp    bh,dh            ; on status line?
  5042.     jae    h19ed1            ; ae = no
  5043.     mov    bh,dh            ; put end on status line
  5044. h19ed1:    call    vtsclr            ; clear it
  5045.     ret
  5046. h19ed2:    cmp    param,1            ; erase start of display to cursor?
  5047.     je    h19esos            ; e = yes
  5048.     cmp    param,2            ; erase entire screen?
  5049.     je    h19clrs            ; e = yes
  5050.     ret                ; else ignore
  5051.  
  5052.                     ; erase entire screen
  5053. h19clrs:cmp    dh,byte ptr low_rgt+1    ; on status line?
  5054.     ja    h19erl            ; a = yes, do just erase in line
  5055.     xor    dx,dx            ; go to upper left corner
  5056.     call    atsetcur        ; do it
  5057.     xor    ax,ax            ; clear screen from (0,0)
  5058.     mov    bx,low_rgt        ; to lower right corner
  5059.     call    vtsclr            ; clear it
  5060.     ret
  5061.  
  5062. h19erl:    xor    al,al            ; erase whole line
  5063.     mov    bl,byte ptr low_rgt    ; physical width
  5064.     jmp    erinline        ; erase whole line, cursor stays put
  5065.  
  5066. h19ero:    xor    al,al            ; erase start of line to cursor
  5067.     mov    bl,dl
  5068.     jmp    erinline        ; clear that part of line
  5069.  
  5070.                     ; erase start of screen to cursor
  5071. h19esos:cmp    dh,byte ptr low_rgt+1    ; on status line?
  5072.     ja    h19ero            ; a = yes, do just erase in line
  5073.     jmp    ersos            ; do regular erase start of screen
  5074.  
  5075. h19wrap:or    vtemu.vtflgop,decawm    ; turn on line wrapping
  5076.     ret
  5077. h19nowrp:and    vtemu.vtflgop,not decawm ; turn off line wrapping
  5078.     ret
  5079.  
  5080. h19herv:mov    ah,curattr        ; get current cursor attribute
  5081.     mov    cl,extattr
  5082.     call    setrev            ; ESC p set reversed video
  5083.     mov    curattr,ah        ; store new attribute byte
  5084.     ret
  5085.  
  5086. h19hxrv:mov    ah,curattr        ; get current cursor attribute
  5087.     mov    cl,extattr
  5088.     call    clrrev            ; ESC q set normal video
  5089.     mov    curattr,ah        ; store new attribute byte
  5090.     ret
  5091.  
  5092. h19sc:    mov    dx,cursor
  5093.     mov    h19cur,dx        ; save cursor position
  5094.     ret
  5095.  
  5096. h19rc:    mov    dx,h19cur        ; saved cursor position
  5097.     jmp    atsetcur            ; set cursor and return
  5098.  
  5099.                     ; Heath-19 set mode "ESC x "
  5100. h19smod:mov    ttstate,offset hsmod    ; setup to parse rest of seq
  5101.     ret
  5102. hsmod:    mov    modeset,1        ; say set mode
  5103.     mov    ttstate,offset atnrm
  5104.     sub    al,'0'            ; remove ascii bias
  5105.     jmp    htrsm1            ; perform mode set
  5106.  
  5107. h19cmod:mov    ttstate,offset hcmod    ; setup to parse rest of seq
  5108.     ret
  5109.  
  5110. hcmod:    mov    modeset,0        ; say reset mode
  5111.     mov    ttstate,offset atnrm
  5112.     sub    al,'0'            ; remove ascii bias
  5113.     jmp    htrsm1            ; perform mode reset
  5114.  
  5115. hrcup:    mov    al,escape        ; send "ESC Y row col" cursor report
  5116.     call    prtbout            ; send with no local echo
  5117.     mov    al,'Y'
  5118.     call    prtbout
  5119.     mov    al,byte ptr cursor+1    ; get row
  5120.     add    al,' '            ; add ascii bias
  5121.  
  5122.     call    prtbout            ; send it
  5123.     mov    al,byte ptr cursor    ; get column
  5124.     add    al,' '            ; add ascii bias
  5125.     call    prtbout            ; and send it too
  5126.     ret
  5127.  
  5128. ; Insert/Delete characters and lines
  5129. inslin    proc    near
  5130.     mov    ax,param        ; insert line
  5131.     or    ax,ax            ; any args?
  5132.     jne    insli1            ; ne = yes
  5133.     inc    ax            ; insert one line
  5134. insli1:    mov    scroll,al        ; lines to scroll
  5135.     mov    dx,cursor        ; current position
  5136.     cmp    dh,mar_bot        ; below bottom margin?
  5137.     ja    insli3            ; a = below bottom margin
  5138.     push    word ptr mar_top
  5139.     mov    mar_top,dh        ; call present position the top
  5140.     call    atscrd            ; scroll down
  5141.     pop    word ptr mar_top    ; restore margins
  5142.     xor    dl,dl            ; go to left margin
  5143.     jmp    atsetcur        ; reposition cursor and return
  5144. insli3: ret
  5145. inslin    endp
  5146.  
  5147. dellin    proc    near
  5148.     mov    ax,param        ; delete line(s)
  5149.     or    ax,ax            ; any args?
  5150.     jne    delli1            ; ne = yes
  5151.     inc    ax            ; insert one line
  5152. delli1:    mov    scroll,al        ; line count
  5153.     mov    dx,cursor        ; where we are presently
  5154.     cmp    dh,mar_bot        ; at or below bottom margin?
  5155.     jae    delli3            ; ae = yes, do not scroll
  5156.     push    word ptr mar_top    ; save current scrolling margins
  5157.     mov    mar_top,dh        ; temp top margin is here
  5158.     call    atscru            ; scroll up
  5159.     pop    word ptr mar_top    ; restore scrolling margins
  5160.     jmp    atsetcur        ; restore cursor
  5161. delli3: ret
  5162. dellin    endp
  5163.  
  5164. ansich    proc    near            ; ANSI insert characters ESC [ Pn @
  5165.     mov    cx,param
  5166.     or    cx,cx            ; any arguments?
  5167.     jne    ansic1            ; ne = no, ignore
  5168.     inc    cx            ; use one
  5169. ansic1:    push    bx            ; use this as insert/delete flag
  5170.     mov    bh,1            ; do an insert operation
  5171. ansic2:    call    insdel            ; do common insert/delete code
  5172.     pop    bx
  5173.     ret
  5174. ansich    endp
  5175.  
  5176. inschr    proc    near            ; insert open (space) char at cursor
  5177.     push    bx            ; use this as insert/delete flag
  5178.     mov    bh,1            ; do an insert operation
  5179.     mov    cx,1            ; do one character
  5180.     call    insdel            ; do common insert/delete code
  5181.     pop    bx
  5182.     ret
  5183. inschr    endp
  5184.  
  5185. atdelc    proc    near
  5186.     mov    cx,param        ; Delete characters(s)
  5187.     or    cx,cx            ; zero becomes one operation
  5188.     jnz    atdelc1
  5189.     inc    cx            ; delete one char. Heath ESC N
  5190. atdelc1:push    bx            ; use this as insert/delete flag
  5191.     mov    bh,-1            ; do a delete operation
  5192. atdelc2:call    insdel            ; do common insert/delete code
  5193.     pop    bx
  5194.     ret
  5195. atdelc    endp
  5196.  
  5197.                     ; Common code for insert/delete char
  5198. insdel    proc    near            ; BH has insert/delete code
  5199.     mov    dx,cursor        ; logical cursor
  5200.     cmp    decrlm,0        ; host writing direction active?
  5201.     je    insdel11        ; e = no
  5202.     call    hldirection
  5203. insdel11:
  5204.     cmp    thisline,0        ; is line already single width?
  5205.     je    insdel1            ; e = yes
  5206.     add    dl,dl            ; double the cursor column
  5207.     add    cx,cx            ; double repeat count
  5208.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  5209.     jz    insdel1            ; z = no
  5210.     shl    mar_right,1        ; this one doubles the margins
  5211. insdel1:mov    bl,mar_right
  5212.     inc    bl            ; number of screen columns
  5213.     sub    bl,dl            ; width - cursor
  5214.     cmp    cl,bl            ; skipping more than screen width?
  5215.     jbe    insdel2            ; be = no
  5216.     mov    cl,bl            ; limit to screen width please
  5217. insdel2:
  5218. ; dh=logical cursor row, dl= logical cursor column, cx has repeat count
  5219. ; bl = logical screen width - 1, bh = +1 for insert, -1 for delete chars.
  5220.     mov    bl,cl            ; offset
  5221.     xor    ch,ch
  5222.     or    bh,bh            ; ins or del?
  5223.     jl    insdel5            ; l = delete
  5224.                     ; Insert processor
  5225.     mov    cl,mar_right        ; right margin
  5226.     sub    cl,dl            ; minus cursor location
  5227.     mov    dl,mar_right        ; start at right margin
  5228. insdel4:push    cx
  5229.     push    dx
  5230.     sub    dl,bl            ; back up by offset
  5231.     call    hldirection
  5232.     call    getatch            ; read char from vscreen
  5233.     pop    dx
  5234.     push    dx
  5235.     call    hldirection
  5236.     call    qsetatch        ; write it farther to the right
  5237.     pop    dx
  5238.     pop    cx
  5239.     dec    dl            ; backup one column
  5240.     loop    insdel4
  5241.     jmp    short insdel7
  5242.                       ; Delete processor
  5243. insdel5:mov    cl,mar_right        ; right margin
  5244.     sub    cl,dl            ; minus starting position
  5245.     sub    cl,bl            ; minus displacement (num deletes)
  5246.     inc    cl            ; count column 0
  5247.     or    cl,cl
  5248.     jle    insdel7
  5249. insdel6:push    cx
  5250.     push    dx
  5251.     add    dl,bl            ; look to right
  5252.     call    hldirection
  5253.     call    getatch            ; read char from vscreen
  5254.     pop    dx
  5255.     push    dx
  5256.     call    hldirection
  5257.     call    qsetatch        ; write it farther to the left
  5258.     pop    dx
  5259.     pop    cx
  5260.     inc    dl            ; next column
  5261.     loop    insdel6
  5262.  
  5263. insdel7:mov    cl,bl            ; fill count
  5264.     xor    ch,ch
  5265.     jcxz    insdel9            ; z = empty
  5266.     mov    ah,scbattr        ; get fill
  5267.     mov    al,' '
  5268. insdel8:push    cx
  5269.     xor    cl,cl            ; extended attributes
  5270.     push    dx
  5271.     call    hldirection
  5272.     call    qsetatch        ; write new char
  5273.     pop    dx
  5274.     inc    dl            ; next column
  5275.     pop    cx
  5276.     loop    insdel8
  5277.  
  5278. insdel9:mov    dx,cursor        ; logical cursor again
  5279.     cmp    thisline,0        ; is line already single width?
  5280.     je    insde10            ; e = yes
  5281.     add    dl,dl            ; move to double char cell
  5282.     test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  5283.     jz    insde10            ; z = no
  5284.     shr    mar_right,1        ; this one doubles the margins
  5285. insde10:call    atsetcur        ; set it to current char
  5286.     mov    dl,dh            ; rows to update
  5287.     call    touchup
  5288.     mov    dx,cursor        ; in case we are called indirectly
  5289.     ret
  5290. insdel    endp
  5291.  
  5292. noins:    mov    insmod,0        ; turn off insert mode
  5293.     ret
  5294.  
  5295. entins:    mov    insmod,0ffh        ; enter insert mode
  5296.     ret
  5297.  
  5298. ; Line type to/from single or double
  5299. linesgl    proc    near            ; convert line to single width char
  5300.     push    ax
  5301.     push    bx
  5302.     push    cx
  5303.     push    dx
  5304.     mov    bx,dx            ; cursor
  5305.     mov    bl,bh
  5306.     xor    bh,bh            ; bx now holds row
  5307.     cmp    linetype [bx],0        ; is line already single width?
  5308.     je    linsglx            ; e = yes
  5309.     mov    linetype [bx],0        ; say will be single now
  5310.     mov    dh,byte ptr cursor+1    ; row
  5311.     xor    dl,dl            ; start in column 0
  5312.     mov    cl,mar_right        ; number of columns on screen - 1
  5313.     inc    cl
  5314.     shr    cl,1            ; number of columns to do
  5315.     xor    ch,ch
  5316.     push    cx            ; save around loop below
  5317. linsgl1:push    cx            ; save loop counter
  5318.     push    dx
  5319.     shl    dl,1            ; double column number
  5320.     call    direction        ; set dx to desired position
  5321.     call    getatch            ; read char (al) and attribute (ah)
  5322.     pop    dx            ; logical attribute to cl
  5323.     push    dx
  5324.     call    direction        ; set dx to desired position
  5325.     call    qsetatch        ; write char (al) and attribute (ah)
  5326.     pop    dx            ; and logical attribute is in cl
  5327.     inc    dl            ; next column
  5328.     pop    cx
  5329.     loop    linsgl1
  5330.     pop    cx            ; recover column counter
  5331.     mov    dl,cl
  5332. linsgl2:push    cx            ; save counter
  5333.     push    dx
  5334.     call    direction        ; set dx to desired position
  5335.     mov    ah,scbattr        ; screen background
  5336.     xor    cl,cl            ; extended attribute
  5337.     mov    al,' '
  5338.     call    qsetatch        ; write char
  5339.     pop    dx
  5340.     pop    cx
  5341.     inc    dl            ; next column
  5342.     loop    linsgl2            ; repeat for all characters
  5343.     mov    dl,dh            ; rows to touchup
  5344.     call    touchup
  5345. linsglx:pop    dx
  5346.     pop    cx
  5347.     pop    bx
  5348.     pop    ax
  5349.     jmp    atscur            ; update cursor and return
  5350. linesgl    endp
  5351.  
  5352. linedbl    proc    near            ; convert line to double width char
  5353.     push    ax            ; must reset physical cursor
  5354.     push    bx            ; to same char as before expansion
  5355.     push    cx            ; but does not modify variable cursor
  5356.     push    dx
  5357.     mov    bx,dx            ; cursor
  5358.     mov    bl,bh
  5359.     xor    bh,bh            ; bx now holds row
  5360.     cmp    linetype [bx],0        ; is line single width?
  5361.     jne    lindblx            ; ne = no. nothing to do
  5362.     mov    linetype [bx],1        ; say will be double width now
  5363.     mov    cl,mar_right        ; number of columns on the screen - 1
  5364.     inc    cl
  5365.     xor    ch,ch
  5366.     shr    cl,1            ; number of items to do
  5367.     mov    dl,cl
  5368.     dec    dl
  5369. lindbl1:push    cx            ; save loop counter
  5370.     push    dx
  5371.     call    direction        ; set dx to desired position
  5372.     call    getatch            ; read char (al) and attribute (ah)
  5373.     pop    dx            ; extended attribute is in cl
  5374.     shl    dl,1            ; double the column number
  5375.     push    dx
  5376.     call    direction        ; set dx to desired position
  5377.     call    qsetatch        ; write char and attribute
  5378.     pop    dx
  5379.     inc    dl            ; move to second column of double
  5380.     push    dx
  5381.     call    direction        ; set dx to desired position
  5382.     mov    al,' '            ; space as filler
  5383.     call    qsetatch        ; write that char
  5384.     pop    dx
  5385.     dec    dl
  5386.     shr    dl,1
  5387.     dec    dl
  5388.     pop    cx
  5389.     loop    lindbl1
  5390.     mov    dl,dh            ; rows to touchup
  5391.     call    touchup
  5392. lindblx:pop    dx
  5393.     pop    cx
  5394.     pop    bx
  5395.     pop    ax
  5396.     jmp    atscur            ; update the cursor and return
  5397. linedbl    endp
  5398.  
  5399. ; Printer support routines
  5400. ansprt    proc near
  5401.     mov    di,offset ansprt0    ; routine to process arguments
  5402.     call    atreps            ; repeat for all parms
  5403.     ret
  5404.  
  5405. ansprt0:mov    ax,param[si]        ; pick up the argument
  5406.     or    ax,ax            ; 0 (print all/part of screen)?
  5407.     jnz    ansprt1            ; nz = no
  5408.     cmp    ninter,0        ; unwanted intermediates?
  5409.     jne    anspr4a            ; ne = got one, illegal here
  5410.     call    fpntchk            ; check printer
  5411.     call    pntext            ; do whole screen or scrolling extent
  5412.     jmp    atsetcur        ; reposition cursor and return
  5413.  
  5414. ansprt1:cmp    ax,1            ; 1 (print current line)?
  5415.     jne    ansprt4            ; ne = no
  5416.     call    fpntchk            ; check for printer ready
  5417.     call    pntlin            ; print current line
  5418.     mov    al,LF
  5419.     call    fpntchr
  5420.     call    fpntflsh        ; flush printer buffer
  5421.     jmp    atsetcur        ; reposition cursor and return
  5422.  
  5423. ansprt4:cmp    ax,4            ; 4 (auto print disable)?
  5424.     jne    ansprt5            ; ne = no
  5425.     cmp    lparam,'?'        ; was it ESC [ ? 4 i
  5426.     jne    anspr4a            ; ne = no, so it was ESC [ 4 i
  5427.     test    anspflg,vtautop        ; check state of print flag
  5428.     jz    anspr4a            ; z = off already
  5429.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  5430.     call    ftrnprs            ; toggle mode line PRN indicator
  5431. anspr4a:ret
  5432.  
  5433. ansprt5:cmp    ax,5            ; 5 (auto print enable)?
  5434.     jne    ansprtx            ; ne = no
  5435.     call    fpntchk            ; check printer, ignore carry ret
  5436.     cmp    lparam,'?'        ; was it ESC [ ? 5 i
  5437.     jne    anspr5a            ; ne = no
  5438.     test    anspflg,vtautop        ; is print already enabled?
  5439.     jnz    ansprtx            ; nz = yes, leave trnprs intact
  5440.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  5441.     call    ftrnprs            ; toggle on mode line PRN indicator
  5442.     ret
  5443. anspr5a:test    anspflg,vtcntp        ; controller print already enabled?
  5444.     jnz    ansprtx            ; nz = yes
  5445.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  5446.     or    anspflg,vtcntp        ; controller print enabled
  5447.     mov    emubufc,0        ; clear string buffer
  5448.     mov    ttstate,offset ansmc    ; do transparent print
  5449.     call    ftrnprs            ; toggle on mode line PRN indicator
  5450. ansprtx:ret
  5451. ansprt    endp
  5452.  
  5453. ; State machine active while Media Copy On (Print Controller ON). Copies all
  5454. ; chars to the printer until and excluding Media Copy Off (ESC [ 4 i) or a
  5455. ; repeated Media Copy On (ESC [ 5 i) has been received or the emulator reset.
  5456. ; New char is in al.
  5457. ansmc    proc    near
  5458.     mov    ttstate,offset ansmc    ; stay in this state
  5459.     cmp    al,escape        ; start a new sequence?
  5460.     je    ansmc1            ; e = yes
  5461.     cmp    al,CSI            ; start a new sequence?
  5462.     je    ansmc0a            ; e = yes
  5463.     mov    emubufc,0        ; say no matched chars
  5464.     call    fpntchr            ; print char in al, ignore errors
  5465.     ret
  5466.                     ; CSI seen
  5467. ansmc0a:call    ansmc5            ; playback previous matches
  5468.     call    atpclr            ; clear parser
  5469.     mov    pardone,offset ansmc4    ; where to go when done
  5470.     mov    parfail,offset ansmc5    ; where to go when fail, playback
  5471.     mov    ttstate,offset ansmc3    ; get numeric arg
  5472.     mov    emubuf,CSI        ; stuff CSI
  5473.     mov    emubufc,1
  5474.     ret
  5475.                     ; Escape seen
  5476. ansmc1:    call    ansmc5            ; playback previous matches
  5477.     mov    ttstate,offset ansmc2    ; get left square bracket
  5478.     mov    emubufc,1        ; one char matched
  5479.     mov    emubuf,al        ; store it
  5480.     ret
  5481.  
  5482. ansmc2:    cmp    al,'['            ; left square bracket?
  5483.     je    ansmc2a            ; e = yes
  5484.     call    ansmc5            ; playback previous matches
  5485.     call    fpntchr            ; print char in al, ignore errors
  5486.     ret
  5487.  
  5488. ansmc2a:inc    emubufc            ; say matched "ESC ["
  5489.     mov    emubuf+1,al        ; store left square brace
  5490.     call    atpclr            ; clear parser
  5491.     mov    pardone,offset ansmc4    ; where to go when done
  5492.     mov    parfail,offset ansmc5    ; where to go when fail, playback
  5493.     mov    ttstate,offset ansmc3    ; get numeric arg
  5494.     ret
  5495.                     ; CSI or ESC [ seen
  5496. ansmc3:    inc    emubufc            ; another char
  5497.     mov    bx,emubufc        ; qty stored
  5498.     mov    emubuf[bx-1],al        ; store it
  5499.     mov    ah,al            ; check for C0 and C1 controls
  5500.     and    ah,not 80h
  5501.     cmp    ah,20h            ; control range?
  5502.     jb    ansmc5            ; b = yes, mismatch, playback
  5503.     jmp    atparse            ; parse control sequence
  5504.                     ; parse succeeded, al has Final char
  5505. ansmc4:    cmp    al,'i'            ; correct Final char?
  5506.     jne    ansmc5            ; ne = no, playback previous matches
  5507.     cmp    lparam,0        ; missing letter parameter?
  5508.     jne    ansmc5            ; ne = no, mismatch
  5509.     cmp    ninter,0        ; missing intermediates?
  5510.     jne    ansmc5            ; ne = no, mismatch
  5511.     mov    cx,nparam        ; number of parameters
  5512.     xor    bx,bx            ; subscript
  5513. ansmc4a:mov    ax,param[bx]
  5514.     add    bx,2            ; next param
  5515.     cmp    ax,4            ; CSI 4 i  MC OFF?
  5516.     je    ansmc4b            ; e = yes, stop printing
  5517.     loop    ansmc4a            ; keep trying all parameters
  5518.     jmp    short ansmc7        ; forget this one, start over
  5519.  
  5520.                     ; Media OFF found
  5521. ansmc4b:mov    ttstate,offset atnrm    ; return to normal state
  5522.     call    fpntflsh        ; flush printer buffer
  5523.     test    anspflg,vtcntp        ; was printing active?
  5524.     jz    ansmc7            ; z = no
  5525.     and    anspflg,not vtcntp    ; yes, disable print controller
  5526.     call    ftrnprs            ; toggle mode line PRN indicator
  5527.     ret
  5528.                     ; playback emubufc matched chars
  5529. ansmc5:    mov    cx,emubufc        ; matched char count
  5530.     jcxz    ansmc7            ; z = none
  5531.     push    ax            ; save current char in al
  5532.     push    si
  5533.     mov    si,offset emubuf    ; matched sequence, cx chars worth
  5534.     cld
  5535. ansmc6:    lodsb                ; get a char
  5536.     call    fpntchr            ; print it, ignore errors
  5537.     loop    ansmc6            ; do all matched chars
  5538.     pop    si
  5539.     pop    ax
  5540.     mov    emubufc,cx        ; clear this counter
  5541. ansmc7:    mov    ttstate,offset ansmc    ; reset state to the beginning
  5542.     ret
  5543. ansmc    endp
  5544.  
  5545. dgprt    proc    near            ; RS F ? <char>     DG Print routines
  5546.     mov    ttstate,offset dgprt1    ; get the <char>
  5547.     ret
  5548. dgprt1:    mov    ttstate,offset atnrm    ; reset state
  5549.     cmp    al,0            ; Simulprint off?
  5550.     jne    dgprt2            ; ne = no
  5551.     mov    al,7            ; reform to be VT autoprint off
  5552.  
  5553. dgprt2:    cmp    al,1            ; Simulprint on?
  5554.     jne    dgprt3            ; ne = no
  5555.     mov    al,8            ; reform to be VT autoprint on
  5556.  
  5557. dgprt3:    cmp    al,3            ; Print Pass Through on?
  5558.     jne    dgprt4            ; ne = no
  5559. dgprt3a:                ; RS F `   alternative to RS F ? 3
  5560.     test    anspflg,vtcntp        ; controller print already enabled?
  5561.     jnz    dgprt7            ; nz = yes
  5562.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  5563.     or    anspflg,vtcntp        ; controller print enabled
  5564.     mov    emubufc,0        ; clear string buffer
  5565.     mov    ttstate,offset dgmc    ; do transparent print
  5566.     call    ftrnprs            ; toggle on mode line PRN indicator
  5567.     ret
  5568.  
  5569. dgprt4:    cmp    al,8            ; VT-style autoprint on?
  5570.     jne    dgprt5            ; ne = no
  5571.     call    fpntchk            ; check printer, ignore carry ret
  5572.     test    anspflg,vtautop        ; is print already enabled?
  5573.     jnz    dgprt7            ; nz = yes, leave trnprs intact
  5574.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  5575.     call    ftrnprs            ; toggle on mode line PRN indicator
  5576.     ret
  5577.  
  5578. dgprt5:    cmp    al,7            ; VT-style autoprint off?
  5579.     jne    dgprt6            ; ne = no
  5580.     test    anspflg,vtautop        ; check state of print flag
  5581.     jz    dgprt7            ; z = off already
  5582.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  5583.     call    ftrnprs            ; toggle mode line PRN indicator
  5584.     ret
  5585.  
  5586. dgprt6:    cmp    al,':'            ; Print Screen?
  5587.     jne    dgprt7            ; ne = no
  5588.     mov    ah,mar_bot        ; save margins
  5589.     mov    al,mar_top
  5590.     push    ax
  5591.     mov    mar_top,0        ; set to full screen height
  5592.     mov    al,byte ptr low_rgt+1    ; bottom text row
  5593.     mov    mar_bot,al
  5594.     push    cursor
  5595.     xor    dx,dx            ; cursor to home
  5596.     call    dgprtwn            ; print this window
  5597.     pop    cursor
  5598.     pop    ax
  5599.     mov    mar_top,al        ; restore margins
  5600.     mov    mar_bot,ah
  5601. dgprt7:    ret
  5602. dgprt    endp
  5603.  
  5604. dgppb    proc    near            ; RS F x <n> Printer Pass back to host
  5605.     mov    bx,offset dgppb1    ; call back routine
  5606.     jmp    get1n            ; setup consume one <n>
  5607. dgppb1:    mov    al,dgescape        ; send RS R x 0  cannot set
  5608.     call    prtbout            ; out, no echo
  5609.     mov    al,'R'
  5610.     call    prtbout
  5611.     mov    al,'x'
  5612.     call    prtbout
  5613.     mov    al,'0'            ; say cannot set NRC printer mode
  5614.     call    prtbout
  5615.     ret
  5616. dgppb    endp
  5617.  
  5618. ; State machine active while DG Simulprint is  On. Copies all chars to the 
  5619. ; printer until and excluding Simulprint Off (RS F ? 0) has been received 
  5620. ; or the emulator reset.
  5621. ; New char is in al.
  5622. dgmc    proc    near
  5623.     mov    ttstate,offset dgmc    ; stay in this state
  5624.     cmp    al,dgescape        ; start a new sequence?
  5625.     je    dgmc1            ; e = yes
  5626.     mov    emubufc,0        ; say no matched chars
  5627.     call    fpntchr            ; print char in al, ignore errors
  5628.     ret
  5629.                     ; RS seen
  5630. dgmc1:    call    ansmc5            ; playback previous matches
  5631.     mov    ttstate,offset dgmc2    ; get next char
  5632.     mov    emubufc,1        ; one char matched
  5633.     mov    emubuf,al        ; store it
  5634.     ret
  5635.  
  5636. dgmc2:    cmp    al,'F'            ; 'F' part of RS F ? 2
  5637.     jne    dgmc7            ; ne = no
  5638.     inc    emubufc            ; say matched "RS F"
  5639.     mov    emubuf+1,al        ; store it
  5640.     mov    ttstate,offset dgmc3    ; get query char
  5641.     ret
  5642.                     ; RS F seen
  5643. dgmc3:    cmp    al,'?'            ; 'F' part of RS F ? 2
  5644.     jne    dgmc4            ; ne = no
  5645.     inc    emubufc            ; say matched "RS F ?"
  5646.     mov    emubuf+1,al        ; store it
  5647.     mov    ttstate,offset dgmc5    ; get final char
  5648.     ret
  5649.  
  5650. dgmc4:    cmp    al,'a'            ; RS F a  alternative?
  5651.     jne    dgmc7            ; ne = no
  5652.     jmp    short dgmc8        ; finish up
  5653.  
  5654. dgmc5:    cmp    al,'2'            ; RS F ? seen, correct final char?
  5655.     je    dgmc8            ; e = yes
  5656.     
  5657. dgmc7:    call    ansmc5            ; playback previous matches
  5658.     call    fpntchr            ; print char in al, ignore errors
  5659.     mov    ttstate,offset dgmc    ; start over
  5660.     ret
  5661.  
  5662. dgmc8:    mov    ttstate,offset atnrm    ; return to normal state
  5663.     call    fpntflsh        ; flush printer buffer
  5664.     test    anspflg,vtcntp        ; was printing active?
  5665.     jz    dgmc9            ; z = no
  5666.     and    anspflg,not vtcntp    ; yes, disable print controller
  5667.     mov    al,6            ; send Control-F to host
  5668.     call    prtbout            ; output, no echo
  5669.     call    ftrnprs            ; toggle mode line PRN indicator
  5670. dgmc9:    ret
  5671. dgmc    endp
  5672.  
  5673. pntlin    proc    near            ; print whole line given by dx
  5674.     push    ax
  5675.     push    bx
  5676.     push    cx
  5677.     push    dx
  5678.     xor    ch,ch
  5679.     mov    cl,mar_right        ; number of columns - 1
  5680.     mov    dl,cl            ; Bios column counter, dh = row
  5681.     inc    cl            ; actual line length, count it down
  5682.     test    vtemu.vtflgop,vswdir    ; writing right to left?
  5683.     jnz    pntlin2            ; nz = yes, do not trim spaces
  5684.     cmp    decrlm,0        ; host writing direction active?
  5685.     jne    pntlin2            ; ne = yes
  5686. pntlin1:push    cx
  5687.     call    getatch            ; read char (al) and attribute (ah)
  5688.     pop    cx            ;  and extended bit pair to cl
  5689.     cmp    al,' '            ; is this a space?
  5690.     jne    pntlin2            ; no, we have the end of the line
  5691.     dec    dl            ; else move left one column
  5692.     loop    pntlin1            ; and keep looking for non-space
  5693.  
  5694. pntlin2:jcxz    pntlin4            ; z = empty line
  5695.     xor    dl,dl            ; start in column 0, do cl chars
  5696. pntlin3:push    cx
  5697.     call    getatch            ; read char (al) and attribute (ah)
  5698.     pop    cx
  5699.     inc    dl            ; inc to next column
  5700.     call    fpntchr            ; print the char (in al)
  5701.     jc    pntlin5            ; c = printer error
  5702.     loop    pntlin3            ; do cx columns
  5703. pntlin4:mov    al,cr            ; add trailing cr for printer
  5704.     call    fpntchr
  5705. pntlin5:pop    dx
  5706.     pop    cx
  5707.     pop    bx
  5708.     pop    ax
  5709.     ret                ; C bit controlled by pntchr
  5710. pntlin    endp
  5711.  
  5712. pntext    proc    near            ; print an extent of lines, depending
  5713.     push    ax            ; on flag bit vtextp
  5714.     push    bx
  5715.     push    dx
  5716.     xor    dx,dx            ; assume starting at top left
  5717.     mov    bx,low_rgt        ;  and extending to lower right
  5718.     test    anspflg,vtextp        ; full screen wanted?
  5719.     jnz    pntext1            ; nz = yes, else scrolling region
  5720.     mov    dh,mar_top        ; top of scrolling region
  5721.     mov    bh,mar_bot        ; bottom of scrolling region
  5722. pntext1:call    pntlin            ; print a line
  5723.     jc    pntext2            ; c = printer error
  5724.     mov    al,LF
  5725.     call    fpntchr
  5726.     jc    pntext2
  5727.     inc    dh
  5728.     cmp    dh,bh            ; done all requested lines?
  5729.     jbe    pntext1            ; be = not yet, do another
  5730.     test    anspflg,vtffp        ; form feed needed at end?
  5731.     jz    pntext2            ; z = no
  5732.     mov    al,ff
  5733.     call    fpntchr            ; print the form feed char
  5734. pntext2:pop    dx
  5735.     pop    bx
  5736.     pop    ax
  5737.     ret
  5738. pntext    endp
  5739.  
  5740. ; Set cursor coordinate DL (row) with consideration for writing direction.
  5741. ; Active only under local writing direction control
  5742. direction proc    near
  5743.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  5744.     jz    direct1            ; z = yes, no changes needed
  5745.     sub    dl,mar_right        ; right margin column number
  5746.     neg    dl            ; make a positive value again
  5747. direct1:ret
  5748. direction endp
  5749.  
  5750. ; Like direction, but functions if host writing direction decrlm is active
  5751. ; as well as local control
  5752. hldirection proc near
  5753.     cmp    decrlm,0        ; host mode inactive?
  5754.     jne    hldirect1        ; ne = no, obey
  5755.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  5756.     jz    hldirect2        ; z = yes, no changes needed
  5757. hldirect1:sub    dl,mar_right        ; right margin column number
  5758.     neg    dl            ; make a positive value again
  5759. hldirect2:ret
  5760. hldirection endp
  5761.  
  5762. ; Erase from cursor (DX, inclusive) to end of screen
  5763. ; sense double width/height
  5764. ereos    proc    near
  5765.     mov    ax,dx            ; erase from cursor to end of screen
  5766.     or    dx,dx            ; cursor at home position?
  5767.     jnz    ereos1            ; nz = no
  5768.                     ; e = yes, roll screen before clear
  5769.     push    word ptr mar_top
  5770.     mov    al,byte ptr low_rgt+1    ; bottom row number
  5771.     mov    mar_bot,al
  5772.     mov    mar_top,dh        ; row of cursor
  5773.     inc    al            ; number of lines to scroll
  5774.     mov    scroll,al
  5775.     call    atscru            ; scroll them up before erasure
  5776.     pop    word ptr mar_top
  5777.                     ; removes double w/h lines too
  5778.     xor    ax,ax            ; erase from here (home)
  5779.     mov    bx,low_rgt        ; bh = bottom row number
  5780.     call    vtsclr            ; clear screen
  5781.     ret
  5782. ereos1:    push    dx            ; save dx
  5783.     mov    bl,dh            ; get row number
  5784.     xor    bh,bh
  5785.     cmp    linetype [bx],0        ; single width line?
  5786.     je    ereos2            ; e = yes
  5787.     shl    dl,1            ; physical column is twice logical
  5788. ereos2:    or    dl,dl            ; starting at left margin?
  5789.     je    ereos3            ; e = yes, this goes to single width
  5790.     inc    bl            ; else start on next line
  5791. ereos3:    cmp    bl,byte ptr low_rgt+1    ; at the end of the screen?
  5792.     ja    ereos4            ; a = yes, stop singling-up
  5793.     mov    byte ptr linetype [bx],0 ; set to single width
  5794.     inc    bx
  5795.     jmp    short ereos3        ; loop, reset lines to end of screen
  5796. ereos4:    mov    ax,dx            ; cursor
  5797.     pop    dx
  5798.     mov    bx,low_rgt        ; erase from cursor to end of screen
  5799.     call    vtsclr            ; clear it
  5800.     ret
  5801. ereos    endp
  5802.  
  5803. ; Erase from start of screen to cursor (inclusive), sense double width/height
  5804. ersos    proc    near
  5805.     xor    ax,ax            ; erase from start of screen
  5806.                     ;  to cursor, inclusive
  5807.     xor    bx,bx            ; start at top row (0)
  5808. ersos1:    cmp    bl,dh            ; check rows from the top down
  5809.     jae    ersos2            ; ae = at or below current line
  5810.     mov    byte ptr linetype [bx],0; set line to single width
  5811.     inc    bx            ; inc row
  5812.     jmp    short ersos1        ; look at next line
  5813. ersos2:    or    dl,dl            ; at left margin of current line?
  5814.     jne    ersos3            ; ne = no, leave line width intact
  5815.     mov    byte ptr linetype [bx],0 ; convert to single width    
  5816. ersos3:    mov    bl,dh            ; get row number
  5817.     xor    bh,bh
  5818.     cmp    linetype [bx],0        ; single width line?
  5819.     je    ersos4            ; e = yes
  5820.     shl    dl,1            ; physical column is twice logical
  5821. ersos4:    mov    bx,dx            ; cursor position to bx
  5822.     call    vtsclr            ; clear it
  5823.     ret
  5824. ersos    endp
  5825.  
  5826. ; Erase in line, from column AL to column BL, in row DH
  5827. erinline proc    near
  5828.     mov    ah,dh            ; set row
  5829.     mov    bh,dh
  5830.     push    bx
  5831.     mov    bl,dh            ; get row
  5832.     xor    bh,bh
  5833.     cmp    linetype [bx],0        ; single width line?
  5834.     pop    bx            ; pop does not affect flags
  5835.     je    erinli1            ; e = yes
  5836.     shl    al,1
  5837.     shl    bl,1            ; physical column is twice logical
  5838. erinli1:cmp    bl,byte ptr low_rgt    ; wider than the physical screen?
  5839.     jb    erinli2            ; b = no, not wider than screen
  5840.     mov    bl,byte ptr low_rgt    ; physical width
  5841. erinli2:cmp    al,byte ptr low_rgt
  5842.     jb    erinli3
  5843.     mov    al,byte ptr low_rgt
  5844. erinli3:call    vtsclr            ; clear it
  5845.     ret
  5846. erinline endp
  5847.  
  5848. ; General erasure command which skips over protected chars.
  5849. ; Preset margins and cursor to obtain all three erasure kinds.
  5850. erprot    proc    near            ; erase cursor to end of region
  5851.     mov    cursor,dx        ; preserve cursor
  5852. erprot1:push    dx
  5853.     call    direction
  5854.     call    getatch            ; read a char, get attributes
  5855.     pop    dx
  5856.     cmp    protectena,0        ; is protected mode enabled?
  5857.     je    erprot4            ; e = no, erase all
  5858.     test    cl,att_protect        ; protected mode?
  5859.     jnz    erprot2            ; nz = yes, retain it
  5860. erprot4:xor    cl,cl            ; clear extended attributes
  5861.     mov    ah,scbattr        ; background attributes
  5862.     mov    al,' '
  5863.     push    dx
  5864.     call    direction
  5865.     call    qsetatch        ; quietly update char
  5866.     pop    dx
  5867. erprot2:inc    dl            ; next column
  5868.     cmp    dl,mar_right        ; did right margin?
  5869.     jbe    erprot1            ; be = no
  5870.     mov    dl,mar_left        ; rest to left margin
  5871.     inc    dh            ; next line down
  5872.     cmp    dh,mar_bot        ; did the last row?
  5873.     jbe    erprot1            ; be = no
  5874. erprot3:mov    dl,byte ptr cursor+1    ; starting line, dh is ending line
  5875.     mov    dh,mar_bot
  5876.     call    touchup            ; repaint part of screen
  5877.     mov    dx,cursor
  5878.     ret
  5879. erprot    endp
  5880.  
  5881. ; Clear screen from AX to BX, where AH = row, AL = column, ditto for BX.
  5882. ; This routine accomodates right to left writing. BX >= AX.
  5883. vtsclr    proc    near
  5884.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  5885.     jz    vtsclr4            ; z = yes
  5886.     cmp    bh,ah            ; same row?
  5887.     je    vtsclr2            ; e = yes
  5888.     push    ax            ; multiple lines
  5889.     push    bx            ; save both coordinates
  5890.     mov    bl,mar_right
  5891.     mov    bh,ah            ; pick just top line
  5892.     call    vtsclr2            ; delete fraction of top line
  5893.     pop    bx            ; recover ending position
  5894.     push    bx
  5895.     inc    ah            ; omit top row, now done
  5896.     dec    bh            ; omit last line, could be fractional
  5897.     cmp    bh,ah            ; any whole lines remaining to delete?
  5898.     jb    vtsclr1            ; b = no, finish up
  5899.     mov    bl,mar_right        ; get right most physical column
  5900.     xor    al,al            ; to end of line (on left)
  5901.     call    atsclr            ; clear top line and whole remainders
  5902. vtsclr1:pop    bx            ; setup for last line to be cleared
  5903.     push    bx            ; get last row again
  5904.     xor    al,al            ; start at logical left margin
  5905.     jmp    short vtsclr3        ; ax and bx are already pushed
  5906.  
  5907. vtsclr2:push    ax            ; erase single line, whole or part
  5908.     push    bx
  5909. vtsclr3:mov    ah,mar_right        ; borrow reg ah (same as bh)
  5910.     sub    ah,bl            ; reflect right to left
  5911.     mov    bl,ah
  5912.     or    bl,bl            ; overflow?
  5913.     jns    vtsclr5            ; ns = no, is ok
  5914.     xor    bl,bl            ; limit to logical screen
  5915. vtsclr5:mov    ah,mar_right
  5916.     sub    ah,al
  5917.     mov    al,ah
  5918.     jns    vtsclr6
  5919.     mov    al,mar_right        ; limit to logical screen
  5920. vtsclr6:mov    ah,bh            ; restore ah
  5921.     xchg    al,bl            ; reverse to get physical ax < bx
  5922.     call    atsclr            ; erase part/all of single line
  5923.     pop    bx
  5924.     pop    ax
  5925.     ret
  5926.                     ; for writing left to right
  5927. vtsclr4:jmp    atsclr            ; do normal erasure and return
  5928. vtsclr    endp
  5929.  
  5930. ; routines supporting scrolling and double width/height chars
  5931. ; scroll has number of lines to scroll
  5932. atscru    proc    near            ; scroll screen up one line
  5933.     push    ax            ; assumes dx holds cursor position
  5934.     push    bx            ; returns with dx = old row, new col
  5935.     push    cx
  5936.     push    si
  5937.     xor    bh,bh
  5938.     mov    bl,mar_top        ; top line to move
  5939.     xor    ch,ch
  5940.     mov    cl,scroll        ; number of lines to move
  5941.     mov    al,mar_bot        ; bottom line to scroll
  5942.     sub    al,bl            ; number of lines minus 1
  5943.     inc    al            ; number of lines
  5944.     cmp    al,cl            ; scrolling region smaller than scroll?
  5945.     jge    atscru1            ; ge = no, is ok
  5946.     mov    scroll,al        ; limit to region
  5947.     cmp    al,1            ; at least one line to scroll?
  5948.     jge    atscru1            ; ge = yes
  5949.     mov    scroll,1        ; no, force one
  5950. atscru1:mov    al,scroll
  5951.     mov    ah,byte ptr low_rgt+1    ; last text line on screen
  5952.     inc    ah            ; number of screen lines
  5953.     cmp    al,ah            ; exceeds number of lines on screen?
  5954.     jbe    atscru8            ; be = scrolling not more than that
  5955.     mov    al,ah            ; limit to screen length
  5956.     mov    scroll,al
  5957. atscru8:xor    ah,ah
  5958.     mov    si,ax            ; scroll interval
  5959.     mov    bl,mar_top
  5960.     mov    cl,mar_bot
  5961.     sub    cl,bl
  5962.     inc    cl            ; number  of lines in region
  5963.     sub    cl,scroll        ; cx = those needing movement
  5964.     cmp    cl,0
  5965.     jle    atscru3
  5966. atscru2:mov    al,linetype[bx+si]    ; get old type
  5967.     mov    linetype[bx],al        ; copy to new higher position
  5968.     mov    al,linescroll[bx+si]    ; get horizontal scroll value
  5969.     mov    linescroll[bx],al    ; copy too
  5970.     inc    bx
  5971.     loop    atscru2
  5972. atscru3:mov    bl,mar_bot        ; set fresh lines to single attribute
  5973.     mov    cl,scroll        ; number of fresh lines (qty scrolled)
  5974.     xor    ch,ch
  5975. atscru4:mov    linetype[bx],0
  5976.     mov    linescroll[bx],0
  5977.     dec    bx
  5978.     loop    atscru4            ; clear old bottom lines
  5979.     mov    bl,dh            ; get row of cursor
  5980.     xor    bh,bh
  5981.     cmp    linetype[bx],0        ; single width?
  5982.     je    atscru5            ; e = yes
  5983.     shr    dl,1            ; reindex to single width columns
  5984. atscru5:pop    si
  5985.     pop    cx
  5986.     pop    bx
  5987.     pop    ax
  5988.     test    anspflg,vtcntp        ; controller print active?
  5989.     jz    atscru6            ; z = no, ok to change screen
  5990.     ret                ;  else keep screen intact
  5991. atscru6:jmp    vtscru            ; call & ret the msy scroll routine
  5992. atscru    endp
  5993.  
  5994. atscrd    proc    near            ; scroll screen down scroll lines
  5995.     push    ax            ; assumes dx holds cursor position
  5996.     push    bx            ; returns with dx = old row, new col
  5997.     push    cx
  5998.     push    si
  5999.     xor    ch,ch
  6000.     mov    cl,scroll        ; number of lines to scroll
  6001.     xor    bh,bh
  6002.     mov    bl,mar_bot        ; bottom line to move
  6003.     mov    al,bl
  6004.     xor    ah,ah
  6005.     sub    al,mar_top        ; number of lines minus 1
  6006.     inc    al            ; number of lines
  6007.     cmp    al,cl            ; scrolling region smaller than scroll?
  6008.     jge    atscrd1            ; ge = no, is ok
  6009.     mov    scroll,al        ; limit to region
  6010.     cmp    al,1            ; at least one line to scroll?
  6011.     jge    atscrd1            ; ge = yes
  6012.     mov    scroll,1        ; no, force one
  6013. atscrd1:mov    al,scroll
  6014.     mov    si,ax            ; si = scroll
  6015.     mov    bl,dh            ; get row of cursor
  6016.     xor    bh,bh            ; make into an index
  6017.     sub    bl,scroll        ; si + this bx will be new bottom line
  6018.     mov    cl,bl
  6019.     sub    cl,mar_top
  6020.     inc    cl
  6021.     cmp    cl,0
  6022.     jle    atscrd3
  6023. atscrd2:mov    al,linetype[bx]        ; get old line's type
  6024.     mov    linetype[bx+si],al    ; copy to new lower position
  6025.     mov    al,linescroll[bx]    ; get per line horizontal scroll
  6026.     mov    linescroll[bx+si],al    ; copy too
  6027.     dec    bx
  6028.     loop    atscrd2
  6029. atscrd3:mov    bl,mar_top        ; start with this line
  6030.     xor    bh,bh
  6031.     mov    cl,scroll        ; number of lines scrolled
  6032.     xor    ch,ch
  6033. atscrd4:mov    linetype[bx],0        ; clear new top lines
  6034.     mov    linescroll[bx],0
  6035.     inc    bx
  6036.     loop    atscrd4
  6037.     mov    bl,dh            ; get row of cursor
  6038.     xor    bh,bh
  6039.     cmp    linetype[bx],0        ; single width?
  6040.     je    atscrd5            ; e = yes
  6041.     shr    dl,1            ; reindex to single width columns
  6042. atscrd5:pop    si
  6043.     pop    cx
  6044.     pop    bx
  6045.     pop    ax
  6046.     test    anspflg,vtcntp        ; controller print active?
  6047.     jz    atscrd6            ; z = no, ok to change screen
  6048.     ret                ;  else keep screen intact
  6049. atscrd6:jmp    vtscrd            ; call & ret the msy scroll routine
  6050. atscrd    endp
  6051.  
  6052. ; Returns carry set if column in DL is a tab stop, else carry clear.
  6053. ; Enter with column number in DL (starts at column 0, max of swidth-1)
  6054. ; and tabstop buffer offset in SI.
  6055. istabs    proc    near
  6056.     push    bx
  6057.     push    cx
  6058.     mov    cl,dl            ; column number (0 to swidth-1)
  6059.     and    cl,00000111b        ; keep bit in byte (0-7)
  6060.     inc    cl            ; map to 1-8
  6061.     mov    bl,dl            ; column
  6062.     shr    bl,1            ; bl / 8 to get byte
  6063.     shr    bl,1
  6064.     shr    bl,1
  6065.     xor    bh,bh            ; clear high byte
  6066.     mov    bl,[si+bx]        ; get a byte of tab bits
  6067.     ror    bl,cl            ; rotate to put tab-set bit into carry
  6068.     pop    cx
  6069.     pop    bx
  6070.     ret
  6071. istabs    endp
  6072.  
  6073. ; Modify (set/clear) a tabstop. Enter with DL holding column (0 to swidth-1)
  6074. ; Set a tabstop into buffer pointed at by SI.
  6075. tabset    proc    near
  6076.     mov    modeset,1        ; set a tabstop
  6077.     jmp    short modtabs
  6078. tabset    endp
  6079.  
  6080. ; Clear a tabstop
  6081. tabclr    proc    near
  6082.     mov    modeset,0        ; clear a tabstop
  6083.     jmp    short modtabs
  6084. tabclr    endp
  6085.  
  6086. ; Worker for set/clear tabstop, si has pointer to tabstops array
  6087. modtabs:push    bx
  6088.     push    cx
  6089.     mov    cl,dl            ; column number (0 to swidth-1)
  6090.     and    cl,00000111b        ; keep bit in byte (0-7)
  6091.     mov    ch,1            ; tab bit to change
  6092.     shl    ch,cl            ; shift to bit-in-byte position
  6093.     mov    bl,dl            ; column
  6094.     shr    bl,1            ; bl / 8 to get byte
  6095.     shr    bl,1
  6096.     shr    bl,1
  6097.     xor    bh,bh            ; clear high byte
  6098.     mov    cl,[si+bx]        ; get byte of tabs bits
  6099.     not    ch            ; invert bit marker to create hole
  6100.     and    cl,ch            ; clear the tab bit
  6101.     not    ch            ; recover setting pattern
  6102.     cmp    modeset,0        ; clear the tab bit?
  6103.     jz    modtab1            ; z = yes
  6104.     or    cl,ch            ; set the tab bit
  6105. modtab1:mov    [si+bx],cl        ; store tab byte
  6106.     pop    cx
  6107.     pop    bx
  6108.     ret
  6109.  
  6110. ; This routine initializes the VT  setups at startup. It is called from
  6111. ; procedure lclyini in module msyibm.
  6112. vsinit    proc    near
  6113.     mov    vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
  6114.     mov    vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
  6115.     mov    savflgs,vsdefaults
  6116.     mov    iniflgs,vsdefaults
  6117.     mov    insmod,0        ; turn off insert mode
  6118.     xor    dl,dl            ; Column 1 has no tab stop
  6119.     mov    si,vtemu.vttbs        ; from the cold-start buffer
  6120.     call    tabclr            ; clear that tabstop
  6121.     push    es
  6122.     push    ds
  6123.     pop    es
  6124.     cld
  6125.     mov    al,1            ; set tabs at columns 9, spaced by 8
  6126.     mov    cx,(swidth-1)/8        ; bytes to do, at 8 bits/byte
  6127.     mov    di,offset deftabs+1    ; starting byte for column 9 (1...)
  6128.     rep    stosb
  6129.     xor    al,al            ; get a zero
  6130.     mov    cx,slen            ; clear linetype array
  6131.     mov    di,offset linetype
  6132.     rep    stosb
  6133.     mov    cx,slen
  6134.     mov    di,offset linescroll    ; clear horiz scroll per line
  6135.     rep    stosb
  6136.     pop    es
  6137.     mov    vtemu.vttbst,offset tabs ; addrs of active tabs for STATUS
  6138.     mov    vtemu.vttbs,offset deftabs  ; addrs of tabs for setup (SET)
  6139.     call    cpytabs            ; copy default to active
  6140.     mov    vtemu.att_ptr,offset att_normal  ; ptr to video attributes
  6141.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  6142.     sub    ah,8            ; place marker 9 columns from margin
  6143.     mov    belcol,ah        ; store column number to ring bell
  6144.     ret
  6145. vsinit    endp
  6146.  
  6147. ; Initialization routine.
  6148. ; Enter with dl = index for baud rate table
  6149. ; dh = parity in bits 4-7, number of data bits in bits 0-3
  6150. ansini    proc    near
  6151.     mov    ax,vtemu.vtflgst    ; setup flags
  6152.     mov    vtemu.vtflgop,ax
  6153.     mov    iniflgs,ax
  6154.     mov    savflgs,ax
  6155.     mov    ax,flags.vtflg        ; get current terminal type
  6156.     cmp    ax,tttek        ; non-text?
  6157.     je    ansin3            ; e = yes
  6158.     mov    oldterm,ax        ; remember it here for soft restarts
  6159. ansin3:    mov    anspflg,0        ; clear printing flag
  6160.     mov    al,byte ptr low_rgt    ; right most column (counted from 0)
  6161.     sub    al,8            ; place marker 9 columns from margin
  6162.     mov    belcol,al        ; store column number to ring bell
  6163.     cmp    dl,lbaudtab        ; out of range index?
  6164.     jb    ansin1            ; b = no, store it
  6165.     mov    dl,lbaudtab-2        ; yes, make it the maximum (128)
  6166. ansin1: mov    baudidx,dl        ; save baud rate index
  6167.     mov    al,dh            ; get parity/number of databits
  6168.     and    al,0FH            ; isolate number of databits
  6169.     mov    datbits,al        ; save
  6170.     mov    cl,4
  6171.     shr    dh,cl            ; isolate parity code
  6172.     cmp    dh,lpartab        ; out of range code?
  6173.     jb    ansin2            ; b = no, store it
  6174.     mov    dh,lpartab-1        ; make it the maximum
  6175. ansin2: mov    parcode,dh        ; save
  6176.     mov    cx,low_rgt
  6177.     mov    oldscrn,cx        ; remember old screen dimensions
  6178.     jmp    atreset            ; reset everything
  6179. ansini    endp
  6180.  
  6181. atxreset proc    near            ; Reset via host command
  6182.     cmp    nparam,0        ; need no Parameters, no Intermediates
  6183.     jne    atxres1            ; ne = not a reset
  6184.     cmp    ninter,0        ; any intermediates?
  6185.     je    atreset            ; e = none, it is a reset
  6186. atxres1:ret                ; ignore command
  6187. atxreset endp
  6188.  
  6189. atreset    proc    near            ; Reset-everything routine
  6190.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  6191.     jnz    atres9
  6192.     test    tekflg,tek_sg         ; special graphics active?
  6193.     jz    atres9            ; z = no
  6194.     call    tekend            ; exit special graphics
  6195. atres9:    mov    ax,apcstring        ; seg of apcmacro memory area
  6196.     or    ax,ax            ; empty?
  6197.     jz    atres10            ; z = yes
  6198.     mov    es,ax
  6199.     mov    ah,freemem
  6200.     int    dos            ; free that memory
  6201. atres10:mov    apcstring,0
  6202.     mov    bracecount,0        ; APC-macro worker variables
  6203.     mov    cursor,0        ; cursor is at 0,0
  6204.     mov    havesaved,0        ; unmark saved cursor section
  6205.     mov    al,1            ; assume underline cursor
  6206.     test    vtemu.vtflgst,vscursor    ; kind of cursor in setup
  6207.     jnz    atres0            ; nz = underline
  6208.     inc    al            ; else say block
  6209. atres0:    mov    atctype,al        ; VTxxx cursor type
  6210.     mov    h19cur,0        ; Heath-19 saved cursor
  6211.     mov    dspstate,0        ; saved modeline state
  6212.     call    udkclear        ; clear User Definable Key contents
  6213.     push    vtemu.vtflgst        ; setup flags
  6214.     pop    vtemu.vtflgop        ; operational flags
  6215.     mov    decrlm,0        ; host writing direction to left-right
  6216.     and    vtemu.vtflgop,not vscntl ; assume no 8-bit controls
  6217.     mov    ax,oldterm        ; get terminal at entry time
  6218.     or    ax,ax            ; inited yet? (initing Tek too)
  6219.     jnz    atres0a            ; nz = yes
  6220.     mov    ax,ttvt320        ; pretend initing VT320
  6221.     jmp    short atres0b
  6222. atres0a:mov    flags.vtflg,ax        ; use it again
  6223. atres0b:test    ax,ttvt102+ttvt100+tthoney+ttpt200 ; VT100 class?
  6224.     jnz    atres1            ; nz = yes, turn on ansi mode
  6225.     test    ax,ttvt320+ttvt220    ; VT320/VT220?
  6226.     jz    atres1a            ; z = no, no ansi, no 8-bit controls
  6227.     test    vtemu.vtflgst,vscntl    ; want 8-bit controls?
  6228.     jz    atres1            ; z = no
  6229.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  6230. atres1:    or    vtemu.vtflgop,decanm    ; turn on ANSI mode
  6231. atres1a:mov    mar_top,0        ; reset scrolling region
  6232.     mov    ax,low_rgt        ; virtual screen lower right corner
  6233.     mov    mar_bot,ah        ; logical bottom of screen
  6234.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  6235.     jz    atres1d            ; z = no
  6236.     mov    al,79            ; trim to 80 col screen
  6237. atres1d:mov    mar_right,al        ; logical right edge of screen
  6238.     mov    mar_left,0        ; DG left/right margins
  6239.     mov    old8bit,-1        ; flags.remflg d8bit status, clear
  6240.     xor    al,al            ; ax is top/bottom margin
  6241.     mov    dgwindow,ax        ; init to first window to full screen
  6242.     mov    dgwindcnt,1        ; DG window count, 1 = full screen
  6243.     mov    cx,25
  6244.     xor    bx,bx
  6245. atres1i:mov    dgwindcomp[bx],al    ; set lines to uncompressed
  6246.     inc    bx
  6247.     loop    atres1i
  6248.     xor    ax,ax
  6249.     mov    savdgmar,ax        ; clear DG saved margins
  6250.     mov    protectena,al        ; disable protected fields
  6251.     mov    blinkdis,al        ; disable blink disable
  6252.     mov    dgroll,1        ; DG roll enabled
  6253.     mov    dgaltid,ax        ; DG alternate model id, clear it
  6254.     mov    dghscrdis,al        ; DG horz scroll disable is disabled
  6255.     mov    cx,16
  6256.     xor    bx,bx
  6257. atres1e:mov    dgcursave[bx],ax    ; clear DG cursor named save area
  6258.     add    bx,2
  6259.     loop    atres1e
  6260.     mov    cx,slen/2
  6261.     xor    bx,bx
  6262. atres1f:mov    word ptr linescroll[bx],ax ; clear DG per line horiz scroll
  6263.     add    bx,2
  6264.     loop    atres1f
  6265.     mov    dgnum,ax        ; DG worker word, to be safe
  6266.     call    dgcrossoff        ; DG turn off crosshair
  6267.     mov    dgcross,al        ; DG crosshair activity, off
  6268.     mov    dglinepat,0ffffh    ; DG line pattern, default all dots
  6269.     mov    dgcaller,offset atign    ; DG default callback, ignorance
  6270.     mov    numdigits,al        ; more DG stuff
  6271.     mov    param[0],ax        ; setup call to atleds
  6272.     xor    si,si
  6273.     call    atleds            ; clear the LED indicators
  6274.     call    cpytabs            ; initialize tab stops
  6275.     test flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttd463+ttd470
  6276.     jz    atres1c            ; z = no
  6277.     mov    al,vtemu.vtchset    ; setup char set
  6278.     cmp    al,1            ; in range for NRCs?
  6279.     jb    atres1c            ; b = no
  6280.     cmp    al,13            ; highest NRC ident?
  6281.     ja    atres1c            ; a = not NRC
  6282.     or    vtemu.vtflgop,vsnrcm    ; set NRC flag bit to activate NRCs
  6283. atres1c:mov    vtemu.vtchop,al        ; remember char set
  6284.     call    chrdef            ; set default character sets
  6285.     call    vtbell            ; ring bell like VT100
  6286.     cmp    flags.modflg,2        ; mode line owned by host?
  6287.     jne    atres1h            ; ne = no
  6288.     mov    flags.modflg,1        ; say now owned by us
  6289. atres1h:xor    ax,ax            ; not exiting connect mode, 80 col
  6290.     test    vtemu.vtflgst,deccol    ; need 132 columns?
  6291.     jz    atres1g            ; z = no, use 80 columns
  6292.     inc    al            ; say set 132 column mode
  6293. atres1g:call    chgdsp            ; call Change Display proc in msy
  6294.     and    vtemu.vtflgop,not deccol; assume mode is reset (80 cols)
  6295.     cmp    byte ptr low_rgt,79    ; is screen narrow now?
  6296.     jbe    atres2            ; be = yes
  6297.     or    vtemu.vtflgop,deccol    ; set the status bit
  6298.  
  6299.                     ; ATRES2 used in 80/132 col resetting
  6300. ATRES2:    mov    cx,slen            ; typically 24 but do max lines
  6301.     xor    di,di
  6302.     xor    al,al
  6303. atres3:    mov    linetype[di],al        ; clear the linetype array to single
  6304.     mov    linescroll[di],al    ; horizontal scroll per line
  6305.     inc    di
  6306.     loop    atres3
  6307.            mov    ah,att_normal        ; get present normal coloring
  6308.     test    vtemu.vtflgop,vsscreen    ; want reverse video?
  6309.     jz    atres4            ; z = no
  6310.     call    revideo            ; reverse them
  6311. atres4:    mov    scbattr,ah        ; set background attributes
  6312.     mov    curattr,ah        ; and cursor attributes
  6313.     mov    extattr,0        ; no reverse video, no underline
  6314.     mov    dx,cursor        ; get cursor
  6315.     call    atsetcur        ; set cursor
  6316.     call    atsctyp            ; set right cursor type
  6317.     xor    ax,ax            ; starting location
  6318.     mov    bx,low_rgt        ; ending location
  6319.     call    vtsclr            ; clear the whole screen
  6320.     cmp    flags.modflg,1        ; mode line on and owned by us?
  6321.     jne    atres5            ; ne = no, leave it alone
  6322.     test    yflags,modoff        ; mode line supposed to be off?
  6323.     jnz    atres5            ; nz = yes
  6324.     push    dx
  6325.     call    fmodlin            ; write normal mode line
  6326.     pop    dx
  6327. atres5:    test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  6328.     jz    atres6            ; z = no
  6329.     or    vtemu.vtflgop,decawm    ; Autowrap active
  6330.     or    vtemu.vtflgst,decawm    ; Autowrap active
  6331. atres6:    call    atpclr            ; clear parser work area
  6332.     xor    ax,ax
  6333.     mov    parstate,ax        ; reset parser
  6334.     mov    emubufc,ax        ; clear work buffer
  6335.     mov    atwrap,al        ; clear wrap flag
  6336.     mov    SSptr,ax        ; clear single shift flag
  6337.     mov    insmod,al        ; reset insert mode
  6338.     mov    h19stat,al        ; clear heath extended status byte
  6339.     mov    h19ctyp,1        ; Heath-19 cursor to underline
  6340.     mov    anspflg,al        ; clear printer flag
  6341.     call    atsc            ; save cursor information
  6342.     jmp    atnorm            ; set normal state
  6343. atreset    endp
  6344.  
  6345. ; Re-initialization routine. Called when Term was called but screen was
  6346. ; restored from a previously saved screen, etc.
  6347. ansrei    proc    near
  6348.     mov    dx,cursor
  6349.     call    atsctyp            ; set cursor type [rbv]
  6350.     mov    ax,vtemu.vtflgst    ; setup
  6351.     or    ax,vtemu.vtflgop    ; operational
  6352.     test    ax,deccol        ; want 80 columns?
  6353.     jnz    ansre2            ; nz = no
  6354.     cmp    byte ptr low_rgt,79    ; want 80 cols. Is active screen wider?
  6355.     jbe    ansre2            ; be = no
  6356.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  6357.     and    vtemu.vtflgop,not deccol
  6358. ansre2:    jmp    stblmds            ; check settable modes, set flags
  6359. ansrei    endp
  6360.  
  6361. ; This routine checks to see whether any of the settable modes have changed
  6362. ; (things that can be changed in both SETUP and by host commands), and
  6363. ; changes those that need to be changed.  TMPFLAGS has the new VT100 setup
  6364. ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
  6365. ; Revised to allow MSY to reset scbattr when not in connect mode,
  6366. ; to do "soft reset" if terminal type has changed, and to do a screen clear
  6367. ; reset if the actual screen colors have changed.
  6368.  
  6369. stblmds proc    near
  6370.     mov    ax,flags.vtflg        ; get current terminal type
  6371.     cmp    ax,tttek        ; non-text?
  6372.     je    stblm10            ; e = yes
  6373.     cmp    ax,oldterm        ; same as before?
  6374.     je    stblm10            ; e = yes, skip over soft reset
  6375.     mov    oldterm,ax        ; remember current terminal type
  6376.     mov    insmod,0        ; reset insert mode flag
  6377.     and    iniflgs,not vsnrcm    ; turn off NRC bit from last time
  6378.     mov    mar_top,0        ; reset top scrolling margin
  6379.     mov    al,byte ptr low_rgt+1    ; and scrolling margin
  6380.     mov    mar_bot,al        ; to last normal line on screen
  6381.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  6382.     sub    ah,8            ; place marker 9 columns from margin
  6383.     mov    belcol,ah        ; store column number to ring bell
  6384.     push    es
  6385.     push    ds
  6386.     pop    es
  6387.     xor    al,al            ; get a zero
  6388.     mov    di,offset linetype    ; line type to single width chars
  6389.     mov    cx,slen            ; screen length
  6390.     cld
  6391.     rep    stosb            ; clear
  6392.     mov    di,offset linescroll    ; line horizontal scroll to none
  6393.     mov    cx,slen
  6394.     rep    stosb
  6395.     pop    es
  6396.     and    vtemu.vtflgop,not decanm
  6397.     test    flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttpt200
  6398.     jz    stblm10            ; z = no, not ansi class
  6399.     or    vtemu.vtflgop,decanm    ; set ansi flag bit
  6400.  
  6401. stblm10:test    flags.vtflg,ttd463+ttd470 ; D463/D470?
  6402.     jz    stblm10a        ; z = no
  6403.     mov    cx,24            ; emulation screen lines
  6404.     xor    al,al
  6405.     xor    bx,bx
  6406. stblm10b:or    al,dgwindcomp[bx]    ; is any line compressed (!= 0)?
  6407.     inc    bx            ; if so remember as non-zero
  6408.     loop    stblm10b
  6409.     or    al,al            ; found any compressed lines?
  6410.     jz    stblm10e        ; z = no
  6411.     test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  6412.     jnz    stblm10d        ; nz = no, use 132 column text mode
  6413.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  6414.     jnz    stblm10e        ; nz = yes
  6415. stblm10c:call    dgsettek        ; setup special graphics mode
  6416.     jmp    short stblm10e
  6417. stblm10d:mov    al,3            ; prep call on atrsm6, 132/80 col
  6418.     mov    modeset,1        ; say want 132 columns
  6419.     call    atrsm6            ; common worker
  6420.     cmp    byte ptr low_rgt,79
  6421.     jbe    stblm10c        ; did not work, use graphics anyway
  6422. stblm10e:mov    al,flags.remflg        ; get 7/8 bit configuration
  6423.     and    al,d8bit        ; select the control bit
  6424.     cmp    old8bit,al        ; changed?
  6425.     je    stblm10a        ; e = no
  6426.     mov    old8bit,al        ; save new state
  6427.     mov    vtemu.vtchop,-1        ; force change below
  6428. stblm10a:mov    al,vtemu.vtchset    ; setup character set
  6429.     cmp    al,vtemu.vtchop        ; operational character set
  6430.     je    stblm3            ; e = same, no changes needed
  6431.     mov    vtemu.vtchop,al        ; remember this set
  6432.     and    vtemu.vtflgop,not vsnrcm ; clear NRC active bit
  6433.     and    vtemu.vtflgst,not vsnrcm
  6434.     cmp    al,1            ; in range for NRC?
  6435.     jb    stblm11            ; b = no
  6436.     cmp    al,13            ; above NRCs?
  6437.     ja    stblm11            ; a = yes
  6438.     or    vtemu.vtflgop,vsnrcm    ; set NRC active bit
  6439.     or    vtemu.vtflgst,vsnrcm
  6440.     and    vtemu.vtflgop,not vscntl ; no 8-bit controls
  6441. stblm11:call    chrdef            ; init char sets
  6442.  
  6443. stblm3:    test    vtemu.vtflgst,vswdir    ; writing direction set?
  6444.     jz    stblm3c            ; z = no
  6445.     mov    decrlm,0        ; yes, suppress host indicator
  6446. stblm3c:mov    ax,iniflgs        ; flags at last entry
  6447.     xor    ax,vtemu.vtflgst    ; find which setup ones have changed
  6448.     test    ax,deccol        ; screen width?
  6449.     jz    stblm3b            ; z = no, don't touch it
  6450.     mov    ax,vtemu.vtflgst    ; Setup bits
  6451.     and    ax,deccol        ; select screen width
  6452.     and    vtemu.vtflgop,not deccol ; clear operational flag bit
  6453.     or    vtemu.vtflgop,ax    ; set current width desired
  6454.     or    al,ah            ; collapse all bits
  6455.     mov    modeset,al        ; non-zero if 132 columns
  6456.     mov    al,3            ; setup call to atrsm6
  6457.     call    atrsm6            ; adjust display width
  6458.  
  6459. stblm3b:cmp    vtclear,1        ; screen need updating?
  6460.     mov    vtclear,0        ; preserves cpu status bits
  6461.     jb    stblm9            ; b = no
  6462.     ja    stblm3a            ; 2 or more means do a reset
  6463.     mov    ah,att_normal        ; 1, get new normal attributes setting
  6464.     mov    scbattr,ah        ; store new values
  6465.     mov    curattr,ah
  6466.     jmp    short stblm9
  6467. stblm3a:mov    cursor,0        ; reset cursor position
  6468.     jmp    atres2            ; go to semi-reset
  6469.  
  6470.                     ; check on screen normal/reversed
  6471. stblm9:    mov    ax,iniflgs        ; flags at last entry
  6472.     xor    ax,vtemu.vtflgst    ; find which setup ones have changed
  6473.     test    ax,vsscreen        ; screen background?
  6474.     jz    stblm8            ; z = no, don't touch it
  6475.     test    vtemu.vtflgop,vsscreen    ; reverse video flag set?
  6476.     jnz    stblm5            ; nz = yes, do it
  6477.     and    vtemu.vtflgop,not vsscreen ; cleared (normal video)
  6478.     jmp    short stblm6        ; reverse everything
  6479. stblm5: or    vtemu.vtflgop,vsscreen    ; set (reverse video)
  6480. stblm6: call    atrss2            ; reverse screen and cursor attribute
  6481.     push    es
  6482.     mov    ax,seg data1
  6483.     mov    es,ax
  6484.     mov    ah,scbattr        ; reset saved attribute also
  6485.     mov    es:savecu+svattr_index,ah
  6486.     pop    es
  6487. stblm8:    cmp    flags.modflg,2        ; mode line enabled and owned by host?
  6488.     je    stblm9a            ; e = yes, leave it alone
  6489.     call    fclrmod            ; clear the mode line
  6490.     test    yflags,modoff        ; mode line supposed to be off?
  6491.     jnz    stblm9a            ; nz = yes
  6492.     call    fmodlin            ; write normal mode line
  6493.     and    yflags,not modoff    ; say modeline is not toggled off
  6494. stblm9a:mov    dx,cursor        ; logical cursor
  6495.     push    dx
  6496.     call    direction        ; set cursor for writing direction
  6497.     call    setpos            ; set the cursor physical position
  6498.     pop    dx
  6499.     push    vtemu.vtflgst
  6500.     pop    iniflgs            ; remember setup flags at this entry
  6501.     call    frepaint
  6502.     ret
  6503. stblmds endp
  6504.  
  6505. ; Routine called when something is typed on the keyboard
  6506.  
  6507. anskbi    proc    near
  6508.     mov    ttkbi,0FFH        ; just set a flag
  6509.     ret
  6510. anskbi    endp
  6511.  
  6512.  
  6513. ; This routine copies the new tab stops when they have changed.
  6514. ; Copies all 132 columns.
  6515. cpytabs proc    near
  6516.     mov    cx,(swidth+7)/8        ; number of bytes in screen width
  6517.     jcxz    cpytab1            ; z = none to do
  6518.     mov    si,offset deftabs    ; source is setup array
  6519.     mov    di,offset tabs        ; destination is active array
  6520.     push    es            ; save es
  6521.     push    ds
  6522.     pop    es            ; set es to data segment
  6523.     cld
  6524.     rep    movsb            ; do the copy
  6525.     pop    es            ; recover es
  6526. cpytab1:ret
  6527. cpytabs endp
  6528.  
  6529. ; Routine to toggle between text and Tek graphics modes. No arguments.
  6530. ; Text terminal type remembered in byte OLDTERM.
  6531. ans52t    proc    FAR
  6532.     mov    ax,flags.vtflg
  6533.     cmp    ax,tttek        ; in Tek mode now?
  6534.     je    ans52b            ; e = yes, exit Tek mode
  6535.     test    tekflg,tek_active    ; doing Tek sub mode?
  6536.     jnz    ans52b            ; nz = yes
  6537.     test    ax,ttd463+ttd470    ; DG 463/D470?
  6538.     jnz    ans52e            ; nz = yes, go into DG graphics mode
  6539.     test    denyflg,tekxflg        ; is Tek mode disabled?
  6540.     jnz    ans52a            ; nz = yes, disabled
  6541.     mov    oldterm,ax        ; save text terminal type here
  6542.     call    atsc            ; save cursor and associated data
  6543.     mov    flags.vtflg,tttek    ; set Tek mode
  6544.     mov    tekflg,tek_tek        ; not a sub mode
  6545.     call    tekini            ; init Tek to switch screens
  6546. ans52a:    call    atnorm
  6547.     ret
  6548.  
  6549. ans52b:    call    tekend            ; exit Tek graphics mode
  6550.     mov    ax,oldterm
  6551.     or    ax,ax            ; inited yet?
  6552.     jnz    ans52c            ; nz = yes
  6553.     mov    ax,ttvt320        ; fall back for initing
  6554. ans52c:    mov    flags.vtflg,ax        ; say text terminal now
  6555.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  6556.     jnz    ans52f            ; nz = yes, cursor is ok already
  6557.     call    atrc            ; restore cursor etc
  6558.     call    atsc            ; save cursor etc
  6559. ans52f:    mov    tekflg,0        ; say not doing tek submode now
  6560.     mov    al,atctype
  6561.     call    atsctyp            ; set correct cursor type
  6562.     test    yflags,modoff        ; is mode line off?
  6563.     jnz    ans52d            ; nz = yes
  6564.     push    dx            ; save cursor position
  6565.     call    frepaint        ; restore text screen
  6566.     call    fmodlin            ; write mode line
  6567.     pop    dx
  6568. ans52d:    call    atnorm
  6569.     ret
  6570.                     ; DG D473 graphics mode entry
  6571. ans52e:    mov    oldterm,ax        ; save text terminal type here
  6572.     call    dgsettek        ; switch to DG graphics
  6573.     jmp    short ans52d
  6574. ans52t    endp
  6575.  
  6576. ;  Honeywell VIP 3.1 i.d. string [FD]
  6577. athoney proc    near
  6578.     cmp    flags.vtflg,tthoney    ; Honeywell mode?
  6579.     jne    athone3            ; ne = no, ignore
  6580.     mov    ttyact,0        ; group for networks
  6581.     mov    cx,VIPstrl        ; length of string
  6582.     mov    si,offset VIPstr    ; ptr to string
  6583.     cld
  6584. athone1:lodsb                ; get a byte
  6585.     push    cx            ; save regs
  6586.     push    si
  6587.     call    prtbout            ; print WITHOUT echo
  6588.     pop    si
  6589.     pop    cx
  6590.     cmp    cx,1            ; last char?
  6591.     ja    athone2            ; a = not yet
  6592.     mov    ttyact,1        ; end of network grouping
  6593. athone2:loop    athone1            ; loop for all characters
  6594. athone3:jmp    atnorm
  6595. athoney endp
  6596.  
  6597. athoncls proc    near            ; Honeywell ESC accent  screen clear
  6598.     cmp    nparam,0        ; absence of parameters?
  6599.     jne    athoncl1        ; ne = no, fail
  6600.     cmp    ninter,0        ; any intermediates?
  6601.     jne    athoncl2        ; ne = yes, not this item
  6602.     cmp    flags.vtflg,tthoney    ; doing Honeywell emulation?
  6603.     jne    athoncl1        ; ne = no
  6604.     xor    dx,dx            ; move cursor to Home position
  6605.     call    ereos            ; erase to end of screen
  6606.     xor    dx,dx
  6607.     jmp    atsetcur        ; set cursor and return
  6608. athoncl1:ret
  6609. athoncl2:jmp    atdgnrc            ; try Norwegian/Danish NRC designation
  6610. athoncls endp
  6611.  
  6612.     ; Data General D463/D470 support routines
  6613.  
  6614.                     ; Data General mode C0 control codes
  6615. dgctrl    proc    near
  6616.     test    anspflg,vtcntp        ; printing desired?
  6617.     jz    dgctrl1            ; z = no
  6618.     call    fpntchr            ; print char in al
  6619. dgctrl1:and    ax,001fh        ; clear for word use below
  6620.     mov    di,ax            ; use AL as a word index
  6621.     shl    di,1
  6622.     jmp    dgc0[di]        ; dispatch on DG C0 control codes
  6623. dgctrl    endp
  6624.  
  6625. ; Consume ESC ... Final 
  6626. dgansi    proc    near
  6627.     mov    ttstate,offset dgansi1    ; come here til end or break
  6628.     ret
  6629. dgansi1:cmp    al,20h            ; control code?
  6630.     jb    dgansi2            ; b = yes, break
  6631.     cmp    al,'['            ; end of ANSI escape sequence part?
  6632.     je    dgansi2            ; e = yes, get parms, intermediates
  6633.     cmp    al,40h            ; parameters, intermediates?
  6634.     jae    dgansi3            ; ae = no, consider it to be a final
  6635. dgansi2:ret                ; else stay in this state
  6636. dgansi3:jmp    atnorm            ; reset state to normal
  6637. dgansi    endp
  6638.  
  6639. dgesc    proc    near            ; Parse Data General RS commands
  6640.     mov    dgnum,0            ; clear numerical result
  6641.     mov    ttstate,offset dgesc1    ; set up to get next char
  6642.     ret
  6643. dgesc1:    mov    bx,offset dgesctab    ; dispatch table
  6644.     mov    ttstate,offset atnrm    ; reset state
  6645.     jmp    atdispat        ; dispatch on char in AL
  6646. dgesc    endp
  6647.  
  6648. ; Parse RS F/G <letter><DGnumber>(repeated)
  6649. ; F/G has been read, letter is next
  6650. dgFSERIES:mov    ttstate,offset Fdisp    ; dispatcher for incoming RS F
  6651.     ret
  6652. Fdisp:    mov    ttstate,offset atnrm    ; normal state
  6653.     mov    bx,offset fltable    ; table of letters
  6654.     jmp    atdispat        ; dispatch to action routine
  6655.  
  6656. dgGSERIES:mov    ttstate,offset Gdisp    ; dispatcher for incoming RS G
  6657.     ret
  6658. Gdisp:    mov    ttstate,offset atnrm    ; normal state
  6659.     mov    bx,offset gltable    ; table of letters
  6660.     jmp    atdispat        ; dispatch to action routine
  6661.  
  6662. dgRSERIES:mov    ttstate,offset Rdisp    ; dispatcher for incoming RS R
  6663.     ret
  6664. Rdisp:    mov    ttstate,offset atnrm    ; normal state
  6665.     mov    bx,offset rltable    ; table of letters
  6666.     jmp    atdispat        ; dispatch to action routine
  6667.  
  6668. ; DG <n>,<nn>,<nnn> processors. Enter with BX holding callback address.
  6669. ; Returns number in dgnum and resets state to atnrm.
  6670.                     ; get one DG numeric
  6671. get1n:    mov    ttstate,offset getnum    ; worker routine
  6672.     mov    dgnum,0            ; clear numerical result
  6673.     mov    numdigits,1        ; wanted qty of digits
  6674.     mov    dgcaller,bx        ; call back address
  6675.     ret
  6676.                     ; get two DG hex digits
  6677. get2n:    mov    ttstate,offset getnum    ; worker routine
  6678.     mov    dgnum,0            ; clear numerical result
  6679.     mov    numdigits,2        ; wanted qty of digits
  6680.     mov    dgcaller,bx        ; call back address
  6681.     ret
  6682.                     ; get three DG hex digits
  6683. get3n:    mov    ttstate,offset getnum    ; worker routine
  6684.     mov    dgnum,0            ; clear numerical result
  6685.     mov    numdigits,3        ; wanted qty of digits
  6686.     mov    dgcaller,bx        ; call back address
  6687.     ret
  6688.  
  6689. get3loc:mov    ttstate,offset getloc    ; get three DG Location digits
  6690.     mov    dgnum,0
  6691.     mov    numdigits,3
  6692.     mov    dgcaller,bx
  6693.     ret
  6694.  
  6695. getloc    proc    near
  6696.     mov    bl,numdigits        ; number of digits remaining
  6697.     xor    bh,bh
  6698.     or    al,al            ; is it truely null (RS L cmd stuff)?
  6699.     jz    getloc3            ; z = yes, exit now
  6700.     and    al,00011111b        ; keep only five lower bits
  6701.     mov    emubuf[bx],al        ; save byte
  6702.     dec    numdigits        ; say one more digit done
  6703.     dec    bx
  6704.     or    bx,bx            ; done all?
  6705.     jz    getloc1            ; z = yes
  6706.     ret                ; else stay in state getloc
  6707. getloc1:mov    cx,3            ; three digits
  6708. getloc2:mov    bx,cx
  6709.     mov    al,emubuf[bx]        ; stored in reverse order
  6710.     push    cx
  6711.     mov    bx,dgnum        ; get current value
  6712.     mov    cl,5
  6713.     shl    bx,cl            ; times 32
  6714.     add    bl,al            ; add current digit
  6715.     adc    bh,0
  6716.     mov    dgnum,bx        ; keep result
  6717.     pop    cx
  6718.     loop    getloc2
  6719.     clc                ; clear carry to say not null term
  6720.     jmp    short getloc4
  6721.  
  6722. getloc3:stc                ; set carry to say ended on NULL
  6723. getloc4:mov    bx,dgcaller        ; get callback address
  6724.     mov    dgcaller,offset atign    ; reset default DG callback processor
  6725.     mov    ttstate,offset atnrm    ; set normal state
  6726.     jmp    bx            ; go to callback address
  6727. getloc    endp
  6728.  
  6729. ; Return binary number in dgnum. When done it resets state to atnrm, 
  6730. ; clears callback address. Note that this proc accepts ALL bytes and uses
  6731. ; only the four lower bits, regardless of what the DG manuals suggest.
  6732. getnum    proc    near
  6733.     and    al,0fh            ; keep lower four bits
  6734.     mov    cl,4
  6735.     mov    bx,dgnum        ; get current value
  6736.     shl    bx,cl            ; times 16
  6737.     and    al,0fh            ; keep lower four bits
  6738.     add    bl,al            ; add current digit
  6739.     adc    bh,0
  6740.     mov    dgnum,bx        ; keep result
  6741.     dec    numdigits        ; say one more digit done
  6742.     cmp    numdigits,0        ; done all?
  6743.     jz    getnum2            ; z = yes
  6744.     ret                ; else stay in this state
  6745. getnum2:mov    bx,dgcaller        ; get callback address
  6746.     mov    dgcaller,offset atign    ; reset default DG callback processor
  6747.     mov    ttstate,offset atnrm    ; set normal state
  6748.     jmp    bx            ; go to callback address
  6749. getnum    endp
  6750.  
  6751. out2n    proc    near            ; send <nn> report from value in AL
  6752.     push    cx
  6753.     mov    ch,al            ; preserve a copy
  6754.     mov    cl,4
  6755.     shr    al,cl            ; get high nibble
  6756.     and    al,0fh
  6757.     add    al,'0'            ; ascii bias
  6758.     call    prtbout
  6759.     mov    al,ch            ; recover copy
  6760.     and    al,0fh            ; get low nibble
  6761.     add    al,'0'
  6762.     call    prtbout
  6763.     pop    cx
  6764.     ret
  6765. out2n    endp
  6766.  
  6767. out2na    proc    near            ; send <nn> report from value in AL
  6768.     push    cx
  6769.     mov    ch,al            ; preserve a copy
  6770.     mov    cl,4
  6771.     shr    al,cl            ; get high nibble
  6772.     and    al,0fh
  6773.     add    al,'@'            ; ascii bias
  6774.     call    prtbout
  6775.     mov    al,ch            ; recover copy
  6776.     and    al,0fh            ; get low nibble
  6777.     add    al,'@'
  6778.     call    prtbout
  6779.     pop    cx
  6780.     ret
  6781. out2na    endp
  6782.  
  6783. dgign1n    proc    near            ; ignore a <n> command
  6784.     mov    bx,offset atnorm    ; ignore the <n>
  6785.     jmp    get1n
  6786. dgign1n    endp
  6787.  
  6788. dgign2n    proc    near            ; ignore a <nn> command
  6789.     mov    bx,offset atnorm    ; ignore the <nn>
  6790.     jmp    get2n
  6791. dgign2n    endp
  6792.  
  6793. dgprtfm    proc    near            ; Control-A  DG print form
  6794.     mov    cursor,dx        ; save cursor location
  6795. dgprtf1:mov    dl,mar_right        ; start at right margin
  6796.     mov    cl,dl
  6797.     sub    cl,mar_left        ; minus left
  6798.     inc    cl
  6799.     xor    ch,ch            ; number of columns to do
  6800. dgprtf3:push    cx
  6801.     call    dgprta            ; get char which would be printed
  6802.     pop    cx
  6803.     cmp    al,' '            ; space?
  6804.     jne    dgprtf4            ; ne = no, end scan here
  6805.     dec    dl            ; scan backward another column
  6806.     loop    dgprtf3
  6807. dgprtf4:jcxz    dgprtf6            ; z = empty line
  6808.     mov    dl,mar_left        ; start at left margin
  6809. dgprtf5:push    cx
  6810.     push    dx
  6811.     call    dgprta            ; get printable
  6812.     call    fpntchr            ; print char in al
  6813.     pop    dx
  6814.     pop    cx
  6815.     jc    dgprtf7            ; c = printer error
  6816.     inc    dl
  6817.     loop    dgprtf5            ; do count
  6818.  
  6819. dgprtf6:mov    al,CR            ; line terminator for printer
  6820.     push    dx
  6821.     call    fpntchr
  6822.     pop    dx
  6823.     jc    dgprtf7            ; c = printer error
  6824.     mov    al,LF
  6825.     push    dx
  6826.     call    fpntchr
  6827.     pop    dx
  6828.     jc    dgprtf7            ; c = printer error
  6829.     inc    dh            ; next row down
  6830.     cmp    dh,mar_bot        ; below window now?
  6831.     jbe    dgprtf1            ; be = no
  6832. dgprtf7:mov    al,6            ; Control-F to host when done
  6833.     call    prtbout            ; output, no echo
  6834.     mov    dx,cursor
  6835.     ret
  6836. dgprtfm    endp
  6837.  
  6838. dgprta    proc    near            ; worker, report printable char at dx
  6839.     call    getatch            ; read char (al) and attribute (ah)
  6840.     cmp    protectena,0        ; protected mode enabled
  6841.     je    dgprta1            ; e = no
  6842.     test    cl,att_protect        ; protected mode?
  6843.     jnz    dgprta2            ; nz = yes, use a space
  6844.     ret                ; else use as-is
  6845. dgprta1:test    ah,att_bold        ; bold?
  6846.     jnz    dgprta3            ; nz = yes, use as-is
  6847. dgprta2:mov    al,' '            ; replace with space
  6848. dgprta3:ret
  6849. dgprta    endp
  6850.  
  6851. dgprtwn    proc    near            ; Control-Q  DG print window
  6852.     mov    cursor,dx        ; save cursor location
  6853. dgprtw1:mov    dl,mar_right        ; start at right margin
  6854.     mov    cl,dl
  6855.     sub    cl,mar_left
  6856.     inc    cl
  6857.     xor    ch,ch            ; number of columns to do
  6858. dgprtw3:push    cx
  6859.     call    dgprtb            ; get char which would be printed
  6860.     pop    cx
  6861.     cmp    al,' '            ; space?
  6862.     jne    dgprtw4            ; ne = no, end scan here
  6863.     dec    dl            ; scan backward another column
  6864.     loop    dgprtw3
  6865. dgprtw4:jcxz    dgprtw6            ; z = empty line
  6866.     mov    dl,mar_left        ; start at left margin
  6867. dgprtw5:push    cx
  6868.     push    dx
  6869.     call    dgprtb            ; get printable
  6870.     call    fpntchr            ; print char in al
  6871.     pop    dx
  6872.     pop    cx
  6873.     jc    dgprtw7            ; c = printer error
  6874.     inc    dl
  6875.     loop    dgprtw5            ; do count
  6876. dgprtw6:mov    al,CR            ; line terminator for printer
  6877.     push    dx
  6878.     call    fpntchr
  6879.     pop    dx
  6880.     jc    dgprtw7            ; c = printer error
  6881.     mov    al,LF
  6882.     push    dx
  6883.     call    fpntchr
  6884.     pop    dx
  6885.     jc    dgprtw7            ; c = printer error
  6886.     inc    dh            ; next row down
  6887.     cmp    dh,mar_bot        ; below window now?
  6888.     jbe    dgprtw1            ; be = no
  6889. dgprtw7:mov    al,6            ; Control-F to host when done
  6890.     call    prtbout            ; output, no echo
  6891.     mov    dx,cursor
  6892.     ret
  6893. dgprtwn    endp
  6894.  
  6895. dgprtb    proc    near            ; worker to yield printable char
  6896.     call    getatch            ; read char (al) and attribute (ah)
  6897.     test    al,80h            ; high bit set?
  6898.     jnz    dgprtb1            ; nz = yes, use a space
  6899.     cmp    al,20h            ; in printables?
  6900.     ja    dgprtb2            ; a = yes
  6901. dgprtb1:mov    al,' '            ; replace with space
  6902. dgprtb2:ret
  6903. dgprtb    endp
  6904.  
  6905. dgrevidon:mov    ah,curattr        ; RS D  Control-V  reverse video on
  6906.     call    setrev            ; reverse video on
  6907.     mov    curattr,ah        ; store new attribute byte
  6908.     ret
  6909.  
  6910. dgrevidoff:mov    ah,curattr        ; RS E  Control-B  reverse video off
  6911.     call    clrrev            ; 2, reverse video off
  6912.     mov    curattr,ah        ; store new attribute byte
  6913.     ret
  6914.  
  6915. dgblkena:mov    blinkdis,0        ; Control-C  DG blink enable
  6916.     ret
  6917. dgblkdis:mov    blinkdis,1        ; Control-D  DG blink disable
  6918.     ret
  6919.  
  6920. dgblkon    proc    near            ; Control-N  DG Blink on
  6921.     cmp    blinkdis,0        ; disabled?
  6922.     jne    dgblkon1        ; ne = blink is disabled
  6923.     mov    ah,curattr        ; get current cursor attribute
  6924.     call    setblink        ; blink enable
  6925.     mov    curattr,ah        ; store new attribute byte
  6926. dgblkon1:ret
  6927. dgblkon    endp
  6928.  
  6929. dgblkoff proc    near            ; Control-O  DG Blink off
  6930.     mov    ah,curattr        ; get current cursor attribute
  6931.     call    clrblink        ;  blink disable
  6932.     mov    curattr,ah        ; store new attribute byte
  6933.     ret
  6934. dgblkoff endp
  6935.  
  6936. dgwinhome proc near            ; Control-H  DG window home
  6937.     mov    dl,mar_left        ; want to skip protected chars too
  6938.     mov    dh,mar_top
  6939.     mov    cursor,dx        ; remember for protected checking
  6940.     jmp    dgsetcur        ; do protected mode positioning
  6941. dgwinhome endp
  6942.  
  6943. dguson    proc    near            ; Control-T  DG underscoring on
  6944.     mov    ah,curattr        ; get current cursor attribute
  6945.     call    setunder
  6946.     mov    curattr,ah        ; store new attribute byte
  6947.     ret
  6948. dguson    endp
  6949.  
  6950. dgusoff    proc    near            ; Control-U  DG underscoring off
  6951.     mov    ah,curattr        ; get current cursor attribute
  6952.     call    clrunder
  6953.     mov    curattr,ah        ; store new attribute byte
  6954.     ret
  6955. dgusoff    endp
  6956.  
  6957. dgdimon    proc    near            ; Control-\  DG dim on
  6958.     mov    ah,curattr        ; get current cursor attribute
  6959.     call    clrbold
  6960.     mov    curattr,ah        ; store new attribute byte
  6961.     ret
  6962. dgdimon    endp
  6963.  
  6964. dgdimoff proc    near            ; Control-]  DG dim off
  6965.     mov    ah,curattr        ; get current cursor attribute
  6966.     call    setbold
  6967.     mov    curattr,ah        ; store new attribute byte
  6968.     ret
  6969. dgdimoff endp
  6970.  
  6971. dgsfc    proc    near            ; RS A <color>, set foreground color
  6972.     mov    ttstate,offset dgsfc1    ; state to get next char
  6973.     ret
  6974. dgsfc1:    mov    ttstate,offset atnrm    ; reset state
  6975.     test    flags.vtflg,ttd463    ; D463?
  6976.     jz    dgsfc2            ; z = no, D470
  6977.     mov    ah,curattr        ; current coloring
  6978.     test    al,0fh            ; setting to background?
  6979.     jnz    dgsfc1a            ; nz = no
  6980.     mov    cl,4
  6981.     rol    ah,cl            ; get background coloring
  6982. dgsfc1a:and    ah,0fh            ; keep foreground
  6983.     mov    dg463fore,ah        ; polygon foreground coloring
  6984.     ret
  6985. dgsfc2:    cmp    al,100            ; select ACM mode?
  6986.     je    dgsfc5            ; ne = no
  6987. dgsfc3:    and    al,0fh            ; keep lower 4 bits
  6988.     jz    dgsfc4            ; z = black
  6989.     xor    al,8            ; invert DG intensity bit
  6990.     jnz    dgsfc4
  6991.     or    al,8            ; pick up dark grey as second except'n
  6992. dgsfc4:    mov    ah,curattr
  6993.     and    ah,not 0Fh        ; remove foreground
  6994.     or    ah,al            ; set new foreground
  6995.     mov    ah,scbattr
  6996.     and    ah,not 0Fh
  6997.     or    ah,al
  6998.     mov    curattr,ah        ; save it
  6999.     mov    scbattr,ah
  7000.     ret
  7001. dgsfc5:    mov    ah,att_normal        ; get normal background colors
  7002.     mov    scbattr,ah
  7003.     mov    curattr,ah        ; set current to them
  7004. dgsfcx:    ret
  7005. dgsfc    endp
  7006.  
  7007. dgsbc    proc    near            ; RS B <color>, set background color
  7008.     mov    ttstate,offset dgsbc1    ; state to get next char
  7009.     ret
  7010. dgsbc1:    mov    ttstate,offset atnrm    ; reset state
  7011.     test    flags.vtflg,ttd463    ; D463?
  7012.     jnz    dgsbcx            ; nz = yes, ignore command
  7013.     cmp    al,100            ; select ACM mode?
  7014.     je    dgsbc2            ; e = yes
  7015.     and    al,0fh            ; mask out all but IBM PC background
  7016.     jz    dgsbc3            ; z = black
  7017.     and    al,7            ; remove IBM PC blinking bit
  7018.     mov    cl,4
  7019.     shl    al,cl            ; move bits to high nibble
  7020. dgsbc3:    mov    ah,curattr
  7021.     and    ah,0fh            ; remove background
  7022.     or    ah,al            ; set new background
  7023.     mov    curattr,ah        ; save it
  7024.     mov    ah,scbattr
  7025.     and    ah,0fh            ; remove background
  7026.     or    ah,al            ; set new background
  7027.     mov    scbattr,ah        ; save it
  7028.     ret
  7029. dgsbc2:    mov    ah,att_normal        ; get normal background colors
  7030.     mov    scbattr,ah        ; set current to them
  7031.     mov    curattr,ah        ; set current to them
  7032. dgsbcx:    ret
  7033. dgsbc    endp
  7034.  
  7035. dgeol    proc    near            ; Control-K DG erase cursor to eol
  7036.     mov    ax,dx            ; cursor position
  7037.     mov    bx,ax
  7038.     mov    bl,mar_right        ; end of line
  7039.     call    atsclr            ; erase from ax to bx
  7040.     ret
  7041. dgeol    endp
  7042.  
  7043. dgeeos    proc    near            ; RS F F  DG erase cursor to end/scrn
  7044.     jmp    erprot
  7045. dgeeos    endp
  7046.  
  7047. dgescn    proc    near            ; RS F E  DG erase from 0,0 to eos
  7048.     xor    dh,dh
  7049.     mov    dl,mar_left        ; left margin, top row
  7050.     call    dggetmar        ; get margins for this window
  7051.     call    atsetcur        ; set cursor
  7052.     mov    ah,curattr
  7053.     call    clrunder        ; clear underline attribute
  7054.     call    clrblink        ; clear blink
  7055.     call    setbold            ; aka clear dim
  7056.     call    clrrev            ; clear reverse video attribute
  7057.     mov    curattr,ah        ; and cursor attributes
  7058.     mov    extattr,0        ; clear extended attributes
  7059.     xor    ax,ax            ; erase from 0,0
  7060.     mov    bh,byte ptr low_rgt+1    ; to end of screen
  7061.     mov    bl,vswidth-1
  7062.     call    atsclr            ; clear screen
  7063.     ret
  7064. dgescn    endp
  7065.  
  7066. dgewin    proc    near            ; Control-L  DG erase window
  7067.     mov    ah,mar_top        ; from top line of window
  7068.     mov    bh,mar_bot        ; to bottom line of window
  7069.     mov    al,mar_left        ; left margin
  7070.     mov    bl,mar_right        ; right margin
  7071.     cmp    savdgmar,0        ; saved permanent margin?
  7072.     je    dgewin1            ; e = no, mar_left/right are permanent
  7073.     mov    al,byte ptr savdgmar    ; use permanent l/r margins
  7074.     mov    bl,byte ptr savdgmar+1
  7075. dgewin1:call    atsclr            ; clear the area
  7076.     jmp    dgwinhome        ; do DG window home
  7077. dgewin    endp
  7078.  
  7079. dgsleft    proc    near            ; RS F C <nn>  DG Scroll Left
  7080.     mov    bx,offset dgslef1    ; get <nn>
  7081.     jmp    get2n
  7082. dgslef1:mov    ax,dgnum        ; qty columns to scroll
  7083.     jmp    dglrworker        ; do common worker
  7084. dgsleft    endp
  7085.  
  7086. dgsright proc    near            ; RS F D <nn>  DG Scroll Right
  7087.     mov    bx,offset dgsrig1    ; get <nn>
  7088.     jmp    get2n
  7089. dgsrig1:mov    ax,dgnum
  7090.     neg    ax            ; go right
  7091.     jmp    dglrworker        ; do common worker
  7092. dgsright endp
  7093.  
  7094. ; Worker to assist dgsleft/dgsright horizontal scroll. Enter with AX holding
  7095. ; the additional scroll value, negative for scrolling left. Updates array
  7096. ; linescroll.
  7097. dglrworker proc    near
  7098.     cmp    dghscrdis,0        ; horiz scrolling disabled?
  7099.     je    dglrwor1        ; e = no
  7100.     ret                ; else ignore request
  7101. dglrwor1:mov    bl,mar_top        ; do entire DG window
  7102.     xor    bh,bh
  7103.     mov    cl,mar_bot
  7104.     xor    ch,ch
  7105.     sub    cx,bx
  7106.     inc    cx            ; number of lines in the window
  7107.     cmp    cl,byte ptr low_rgt+1    ; includes whole screen?
  7108.     jbe    dglrwor2        ; be = no
  7109.     inc    cx            ; include status line
  7110.  
  7111. dglrwor2:push    cx
  7112.     mov    cl,linescroll[bx]    ; get horz scroll value
  7113.     xor    ch,ch
  7114.     add    cx,ax            ; accumulate scroll
  7115.     jge    dglrwor3        ; ge = non-negative
  7116.     xor    cx,cx            ; set to zero
  7117. dglrwor3:cmp    cx,127            ; max scroll
  7118.     jbe    dglrwor4        ; be = in limits
  7119.     mov    cl,127            ; set to max left
  7120. dglrwor4:cmp    linescroll[bx],cl    ; any change?
  7121.     je    dglrwor5        ; e = no
  7122.     mov    linescroll[bx],cl    ; set scroll
  7123.     push    dx
  7124.     mov    dl,bl
  7125.     mov    dh,bl            ; start/stop line numbers
  7126.     call    touchup            ; repaint just this line
  7127.     pop    dx
  7128. dglrwor5:inc    bx            ; next line
  7129.     pop    cx
  7130.     loop    dglrwor2
  7131.     ret
  7132. dglrworker endp
  7133.  
  7134. dginsl    proc    near            ; RS F H  DG Insert Line in window
  7135.     push    dx            ; save cursor
  7136.     mov    param,0            ; set up ANSI call
  7137.     call    inslin            ; do insert line, can scroll
  7138.     pop    dx            ; recover cursor
  7139.     jmp    atsetcur        ; reset cursor
  7140. dginsl    endp
  7141.  
  7142. dgdell    proc    near            ; RS F I  DG Delete Line in window
  7143.     mov    scroll,1        ; line count
  7144.     push    word ptr mar_top    ; save current scrolling margins
  7145.     mov    mar_top,dh        ; temp top margin is here
  7146.     call    atscru            ; scroll up
  7147.     pop    word ptr mar_top    ; restore scrolling margins
  7148.     ret
  7149. dgdell    endp
  7150.  
  7151. dgnarrow proc    near            ; RS F J  DG select normal spacing
  7152.     mov    cx,dgwindcnt        ; number of windows
  7153.     xor    bx,bx
  7154.     jcxz    dgnarr3            ; z = none
  7155.     inc    cx            ; let implied last window be seen
  7156. dgnarr1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  7157.     jbe    dgnarr3            ; be = cursor is in this window
  7158.     add    bx,2            ; skip two margin bytes
  7159.     loop    dgnarr1            ; next window
  7160. dgnarr2:ret
  7161.  
  7162. dgnarr3:mov    cx,dgwindow[bx]        ; get mar_top and mar_bot (ch)
  7163.     push    cx            ; save margins for touchup below
  7164.     mov    bl,cl            ; mar_top
  7165.     xor    bh,bh
  7166.     sub    ch,cl            ; mar_bot - mar_top = lines in win -1
  7167.     xchg    ch,cl
  7168.     xor    ch,ch
  7169.     inc    cx
  7170.     xor    ax,ax            ; zero and make ah a changed flag
  7171. dgnarr4:xchg    al,dgwindcomp[bx]    ; set this window to normal width
  7172.     add    ah,al            ; remember if window line were wide
  7173.     xor    al,al            ; get zero again
  7174.     inc    bx
  7175.     loop    dgnarr4            ; do all lines in the window
  7176.     mov    cl,byte ptr low_rgt+1    ; see if any screen lines are wide
  7177.     inc    cl            ; text lines
  7178.     xor    ch,ch
  7179.     xor    bx,bx
  7180.     xor    al,al
  7181. dgnarr5:cmp    dgwindcomp[bx],0    ; count wide lines
  7182.     je    dgnarr6            ; e = narrow
  7183.     inc    al
  7184.     jmp    short dgnarr7        ; one wide line is enough to count
  7185. dgnarr6:inc    bx
  7186.     loop    dgnarr5
  7187.  
  7188. dgnarr7:pop    cx            ; margins
  7189.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  7190.     jz    dgnarr8            ; z = no
  7191.     or    ah,ah            ; any line widths changed?
  7192.     jz    dgnarr7a        ; z = no
  7193.     push    dx
  7194.     mov    dx,cx            ; cx = saved margins 
  7195.     call    touchup            ; dl, dh are start stop rows
  7196.     pop    dx
  7197. dgnarr7a:ret
  7198. dgnarr8:or    al,al            ; count of wide lines
  7199.     jz    dgnarr9            ; z = all are narrow, go to 80 cols
  7200.     ret                ; leave screen as-is with wide line(s)
  7201. dgnarr9:mov    al,3            ; prep call on atrsm6, 132/80 col
  7202.     mov    modeset,0        ; say want 80 columns
  7203.     jmp    atrsm6            ; common worker
  7204. dgnarrow endp
  7205.  
  7206. dgwide    proc    near            ; RS F K  DG select compressed spacing
  7207.     mov    cx,dgwindcnt        ; number of windows
  7208.     xor    bx,bx
  7209.     jcxz    dgwide3            ; z = none, means one as whole screen
  7210.     inc    cx            ; let implied last window be seen
  7211. dgwide1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  7212.     jbe    dgwide3            ; be = cursor is in this window
  7213.     add    bx,2            ; skip two margin bytes
  7214.     loop    dgwide1            ; next window
  7215. dgwide2:ret
  7216.  
  7217. dgwide3:mov    cx,dgwindow[bx]        ; get mar_top and mar_bot (ch)
  7218.     push    cx            ; save them for touchup below
  7219.     mov    bl,cl            ; mar_top
  7220.     xor    bh,bh
  7221.     sub    ch,cl            ; mar_bot - mar_top = lines in win -1
  7222.     xchg    ch,cl
  7223.     xor    ch,ch
  7224.     inc    cx
  7225.     mov    ax,1            ; al is set, ah is changed flag
  7226. dgwide5:xchg    al,dgwindcomp[bx]    ; set this line to wide width
  7227.     dec    al            ; convert old 1 to a zero
  7228.     add    ah,al            ; accumulate changes
  7229.     mov    al,1            ; get a 1 again
  7230.     inc    bx
  7231.     loop    dgwide5            ; do all lines in the window
  7232.     pop    cx            ; margins
  7233.     test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  7234.     jnz    dgwide8            ; nz = no, use 132 column text mode
  7235.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  7236.     jnz    dgwide7            ; nz = yes
  7237. dgwide6:push    cx
  7238.     push    dx
  7239.     call    dgsettek        ; setup special graphics mode
  7240.     pop    dx
  7241.     pop    cx
  7242.     ret
  7243. dgwide7:or    ah,ah            ; any changes to width?
  7244.     jz    dgwide7a        ; z = no
  7245.     push    dx
  7246.     mov    dx,cx            ; saved margins
  7247.     call    touchup            ; dl, dh are start stop rows
  7248.     pop    dx
  7249. dgwide7a:ret
  7250. dgwide8:mov    al,3            ; prep call on atrsm6, 132/80 col
  7251.     mov    modeset,1        ; say want 132 columns
  7252.     call    atrsm6            ; common worker
  7253.     cmp    byte ptr low_rgt,79
  7254.     jbe    dgwide6            ; did not work, use graphics anyway
  7255.     ret
  7256. dgwide    endp
  7257.  
  7258. ; Toggle Normal/Compressed modes from the keyboard.
  7259. dgnctoggle proc    far
  7260.     mov    dx,cursor        ; get cursor
  7261.     mov    bl,dh            ; get row
  7262.     xor    bh,bh
  7263.     cmp    dgwindcomp[bx],0    ; normal mode?
  7264.     je    dgnctog4        ; e = yes, do compressed
  7265.     call    dgnarrow        ; do normal
  7266.     ret
  7267. dgnctog4:call    dgwide            ; do compressed
  7268.     ret
  7269. dgnctoggle endp
  7270.  
  7271. dgdelc    proc    near            ; RS K  DG Delete char
  7272.     mov    param,0            ; set up ANSI call for one char
  7273.     jmp    atdelc            ; do delete
  7274. dgdelc    endp
  7275.  
  7276. dgilbm    proc    near            ; RS F [ Insert line between margins
  7277.     mov    al,dghscrdis        ; save horz scrolling disable flag
  7278.     push    ax            ; save til the end
  7279.     mov    dghscrdis,1        ; disable horz scrolling for this cmd
  7280.     mov    cursor,dx        ; save this
  7281.     mov    dl,mar_left        ; start at the left side
  7282.     mov    dh,mar_bot        ; bottom of window
  7283.     or    dh,dh            ; row zero?
  7284.     jz    dgilbm2            ; z = yes, just clear the line
  7285.  
  7286. dgilbm1:dec    dh            ; up one row
  7287.     call    getatch            ; read a char
  7288.     inc    dh            ; go down a row
  7289.     call    qsetatch        ; write the char
  7290.     inc    dl            ; next column
  7291.     cmp    dl,mar_right        ; off end of row yet?
  7292.     jbe    dgilbm1            ; be = no
  7293.     or    dh,dh            ; finished top row?
  7294.     jz    dgilbm2            ; z = yes
  7295.     dec    dh            ; redo this one row up
  7296.     mov    dl,mar_left        ; reset to left window margin
  7297.     cmp    dh,byte ptr cursor+1    ; finished cursor row yet?
  7298.     jae    dgilbm1            ; ae = no
  7299. dgilbm2:mov    dx,cursor        ; clear line cursor was on
  7300.     mov    al,mar_left        ; from left margin
  7301.     mov    bl,mar_right        ; to right window margin
  7302.     call    erinline        ; clear the window line
  7303.     mov    dl,dh
  7304.     mov    dh,mar_bot        ; lines changed
  7305.     call    touchup            ; redisplay the new material
  7306.     mov    dx,cursor
  7307.     pop    ax            ; recover horz scroll disable flag
  7308.     mov    dghscrdis,al
  7309.     ret
  7310. dgilbm    endp
  7311.  
  7312. dgdlbm    proc    near            ; RS F \ Delete line between margins
  7313.     mov    al,dghscrdis        ; get horizontal scroll disable flag
  7314.     push    ax            ; save til the end
  7315.     mov    dghscrdis,1        ; disable horz scrolling for this cmd
  7316.     mov    cursor,dx        ; save cursor position
  7317.     mov    dl,mar_left        ; start at the left side
  7318. dgdlbm1:inc    dh            ; down one row
  7319.     call    getatch            ; read a char
  7320.     dec    dh            ; go up a row
  7321.     call    qsetatch        ; write the char
  7322.     inc    dl            ; next column
  7323.     cmp    dl,mar_right        ; off end of row yet?
  7324.     jbe    dgdlbm1            ; be = no
  7325.     inc    dh            ; redo this one row down
  7326.     mov    dl,mar_left        ; reset to left window margin
  7327.     cmp    dh,mar_bot        ; finished bottom row yet
  7328.     jbe    dgdlbm1            ; be = no
  7329.     mov    dh,mar_bot        ; clear last line in window
  7330.     mov    al,mar_left
  7331.     mov    bl,mar_right
  7332.     call    erinline        ; clear the window line
  7333.     pop    ax            ; recover horz scroll disable flag
  7334.     mov    dghscrdis,al
  7335.     mov    dx,cursor
  7336.     mov    dl,dh            ; region changed
  7337.     mov    dh,mar_bot
  7338.     call    touchup
  7339.     ret
  7340. dgdlbm    endp
  7341.  
  7342. dgscs    proc    near            ; RS F S <nn>  DG Select Char Set
  7343.     mov    bx,dgscs1        ; setup for <nn> value
  7344.     jmp    get2n
  7345. dgscs1:    mov    bx,dgnum        ; get DG char set idents
  7346.     cmp    bl,1fh            ; last hard char set
  7347.     jbe    dgscs2            ; be = in the hard sets
  7348.     mov    bl,20h            ; specify default soft set of trash
  7349. dgscs2:    or    bl,bl            ; use "keyboard language"?
  7350.     jnz    dgscs3            ; nz = no
  7351.     mov    bl,vtemu.vtchset    ; get setup char set
  7352.     cmp    bl,13            ; top of the NRCs
  7353.     jbe    short dgscs4        ;  as keyboard language
  7354.     xor    bx,bx            ; default to ASCII
  7355. dgscs3:    mov    bl,dgchtab[bx]        ; translate to Kermit idents
  7356. dgscs4:    cmp    GLptr,offset G0set    ; are we shifted out?
  7357.     jne    dgscs5            ; ne = yes, presume G1set
  7358.     mov    Gsetid,bl        ; new set ident for G0
  7359.     jmp    short dgscs6
  7360. dgscs5:    mov    Gsetid+1,bl        ; new set ident for G1
  7361. dgscs6:    mov    bx,offset Gsetid    ; pass list of sets to setup
  7362.     jmp    chrsetup        ; go make the new set
  7363. dgscs    endp
  7364.  
  7365. dgalign    proc    near            ; RS F > char DG fill screen with char
  7366.     mov    ttstate,offset dgalig1    ; get char
  7367.     ret
  7368. dgalig1:mov    ttstate,offset atnrm    ; reset state
  7369.     jmp    atalig1            ; do DEC alignment work, char in AL
  7370. dgalign    endp
  7371.  
  7372. dggrid    proc    near            ; RS F 9 char DG fill screen with grid
  7373.     mov    al,'#'            ; set grid char in standard place
  7374.     jmp    atalig1            ; do DEC alignment work, char in AL
  7375. dggrid    endp
  7376.  
  7377.     
  7378. dgrolldis:mov    dgroll,0        ; Control-S  DG roll disable
  7379.     ret
  7380.  
  7381. dgrollena:mov    dgroll,1        ; Control-R  DG roll enable
  7382.     ret
  7383.  
  7384. dghsena:mov    dghscrdis,0        ; RS F ^  DG horiz scroll enable
  7385.     mov    dx,cursor
  7386.     jmp    atsetcur        ; set cursor to cause screen update
  7387.  
  7388. dghsdis:mov    dghscrdis,1        ; RS F ]  DG horiz scroll disable
  7389.     ret
  7390.  
  7391. dgpton:    call    setprot            ; RS F L  DG Protect on
  7392.     ret
  7393.  
  7394. dgptoff:call    clrprot            ; RS F M  DG Protect off
  7395.     ret
  7396.  
  7397. protena:mov    protectena,1        ; RS F V  DG Protect enable
  7398.     ret                ; 
  7399.     
  7400. protdis:mov    protectena,0        ; RS F W  DG Protect disable
  7401.     ret                ; 
  7402.  
  7403. dg78bit    proc    near            ; RS F U <n>  DG Select 7/8 bit ops
  7404.     mov    bx,dg78bit1        ; get <n>
  7405.     jmp    get1n
  7406. dg78bit1:cmp    dgnum,1            ; 0 is 7 bit, 1 is 8 bit
  7407.     ja    dg78bit3        ; a = illegal value, ignore
  7408.     je    dg78bit2        ; e = 1
  7409.     and    flags.remflg,not d8bit    ; 7-bit, chop DG high bit
  7410.     ret
  7411. dg78bit2:or    flags.remflg,d8bit    ; 8-bit
  7412. dg78bit3:ret
  7413. dg78bit    endp
  7414.  
  7415. dgdhdw    proc    near            ; RS R E <n>  DG Double high/wide
  7416.     mov    bx,offset dgdhdw1
  7417.     jmp    get1n            ; set up for <n> arg
  7418. dgdhdw1:mov    ax,dgnum        ; get <nn> result
  7419.     or    ax,ax            ; 2 and above are double highs
  7420.     jz    dgdhdw2
  7421.     mov    al,2            ; map double highs to 2
  7422.     jmp    linedbl            ; make line double width
  7423. dgdhdw2:jmp    linesgl            ; make single width
  7424. dgdhdw    endp
  7425.  
  7426. dgs25l    proc                ; RS F z <n>  DG go to/set status line
  7427.     mov    bx,offset dgs25l1    ; prep for <n> mode value
  7428.     jmp    get1n
  7429. dgs25l1:mov    ax,dgnum        ; get mode
  7430.     or    ax,ax            ; 0, 25th line is status?
  7431.     jnz    dgs25l2            ; nz = no
  7432.     mov    param,1            ; turn on regular mode line
  7433.     jmp    atssdt1            ; do main worker
  7434. dgs25l2:cmp    al,3            ; blank the line?
  7435.     jne    dgs25l3            ; ne = no
  7436.     jmp    atssdt1            ; do main worker
  7437.     cmp    al,2            ; use as ordinary text?
  7438.     jne    dgs25l3            ; ne = no
  7439.     ret                ; ignore this request
  7440. dgs25l3:cmp    al,1            ; get msg for line?
  7441.     je    dgs25l4            ; e = yes
  7442.     ret
  7443. dgs25l4:mov    bx,offset dgs25l5    ; prep for <nn> text
  7444.     jmp    get2n
  7445. dgs25l5:mov    dspcmain,dx        ; save cursor in special area
  7446.     mov    dspstate,dsptype    ; say on status line
  7447.     mov    al,mar_left
  7448.     mov    ah,mar_right
  7449.     mov    dspmsave,ax        ; save margins
  7450.     mov    mar_left,0        ; set left to screen left
  7451.     call    fclrmod            ; clear the line
  7452.     and    yflags,not modoff    ; say modeline is not toggled off
  7453.     mov    flags.modflg,2        ; say mode line is owned by host
  7454.     mov    dh,byte ptr low_rgt+1    ; bottom text line
  7455.     inc    dh            ; status line
  7456.     xor    dl,dl            ; absolute left margin
  7457.     call    atsetcur        ; set cursor
  7458.     cmp    dgnum,0            ; chars of text
  7459.     je    dgs25l7            ; e = yes
  7460.     mov    ttstate,offset dgs25l6    ; come here for text
  7461.     ret
  7462. dgs25l6:mov    ttstate,offset atnrm    ; reset state
  7463.     call    atnrm            ; write the character
  7464.     dec    dgnum            ; one less to do
  7465.     cmp    dgnum,0            ; done?
  7466.     jle    dgs25l7            ; le = yes
  7467.     ret                ; stay on status line
  7468. dgs25l7:mov    dx,dspcmain        ; restore cursor
  7469.     mov    ax,dspmsave        ; saved margins
  7470.     mov    mar_left,al
  7471.     mov    mar_right,ah
  7472.     mov    dspstate,0        ; no longer on mode line
  7473.     jmp    atsetcur        ; set cursor
  7474. dgs25l    endp
  7475.  
  7476. dgnscur    proc    near            ; RS F } <n> <n> DG cursor named save
  7477.     mov    bx,offset dgnscu1    ; get <n> memory cell (name, 0..15)
  7478.     jmp    get1n
  7479. dgnscu1:mov    ax,dgnum        ; get cell number
  7480.     mov    word ptr emubuf,ax    ; save here
  7481.     mov    bx,offset dgnscu2    ; get <n> save (0) / restore (1)
  7482.     jmp    get1n
  7483. dgnscu2:mov    bx,word ptr emubuf    ; get named subscript
  7484.     mov    ax,dgnum        ; get op code
  7485.     cmp    ax,1            ; save?
  7486.     jb    dgnscu3            ; b = save
  7487.     ja    dgnscu4            ; a = illegal, ignore
  7488.     mov    al,dgctypesave[bx]    ; get cursor size/type
  7489.     mov    atctype,al        ; active type
  7490.     call    csrtype            ; set it
  7491.     mov    dx,dgcursave[bx]    ; restore cursor position from storage
  7492.     mov    cursor,dx        ; remember for protected checking
  7493.     jmp    dgsetcur        ; set the cursor DG style
  7494. dgnscu3:mov    dgcursave[bx],dx    ; save cursor
  7495.     mov    al,atctype        ; get cursor type
  7496.     mov    dgctypesave[bx],al    ; save
  7497. dgnscu4:ret
  7498. dgnscur    endp
  7499.  
  7500. dgsps    proc    near                 ; DG dual emulation set split screen
  7501.     mov    ttstate,offset dgsps1    ; RS R A 0 <nn><n> or RS R A 1 <nn>
  7502.     ret
  7503. dgsps1:    mov    bx,offset atnrm        ; setup to ignore command
  7504.     cmp    al,1            ; 0 or 1 expected
  7505.     ja    dgsps3            ; a = illegal, ignore
  7506.     je    dgsps2            ; e = case 1 <nn>
  7507.     jmp    get3n            ; case 0 <nn><n> as <nnn>
  7508. dgsps2:    jmp    get2n
  7509. dgsps3:    ret
  7510. dgsps    endp
  7511.  
  7512. dgdcs    proc    near            ; RS F q <nn><nn> Dealloc Char Sets
  7513.     mov    bx,offset dgdcs1    ; ignore for now
  7514.     jmp    get2n
  7515. dgdcs1:    mov    bx,offset atnrm
  7516.     jmp    get2n
  7517. dgdcs    endp
  7518.  
  7519. dgdefch    proc    near            ; RS F R <char> 12<nn>'s Def Char
  7520.     mov    ttstate,dgdefc1        ; get and discard char
  7521.     mov    emubufc,0        ; set counter
  7522.     ret
  7523. dgdefc1:inc    emubufc            ; count a <nn> pair
  7524.     cmp    emubufc,12        ; done all?
  7525.     jae    dgdefc2            ; ae = yes
  7526.     mov    bx,offset dgdefc1    ; absorb 12 <nn> pairs
  7527.     jmp    get2n
  7528. dgdefc2:mov    emubufc,0        ; clear counter
  7529.     jmp    atnorm            ; reset state
  7530. dgdefch    endp
  7531.  
  7532. dgrchr    proc    near            ; RS F d  DG Read Chars Remaining
  7533.     mov    al,dgescape        ; response string
  7534.     call    prtbout
  7535.     mov    al,'o'
  7536.     call    prtbout
  7537.     mov    al,'9'
  7538.     call    prtbout
  7539.     mov    al,'0'            ; high part of 10 bit count
  7540. ;graphics    mov al,'_'
  7541.     call    prtbout
  7542.     mov    al,'0'            ; low part of 10 bit count
  7543. ;graphics    mov al,'_'
  7544.     call    prtbout
  7545.     ret
  7546. dgrchr    endp
  7547.  
  7548. dgresch    proc    near            ; RS F e <n><n>  DG Reserve Character
  7549.     mov    bx,offset atnorm    ; discard
  7550.     jmp    get2n
  7551. dgresch    endp
  7552.  
  7553. dgskl    proc    near            ; RS F f <n>  DG Set Kbd Language
  7554.     mov    bx,offset dgskl1
  7555.     jmp    get1n            ; get parameter
  7556. dgskl1:    mov    ax,dgnum        ; 0=setup, 1=DG Int, 2=Latin1
  7557.     cmp    ax,2            ; in range?
  7558.     ja    dgskl4            ; a = no
  7559.     cmp    ax,1            ; DG International?
  7560.     je    dgskl2            ; e = yes
  7561.     ja    dgskl3            ; a = no, Latin1
  7562.     mov    al,vtemu.vtchset    ; get setup char set
  7563.     mov    dgkbl,al        ; store keyboard language ident
  7564.     ret
  7565. dgskl2:    mov    dgkbl,20        ; DG International
  7566.     ret
  7567. dgskl3:    mov    dgkbl,16        ; Latin1
  7568. dgskl4:    ret
  7569. dgskl    endp
  7570.  
  7571. dgsdo    proc    near            ; RS R B <n><n><n> Set Device Options
  7572.     mov    bx,offset dgsdo1    ; get first <n>
  7573.     jmp    get1n
  7574. dgsdo1:    mov    bx,offset atnrm        ; get second and third <n>'s
  7575.     jmp    get2n            ; discard all
  7576. dgsdo    endp
  7577.  
  7578. dgsfield:mov    bx,offset dgsfie1    ; RS F C <ss><rr>  Field attributes
  7579.     jmp    get2n            ; get first <nn>
  7580. dgsfie1:mov    bx,offset atnrm        ; discard proc
  7581.     jmp    get2n            ; get second <nn>
  7582.  
  7583. dgspage:mov    bx,offset dgspag1    ; RS F D <ss><rr>  Page attributes
  7584.     jmp    get2n            ; get first <nn>
  7585. dgspag1:mov    bx,offset atnrm        ; discard proc
  7586.     jmp    get2n            ; get second <nn>
  7587.  
  7588. dgsetw    proc    near            ; RS F B <nn><n>.. Set windows
  7589.     mov    dgwindcnt,0        ; count of windows entries
  7590.     mov    emubuf+4,0        ; normal(0)/compressed (!0) flag
  7591. dgsetw1:mov    bx,offset dgsetw2    ; next processor
  7592.     jmp    get2n            ; get a <nn> window length
  7593. dgsetw2:mov    ax,dgnum
  7594.     mov    word ptr emubuf,ax    ; save around get1n work
  7595.     mov    bx,offset dgsetw2a    ; get <n> 0/1, compressed mode
  7596.     jmp    get1n
  7597. dgsetw2a:mov    ax,dgnum
  7598.     mov    emubuf+4,al        ; save copy for just this window
  7599.     mov    ax,word ptr emubuf    ; <nn> length, 0 (end) to 24
  7600.     or    ax,ax            ; end of set indicator?
  7601.     jnz    dgsetw2b        ; nz = no
  7602.     mov    ax,24            ; pseudo end
  7603. dgsetw2b:xchg    al,ah            ; put row in ah
  7604.     mov    bx,dgwindcnt        ; get subscript
  7605.     cmp    bx,24            ; too many windows? (24 == DG limit)
  7606.     ja    dgsetw7            ; a = yes, else accept data
  7607.     inc    bx
  7608.     mov    dgwindcnt,bx        ; update counter (1 == one window)
  7609.     dec    bx
  7610.     shl    bx,1            ; index words
  7611.     or    bx,bx            ; initial window?
  7612.     jnz    dgsetw3            ; nz = no
  7613.     xor    al,al            ; start at 0,0
  7614.     jmp    short dgsetw4
  7615. dgsetw3:mov    al,byte ptr dgwindow[bx-1] ; previous ending line
  7616.     inc    al            ; start this window down one line
  7617. dgsetw4:add    ah,al            ; new mar_bot = new mar_top + skip
  7618.     dec    ah            ; count lines from zero
  7619.     cmp    ah,byte ptr low_rgt+1    ; bottom of displayable screen?
  7620.     jb    dgsetw5            ; b = no
  7621.     mov    ah,byte ptr low_rgt+1    ; clamp to that bottom
  7622. dgsetw5:mov    dgwindow[bx],ax        ; save [al=mar_top,ah=mar_bot] pair
  7623.     mov    al,ah            ; get current bottom
  7624.     mov    ah,byte ptr low_rgt+1    ; last text line
  7625.     mov    dgwindow[bx+2],ax    ; fill remaining space with next wind
  7626.  
  7627.     push    bx            ; setup new margins, keep window ptr
  7628.     mov    dghscrdis,0        ; horz scroll disable is disabled
  7629.     mov    cx,slen            ; max screen length
  7630.     mov    al,mar_left
  7631.     xor    bx,bx
  7632. dgsetw6:mov    linescroll[bx],al    ; horiz scroll left margin to edge
  7633.     inc    bx
  7634.     loop    dgsetw6
  7635.     pop    bx            ; recover current line count in bx
  7636.  
  7637.     mov    al,emubuf+4        ; get compressed/normal for this wind
  7638.     mov    dh,byte ptr dgwindow[bx+1]; set cursor to bottom row of window
  7639.     or    al,al            ; to regular width?
  7640.     jnz    dgsetw7            ; nz = no, to compressed
  7641.     call    dgnarrow        ; to normal width
  7642.     jmp    short dgsetw8
  7643. dgsetw7:call    dgwide            ; compress things
  7644.  
  7645. dgsetw8:mov    bx,dgwindcnt        ; get window count
  7646.     or    bx,bx            ; any windows (0 = no)
  7647.     jz    dgsetw9
  7648.     dec    bx            ; count from 0
  7649.     shl    bx,1            ; count words
  7650.     mov    al,byte ptr low_rgt+1    ; last text line on screen (typ 23)
  7651.     cmp    byte ptr dgwindow[bx+1],al ; DG limit of 24 lines?
  7652.     jb    dgsetw1            ; b = not reached yet, keep going
  7653.  
  7654. dgsetw9:call    dgshome            ; do necessary DG Screen Home
  7655.     ret
  7656. dgsetw    endp
  7657.  
  7658. dgwwa    proc    near            ; Control-P col row
  7659.     mov    ttstate,offset dgwwa1    ; DG Write window address (win rel)
  7660.     ret                ; get raw binary col
  7661. dgwwa1:    mov    emubuf,al        ; save col
  7662.     mov    ttstate,offset dgwwa2    ; get raw binary row
  7663.     ret
  7664. dgwwa2:    mov    ttstate,offset atnrm    ; reset state
  7665.     cmp    al,127            ; 127 means use current row
  7666.     je    dgwwa3            ; e = yes
  7667.     add    al,mar_top        ; relative to window top
  7668.     mov    dh,al            ; set cursor row
  7669. dgwwa3:    xor    al,al            ; get a zero
  7670.     xchg    al,emubuf        ; get raw column, clear temp word
  7671.     cmp    al,127            ; 127 means use current column
  7672.     je    dgwwa4            ; e = yes
  7673.     add    al,mar_left        ; add left margin
  7674.     mov    dl,al            ; new cursor position
  7675. dgwwa4:    cmp    dh,mar_bot        ; below bottom of window?
  7676.     jbe    dgwwa5            ; be = no, in bounds
  7677.     mov    dh,mar_bot        ; peg at bottom
  7678. dgwwa5:    cmp    dl,mar_right        ; beyond right margin?
  7679.     jbe    dgwwa6            ; be = no, in bounds
  7680.     mov    dl,mar_right        ; peg at right
  7681. dgwwa6:    jmp    atsetcur        ; set cursor within window
  7682. dgwwa    endp
  7683.  
  7684. dgwsa    proc    near            ; RS F P <nn><nn> Write screen address
  7685.     mov    bx,offset dgwsa1    ; get <nn> col
  7686.     jmp    get2n
  7687. dgwsa1:    mov    ax,dgnum        ; absolute column
  7688.     mov    ah,mar_right        ; right most virtual column
  7689.     cmp    al,-1            ; means same screen column?
  7690.     je    dgwsa2a            ; e = yes
  7691.     cmp    al,ah            ; beyond right screen limit?
  7692.     jbe    dgwsa2            ; be = no
  7693.     mov    al,ah            ; peg at the right
  7694. dgwsa2:    mov    byte ptr cursor,al    ; column of cursor
  7695. dgwsa2a:mov    bx,offset dgwsa3    ; get <nn> row
  7696.     jmp    get2n
  7697. dgwsa3:    mov    ax,dgnum        ; get absolute row
  7698.     mov    ah,byte ptr low_rgt+1    ; last text row
  7699.     cmp    al,-1            ; means same screen row?
  7700.     je    dgwsa5            ; e = yes
  7701.     cmp    al,ah            ; below text screen?
  7702.     jbe    dgwsa4            ; be = no
  7703.     mov    al,ah            ; peg at the bottom
  7704. dgwsa4:    mov    byte ptr cursor+1,al    ; new row
  7705. dgwsa5:    mov    dx,cursor
  7706.     call    dggetmar        ; get margins for this dx
  7707.     call    getatch            ; check for protected field
  7708.     test    cl,att_protect        ; protected?
  7709.     jz    dgwsa6            ; z = no
  7710.     jmp    dgcuf            ; do DG cursor right
  7711. dgwsa6:    jmp    atsetcur        ; set cursor physical position
  7712. dgwsa    endp
  7713.  
  7714. dgshome    proc    near            ; RS F G  DG Screen Home
  7715.     xor    dh,dh            ; absolute screen top
  7716.     call    dggetmar        ; get margins for this dx
  7717.     mov    dl,mar_left        ; go to left margin
  7718.     jmp    atsetcur        ; set the cursor
  7719. dgshome    endp
  7720.  
  7721. dgsetmar proc    near            ; RS F X <nn> <nn> Set margins
  7722.     call    dggetmar        ; get margins for this window row
  7723.     mov    bx,offset dgsetm1    ; get <nn> left margin
  7724.     jmp    get2n
  7725. dgsetm1:mov    al,mar_left        ; current left margin
  7726.     mov    emubuf,al
  7727.     mov    ax,dgnum        ; get left margin info
  7728.     cmp    al,-1            ; use current margin?
  7729.     je    dgsetm2            ; e = yes
  7730.     mov    emubuf,al        ; set left margin
  7731. dgsetm2:mov    bx,offset dgsetm3    ; get right margin
  7732.     jmp    get2n
  7733. dgsetm3:mov    ax,dgnum        ; get right margin info
  7734.     cmp    al,-1            ; use current margin?
  7735.     jne    dgsetm4            ; ne = no
  7736.     mov    al,vswidth-1        ; use full screen
  7737. dgsetm4:cmp    al,vswidth-1        ; check sanity
  7738.     ja    dgsetmx            ; a = too large a right margin
  7739.     or    al,al            ; how about zero too?
  7740.     jz    dgsetmx            ; z = bad value
  7741.     cmp    al,mar_left        ; getting things on the wrong side?
  7742.     ja    dgsetm5            ; a = no
  7743.     mov    al,mar_left
  7744.     inc    al            ; one column wide screen
  7745. dgsetm5:mov    mar_right,al        ; set right margin
  7746.     cmp    mar_left,vswidth-1    ; this side too
  7747.     jae    dgsetmx            ; ae = too large
  7748.     mov    al,emubuf        ; new left
  7749.     mov    mar_left,al        ; new left
  7750.     mov    byte ptr cursor,al    ; set cursor to left margin
  7751.     mov    dx,cursor
  7752.     mov    emubuf,al        ; preset args for dgschw1
  7753.     mov    al,mar_right
  7754.     mov    emubuf+1,al
  7755.     jmp    dgschw1            ; try to show both margins, set cursor
  7756.  
  7757. dgsetmx:jmp    dggetmar        ; fail back to current margins
  7758. dgsetmar endp
  7759.  
  7760. dgsetamar proc    near            ; DG RS F Y <nn><nn><nn>
  7761.     cmp    savdgmar,0        ; have we saved l/r margins?
  7762.     jne    dgsetam0        ; ne = yes, don't save current
  7763.     mov    ah,mar_right        ; save originals
  7764.     mov    al,mar_left
  7765.     mov    savdgmar,ax        ; saved
  7766. dgsetam0:mov    bx,offset dgsetam1    ; Set Alternate Margins
  7767.     jmp    get2n            ; get cursor row
  7768. dgsetam1:mov    ax,dgnum        ; cursor row wrt top margin
  7769.     mov    bl,dh            ; row of cursor
  7770.     cmp    al,-1            ; use current row?
  7771.     je    dgsetam2        ; e = yes
  7772.     mov    bl,mar_top        ; get row at top of this window
  7773.     add    bl,al            ; new cursor row is mar_top + new
  7774. dgsetam2:cmp    bl,mar_bot        ; below window?
  7775.     jbe    dgsetam3        ; be = no
  7776.     mov    bl,mar_bot        ; clamp to window bottom
  7777. dgsetam3:mov    byte ptr param,bl    ; save cursor row
  7778.     mov    bx,offset dgsetam4    ; get <nn> col of new left margin
  7779.     jmp    get2n
  7780. dgsetam4:mov    ax,dgnum
  7781.     mov    bl,byte ptr savdgmar    ; get permanent left margin
  7782.     cmp    al,-1            ; use current left margin?
  7783.     je    dgsetam5        ; e = yes
  7784.     add    bl,al            ; new left, wrt old left
  7785. dgsetam5:mov    param+2,bx        ; save left margin
  7786.     mov    bx,offset dgsetam6    ; get <nn> right margin
  7787.     jmp    get2n
  7788. dgsetam6:mov    ax,dgnum
  7789.     mov    bl,byte ptr savdgmar+1    ; current right margin
  7790.     cmp    al,-1            ; use current right margin?
  7791.     je    dgsetam7        ; e = yes
  7792.     mov    bl,al
  7793.     add    bl,byte ptr param+2    ; relative to new left margin
  7794.     cmp    bl,byte ptr savdgmar+1    ; exceeds old right_margin?
  7795.     jbe    dgsetam7        ; be = no
  7796.     mov    bl,byte ptr savdgmar+1    ; yes, use old right_margin
  7797. dgsetam7:cmp    bl,vswidth-1        ; too far right?
  7798.     ja    dgsetam9        ; a = yes, abandon the command
  7799.     mov    mar_right,bl        ; alt right margin
  7800.     mov    al,byte ptr param+2    ; get alt left margin
  7801.     mov    mar_left,al
  7802.     mov    dl,al            ; cursor to left margin
  7803.     mov    dh,byte ptr param    ; get row for cursor
  7804.     mov    dghscrdis,1        ; horz scroll disabled (if 1)
  7805.     call    atsetcur        ; set cursor
  7806. dgsetam9:ret
  7807. dgsetamar endp
  7808.  
  7809. dgrnmar    proc    near            ; RS F Z  DG Restore normal margins
  7810.     cmp    savdgmar,0        ; anything saved?
  7811.     jz    dgrnma1            ; z = no, do nothing
  7812.     xor    ax,ax            ; get a null
  7813.     xchg    ax,savdgmar        ; recover saved margins, clear saved
  7814.     mov    mar_left,al
  7815.     mov    mar_right,ah
  7816. dgrnma1:ret
  7817. dgrnmar    endp
  7818.  
  7819. ; Worker. Given cursor in dx, set mar_top, mar_bot based on finding the 
  7820. ; DG window for that cursor row.
  7821. dggetmar proc    near
  7822.     mov    cx,dgwindcnt        ; number of windows
  7823.     xor    bx,bx
  7824.     jcxz    dggetma2        ; z = none
  7825.     inc    cx            ; let implied last window be seen
  7826. dggetma1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  7827.     jbe    dggetma3        ; be = cursor is in this window
  7828.     add    bx,2            ; skip two margin bytes
  7829.     loop    dggetma1        ; next window
  7830. dggetma2:ret
  7831.  
  7832. dggetma3:mov    ax,dgwindow[bx]        ; DG Window structure
  7833.     mov    mar_top,al
  7834.     mov    mar_bot,ah
  7835.     ret
  7836. dggetmar endp
  7837.  
  7838. ; Worker. Given cursor in dx, and al=mar_top, ah=mar_bot
  7839. ; store these margins in the window structure for that row, based on
  7840. ; finding the DG window for that cursor row.
  7841. dgstoremar proc    near
  7842.     push    cx
  7843.     mov    cx,dgwindcnt        ; number of windows
  7844.     xor    bx,bx
  7845.     jcxz    dgstore2        ; z = none
  7846. dgstore1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  7847.     jbe    dgstore2        ; be = cursor is in this window
  7848.     add    bx,2            ; skip two margin bytes
  7849.     loop    dgstore1        ; next window
  7850.     xor    bx,bx            ; fail, use first window slot
  7851. dgstore2:pop    cx
  7852.     mov    dgwindow[bx],ax
  7853.     ret
  7854. dgstoremar endp
  7855.  
  7856. dgsmid    proc    near            ; RS F { <nn><n> DG Set Model ID
  7857.     mov    bx,offset dgsmid1    ; setup for <nn>
  7858.     jmp    get2n
  7859. dgsmid1:mov    ax,dgnum        ; get new model id
  7860.     mov    byte ptr dgaltid,al    ; save
  7861.     mov    bx,dgsmid2        ; get graphics possible (1) bit
  7862.     jmp    get1n
  7863. dgsmid2:mov    ax,dgnum
  7864.     mov    byte ptr dgaltid+1,al
  7865.     ret
  7866. dgsmid    endp
  7867.  
  7868. dgscrup    proc    near            ; DG  RS H
  7869.     mov    scroll,1
  7870.     call    atscru            ; scroll up one line
  7871.     ret
  7872. dgscrup endp
  7873.  
  7874. dgscrdn    proc    near            ; DG  RS I
  7875.     mov    scroll,1
  7876.     call    atscrd            ; scroll down one line
  7877.     ret
  7878. dgscrdn    endp
  7879.  
  7880. dgcuu    proc    near            ; Control-W  DG cursor up
  7881.     mov    cursor,dx        ; remember for worker
  7882. dgcuu1:    cmp    dh,mar_top        ; above the top margin?
  7883.     ja    dgcuu2            ; a = not on top margin
  7884.     mov    dh,mar_bot        ; roll to bottom margin
  7885.     inc    dh
  7886. dgcuu2:    dec    dh            ; go up one row
  7887.     call    dgcurpchk        ; do proteced mode check
  7888.     jc    dgcub1            ; c = protected, do cursor back
  7889.     jmp    atsetcur        ; set the cursor
  7890. dgcuu    endp
  7891.  
  7892. dgcud    proc    near            ; Control-Z  DG cursor down
  7893.     mov    cursor,dx        ; remember for worker
  7894. dgcud1:    cmp    dh,mar_bot        ; below the bottom text line?
  7895.     jb    dgcud2            ; b = no
  7896.     mov    dh,mar_top        ; roll to top margin
  7897.     dec    dh
  7898. dgcud2:    inc    dh            ; go down one row
  7899.     call    dgcurpchk        ; check for protected cell
  7900.     jc    dgcuf1            ; c = on protected cell, go forward
  7901.     jmp    dgsetcur        ; set cursor
  7902. dgcud    endp
  7903.  
  7904. dgcuf    proc    near            ; Control-X  DG cursor forward
  7905.     mov    cursor,dx        ; remember where we started
  7906.     cmp    dl,mar_right        ; test for about to wrap
  7907.     jb    dgcuf1            ; b = not wrapping
  7908.     test    anspflg,vtautop        ; printing desired?
  7909.     jz    dgcuf1            ; e = no
  7910.     push    dx            ; save cursor value
  7911.     call    pntlin            ; print line current line
  7912.     mov    al,LF            ; terminate in LF
  7913.     call    fpntchr
  7914.     call    fpntflsh        ; flush printer buffer
  7915.     mov    atwrap,0
  7916.     pop    dx
  7917.  
  7918. dgcuf1:    cmp    dl,mar_right        ; to right of right margin?
  7919.     jb    dgcuf5            ; b = not on right margin
  7920.     mov    dl,mar_left        ; go to left margin
  7921.     inc    dh            ; and down one
  7922.     cmp    dh,mar_bot        ; below bottom line now?
  7923.     jbe    dgcuf6            ; be = no
  7924.     mov    dh,mar_bot        ; stay on bottom line
  7925.     cmp    dgroll,0        ; is roll mode disabled?
  7926.     jne    dgcuf3            ; ne = no, do the scroll
  7927.     mov    dh,mar_top        ; yes, wrap to top
  7928.     jmp    short dgcuf6
  7929. dgcuf3:    mov    scroll,1
  7930.     call    atsetcur        ; set cursor before the scroll
  7931.     call    atscru            ; scroll up one line
  7932.     ret
  7933. dgcuf5:    inc    dl            ; go right one column
  7934. dgcuf6:    call    dgcurpchk        ; check protection
  7935.     jc    dgcuf1            ; c = stepped on protected cell
  7936.     jmp    atsetcur        ; set cursor
  7937. dgcuf    endp
  7938.  
  7939. dgcub    proc    near            ; Control-Y  DG cursor left
  7940.     mov    cursor,dx        ; remember for worker
  7941. dgcub1:    cmp    dl,mar_left        ; to left of left margin?
  7942.     ja    dgcub2            ; a = no
  7943.     mov    dl,mar_right        ; go to right margin 
  7944.     jmp    dgcuu1            ; and do a cursor up
  7945. dgcub2:    dec    dl            ; go left one column
  7946.     call    dgcurpchk        ; check protection
  7947.     jc    dgcub1            ; c = stepped on protected cell
  7948.     jmp    atsetcur        ; set real cursor and exit
  7949. dgcub    endp
  7950.  
  7951. dgcurpchk proc    near
  7952.     cmp    protectena,0        ; protected mode enabled?
  7953.     je    dgcurpc1        ; e = no
  7954.     call    getatch            ; read char under new cursor position
  7955.     test    cl,att_protect        ; protected?
  7956.     jz    dgcurpc1        ; z = no, accept this position
  7957.     cmp    dx,cursor        ; is this where we started?
  7958.     je    dgcurpc1        ; e = yes
  7959.     stc                ; say stepping on protected char cell
  7960.     ret
  7961. dgcurpc1:clc                ; say no other action needed
  7962.     ret
  7963. dgcurpchk endp
  7964.  
  7965. ; Worker for cursor cmds. Skips protected fields, but remembers if we have
  7966. ; come full circle and then does a cursor right from there. Enter with
  7967. ; pre-motion cursor in "cursor", new desired position in dx.
  7968. dgsetcur proc    near
  7969.     call    dgcurpchk        ; call protected cell checker
  7970.     jnc    dgsetcu1        ; nc = ok, accept this position
  7971.     jmp    dgcuf1            ; do cursor forward
  7972. dgsetcu1:mov    bl,dh            ; get row
  7973.     xor    bh,bh
  7974.     cmp    dl,linescroll[bx]    ; to left of visible screen?
  7975.     jae    dgsetcu2        ; ae = no
  7976.     mov    emubuf,dl        ; set desired left margin
  7977.     mov    cl,mar_right
  7978.     mov    emubuf+2,cl        ; set desired right margin
  7979.     mov    cursor,dx        ; preset for dgschw1
  7980.     jmp    dgschw1            ; do Show Window to track cursor
  7981.  
  7982. dgsetcu2:jmp    atsetcur        ; set real cursor and exit
  7983. dgsetcur endp
  7984.  
  7985. dglf    proc    near            ; Control-J  DG New Line
  7986.     test    anspflg,vtautop        ; printing desired?
  7987.     jz    dglf1            ; e = no
  7988.     push    dx            ; save cursor
  7989.     call    pntlin            ; print line
  7990.     mov    al,LF            ; terminate in LF
  7991.     call    fpntchr
  7992.     call    fpntflsh        ; flush printer buffer
  7993.     mov    atwrap,0
  7994.     pop    dx
  7995. dglf1:    mov    dl,mar_left        ; to left margin
  7996.     cmp    dh,mar_bot        ; on bottom margin?
  7997.     jb    dglf3            ; b = no
  7998.     cmp    dgroll,0        ; is roll disabled
  7999.     je    dglf2            ; e = yes, do home
  8000.     call    dgsetcur        ; set cursor, does show columns too
  8001.     mov    scroll,1
  8002.     jmp    atscru            ; do a scroll up by one line
  8003.  
  8004. dglf2:    mov    dh,mar_top        ; do window Home
  8005.     jmp    short dglf4
  8006. dglf3:    inc    dh            ; down one row
  8007. dglf4:    jmp    dgsetcur        ; set cursor wrt protected mode
  8008. dglf    endp
  8009.  
  8010. dgcr    proc    near            ; DG Control-M
  8011.     mov    dl,mar_left        ; go to left margin, same row
  8012.     jmp    dgsetcur        ; set cursor, with protected mode
  8013. dgcr    endp
  8014.  
  8015. dgrmid    proc    near            ; RS C  DG Read Model ID
  8016.     mov    al,dgescape        ; resp RS o # <mm> <x> <y>
  8017.     call    prtbout
  8018.     mov    al,'o'
  8019.     call    prtbout
  8020.     mov    al,'#'
  8021.     call    prtbout
  8022.     mov    al,'6'            ; 6 is DG D413/D463
  8023.     test    flags.vtflg,ttd470    ; D470?
  8024.     jz    dgrmid6            ; z = no
  8025.     mov    al,44            ; 44 is DG D470
  8026. dgrmid6:cmp    byte ptr dgaltid,0    ; alternate ID given?
  8027.     je    dgrmid1            ; e = no
  8028.     mov    al,byte ptr dgaltid    ; use alternate
  8029. dgrmid1:call    prtbout
  8030.     xor    al,al            ; <x> byte, clear it
  8031.     test    flags.remflg,d8bit    ; using 8 bits?
  8032.     jz    dgrmid2            ; z = no
  8033.     or    al,10h            ; say 8-bit mode
  8034. dgrmid2:push    ax
  8035.     mov    ah,ioctl        ; get printer status, via DOS
  8036.     mov    al,7            ; status for output
  8037.     push    bx
  8038.     mov    bx,4            ; std handle for system printer
  8039.     int    dos
  8040.     pop    bx
  8041.     jnc    dgrmid3            ; nc = call succeeded
  8042.     mov    al,0ffh
  8043. dgrmid3:cmp    al,0ffh            ; code for Ready
  8044.     pop    ax
  8045.     jne    dgrmid4            ; ne = not ready
  8046.     or    al,8            ; say printer present
  8047. dgrmid4:or    al,40h
  8048.     call    prtbout            ; send composite byte
  8049.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  8050.     xor    bh,bh
  8051.     mov    al,nrcdgkbd[bx]        ; <y>, get DG keyboard code from table
  8052.     or    al,50h            ; 01+kbd installed (no graphics)
  8053.     or    al,20h            ; say have graphics
  8054.     cmp    byte ptr dgaltid,0    ; alternate id given?
  8055.     je    dgrmid5            ; e = no
  8056.     cmp    byte ptr dgaltid+1,0    ; host wants to say no graphics?
  8057.     jne    dgrmid5            ; ne = no, let things stand
  8058.     and    al,not 20h        ; remove graphics bit
  8059. dgrmid5:call    prtbout
  8060.     ret
  8061. dgrmid    endp
  8062.                     ; D470 command, absent from D463's
  8063. dgscmap    proc    near            ; RS F c <n><n><n><n> DG set color map
  8064.     mov    bx,offset dgscmap1    ; get language ident
  8065.     jmp    get3n            ; get three of the <n>'s
  8066. dgscmap1:mov    bx,offset dgscmap2    ; get the fourth
  8067.     jmp    get1n
  8068. dgscmap2:ret
  8069. dgscmap    endp
  8070.  
  8071. dgshcol    proc    near            ; RS F _ <nn><nn>  DG Show Columns
  8072.     mov    bx,offset dgshco1    ; get left col to show
  8073.     jmp    get2n
  8074. dgshco1:mov    ax,dgnum        ; left column to show, is dominant
  8075.     mov    cx,vswidth        ; max columns in vscreen
  8076.     dec    cx            ; max column ident
  8077.     sub    cl,byte ptr low_rgt    ; visible display width - 1
  8078.     sbb    ch,0            ; max left column showable
  8079.     cmp    ax,cx            ; want further right than this?
  8080.     jbe    dgshco2            ; be = no
  8081.     mov    ax,cx            ; limit to max
  8082. dgshco2:mov    emubuf,al        ; save max left col to show
  8083.     mov    bx,offset dgshco3    ; get right col to show
  8084.     jmp    get2n
  8085. dgshco3:mov    ax,dgnum        ; right col
  8086.     mov    emubuf+1,al
  8087.     cmp    dghscrdis,0        ; is horizontal scrolling disabled?
  8088.     je    dgschw1            ; e = no
  8089.     ret                ; disabled, ignore this command
  8090.  
  8091. ; worker. emubuf=wanted visible left, emubuf+1=wanted visible right margin
  8092. dgschw1:mov    bl,mar_top        ; get window top
  8093.     xor    bh,bh
  8094.     mov    cl,mar_bot
  8095.     sub    cl,bl
  8096.     inc    cl
  8097.     xor    ch,ch            ; lines in window
  8098.     mov    al,emubuf+1        ; desired right margin
  8099.     sub    al,emubuf        ; minus desired left
  8100.     cmp    al,byte ptr low_rgt    ; more than a screen's width?
  8101.     jbe    dgschw2            ; be = no
  8102.     mov    al,emubuf        ; desired left
  8103.     add    al,byte ptr low_rgt    ; plus screen width
  8104.     mov    emubuf+1,al        ; chop desired rm to give one screen
  8105.  
  8106. dgschw2:mov    al,linescroll[bx]    ; get scroll now in effect
  8107.     cmp    emubuf,al        ; is left margin to left of screen?
  8108.     jb    dgshw4            ; b = yes, put it on screen
  8109.     je    dgshw8            ; e = there now, do nothing
  8110.     mov    ah,emubuf+1        ; right margin to use
  8111.     add    al,byte ptr low_rgt    ; visible right edge
  8112.     cmp    al,ah            ; visible vs wanted right edge
  8113.     jae    dgshw8            ; ae = rm visible now, do nothing
  8114.     sub    ah,al            ; distance right margin is invisible
  8115.     xchg    ah,al
  8116.     add    al,linescroll[bx]    ; new shift plus current shift
  8117.     jmp    short dgshw5
  8118.  
  8119. dgshw4:    mov    al,emubuf        ; new scroll
  8120. dgshw5:    mov    linescroll[bx],al    ; horiz scroll for this line (window)
  8121.     inc    bx
  8122.     loop    dgshw5            ; do all lines in this window
  8123.     mov    dx,cursor
  8124.     cmp    dl,al            ; is cursor off to the left?
  8125.     jae    dgshw6            ; ae = no
  8126.     mov    dl,al            ; offset cursor too
  8127. dgshw6:    add    al,byte ptr low_rgt    ; visible right edge
  8128.     cmp    dl,al            ; cursor is on screen?
  8129.     jbe    dgshw7            ; be = yes
  8130.     mov    dl,al            ; move cursor to right edge
  8131. dgshw7:    mov    cursor,dx
  8132.     mov    dl,mar_top        ; region affected
  8133.     mov    dh,mar_bot
  8134.     call    touchup            ; repaint based on new linescroll
  8135. dgshw8:    mov    dx,cursor        ; update visible cursor
  8136.     jmp    atsetcur        ; set cursor, updates screen
  8137. dgshcol    endp
  8138.  
  8139. dgrnmod    proc    near            ; RS F w  DG Read New Model ID
  8140.     mov    al,dgescape        ; resp RS o w <c><s><r><n><res>
  8141.     call    prtbout
  8142.     mov    al,'o'
  8143.     call    prtbout
  8144.     mov    al,'w'
  8145.     call    prtbout
  8146. ;    mov    al,'3'            ; <c> D413 level graphics terminal
  8147.     mov    al,'8'            ; <c> D470/D463 graphics terminal
  8148.     call    prtbout
  8149.     mov    al,'0'            ; <s> pair, 01 is D470/D463
  8150.     call    prtbout
  8151.     mov    al,'1'
  8152.     call    prtbout
  8153.     mov    al,'0'            ; <r> rev level as <nn>
  8154.     call    prtbout            ; report 00
  8155.     mov    al,'0'
  8156.     call    prtbout
  8157.     mov    cx,4
  8158. ;;    mov    si,offset d413model    ; 8 char name, all printables
  8159.     mov    si,offset d463model    ; graphics term name, 8 printables
  8160.     test    flags.vtflg,ttd470    ; D470?
  8161.     jz    dgrnmo1            ; z = no
  8162.     mov    si,offset d470model
  8163. dgrnmo1:lodsb
  8164.     push    cx
  8165.     call    prtbout
  8166.     pop    cx
  8167.     loop    dgrnmo1
  8168.     mov    cx,4+4            ; <reserved> four spaces
  8169. dgrnmo2:mov    al,' '
  8170.     push    cx
  8171.     call    prtbout
  8172.     pop    cx
  8173.     loop    dgrnmo2
  8174.     ret
  8175. dgrnmod    endp
  8176.  
  8177. dgunix    proc    near            ; RS P @ <n>  DG Unix mode
  8178.     mov    ttstate,offset dgunix1    ; setup to ignore @
  8179.     ret
  8180. dgunix1:mov    bx,offset atnrm        ; consume the <n>
  8181.     jmp    get1n
  8182. dgunix    endp
  8183.  
  8184. dgsct    proc    near            ; RS F Q <n>  DG Set Cursor Type
  8185.     mov    bx,offset dgsct1
  8186.     jmp    get1n            ; get the <n> arg
  8187. dgsct1:    mov    ax,dgnum        ; get cursor type
  8188.     or    al,al            ; case 0, invisible/off?
  8189.     jnz    dgsct2            ; nz = no
  8190.     call    csrtype            ; set text cursor bits, keep kind
  8191.     or    atctype,4        ; remember, is off
  8192.     jmp    short dgsct5
  8193.  
  8194. dgsct2:    cmp    al,2            ; standard 1,2? (underline, block)
  8195.     jbe    dgsct4            ; be = yes
  8196.     sub    al,5
  8197.     neg    al            ; 5 - AL
  8198.     js    dgsct6            ; s = out of range, ignore
  8199.     jnz    dgsct4            ; nz = cases 3 and 4 (block, uline)
  8200.     mov    al,atctype        ; case 5, use saved cursor type
  8201.     and    al,not 4        ; remove invisible bit
  8202. dgsct4:    mov    atctype,al        ; save text cursor type here
  8203.     push    ax
  8204.     or    vtemu.vtflgop,vscursor ; set to underlined
  8205.     test    al,2            ; setting to block?
  8206.     jz    dgsct4a            ; z = no, underline
  8207.     and    vtemu.vtflgop,not vscursor ; say block in status word
  8208. dgsct4a:call    csrtype            ; set the cursor bits
  8209.     pop    ax
  8210. dgsct5:    test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8211.     jz    dgsct6            ; z = no
  8212.     mov    dx,cursor
  8213.     call    teksetcursor        ; set new cursor
  8214. dgsct6:    ret
  8215. dgsct    endp
  8216.  
  8217. dgchatr    proc    near            ; RS F N <nnn><n><n> DG change attrib
  8218.     mov    bx,offset dgchat1    ; get <nnn> qty chars to change
  8219.     jmp    get3n
  8220. dgchat1:mov    ax,dgnum        ; qty chars to change
  8221.     mov    word ptr emubuf,ax    ; save
  8222.     mov    bx,offset dgchat2    ; get <n> set list
  8223.     jmp    get1n
  8224. dgchat2:mov    ax,dgnum        ; bitfield for characteristics
  8225.     mov    emubuf+2,al        ; save set list
  8226.     mov    bx,offset dgchat3    ; get final <n> reset list
  8227.     jmp    get1n
  8228. dgchat3:mov    bl,byte ptr dgnum    ; get reset list to BL
  8229.     mov    emubuf+3,bl        ; save reset list
  8230.     mov    bh,emubuf+2        ; set list
  8231.     and    bh,bl            ; get toggle bits
  8232.     mov    emubuf+4,bh        ; save toggle list here
  8233.     not    bh            ; clear out bits processed here
  8234.     and    emubuf+2,bh        ; update set list
  8235.     and    emubuf+3,bh        ; update reset list
  8236.     mov    cursor,dx        ; save cursor location
  8237.  
  8238.     mov    cx,word ptr emubuf    ; qty of bytes to change, max
  8239.     or    cx,cx            ; some count?
  8240.     jnz    dgchag4            ; nz = something to do
  8241.     ret
  8242. dgchag4:mov    al,extattr        ; preserve settable attributes
  8243.     mov    ah,scbattr
  8244.     push    ax
  8245. dgchag4a:push    cx            ; save loop counter
  8246.     call    getatch            ; get video in ah, extended att in cl
  8247.     mov    extattr,cl        ; place extended where procs can see
  8248.     mov    emubuf+5,al        ; save char
  8249.     call    dgchag10        ; process this char
  8250.     mov    al,emubuf+5        ; restore char
  8251.     call    qsetatch        ; quietly update the char
  8252.     pop    cx
  8253.     inc    dl            ; next column
  8254.     cmp    dl,mar_right        ; at the right margin?
  8255.     jbe    dgchag5            ; be = no, not yet
  8256.     mov    dl,mar_left        ; wrap to left and next line
  8257.     inc    dh            ; next line down
  8258.     cmp    dh,mar_bot        ; below the window bottom?
  8259.     ja    dgchag6            ; a = yes, all done
  8260. dgchag5:loop    dgchag4a        ; do more chars
  8261. dgchag6:pop    ax
  8262.     mov    extattr,al        ; restore setables
  8263.     mov    scbattr,ah
  8264.     mov    dl,byte ptr cursor+1    ; dl = starting row, dh = ending row
  8265.     mov    dh,mar_bot
  8266.     call    touchup            ; repaint part of screen
  8267.     mov    dx,cursor        ; reset cursor location
  8268.     ret
  8269.  
  8270. ; worker for dgchag            ; do toggle mode
  8271. dgchag10:mov    bh,emubuf+4        ; toggle list
  8272.     or    bh,bh            ; any work?
  8273.     jz    dgchag20        ; z = no
  8274.     test    bh,1            ; blink?
  8275.     jz    dgchag11        ; z = no
  8276.     xor    ah,att_blink        ; xor blink
  8277. dgchag11:test    bh,2            ; underscore?
  8278.     jz    dgchag13        ; z = no
  8279.     test    cl,att_uline        ; is it set now?
  8280.     jz    dgchag12        ; z = no
  8281.     call    clrunder        ; reset it
  8282.     jmp    short dgchag13
  8283. dgchag12:call    setunder        ; set it
  8284. dgchag13:test    bh,4            ; reverse video
  8285.     jz    dgchag15        ; z = no
  8286.     test    cl,att_rev        ; reversed now?
  8287.     jz    dgchag14        ; z = no
  8288.     call    clrrev            ; unreverse it
  8289.     jmp    short dgchag15
  8290. dgchag14:call    setrev            ; reverse it
  8291. dgchag15:test    bh,8            ; Dim
  8292.     jz    dgchag20
  8293.     xor    ah,att_bold
  8294.                     ; do set list from emubuf+2
  8295. dgchag20:mov    bh,emubuf+2        ; get set list
  8296.     or    bh,bh            ; any work?
  8297.     jz    dgchag30        ; z = no
  8298.     test    bh,1            ; blink?
  8299.     jz    dgchag21        ; z = no
  8300.     call    setblink        ; set blink
  8301. dgchag21:test    bh,2            ; underscore?
  8302.     jz    dgchag22        ; z = no
  8303.     call    setunder        ; set underline
  8304. dgchag22:test    bh,4            ; reverse video?
  8305.     jz    dgchag23        ; z = no
  8306.     call    setrev            ; set reverse video
  8307. dgchag23:test    bh,8            ; dim?
  8308.     jz    dgchag30        ; z = no
  8309.     call    clrbold            ; set Dim
  8310.                     ; do reset list from emubuf+3
  8311. dgchag30:mov    bh,emubuf+3        ; get reset list
  8312.     or    bh,bh            ; any work?
  8313.     jz    dgchag34        ; z = no
  8314.     test    bh,1            ; blink?
  8315.     jz    dgchag31        ; z = no
  8316.     call    clrblink        ; clear blink
  8317. dgchag31:test    bh,2            ; underscore?
  8318.     jz    dgchag32        ; z = no
  8319.     call    clrunder        ; clear underscore
  8320. dgchag32:test    bh,4            ; reverse video?
  8321.     jz    dgchag33        ; z = no
  8322.     call    clrrev
  8323. dgchag33:test    bh,8            ; Dim?
  8324.     jz    dgchag34        ; z = no
  8325.     call    setbold            ; reset dim
  8326. dgchag34:ret                ; end of callable worker
  8327. dgchatr    endp
  8328.  
  8329. dgsclk    proc    near            ; RS r <n> <pos> <time> DG Set Clock
  8330.     mov    bx,offset dgsclk1    ; set up to get <n><0000>
  8331.     jmp    get3n
  8332. dgsclk1:mov    bx,offset dgsclk2    ; setup to get HH
  8333.     jmp    get1n
  8334. dgsclk2:mov    ttstate,offset dgsclk3    ; setup to get ":"
  8335.     ret
  8336. dgsclk3:mov    bx,offset atnrm        ; absorb final MM
  8337.     jmp    get1n
  8338. dgsclk    endp
  8339.  
  8340. dgrss    proc    near            ; RS F t  DG Report Screen Size
  8341.     mov    al,dgescape        ; resp RS o < <5 more items>
  8342.     call    prtbout
  8343.     mov    al,'o'
  8344.     call    prtbout
  8345.     mov    al,'<'
  8346.     call    prtbout
  8347.     mov    al,byte ptr low_rgt+1    ; number of screen rows -1
  8348.     inc    al
  8349.     call    out2n            ; first item
  8350.     mov    al,207            ; number of screen cols (DG hard #)
  8351.     call    out2n            ; second item
  8352.     mov    al,mar_bot
  8353.     sub    al,mar_top
  8354.     inc    al            ; third item, num rows in window
  8355.     call    out2n
  8356.     mov    al,mar_right
  8357.     sub    al,mar_left
  8358.     inc    al            ; fourth item, num cols in window
  8359.     call    out2n
  8360.     mov    al,01110000b        ; fifth item, status
  8361.     call    prtbout
  8362.     ret
  8363. dgrss    endp
  8364.  
  8365. dgrhso    proc    near            ; RS F O  DG Read Horz Scroll Offset
  8366.     mov    al,dgescape        ; resp RS o : <nn>
  8367.     call    prtbout
  8368.     mov    al,'o'
  8369.     call    prtbout
  8370.     mov    al,':'
  8371.     call    prtbout
  8372.     mov    bl,dh            ; get current row
  8373.     xor    bh,bh
  8374.     mov    al,linescroll[bx]    ; get scroll value
  8375.     call    out2na
  8376.     ret
  8377. dgrhso    endp
  8378.  
  8379. dgrwa    proc    near            ; Control-E  DG Read Window Address
  8380.     mov    al,1fh            ; Response string Control-_ col row
  8381.     call    prtbout
  8382.     mov    al,dl            ; col, raw binary
  8383.     call    prtbout
  8384.     mov    al,dh            ; row, raw binary
  8385.     call    prtbout
  8386.     ret
  8387. dgrwa    endp
  8388.  
  8389. dgrsa    proc    near            ; RS F b  DG Read Screen Address
  8390.     mov    al,dgescape        ; resp RS o 8 <nn> <nn>
  8391.     call    prtbout
  8392.     mov    al,'o'
  8393.     call    prtbout
  8394.     mov    al,'8'
  8395.     call    prtbout
  8396.     mov    al,byte ptr cursor    ; column
  8397.     call    out2na
  8398.     mov    al,byte ptr cursor+1    ; row
  8399.     call    out2na
  8400.     ret
  8401. dgrsa    endp
  8402.  
  8403. dgrwc    proc    near            ; RS F v <r1> <c1> <r2> <c2>
  8404.     mov    emubufc,0        ; counter. DG Read Window Contents
  8405. dgrwc1:    mov    bx,offset dgrwc2
  8406.     jmp    get2n            ; read <nn>
  8407. dgrwc2:    mov    bx,emubufc        ; get counter
  8408.     inc    emubufc
  8409.     mov    ax,dgnum        ; r1, c1, r2, or c2
  8410.     mov    emubuf[bx],al        ; save here
  8411.     cmp    bx,3            ; done all four?
  8412.     jb    dgrwc1            ; b = no, get more
  8413.     mov    dh,emubuf        ; starting row
  8414.     cmp    dh,emubuf+2        ; versus ending row
  8415.     ja    dgrwc8            ; a = fail if wrong order
  8416. dgrwc3:    mov    dl,emubuf+3        ; ending column
  8417.     mov    cl,dl
  8418.     sub    cl,emubuf+1        ; minus starting column
  8419.     jl    dgrwc8            ; fail if wrong order
  8420.     inc    cl            ; number of cells to examine
  8421.     xor    ch,ch
  8422.  
  8423. dgrwc4:    push    cx
  8424.     push    dx
  8425.     call    direction
  8426.     call    getatch            ; read char into AL at cursor dx
  8427.     pop    dx
  8428.     pop    cx
  8429.     cmp    al,' '            ; space?
  8430.     jne    dgrwc5            ; found non-space
  8431.     dec    dl
  8432.     loop    dgrwc4
  8433. dgrwc5:    jcxz    dgrwc7            ; z = only spaces on the line
  8434.     mov    dl,emubuf+1        ; staring column
  8435. dgrwc6:    push    cx
  8436.     push    dx
  8437.     call    direction
  8438.     call    getatch            ; get char and attribute
  8439.     call    prtbout            ; send char in al
  8440.     pop    dx
  8441.     pop    cx
  8442.     inc    dl            ; across the row
  8443.     loop    dgrwc6            ; do all interesting cols
  8444. dgrwc7:    push    dx
  8445.     mov    al,CR            ; send line terminators
  8446.     call    prtbout
  8447.     mov    al,LF
  8448.     call    prtbout
  8449.     pop    dx
  8450.     inc    dh            ; next row down
  8451.     cmp    dh,emubuf+2        ; beyond last row?
  8452.     jbe    dgrwc3            ; be = no
  8453.     mov    dx,cursor
  8454.     mov    emubufc,0        ; clear counter
  8455. dgrwc8:    ret
  8456. dgrwc    endp
  8457.         ; Data General D463/D470 graphics commands
  8458.  
  8459. dggline    proc    near            ; RS L and RS G 8  DG line drawing
  8460.     call    dgsettek        ; setup special graphics mode
  8461. dggline1:mov    bx,offset dggline2    ; get <NNN> x coord
  8462.     jmp    get3loc
  8463. dggline2:jc    dggline9        ; c = read null terminator
  8464.     mov    ax,dgnum        ; start x coord
  8465.     mov    param+0,ax        ; save here
  8466.     mov    param+4,ax        ; and here
  8467.     mov    bx,offset dggline3    ; get <NNN> y coord
  8468.     jmp    get3loc
  8469. dggline3:jc    dggline9
  8470.     mov    ax,dgnum
  8471.     mov    param+2,ax        ; start y
  8472.     mov    param+6,ax        ; and here
  8473. dggline4:mov    bx,offset dggline5    ; get <NNN> end x coord
  8474.     jmp    get3loc
  8475. dggline5:jc    dggline8        ; c = ending on single coord, do a dot
  8476.     mov    ax,dgnum
  8477.     mov    param+4,ax        ; end x
  8478.     mov    bx,offset dggline6    ; get <NNN> end y coord
  8479.     jmp    get3loc
  8480. dggline6:jc    dggline9        ; c = null char
  8481.     mov    ax,dgnum        ; end y
  8482.     mov    param+6,ax
  8483.     call    dggline8        ; plot line
  8484.     jmp    short dggline4        ; continue gathering coord pairs
  8485.  
  8486. dggline8:
  8487.     push    word ptr mar_top    ; mar_top in low byte
  8488.     push    dglinepat        ; line pattern
  8489.     push    param+6            ; end y
  8490.     push    param+4            ; end x
  8491.     push    param+2            ; start y
  8492.     push    param+0            ; start x
  8493.     call    dgline            ; do the line
  8494.     add    sp,12            ; clear the argument stack
  8495.     mov    ax,param+4        ; old end is new beginning
  8496.     mov    param,ax
  8497.     mov    ax,param+6
  8498.     mov    param+2,ax
  8499. dggline9:ret
  8500. dggline    endp
  8501.  
  8502. dggarc    proc    near            ; RS G 0  DG arc drawing
  8503.     mov    bx,offset dggarc1    ; get <NNN> x coord
  8504.     jmp    get3loc
  8505. dggarc1:jc    dggarc9            ; unexpected terminator
  8506.     mov    ax,dgnum        ; x coord
  8507.     mov    param,ax        ; save here
  8508.     mov    bx,offset dggarc2    ; get <NNN> y coord
  8509.     jmp    get3loc
  8510. dggarc2:jc    dggarc9
  8511.     mov    ax,dgnum
  8512.     mov    param+2,ax
  8513.     mov    bx,offset dggarc3    ; get <NNN> radius
  8514.     jmp    get3loc
  8515. dggarc3:jc    dggarc9
  8516.     mov    ax,dgnum
  8517.     mov    param+4,ax
  8518.     mov    bx,offset dggarc4    ; get <NNN> start angle
  8519.     jmp    get3loc
  8520. dggarc4:jc    dggarc9
  8521.     mov    ax,dgnum
  8522.     mov    param+6,ax
  8523.     mov    bx,offset dggarc5    ; get <NNN> end angle
  8524.     jmp    get3loc
  8525. dggarc5:call    dgsettek        ; setup graphics mode
  8526.     mov    al,mar_bot        ; bottom margin in PC text lines
  8527.     xor    ah,ah
  8528.     push    ax
  8529.     mov    al,mar_top        ; top margin in PC text lines
  8530.     push    ax
  8531.     push    dgnum            ; end angle
  8532.     push    param+6            ; start angle
  8533.     push    param+4            ; radius
  8534.     push    param+2            ; start y
  8535.     push    param+0            ; start x
  8536.     call    dgarc            ; draw the arc in msgibm
  8537.     add    sp,14            ; clean stack
  8538. dggarc9:ret
  8539. dggarc    endp
  8540.  
  8541. dggbar    proc    near            ; RS G 1  DG bar drawing
  8542.     call    dgsettek        ; setup special graphics mode
  8543.     mov    bx,offset dggbar1    ; get <NNN> x coord, lower left
  8544.     jmp    get3loc
  8545. dggbar1:jc    dggbar9            ; c = unexpected terminator
  8546.     mov    ax,dgnum        ; x coord
  8547.     mov    param,ax        ; save here
  8548.     mov    bx,offset dggbar2    ; get <NNN> y coord
  8549.     jmp    get3loc
  8550. dggbar2:jc    dggbar9
  8551.     mov    ax,dgnum
  8552.     mov    param+2,ax
  8553.     mov    bx,offset dggbar3    ; get <NNN> width
  8554.     jmp    get3loc
  8555. dggbar3:jc    dggbar9
  8556.     mov    ax,dgnum
  8557.     mov    param+4,ax
  8558.     mov    bx,offset dggbar4    ; get <NNN> height
  8559.     jmp    get3loc
  8560. dggbar4:jc    dggbar9
  8561.     mov    ax,dgnum
  8562.     mov    param+6,ax
  8563.     mov    bx,offset dggbar5    ; get <n> foreground/background
  8564.     jmp    get1n
  8565. dggbar5:jc    dggbar9
  8566.     xor    ah,ah
  8567.     mov    al,mar_bot
  8568.     push    ax
  8569.     mov    al,mar_top
  8570.     push    ax
  8571.     push    dgnum            ; fore(1) or background (0) color
  8572.     push    param+6            ; height
  8573.     push    param+4            ; width
  8574.     push    param+2            ; start y lower left corner
  8575.     push    param+0            ; start x
  8576.     call    dgbar            ; msgibm bar drawer
  8577.     add    sp,14            ; clean stack
  8578. dggbar9:ret
  8579. dggbar    endp
  8580.  
  8581. dggpoly    proc    near            ; RS G :  DG polygon fill drawing
  8582.     mov    word ptr rdbuf,0    ; count argument pairs
  8583. dggpol1:mov    bx,offset dggpol2    ; get <NNN> x coord
  8584.     jmp    get3loc
  8585. dggpol2:jc    dggpol4            ; c = got null terminator
  8586.     mov    ax,dgnum        ; x coord
  8587.     mov    param,ax        ; save here
  8588.     mov    bx,offset dggpol3    ; get <NNN> y coord
  8589.     jmp    get3loc
  8590. dggpol3:jc    dggpol4
  8591.     mov    bx,word ptr rdbuf    ; vertex index
  8592.     shl    bx,1            ; count words
  8593.     shl    bx,1            ; count pairs
  8594.     mov    cx,param        ; x coord
  8595.     mov    ax,dgnum        ; y coord
  8596.     mov    word ptr rdbuf+2[bx],cx    ; stuff x
  8597.     mov    word ptr rdbuf+2[bx+2],ax ; stuff y
  8598.     inc    word ptr rdbuf        ; another vertex in list
  8599.     jmp    short dggpol1        ; get another vertex
  8600. dggpol4:cmp    word ptr rdbuf,3    ; minimum viable point count
  8601.     jb    dggpol6            ; b = insufficient qty
  8602.     mov    bx,word ptr rdbuf    ; vertex index
  8603.     shl    bx,1            ; count words
  8604.     shl    bx,1            ; count pairs
  8605.     mov    al,mar_top
  8606.     xor    ah,ah
  8607.     mov    word ptr rdbuf+2[bx],ax    ; top margin, PC text lines
  8608.     mov    al,mar_bot
  8609.     mov    word ptr rdbuf+2[bx+2],ax ; bottom margin, PC text lines
  8610.     call    dgsettek        ; setup special graphics mode
  8611.     mov    al,curattr        ; save current coloring
  8612.     push    ax
  8613.     test    flags.vtflg,ttd463    ; D463?
  8614.     jz    dgpoly5            ; z = no
  8615.     and    al,0f0h            ; remove foreground
  8616.     or    al,dg463fore        ; OR in D463 foreground color
  8617.     mov    curattr,al        ; set drawing coloring
  8618. dgpoly5:call    dgpoly            ; call worker in msgibm
  8619.     pop    ax
  8620.     mov    curattr,al        ; restore coloring
  8621. dggpol6:ret
  8622. dggpoly    endp
  8623.  
  8624. dggsetp    proc    near            ; RS G p 1  DG Set Pattern
  8625.     mov    ttstate,offset dggset1    ; setup to read the 1
  8626.     ret
  8627. dggset1:cmp    al,'1'            ; correct?
  8628.     je    dggset2            ; e = yes
  8629. dggsetx:jmp    atnorm            ; fail and reset state
  8630. dggset2:mov    ttstate,offset dggset3    ; setup to read <offset>
  8631.     mov    dglinepat,0        ; init line pattern to all zeros
  8632.     call    dgsettek        ; setup special graphics mode
  8633.     ret
  8634. dggset3:sub    al,'@'            ; remove ASCII bias
  8635.     jc    dggset9            ; c = failure
  8636.     and    al,1fh            ; keep lower five bits
  8637.     xor    ah,ah
  8638.     mov    param,ax        ; save initial bit position
  8639.     mov    cl,al
  8640.     rcl    dglinepat,cl        ; rotate initial pattern
  8641.     mov    ttstate,offset dggset4    ; setup to read <n> 0/1 bit
  8642.     ret
  8643. dggset4:or    al,al            ; null terminator?
  8644.     jz    dggset6            ; z = yes
  8645.     and    al,0fh            ; keep lower four bits of <n>
  8646.     cmp    al,1            ; legal values are 0, 1, and other
  8647.     jbe    dggset5            ; be = 0 or 1
  8648.     xor    al,al            ; above 1 is made to be zero
  8649. dggset5:rcr    al,1
  8650.     rcr    dglinepat,1        ; put into line pattern high bit
  8651.     inc    param            ; count bit added to pattern
  8652.     ret                ; continue in state dggset4
  8653.  
  8654. dggset6:mov    cx,16            ; bits in pattern
  8655.     sub    cx,param        ; get pattern bit count
  8656.     jle    dggset9            ; le = rotated enough
  8657.     mov    ax,dglinepat        ; pattern
  8658.     mov    bx,ax            ; a copy
  8659.     mov    cx,param        ; pattern bit count
  8660.     mov    dx,16            ; overall bits
  8661. dggset6a:sub    dx,cx            ; minus original pattern
  8662.     jg    dggset7            ; g = still have room to copy
  8663.     je    dggset8            ; e = all done
  8664.     neg    dx
  8665.     mov    cx,dx            ; else tag end
  8666. dggset7:ror    ax,cl            ; rotate pattern to starting position
  8667.     or    ax,bx            ; move in a copy
  8668.     jmp    short dggset6a
  8669.  
  8670. dggset8:mov    dglinepat,ax        ; store line pattern
  8671. dggset9:mov    ttstate,offset atnrm
  8672.     ret
  8673. dggsetp    endp
  8674.  
  8675. dggrcl    proc    near            ; RS G ? |  DG Read Cursor Location
  8676.     mov    ttstate,offset dggrcl1
  8677.     ret
  8678. dggrcl1:mov    ttstate,atnrm        ; reset state
  8679.     cmp    al,'|'            ; correct terminator?
  8680.     jne    dggrcl3            ; ne = no
  8681. dggrcl2:call    dgcrossrpt        ; generate report in msgibm
  8682. dggrcl3:ret
  8683. dggrcl    endp
  8684.  
  8685. dggcon    proc    near            ; RS G B  DG Cursor on
  8686.     call    dgsettek        ; setup special graphics mode
  8687.     call    dgcrosson        ; turn on crosshair
  8688.     ret
  8689. dggcon    endp
  8690.  
  8691. dggcoff    proc    near            ; RS G C  DG Cursor off
  8692.     call    dgcrossoff        ; turn off crosshair
  8693.     ret
  8694. dggcoff    endp
  8695.  
  8696. dggcloc    proc    near            ; RS G > | <NNN> <NNN> DG Cursor loc
  8697.     mov    ttstate,offset dggclo1    ; get vertical bar
  8698.     ret
  8699. dggclo1:mov    ttstate,offset atnrm    ; reset state
  8700.     cmp    al,'|'            ; correct character?
  8701.     je    dggclo2            ; e = yes
  8702.     ret
  8703. dggclo2:mov    bx,offset dggclo3    ; get <nnn> x ordinate
  8704.     jmp    get3loc            ; as 15 bit location argument
  8705. dggclo3:mov    ax,dgnum
  8706.     mov    param,ax        ; got x ordinate
  8707.     mov    bx,offset dggclo4    ; get <nnn> y ordinate
  8708.     jmp    get3loc            ; as 15 bit location argument
  8709. dggclo4:mov    bx,dgnum        ; setup registers for call
  8710.     mov    ax,param
  8711.     call    dgsetcrloc        ; setup crosshair location
  8712.     ret
  8713. dggcloc    endp
  8714.  
  8715. dggctrk    proc    near            ; RS G H <n>  DG Cursor track
  8716.     mov    bx,offset dggctr1
  8717.     jmp    get1n
  8718. dggctr1:and    al,2+4            ; pick out our trackables
  8719.     and    dgcross,not (2+4)    ; preserve on/of bit (1)
  8720.     or    dgcross,al        ; track keypad (2) and/or mouse (4)
  8721.     ret
  8722. dggctrk    endp
  8723.  
  8724. dggcatt    proc    near            ; RS G @  DG graphics cursor attribute
  8725.     mov    al,dgescape
  8726.     call    prtbout
  8727.     mov    al,'o'
  8728.     call    prtbout
  8729.     mov    al,','
  8730.     call    prtbout
  8731.     mov    al,'0'            ; say crosshair is off
  8732.     test    dgcross,1        ; is it on?
  8733.     jz    dggcatt1        ; z = no
  8734.     inc    al            ; say '1' for on
  8735. dggcatt1:call    prtbout            ; output <v1>
  8736.     mov    al,'0'            ; <v2> is always 0 for not blinking
  8737.     call    prtbout
  8738.     mov    al,'1'            ; <v3> is 1 for long crosshair, D463
  8739.     test    flags.vtflg,ttd470    ; D470?
  8740.     jz    dggcatt2        ; z = no
  8741.     dec    al            ; <v3> is 0 for short crosshair, D470
  8742. dggcatt2:call    prtbout
  8743.     mov    al,dgcross        ; get tracked devices
  8744.     and    al,2+4            ; pick out just devices
  8745.     add    al,'0'            ; bias
  8746.     call    prtbout            ; output <v4>
  8747.     mov    al,CR            ; terminal character
  8748.     call    prtbout
  8749.     ret
  8750. dggcatt    endp
  8751.  
  8752. dggcrst    proc    near            ; RS G A  DG Cursor reset
  8753.     call    dgcrossoff        ; turn off crosshair
  8754.     mov    dgcross,0        ; and no kind of tracking
  8755.     ret
  8756. dggcrst    endp
  8757.  
  8758.         ; End of Data General specific routines
  8759.  
  8760.  
  8761. ; Display "LEDs" routine. yflags from MSYIBM is needed to know if the mode
  8762. ; line is enabled. Display current state of "LEDs" on line 25.
  8763. ansdsl    proc    near            ; display "LEDs"
  8764.     test    yflags,modoff        ; mode line off?
  8765.     jnz    ansdsl2            ; nz = yes, just return
  8766.     cmp    flags.modflg,1        ; mode line on and owned by us?
  8767.     jne    ansdsl2            ; ne = no, leave it intact
  8768.     mov    cx,10            ; length of the array
  8769.     call    getled            ; set si to string, c set if no leds
  8770.     push    es
  8771.     mov    di,ds
  8772.     mov    es,di
  8773.     mov    di,led_col+offset modbuf ; mode line buffer, our position
  8774.     cld
  8775.     rep    movsb
  8776.     pop    es
  8777. ansdsl2:ret
  8778. ansdsl    endp
  8779.  
  8780. ; Return pointer to "led" display in si, set carry if terminal type does
  8781. ; not have leds 1..4.
  8782. getled    proc    near
  8783.     mov    ax,flags.vtflg        ; terminal type
  8784.     mov    si,offset v320leds    ; VT320 ident
  8785.     cmp    ax,ttvt320        ; VT320?
  8786.     je    getled2            ; e = yes
  8787.     mov    si,offset v220leds    ; VT220 ident
  8788.     cmp    ax,ttvt220        ; VT220?
  8789.     je    getled2            ; e = yes
  8790.     mov    si,offset v102leds    ; VT102 ident
  8791.     cmp    ax,ttvt102        ; VT102 mode?
  8792.     je    getled2            ; e = yes
  8793.     mov    si,offset v100leds
  8794.     cmp    ax,ttvt100        ; VT100?
  8795.     je    getled2            ; e = yes
  8796.     mov    si,offset honeyleds
  8797.     cmp    ax,tthoney        ; Honeywell?
  8798.     je    getled2            ; e = yes
  8799.     mov    si,offset v52leds    ; VT52 ident
  8800.     cmp    ax,ttvt52        ; VT52?
  8801.     je    getled1            ; e = yes, no leds
  8802.     mov    si,offset pt20leds
  8803.     cmp    ax,ttpt200        ; Prime PT200?
  8804.     je    getled2            ; e = yes
  8805.     mov    si,offset d463leds
  8806.     cmp    ax,ttd463        ; DG D463?
  8807.     je    getled1            ; e = yes, but no led dots
  8808.     mov    si,offset d470leds
  8809.     cmp    ax,ttd470        ; DG D470?
  8810.     je    getled1            ; e = yes, but no led dots
  8811.     mov    si,offset h19leds    ; Heath-19 ident
  8812. getled1:stc                ; c = set, does not have leds 1..4
  8813.     ret
  8814. getled2:clc                ; c = clear, has leds 1..4
  8815.     ret
  8816. getled    endp
  8817.  
  8818. ; This routine is called to adjust the cursor for the "indexing" like commands
  8819. ; (e.g., index, reverse index, newline, etc.).    It contrains the cursor, and
  8820. ; indicates if scrolling is necessary, and if so, in which direction.
  8821. ;
  8822. ; Call: cursor = "old" cursor position
  8823. ;    dx =     "new" cursor position
  8824. ;
  8825. ; Return: ax = pointer to scrolling routine to call (or to a ret)
  8826. ;      bx = "old" cursor position
  8827. ;      dx = "new" cursor position adjusted for screen limits or
  8828. ;               scrolling region, depending on whether the original
  8829. ;               cursor position was inside or outside the scrolling region.
  8830. ;
  8831. ; On the VT100, a scroll does not occur unless the original cursor position
  8832. ; was on the top or bottom margin. This routine assumes that when decom is
  8833. ; set the cursor position is set to the new origin, and that no other routine
  8834. ; allows the cursor to be positioned outside the scrolling region as long
  8835. ; as decom is set (which is the way a real VT100 works).  Note that for the
  8836. ; normal case (no limited scrolling region defined) the margins are the same
  8837. ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
  8838. ; an attempt is made to index off the screen. Preserves cx.
  8839.  
  8840. atccic    proc    near
  8841.     push    cx
  8842.     mov    cl,byte ptr low_rgt    ; get right margin
  8843.     mov    bl,dh            ; get row
  8844.     xor    bh,bh
  8845.     cmp    bl,crt_lins        ; below screen?
  8846.     jae    atcci0            ; ae = yes, use single width line
  8847.     cmp    linetype[bx],0        ; single width chars?
  8848.     je    atcci0            ; e = yes, single width
  8849.     shr    cl,1            ; halve margin for double wides
  8850. atcci0:    mov    ax,offset atign        ; assume no scrolling necessary
  8851.     mov    bx,cursor        ; get old cursor
  8852.     test    flags.vtflg,ttd463+ttd470 ; DG terminal?
  8853.     jz    atcci0a            ; z = no
  8854.     mov    cl,mar_right
  8855.     cmp    dl,mar_left        ; left of left margin?
  8856.     jae    atcci1            ; ae = no
  8857.     mov    dl,mar_right        ; fold to right
  8858.     dec    dh            ; and go up
  8859.     jmp    short atcci1
  8860. atcci0a:cmp    dl,250            ; left of left margin? (wide screen)
  8861.     jb    atcci1            ; b = no, go check right
  8862.     xor    dl,dl            ; set to left margin
  8863. atcci1:    cmp    dl,cl            ; left of right margin
  8864.     jbe    atcci2            ; be = yes, go check top
  8865.     mov    dl,cl            ; set to right margin
  8866.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  8867.     jz    atcci2            ; z = no
  8868.     mov    dl,mar_left        ; to left margin
  8869.     inc    dh            ; and down one
  8870. atcci2:    pop    cx
  8871.     cmp    bh,mar_top        ; was old pos above scroll top margin?
  8872.     jb    atcci7            ; b = yes
  8873.     cmp    dh,mar_top        ; want to go above top margin?
  8874.     jge    atcci5            ; ge = no
  8875.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  8876.     jz    atcci3            ; z = no
  8877.     mov    dh,mar_bot        ; roll over to bottom margin
  8878.     ret
  8879. atcci3:    mov    scroll,1
  8880.     mov    ax,offset atscrd    ; indicate scroll down required
  8881.     mov    dh,mar_top        ; set to top margin
  8882.     ret
  8883.  
  8884. atcci5:    cmp    bh,mar_bot        ; old position below bottom margin?
  8885.     ja    atcci7            ; a = yes
  8886.     cmp    dh,mar_bot        ; want to go below?
  8887.     jbe    atcci6            ; be = no, nothing to worry about
  8888.     mov    scroll,1        ; 1 line
  8889.     mov    ax,offset atscru    ; indicate scroll up required
  8890.     mov    dh,mar_bot        ; set to bottom margin
  8891. atcci6:    ret
  8892. atcci7:    jmp    short atccpc        ; old pos was outside scrolling region
  8893. atccic    endp
  8894.  
  8895. ; This routine is called to check the cursor position after any kind of cursor
  8896. ; positioning command.    Note that cursor positioning does NOT cause scrolling
  8897. ; on a VT100 (hence the need for a routine separate from this for "indexing".
  8898. ; Call:    dx = "new" cursor position (modified cursor)
  8899. ; Return: dx = "new" cursor position adjusted for screen limits (if
  8900. ;        decom is reset), or scrolling region (if decom is set).
  8901. ; Preserves ax, bx, and cx.
  8902.  
  8903. atccpc    proc    near
  8904.     push    bx            ; save bx and cx
  8905.     push    cx
  8906.     mov    cx,low_rgt        ; margins, cl = right margin
  8907.     mov    bl,dh            ; get row
  8908.     xor    bh,bh
  8909.     cmp    linetype [bx],0        ; single width line?
  8910.     je    atccp0            ; e = yes, single width
  8911.     shr    cl,1            ; halve right margin for double wides
  8912. atccp0:    test    flags.vtflg,ttd463+ttd470 ; DG terminal?
  8913.     jz    atccp0a            ; z = no
  8914.     mov    cl,mar_right
  8915.     cmp    dl,mar_left        ; left of margin?
  8916.     jae    atccp1            ; ae = no
  8917.     mov    dl,mar_right        ; go to right margin
  8918.     dec    dh            ; do a cursor up
  8919.     jmp    short atccp1        ; do a cursor up
  8920.  
  8921. atccp0a:cmp    dl,250            ; to left of left margin?(wide screen)
  8922.     jb    atccp1            ; b = no, go check right
  8923.     xor    dl,dl            ; set to left margin
  8924. atccp1: cmp    dl,cl            ; to right of right margin?
  8925.     jbe    atccp2            ; be = yes, go check top
  8926.     mov    dl,cl            ; set to right margin
  8927.  
  8928.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  8929.     jz    atccp2            ; z = no
  8930.     mov    dl,mar_left        ; to left margin
  8931.     jmp    atlf            ; do a LF operation now
  8932.  
  8933. atccp2:    pop    cx
  8934.     pop    bx
  8935.     test    vtemu.vtflgop,decom    ; Origin mode set?
  8936.     jnz    atccp5            ; nz = yes, stay in scrolling region
  8937.     or    dh,dh            ; above top of screen?
  8938.     jae    atccp3            ; ae = no, check bottom
  8939.     xor    dh,dh            ; stop here
  8940. atccp3: cmp    dh,byte ptr low_rgt+1    ; below bottom of screen?
  8941.     jbe    atccp4            ; be = no, stay in margins
  8942.     mov    dh,byte ptr low_rgt+1    ; stop at end of text screen
  8943.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  8944.     jne    atccp4            ; ne = no
  8945.     test    h19stat,h19l25        ; 25th line enabled?
  8946.     jnz    atccp4            ; nz = yes
  8947.     inc    dh            ; allow 25th line
  8948. atccp4:    ret
  8949.  
  8950. atccp5: cmp    dh,mar_top        ; above top of scrolling region?
  8951.     jae    atccp6            ; ae = no, check bottom
  8952.     mov    dh,mar_top        ; yes, stop there
  8953.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  8954.     jz    atccp6            ; z = no
  8955.     mov    dh,mar_bot        ; roll to bottom
  8956.     ret
  8957. atccp6: cmp    dh,mar_bot        ; below bottom perhaps?
  8958.     jbe    atccp4            ; be = no, return
  8959.     mov    dh,mar_bot        ; yes, stop at the bottom margin
  8960.     test    flags.vtflg,ttd463+ttd470 ; DG D463/D470?
  8961.     jz    atccp7            ; z = no
  8962.     mov    dh,mar_top        ; roll to top
  8963. atccp7:    ret
  8964. atccpc    endp
  8965.  
  8966.  
  8967. ; Routine to set cursor type (off, block, underline).
  8968. ; 4 = do not show, but keep block/underline attributes.
  8969. ; 2 = block, 1 = underline
  8970. atsctyp:cmp    flags.vtflg,ttheath    ; Heath-19?
  8971.     jne    atsct1            ; ne = no
  8972.     mov    al,h19ctyp        ; get cursor kind and on/off bit
  8973.     test    al,4            ; is cursor to be off?
  8974.     jz    atsct4            ; z = no, al has kind
  8975.     xor    al,al            ; turn off cursor
  8976.     jmp    short atsct4        ; do it
  8977. atsct1:    test    atctype,4        ; VTxxx cursor type, off?
  8978.     jnz    atsct3            ; z = no
  8979. atsct2:    mov    al,1            ; assume underline
  8980.     test    vtemu.vtflgop,vscursor    ; block?
  8981.     jnz    atsct3            ; nz = no, underline
  8982.     inc    al
  8983. atsct3:    mov    atctype,al        ; save VTxxx cursor type here
  8984. atsct4:    call    csrtype            ; set the cursor type
  8985.     ret
  8986.  
  8987. atdeb    proc    near            ; Debug, display all chars in tty style
  8988.     test    yflags,capt        ; capturing output?
  8989.     jz    atdeb3            ; z = no, forget this part
  8990.     call    fcptchr            ; give it captured character
  8991. atdeb3:    mov    bl,curattr        ; save attribute
  8992.     push    bx
  8993.     push    word ptr mar_top    ; save limited scrolling region
  8994.     push    ax            ; save character for a second
  8995.     mov    ah,curattr        ; get attribute
  8996.     call    clrblink        ; clear blink attribute
  8997.     call    clrunder        ; clear underline attribute
  8998.     mov    extattr,0        ; extended attribute
  8999.     mov    curattr,ah        ; store
  9000.     or    vtemu.vtflgop,decawm    ; set autowrap temporarily
  9001.     mov    mar_top,0        ; set scrolling region to entire page
  9002.     mov    al,byte ptr low_rgt+1
  9003.     mov    mar_bot,al
  9004.     pop    ax            ; restore character
  9005.     test    al,80h            ; high bit set?
  9006.     jz    atdeb0            ; z = not set
  9007.     push    ax            ; save the character for a second
  9008.     mov    al,7eh            ; output a tilde
  9009.     call    atnrm2
  9010.     pop    ax            ; restore character
  9011.     and    al,7fh            ; and remove high bit
  9012. atdeb0:    cmp    al,del            ; DEL?
  9013.     je    atdeb1            ; e = yes, output "^?"
  9014.     cmp    al,20h            ; control character?
  9015.     jnb    atdeb2            ; nb = no, just output char in al
  9016. atdeb1: push    ax            ; save the character for a second
  9017.     mov    al,5eh            ; output a caret
  9018.     call    atnrm2
  9019.     pop    ax            ; restore character
  9020.     add    al,40h            ; make ^letter (or ^? for DEL)
  9021.     and    al,7fh            ; clear bit 7 (for DEL)
  9022. atdeb2: call    atnrm2            ; output translated character
  9023.     pop    word ptr mar_top    ; restore scrolling region,
  9024.     pop    bx            ;  flags, and cursor attribute
  9025.     mov    curattr,bl
  9026.     ret
  9027. atdeb    endp
  9028. code1    ends
  9029.     end
  9030.