home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msk316src.zip / MSZIBM.ASM < prev   
Assembly Source File  |  1999-04-24  |  375KB  |  11,814 lines

  1.     NAME    mszibm
  2. ; File MSZIBM.ASM
  3.     include mssdef.h
  4. ;    Copyright (C) 1982, 1999, Trustees of Columbia University in the 
  5. ;    City of New York.  The MS-DOS Kermit software may not be, in whole 
  6. ;    or in part, licensed or sold for profit as a software product itself,
  7. ;    nor may it be included in or distributed with commercial products
  8. ;    or otherwise distributed by commercial concerns to their clients 
  9. ;    or customers without written permission of the Office of Kermit 
  10. ;    Development and Distribution, Columbia University.  This copyright 
  11. ;    notice must not be removed, altered, or obscured.
  12. ;
  13. ; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
  14. ; VT52, VT102, and VT320, Honeywell VIP7809, Prime PT200, DG D463 and D470,
  15. ; and Wyse-50. 
  16. ; Original version for VT100 done by James Harvey, Indiana Purdue Univ, for 
  17. ; MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ for 
  18. ; MS Kermit 2.29 et seq.
  19. ; Edit history
  20. ; 12 Jan 1995 version 3.14
  21. ; Last edit
  22. ; 12 Jan 1995
  23.  
  24.     public    anstty, ansini, ansrei, ansdsl, anskbi ; Entry points
  25.     public    ans52t, vsinit, tabset, tabclr, tekflg
  26.     public    mar_top, mar_bot, anspflg, scroll, cursor, curattr
  27.     public    dnparam, dparam, dlparam, dninter, dinter, emubufc, emubuf
  28.     public    emubufl, dcsstrf, upss, att_normal
  29.     public    GRptr, G0set, G1set, G2set, G3set
  30.     public    savezlen, savezoff, blinkdis, protectena, dghscrdis
  31.     public    linescroll, xltkey, dgkbl, dgwindcomp, atctype, dgcross
  32.     public    dgnctoggle, apcstring, dgd470mode, chrdef
  33.  
  34. public modeset, setptr, atrsm10, mkascii, mkaltrom, chrsetup
  35. ;
  36. ; DEC and VT are trademarks of Digital Equipment Corporation.
  37. ;
  38. ; Description of the global entry points and calls on external routines
  39. ; needed by this emulator.
  40. ;
  41. ; vsinit - start up routine called as Kermit initializes. Takes no arguments.
  42. ;       Sets up address pointers to tabs, reads default terminal parameters
  43. ;       reads current screen coloring. Examines and updates structure
  44. ;       "vtemu." which is how mssset communicates changed information
  45. ;       about many Set Term parameters; "flags." is a Kermit structure
  46. ;       carrying the other Set Term parameters.
  47. ; anstty - starting point for displaying a character, delivered in AL.
  48. ;       Returns when the display operation is completed and that may
  49. ;       take many many instructions. All normal "characters received by
  50. ;       the terminal" are provided by calling anstty with the char in AL.
  51. ; ansini - entry point to initialize the emulator. It requires information
  52. ;       from msy in four registers: the Kermit terminal routine flags
  53. ;       "yflags" (used mainly to sense debug mode and the mode line toggle)
  54. ;       "low_rgt" (bh = row, bl = column of the lower right display corner)
  55. ;       "lbaudtab" (index into baud rate table, for status reporting)
  56. ;       "lpartab" (index into parity table, for status reporting)
  57. ;       Ansini causes a full reset of the emulator, including screen 
  58. ;       clearing and a beep. Ansini is also called by msy in response to
  59. ;       sensing the Alt = key combination to fully reset the emulator.
  60. ; ansrei - entry point to reinitialize the emulator. Nearly the same as
  61. ;       ansini except operating flags, tabs, etc are retained from the
  62. ;       previous emulator session. Items which can be changed by Set Term
  63. ;       are examined and updated. The msy flags "yflags" are needed.
  64. ;       This is the warm-restart entry point used when connect mode
  65. ;       is reentered gracefully. The screen is cleared only if the coloring
  66. ;       has changed. The starting cursor location is whereever msy puts it.
  67. ; ansdsl - display "led" (status line) information. Invoked by msy when
  68. ;       the mode line is constructed so the emulator can write the 
  69. ;       terminal type and the VT100 led status lights when Connect mode
  70. ;       is started. Requires "yflags" from msy to sense whether the mode
  71. ;       line is to be shown.
  72. ; anskbi - a routine called by msy to notify the emulator that a character
  73. ;       is available from the keyboard. No character is read, just flag
  74. ;       ttkbi is set. This is actually used only to beep when the cursor
  75. ;       goes beyond column 72 and the margin bell flag is on.
  76. ; ans52t - called by msy to change terminal types "on the fly" without
  77. ;       fully updating all operating parameters and without losing setup
  78. ;       information. Msy senses the Alt minus key and calls ans52t with
  79. ;       no arguments. Ans52t cycles among terminal types.
  80. ; other modules in msy are called by this file to handle screen scrolling
  81. ;       mode line on/off, output to the serial port (reports), screen
  82. ;       particulars (location, cursor shape, blanking). The list is
  83. ;       the set of code extrn procedures below; all are in file msy.
  84. ;
  85. ; data exchange is directly with msy to assist in scrolling (varaibles
  86. ;       "mar_top", "mar_bot") and in sensing the non-connect
  87. ;       mode screen coloring ("scbattr"). Screen coloring controlled by
  88. ;       the emulator is not permitted to influence the non-connect mode
  89. ;       screens whereas the emulator attempts to use the regular Kermit
  90. ;       screen colors as defaults. The kind of terminal to emulate is
  91. ;       held in word "flags.vtflg" which is set by Set Term and by this
  92. ;       module for global information within Kermit.
  93. ;
  94. ; Many things have been added or modified since James Harvey donated this
  95. ;       code to Columbia University for use in Kermit.              [jrd]
  96. ; Character sets in VT320 and VT102 modes:
  97. ;  ASCII ("B"/94)
  98. ;  ISO Latin-1 ("A"/96)
  99. ;  DEC UK-ASCII ("A"/94, available only in VT102 mode)
  100. ;  DEC Supplemental Graphics ("%5"/94),
  101. ;  DEC Technical Graphics (">"/94), an extension taken from the VT340,
  102. ;  DEC Special Graphics ("0"/94 and "2"/94)
  103. ;  ALT-ROM (Kermit specific, "1"/94/96)
  104. ;  DEC National Replacement Chars (all 12 sets)
  105. ;  Startup:
  106. ;   GL = G0 = G1 = ASCII (or ALT-ROM if selected by SET TERM CHAR ALT-ROM),
  107. ;   GR = G2 = G3 = ISO Latin-1.
  108. ;   When an NRC is selected by SET TERM CHAR <country> and enabled by
  109. ;   CSI ? 42 h the NRC table replaces G0..G3 at the time of selection. When
  110. ;   thus designated and selected incoming characters are forced to 7 bits and
  111. ;   8-bit Controls (outgoing) is turned off. No designation means no selection.
  112. ;  Selecting a character set with the wrong sized designator yields no action.
  113. ;
  114. ;  Startup in D463/D470 mode:
  115. ;   GL = G0 = ASCII
  116. ;   GR = G1 = Data General International if using 8-bit characters, else
  117. ;   GR = G1 = Data General Word Processing.
  118. ;
  119. ; References:
  120. ;  "PT200 Programmers Reference Guide", 1984, Prime Computer # DOC 8621-001P
  121. ;  "Video Terminal Model H19, Operation", 1979, Heath Company # 595-2284-05
  122. ;  "VT100 User's Guide", 2nd ed., Jan 1979, DEC # EK-VT100-UG
  123. ;  "Rainbow 100+/100B Terminal Emulation Manual", June 1984, DEC # QV069-GZ
  124. ;  "Installing and Using The VT320 Video Terminal", June 1987,
  125. ;    DEC # EK-VT320-UU-001
  126. ;  "VT320 Programmer Reference Manual", July 1987, DEC # EK-VT320-RM-001
  127. ;  "VT330/340 Programmer Ref Manual", 2nd ed, May 1988,
  128. ;    Vol 1: Text programming DEC # EK-VT3XX-TP-002
  129. ;    Vol 2: Graphics programming DEC # EK-VT3XX-GP-002
  130. ;  "Programming the Display Terminal: Models D217, D413, and D463", Data
  131. ;    General Corp, 014-00211-00, 1991.
  132. ;  "Installing and Operating Your D216E+, D217, D413, and D463 Display
  133. ;    Terminals", Data General Corp, 014-002057-01, 1991.
  134. ;  "Dasher D470C Color Display Terminal, Programmer's Reference Manual",
  135. ;    Data General Corp, 014-001015, 1984.
  136. ;  "WY-50 Display Terminal Quick-Reference Guide", Wyse Technology,
  137. ;    Wyse No. 88-021-01, 1983.
  138. ; ---------------------------------------------------------------------------
  139.  
  140. vswidth    equ    207            ; cross correlate with msyibm
  141. swidth  equ     207            ; assumed max screen width
  142. slen    equ    60            ; assumed max screen length 
  143. maxparam equ    10            ; number of ESC and DCS Parameters
  144. maxinter equ    10            ; number of ESC and DCS Intermediates
  145. gsize    equ    128            ; character set storage size
  146.                     ; anspflg bit field definitions:
  147. ; prtscr equ    1            ; used in msyibm print screen toggle
  148. vtautop    equ    1            ; autoprint enabled (1)
  149. vtcntp    equ    2            ; controller print enabled (1)
  150. vtextp    equ    4            ; printer extent set (1)
  151. vtffp    equ    10h            ; form feed wanted at end of print (1)
  152.  
  153. h19l25    equ    1            ; h19stat, line 25 enabled
  154. h19alf    equ    2            ; h19stat, auto cr/lf when cr seen
  155.                     ; display save-info for dspstate
  156. dsptype    equ    1            ; main (0) or status line (1) flag
  157. dspdecom equ    2            ; remembered origin mode (1=on)
  158.  
  159. att_bold    equ    08h        ; bold        in main video word
  160. att_blink    equ    80h        ; blinking    in main video word
  161. att_protect    equ    01h        ; protected    in vsatt
  162. att_uline    equ    02h        ; underscored    in vsatt
  163. att_rev        equ    04h        ; reversed video  in vsatt
  164. ;softfonts    are    top 5 bits of extended attributes
  165.  
  166. braceop    equ    7bh            ; opening curly brace
  167. bracecl    equ    7dh            ; closing curly brace
  168.  
  169. ; DEC emulator status flags (bits in words vtemu.vtflgst and vtemu.vtflgop)
  170. ;anslnm  equ    1H            ; ANSI line feed/new line mode
  171. ;decawm  equ    2H            ; DEC autowrap mode
  172. ;decscnm equ    80H            ; DEC screen mode
  173. ;decckm  equ    200H            ; DEC cursor keys mode
  174. ;deckpam equ    400H            ; DEC keypad application mode
  175. ;decom   equ    800H            ; DEC origin mode
  176. ;deccol     equ    1000H            ; DEC column mode (0=80 col)
  177. ;decanm  equ    2000H            ; ANSI mode
  178. ;;dececho equ    4000H            ; ANSI local echo on (1 = on)
  179.      
  180. ; Terminal SETUP mode flags (joint with bits above, some name dups)
  181. ;vsnewline    equ    1H        ; ANSI new line (0 = off)
  182. ;vswrap        equ    2H        ; Line wrap around (0 = no wrap)
  183. ;vsnrcm        equ    4H        ; National Rep Char set (0=none)
  184. ;vswdir        equ    8H        ; Writing direction (0=left, 1 right)
  185. ;vskeyclick    equ    10H        ; Keyclick (0 = off)
  186. ;vsmarginbell    equ    20H        ; Margin bell (0 = off)
  187. ;vscursor    equ    40H        ; Cursor (0 = block, 1 = underline)
  188. ;vsscreen    equ    80H        ; Screen (0 = normal, 1 = rev. video)
  189. ;vscntl        equ    100h        ; 8 or 7 bit controls (1 = 8-bit)
  190. ;vshscroll    equ    4000h        ; horiz scroll (0=auto, 1=manual)
  191. ;vscompress    equ    8000h        ; compressed text(0=graphics,1=132col)
  192.  
  193. ;vsdefaults    equ    0+vscursor
  194.  
  195. ; Kinds of terminals available
  196. ;ttgenrc    equ    0        ; no emulation done by Kermit
  197. ;ttheath    equ    1        ; Heath-19
  198. ;ttvt52        equ    2        ; VT52
  199. ;ttvt100    equ    4        ; VT100
  200. ;ttvt102    equ    8        ; VT102
  201. ;ttvt220    equ    10h        ; VT220
  202. ;ttvt320    equ    20h        ; VT320
  203. ;tttek        equ    40h        ; Tektronix 4010
  204. ;tthoney    equ    80h        ; Honeywell VIP7809
  205. ;ttpt200    equ    100h        ; Prime PT200
  206. ;ttd463        equ    200h        ; Data General D463
  207. ;ttd470        equ    400h        ; Data General D440
  208. ;ttwyse        equ    800h        ; Wyse-50
  209. ;ttd217        equ    1000h        ; Data General D217 (D463 w/217 ident)
  210. ;ttansi        equ    2000h        ; Ansi.sys flavor (VT100 base)
  211. ;TTTYPES    equ    15        ; Number of terminal types defined
  212. ;; tekflg bits in byte
  213. ;tek_active equ    1            ; actively in graphics mode
  214. ;tek_tek equ    2            ; Tek terminal
  215. ;tek_dec equ    4            ; Tek submode of DEC terminals
  216. ;tek_sg    equ    8            ; special graphics mode
  217.  
  218. ;emulst    struc        ; structure of vtemu.xxx for VTxxx emulator
  219. ;vtflgst dw    0    ; DEC setup flags (from SET)
  220. ;vtflgop dw    0    ; DEC runtime flags, like setup flags (here & STAT)
  221. ;vttbs    dw    0    ; pointer to default tab stops, for SET
  222. ;vttbst    dw    0    ; pointer to active tab stops, for STATUS
  223. ;vtchset db    1    ; value of default character set (1=US-ascii)
  224. ;att_ptr dw    0    ; pointer to normal & reverse video attributes
  225. ;emulst    ends
  226. ;;;;;;;;;;;;;;;;  end references ;;;;;;;;;;;;;;;;;;;;
  227.  
  228. data    segment
  229.     extrn    vtemu:byte, scbattr:byte, flags:byte, yflags:byte
  230.     extrn    crt_lins:byte, rxtable:byte, denyflg:word, low_rgt:word
  231.     extrn    vtclear:byte, dosnum:word, apcenable:byte, trans:byte
  232.     extrn    parstate:word, pardone:word, parfail:word, nparam:word
  233.     extrn    param:word, lparam:byte, ninter:word, inter:byte, ttyact:byte
  234.     extrn    L1cp437:byte, L1cp850:byte, L1cp860:byte, L1cp863:byte
  235.     extrn    L1cp865:byte, L5cp866:byte, modbuf:byte, extattr:byte
  236.     extrn    rdbuf:byte
  237.     extrn    vtenqenable:byte, vtcpage:word, prnhand:word,reset_color:byte
  238.     extrn    vtclrflg:byte, enqbuf:byte, crdisp_mode:byte
  239.     extrn    isps55:byte        ; [HF]940130 Japanese PS/55 mode
  240.     extrn    ps55mod:byte        ; [HF]940206 PS/55 modeline status
  241. ifndef    no_graphics
  242.     extern    softptr:word, chcontrol:byte
  243. endif    ; no_graphics
  244.  
  245.     even                    ; C0 7-bit control code table
  246. ansc0    dw    5 dup (atign)            ; NUL, SOH, STX, ETX, EOT
  247.     dw    atenq,atign,vtbell,atbs,atht     ; ENQ, ACK, BEL, BS,  HT
  248.     dw    atlf, atlf, atff, atcr,atls1    ; LF,  VT,  FF,  CR,  SO
  249.     dw    atls0, 4 dup (atign)        ; SI,  DLE, DC1, DC2, DC3
  250.     dw    4 dup (atign), atcan        ; DC4, NAK, SYN, ETB, CAN
  251.     dw    atign, atnrm, atesc,atign,atign    ; EM,  SUB, ESC, FS,  GS
  252.     dw    2 dup (atign)            ; RS,  US
  253.  
  254.                         ; C1 8-bit control code table
  255. ansc1    dw    4 dup (atign), atind        ; ignore 4, IND
  256.     dw    atnel,atign,atign,athts,atign    ; NEL, SSA, ESA, HTS, HTJ
  257.     dw    atign,atign,atign,atri, atss2    ; VTS, PLD, PLU, RI,  SS2
  258.     dw    atss3,atdcs,3 dup (atign)    ; SS3, DCS, PU1, PU2, STS
  259.     dw    atign,atign,protena,protdis,atign ; CCH, MW, SPA, EPA,ignore
  260.     dw    atign,atign,atcsi,atgotst,atdcsnul; ignore 2, CSI, ST, OSC
  261.     dw    atdcsnul, atapc            ; PM,  APC
  262.  
  263. ; Heath-19 mode escape follower table
  264. h19esc    db    36            ; number of entries
  265.     dw    h19ejt            ; address of action routines
  266.     db    '<=>@A','BCDEF','GHIJK','LMNOY','Z[bjk','lnopq','rvwxy','z'
  267.  
  268. ; Dispatch table for Heath-19 escape sequence table h19esc
  269.     even
  270. h19ejt    dw    h19sans, atkpam,  atkpnm,  entins,  atcuu    ; '<=>@A'
  271.     dw    atcud,   atcuf,   atcub,   h19clrs, v52sgm    ; 'BCDEF'
  272.     dw    chrdef,  atcup,   atri0,   ated,    atel    ; 'GHIJK'
  273.     dw    inslin,  dellin,  atdelc,  noins,   v52pos    ; 'LMNOY'
  274.     dw    decid,   h19csi,  h19esos, h19sc,   h19rc    ; 'Z[bjk'
  275.     dw    h19erl,  hrcup,   h19ero,  h19herv, h19hxrv    ; 'lnopq'
  276.     dw    atnorm,  h19wrap, h19nowrp,h19smod, h19cmod    ; 'rvwxy'
  277.     dw    atxreset                    ; 'z'
  278.  
  279. h19ans    db    21            ; Heath-19 ANSI style escape sequences
  280.     dw    h19jmp            ; address of action routine table
  281.     db    'ABCDH','JKLMP','fhlmn','pqrsu','z'
  282.  
  283. ; Heath-19 action table for h19ans
  284.     even
  285. h19jmp    dw    atcuu, atcud, atcuf,  atcub,  atcup        ; 'ABCDH'
  286.     dw    h19ed, atel,  inslin, dellin, atdelc        ; 'JKLMP'
  287.     dw    atcup, atsm,  atrm,   atsgr,  rpcup        ; 'fhlmn'
  288.     dw    atign, atign, atign,  h19sc,  h19rc        ; 'pqrsu'
  289.     dw    atxreset                    ; 'z'
  290.  
  291. ; VT52 compatibility mode escape follower table
  292. v52esc    db    23            ; number of entries
  293.     dw    v52ejt            ; address of action routines
  294.     db    '78<=>', 'ABCDF', 'GHIJK', 'VWXYZ'
  295.     db    ']',5eh,5fh        ; 5eh = caret, 5fh = underscore
  296.  
  297. ; Dispatch for v52esc table
  298.     even
  299. v52ejt    dw    atsc,   atrc,   v52ans, atkpam, atkpnm        ; '78<=>'
  300.     dw    atcuu,  atcud,  atcuf,  atcub,  v52sgm        ; 'ABCDF'
  301.     dw    chrdef, atcup,  atri0,  ated,   atel        ; 'GHIJK'
  302.     dw    v52pl,  v52pcb, v52pce, v52pos, decid        ; 'VWXYZ'
  303.     dw    v52ps,  v52pcb, v52pce                ; ']^_'
  304.  
  305. ; Prime PT200 escape follower table
  306. pt200esc db    38            ; number of entries
  307.     dw    p20ejt            ; address of action routines
  308.     db    '01234','5678<', '=>?AB', 'DEFGH', 'JMNOP'
  309.     db    'Z[\]',5eh        ; 5eh = caret
  310.     db    5fh,'cno',7bh        ; 5fh=underscore, 7bh=left curly brace
  311.     db    7ch,7dh,7eh   ; 7ch=vert bar, 7dh=right curly brace, 7eh=tilde
  312.  
  313. ; Dispatch for p20esc
  314.     even
  315. p20ejt    dw    atdgf0, atdgf1, atdgf0, atsdhl, atsdhl         ; '01234'
  316.     dw    4 dup (atsdhl), atdgfu                ; '5678<'
  317.     dw    atkpam, atnorm, p20ed, atdgfA, atdgfB         ; '=>?AB'
  318.     dw    atind,  atnel,  ats7c, ats8c,  athts        ; 'DEFGH'
  319.     dw    ated,   atri,   atss2, atss3,  atdcs        ; 'JMNOP'
  320.     dw    decid,  atcsi,  atgotst, 2 dup(atdcsnul)    ; 'Z[\]^'
  321.     dw    atdcsnul, atxreset,atls2, atls3, atpriv        ; '_cno{'
  322.     dw    atls3r, atls2r, atls1r                ; '|}~'
  323.  
  324. ; VT320/VT102/VT100/Honewell ANSI mode escape follower table
  325. ansesc    db    52            ; number of entries
  326.     dw    ansejt            ; address of action routines
  327.     db    '01234','56789','<=>?@'
  328.     db    'ABCDE','FGHIJ','KLMN','OPQRV'
  329.     db    'WYZ[\',']',5eh,5fh    ; 5eh = caret, 5fh=underscore
  330.     db    60h,'c','fgno',7bh    ; 7bh=left curly brace,  7ch=vert bar
  331.     db    7ch,7dh,7eh        ; 7dh=right curly brace, 7eh=tilde
  332.  
  333. ; Dispatch for ansesc table
  334.     even
  335. ansejt    dw    atdgf0, atdgf1, atdgf0, atsdhl, atsdhl         ; '01234'
  336.     dw    4 dup (atsdhl), atdgnrc                ; '56789'
  337.     dw    atdgfu,atkpam, atdgft, atdgfq, atdgfB        ; '<=>?@'
  338.     dw    atdgfA,atdgfB, atdgnrc, atind0, atnel0         ; 'ABCDE'
  339.     dw    ats7c, ats8c, athts0, atdgfI, atdgfJ        ; 'FGHIJ'
  340.     dw    atdgnrc,atdgnrc,atri0, atss2            ; 'KLMN'
  341.     dw    atss3, atdcs0, atdgnrc, atdgnrc, dgpton        ; 'OPQRV'
  342.     dw    dgptoff, decid, atdgnrc, atcsi0, atgotst0    ; 'WYZ[\'
  343.     dw    2 dup (atdcsnul0),atapc, athoncls, atxreset    ; ']^_`c'
  344.     dw    atdgnrc,atdgnrc,atls2,atls3, atpriv        ; 'fgno{'
  345.     dw    atls3r, atls2r, atls1r                ; '|}~'
  346.  
  347. ; Final char table for VT320/VT102/VT100/Honeywell ANSI control sequences
  348. anstab    db    40            ; number of entries
  349.     dw    ansjmp            ; address of action routines
  350.     db    '@ABCD','EFGHI','JKLMP', 'Xacde','fghil','mnpqr','uwxyz'
  351.     db    7ch,7dh,7eh        ; 7dh=right curly brace, 7eh=tilde
  352.     db    'su'
  353.  
  354. ; Dispatch for anstab table
  355.     even
  356. ansjmp    dw    ansich, atcuu,  atcud,  atcuf,  atcub        ; '@ABCD'
  357.     dw    atcnl,  atcpl,  atcha,  atcup,  atcht        ; 'EFGHI'
  358.     dw    ated,   atel,   inslin, dellin, atdelc        ; 'JKLMP'
  359.     dw    atech,  atcuf,  atda,   atcva,    atcud          ; 'Xacde'
  360.     dw    atcup,  attbc,  atsm,   ansprt, atrm        ; 'fghil'
  361.     dw    atsgr,  atdsr,  decscl, decsca, atstbm        ; 'mnpqr'
  362.     dw    atrqtsr,atrqpsr,atreqt, atctst, atxreset    ; 'uwxyz'
  363.     dw    atscpp, atsasd, atssdt                ; '|}~'
  364.     dw    atsc                        ; 's'
  365.  
  366. ; Final character table for Device Control Strings (DCS, ESC P)
  367. dcstab    db    5            ; number of entries
  368.     dw    dcsjmp            ; address of action routines
  369.     db    'pqu',7bh,7ch        ; 7bh = left curly brace
  370.  
  371. ; Dispatch for dcstab table
  372.     even
  373. dcsjmp    dw    atcrqq, atcrq, atupss, atdcsnul, atudk        ; 'pqu{|'
  374. ;;; DCS Ps $ p string ST   page 209 restore color palette
  375.  
  376. ; Data General D463/D470 terminal section
  377. dgescape equ    1eh                ; DG escape char (RS)
  378.  
  379.     even                ; DG C0 7-bit control code table
  380. dgc0    dw    atign,dgprtfm,dgrevidoff,dgblkena,dgblkdis;NUL,SOH,STX,ETX,EOT
  381.     dw    dgrwa,atign,vtbell,dgwinhome,atign  ; ENQ, ACK, BEL, BS,  HT
  382.     dw    dglf, dgeol, dgewin, dgcr,dgblkon   ; LF,  VT,  FF,  CR,  SO
  383.     dw    dgblkoff,dgwwa,dgprtwn,dgrollena,dgrolldis ;SI,DLE,DC1,DC2,DC3
  384.     dw    dguson,dgusoff,dgrevidon,dgcuu,dgcuf ; DC4, NAK, SYN, ETB, CAN
  385.     dw    dgcub, dgcud,atign,dgdimon,dgdimoff ; EM, SUB, ESC, FS, GS
  386.     dw    dgesc, atign                ; RS, US
  387.  
  388. ; DG D463/D470 DG-escape (RS) follower table
  389.  
  390. dgesctab db    17            ; number of entries
  391.     dw    dgejt            ; address of action routines
  392.     db    'ABCDE','FGHIJ','KLMNO','PR'
  393.  
  394. ; Dispatch for dgesctab table
  395.     even
  396. dgejt    dw    dgsfc, dgsbc, dgrmid, dgrevidon, dgrevidoff     ; 'ABCDE'
  397.     dw    dgFSERIES, dgGSERIES, dgscrup, dgscrdn, dginsc    ; 'FGHIJ'
  398.     dw    dgdelc, dggline, atign, atls1, atls0        ; 'KLMNO'
  399.     dw    dgunix, dgRSERIES                ; 'PR'
  400.  
  401. fltable    db    61                ; RS F letter dispatch table
  402.     dw    faction                ; table of action routines
  403.     db    '789;<', '>?ABC', 'DEFGH', 'IJKLM', 'NOPQR'
  404.     db    'STUVW', 'XYZ[\', ']^_`a', 'bcdef', 'hikmq'
  405.     db    'rstvw', 'xz{}~', '@'
  406.  
  407. ; Dispatch for fltable table
  408.     even
  409. faction    dw    dgign2n, atign, dggrid, atign, atign        ; '789;<'
  410.     dw    dgalign, dgprt, atreset, dgsetw, dgsleft    ; '>?ABC'
  411.     dw    dgsright, dgescn, dgeeos, dgshome, dginsl    ; 'DEFGH'
  412.     dw    dgdell, dgnarrow, dgwide, dgpton, dgptoff    ; 'IJKLM'
  413.     dw    dgchatr, dgrhso, dgwsa, dgsct, dgdefch        ; 'NOPQR'
  414.     dw    dgscs, dgign1n, dg78bit, protena, protdis    ; 'STUVW'
  415.     dw    dgsetmar, dgsetamar, dgrnmar, dgilbm, dgdlbm    ; 'XYZ[\'
  416.     dw    dghsdis, dghsena, dgshcol, dgprt3a, atign    ; ']^_`a'
  417.     dw    dgrsa, dgscmap, dgrchr, dgresch, dgskl        ; 'bcdef'
  418.     dw    atign, atign, atnorm, atnorm, dgdchs         ; 'hikmq'
  419.     dw    dgsclk, dgign1n, dgrss, dgrwc, dgrnmod        ; 'rstvw'
  420.     dw    dgppb, dgs25l, dgsmid, dgnscur, dgign2n        ; 'xz{}~'
  421.     dw    dgtoansi                    ; '@'
  422.  
  423. gltable    db    14                ; RS G letter dispatch table
  424.     dw    gaction                ; table of action routines
  425.     db    '018:>','?@ABC','HInp'
  426.  
  427. ; Dispatch for gltable table
  428.     even
  429. gaction    dw    dggarc, dggbar, dggline, dggpoly, dggcloc    ; '018:>'
  430.     dw    dggrcl, dggcatt, dggcrst, dggcon, dggcoff    ; '?@ABC'
  431.     dw    dggctrk, atnorm, atnorm, dggsetp        ; 'HInp'
  432.  
  433. rltable    db    6            ; Data General D463/D470 RS R series
  434.     dw    raction
  435.     db    '@ABCD','E'
  436.  
  437. ; Dispatch for rltable table
  438. raction    dw    dgign2n, dgsps, dgsfield, dgspage, dgsdo    ; '@ABCD'
  439.     dw    dgdhdw                        ; 'E'
  440.  
  441. dgescftab db    34            ; DG ESC.. Final escape follower tab
  442.     dw    dgescfjmp        ; address of action routines
  443.     db    '01234','56789',':;<=>','?ABHI','JKL'
  444.     db    'cDEMN','OPVW[','\'
  445.  
  446. dgescfjmp dw    23 dup (dgesc_ch)      ; '01234','56789',':;<=>','?ABHI','JKL'
  447.     dw    dgesc_c,dgesc_D,dgesc_E,dgesc_M,atss2    ; 'cDEMN'
  448.     dw    atss3,atdcs0,dgesc_V,dgesc_W,atcsi0    ; 'OPVW['
  449.     dw    atgotst0                ; '\'
  450.  
  451. dganstab db    28            ; DG CSI .. Final  char dsptch
  452.     dw    dgcjmp            ; address of action routines
  453.     db    '@ABCD','HJKLM','PSTfh','ilmnp','qrstu','vwx'
  454.  
  455.                     ; DG ANSI dispatch table
  456. dgcjmp    dw    dgcsi_@,dgcsi_A,dgcsi_B,dgcsi_C,dgcsi_D    ; '@ABCD'
  457.     dw    dgcsi_f,ated,  atel,   dgcsi_L,dgcsi_M    ; 'HJKLM'
  458.     dw    atdelc,dgcsi_S,dgcsi_T,dgcsi_f,dgcsi_h    ; 'PSTfh'
  459.     dw    dgcsi_i,dgcsi_sl,atsgr,dgcsi_n,dgcsi_sp    ; 'ilmnp'
  460.     dw    dgcsi_q,dgcsi_r,dgcsi_ss,dgcsi_st,dgcsi_u ; 'qrstu'
  461.     dw    dgcsi_v,dgcsi_w,dgcsi_x            ; 'uwx'
  462.  
  463. dgdcstab db    6            ; DG DCS dispatch table
  464.     dw    dgdcsjmp
  465.     db    'ABCDE','F'
  466.  
  467. dgdcsjmp dw    dgdefch,dggline,dggset2,dgsetw,dggpoly        ; 'ABCDE'
  468.     dw    dgdcs_F                        ; 'F'
  469.  
  470.                 ; Wyse-50 control codes
  471.     even                    ; C0 7-bit control code table
  472. wyc0    dw    5 dup (atign)            ; NUL, SOH, STX, ETX, EOT
  473.     dw    atenq,atign,vtbell,wycub,atht     ; ENQ, ACK, BEL, BS,  HT
  474.     dw    atlf, wycup, dgcuf, atcr,atign    ; LF,  VT,  FF,  CR,  SO
  475.     dw    atign, atign, atign, wyprton, atign ; SI,  DLE, DC1, DC2, DC3
  476.     dw    wyprtoff,3 dup (atign), wy_d2    ; DC4, NAK, SYN, ETB, CAN
  477.     dw    atign, wysub, wyesc,atign,atign    ; EM,  SUB, ESC, FS,  GS
  478.     dw    wyhome, atlf1            ; RS,  US
  479.  
  480.                 ; Wyse-50 escape dispatch table
  481. wyescf    db    50
  482.     dw    wyejt                ; table of action routines
  483.     db    ' !&',27h,'(',')*+,-','./012','89:;=','?ADEF'
  484.     db    'GHIMN','OQRTV','WY`ab','dijqr','txyz{'
  485.  
  486. wyejt    dw    wyenq,wy_bang,protena,protdis,clrprot    ; ' !&'('
  487.     dw    setprot,wy_star,wy_star,wy_comma,wy_minus ; ')*+,-'
  488.     dw    wy_dot,wy_slash,wytab0,athts,wytab2    ; './012'
  489.     dw    wy_8,wy_9,wysub,wysub,wy_equ        ; '89:;='
  490.     dw    wy_query,wy_A,atnorm,inslin,wy_F    ; '?ADEF'
  491.     dw    wy_G,wy_H,wy_I,wy_M,wy_N        ; 'GHIMN'
  492.     dw    wy_O,ansich,wy_R,atel0,wy_V        ; 'OQRTV'
  493.     dw    atdelc,ereos,wy_acc,wy_sa,wy_b        ; 'WY`ab'
  494.     dw    wy_d,atht,atri,wy_q,wy_sr        ; 'dijqr'
  495.     dw    atel0,wy_x,ereos,wy_z,wyhome        ; 'txyz{'
  496.  
  497. ;; Notes on char set idents
  498. ; Kermit ident         size    ident    comment            designator
  499. ;    0        94    'B',0    ASCII             "B"
  500. ;    1        94    'A',0    British NRC         "A"
  501. ;    2        94    '4',0    Dutch NRC         "4"
  502. ;    3        94    '5',0    Finnish    NRC (also "C")    "5"
  503. ;    4        94    'R',0    French NRC (also "f")    "R"
  504. ;    5        94    '9',0    French Canadian NRC     "9"
  505. ;    6        94    'K',0    German NRC        "K"
  506. ;    7        94    'Y',0    Italian    NRC        "Y"
  507. ;    8        94    '`',0    Norwegian/Danish NRC    "`"
  508. ;    9        94    '%','6'    Portugese NRC ("L","g") "%6"
  509. ;    10        94    'Z',0    Spanish    NRC        "Z"
  510. ;    11        94    '7',0    Swedish    NRC        "7"
  511. ;    12        94    '=',0    Swiss NRC        "="
  512. ;    13        94    '=','%' DEC Hebrew NRC        "=%'
  513. ;    14        94    '1',0    Alt-ROM            "1"
  514. ;    15        96    '?',0    Transparent        "?"
  515. ;    16        96    'A',0    Latin1            "A"
  516. ;    17        94    '%','5'    DEC Multinat (Sup Gr)     "%5"
  517. ;    18        94    '>',0    DEC Technical        ">"
  518. ;    19        94    '0',0    DEC-Special          "0","2"
  519. ;    20        94    'D','I' DG International    "DI"
  520. ;     21        94    'D','L'    DG Line Drawing        "DL"
  521. ;    22        94    'D','W' DG Word Processing    "DW"
  522. ;    23        96    'B',0   Latin2            "B"
  523. ;    24        96    'H',0   Hebrew-ISO        "H"
  524. ;    25        94    '"','4' DEC Hebrew        ""4"
  525. ;    26        94    'YW'    Wyse-50 graphics    "YW"
  526. ;    27        96    'H','P'    HP-Roman8        "HP"
  527. ;    28        96    'CI'  ISO 8859-5 Latin/Cyrillic "CI"
  528. ;    29        96    'CK'  KOI8-Cyrillic        "CK"
  529. ;    30        96    'CS'  Short-KOI Cyrillic    "CS"
  530. ;      100 - 131    94    'D','U' DG soft sets        "DU"
  531. ;      141 (128+13)    94    'I' JIS-Katanaka (JIS X 201)    "I"
  532. ;      142 (128+14)    94    'J' JIS-Roman (JIS X 201)    "J"
  533. ;      215 (128+87)    94    'B','$' JIS-Kanji (JIS X 208)    "B$"
  534. ;; End of notes
  535.  
  536. ; Heath-19 special graphics characters to CP437. Use as offsets from caret
  537. ; (94D)
  538. hgrtab    db    249, 17,179,196,197    ; caret,underscore,accent grave,a,b
  539.     db    191,217,192,218,241    ; c,d,e,f,g
  540.     db     26,177,219, 25,220    ; h,i,j,k,l
  541.     db    220,223,223,223,222    ; m,n,o,p,q
  542.     db     16,194,180,193,195    ; r,s,t,u,v
  543.     db    'X','/','\',223,220    ; w,x,y,z,left curly brace
  544.     db    221,222, 20        ; vertical bar,right curly brace,tilde
  545. hgrtabl    equ ($-hgrtab)
  546.  
  547. ; Data General Line Drawing Character Set, based on CP437, starting in 10/0
  548. dgldc    db    20h,0dah,0bfh,0c0h,0d9h,0c2h,0b4h,0c3h        ; 2/0
  549.     db    0c1h,0c5h,0b3h,0c4h,0c2h,0b4h,0c3h,0c1h
  550.     db    0b3h,0c9h,0bbh,0c8h,0bch,0cbh,0b9h,0cch        ; 3/0
  551.     db    0cah,0ceh,0bah,0cdh,0c4h,0f6h,9bh,3fh
  552.     db    3fh,3fh,3fh                    ; 4/0
  553. dgldclen equ    ($-dgldc)
  554.  
  555. ; VT320/VT102 "Special graphics" set translation table for characters 95..126d
  556. ; when the special graphics set is selected. Some characters (98, 99, 100,
  557. ; 101, 104, 105, 111, 112, 114, 115, and 116) do not have exact equivalents
  558. ; in the available set on the IBM, so a close substitution is made.
  559. ; Table is indexed by ASCII char value minus 95 for chars 95..126d.
  560. sgrtab    db     32,  4,177, 26, 23,  27, 25,248,241, 21
  561.     db     18,217,191,218,192, 197,196,196,196,196
  562.     db    196,195,180,193,194, 179,243,242,227,157
  563.     db    156,250
  564. sgrtabl    equ    $-sgrtab
  565.  
  566.  
  567.     ; DEC National Replacement Char sets, referenced to Latin1
  568. nrclat    db    23h,40h,5bh,5ch,5dh,5eh        ; 0, ASCII, "B", dispatch ref
  569.     db    5fh,60h,7bh,7ch,7dh,7eh
  570.     db    94,'B',0            ; 94 byte set, letter pair
  571.     db    0a3h,40h,5bh,5ch,5dh,5eh    ; 1, British, "A"
  572.     db    5fh,60h,7bh,7ch,7dh,7eh
  573.     db    94,'A',0
  574.     db    0a3h,0beh,0ffh,0bdh,7ch,5eh    ; 2, Dutch, "4"
  575.     db    5fh,60h,0a8h,66h,0bch,0b4h
  576.     db    94,'4',0
  577.     db    23h,40h,0c4h,0d6h,0c5h,0dch    ; 3, Finnish, "5"
  578.     db    5fh,0e9h,0e4h,0f6h,0e5h,0fch
  579.     db    94,'5',0
  580.     db    0a3h,0e0h,0b0h,0e7h,0a7h,5eh    ; 4, French, "R"
  581.     db    5fh,60h,0e9h,0f9h,0e8h,0fbh
  582.     db    94,'R',0
  583.     db    23h,0e0h,0e2h,0e7h,0eah,0eeh    ; 5, French Canadian, "9"
  584.     db    5fh,0f4h,0e9h,0f9h,0e8h,0f8h
  585.     db    94,'9',0
  586.     db    23h,0a7h,0c4h,0d6h,0dch,5eh    ; 6, German, "K"
  587.     db    5fh,60h,0e4h,0f6h,0fch,0dfh
  588.     db    94,'K',0
  589.     db    0a3h,0a7h,0b0h,0e7h,0e9h,5eh    ; 7, Italian, "Y"
  590.     db    5fh,97h,0e0h,0f2h,0e8h,0ech
  591.     db    94,'Y',0
  592.     db    23h,40h,0c6h,0d8h,0c5h,5eh    ; 8, Norwegian/Danish, "`"
  593.     db    5fh,60h,0e6h,0f8h,0e5h,7eh
  594.     db    94,60h,0
  595.     db    23h,40h,0c4h,0c7h,0d6h,5eh    ; 9, Portugese, "%6"
  596.     db    5fh,60h,0e4h,0e7h,0f6h,7eh
  597.     db    94,'%','6'
  598.     db    0a3h,0a7h,0a1h,0d1h,0bfh,5eh    ; 10, Spanish, "Z"
  599.     db    5fh,60h,0b0h,0f1h,0e7h,7eh
  600.     db    94,'Z',0
  601.     db    23h,0c9h,0c4h,0d6h,0c5h,0dch    ; 11, Swedish, "7"
  602.     db    5fh,0e9h,0e4h,0f6h,0e5h,0fch
  603.     db    94,'7',0
  604.     db    0f9h,0e0h,0e9h,0e7h,0eah,0eeh    ; 12, Swiss, "="
  605.     db    0e8h,0f4h,0e4h,0f6h,0fch,0fbh
  606.     db    94,'=',0
  607.  
  608. nrcfinal db    'A45CRf9QKY`E6Z7H=Lg'        ; NRC country letters
  609. nrcflen    equ    $-nrcfinal            ; "%6" "%=" done separately
  610. nrcnum    db    1,2,3,3,4,4,5,5,6,7,8,8,8,10,11,11,12,9,9 
  611.                         ; country numbers matching
  612.                         ; nrcfinal letters
  613.  
  614. ;NRC to DEC keyboard codes, North American (ASCII is nrckbd 1),+ALT-ROM+transp
  615. nrckbd    db    1,2,8,6,14,4,7,9,13,16,15,12,11,1, 1,1,1,1,1,1,1
  616. ;NRC to DG keyboard codes, North American + ALT-ROM+transparent
  617. nrcdgkbd db    19h,1ah,0,1dh,1bh,18h,1ch,17h,1fh,0,1eh,1dh,14h,19h, 19h,18h
  618.     db    19h,19h,19h,19h,19h
  619. ; DG char set idents to Kermit set idents
  620. ; DG set values 0 1 2 3 4  5  6    7     8   9  0a  0b  0c  0d 0e  0f  hex
  621. dgchtab    db    0,0,1,4,6,11,10,8,   12,100,100,100,100,100,20,100 ; decimal
  622. ;        10 11  12 13 14 15  16   17  18  19  1a  1b  1c 1d 1e 1f
  623.     db    22,21,100,15,17,19,100, 100,100,100,100,100,100, 0,15,16
  624. ;        20h and above map to soft set filler 100
  625.     db    100                        ; filler set
  626.  
  627. d470chr    db    '12345','6ABHK','L'        ; D470 ANSI char idents
  628. d470chrlen equ    ($-d470chr)
  629. mskchr    db    10,8,12,20,22, 21,1,0,3,6, 4    ; Kermit char idents
  630.  
  631. ; Device attributes response string. Make strings asciiz.
  632. v32str    db    escape,'[?63;1;2;4;6;8;9;15;22c',0 ; VT320, level 3, 132 col, 
  633. ;printer, selective chars, Sixel graphics, UDkeys, NRC, DEC Tech Chars, color
  634. v32sda    db    escape,'[>24;0;0c',0    ; VT320 secondary DA response
  635. v22str    db    escape,'[?62;1;2;4;6;8;9;15c',0; VT220, level 2, etc as above
  636. v102str    db    escape,'[?6;0c',0    ; VT102
  637. v100str db    escape,'[?1;0c',0    ; vanilla VT100
  638. v52str    db    escape,'/Z',0        ; VT100 in VT52 compatibility mode
  639. h19str    db    escape,'/K',0        ; Heath-19 (says plain VT52)
  640. VIPstr    db    escape,'[8p  OT',03h,escape,'[y7813  P GC  A ',03h,0
  641. VIPstrl    equ    $-VIPstr        ; Honeywell MOD400 3.1 id for ESC [ y
  642. ENQhstr    db    '7813  P GC  A',03h    ; Honeywell MOD400 4.0 id string
  643. ENQhstrl equ    $-ENQhstr
  644. pt20str    db    escape,'! ~0 ~..6~C~2 ~$',0 ; Prime PT200
  645. ENQstr    db    'MS-DOS-KERMIT'        ; generic enquiry response
  646. ENQstrl    equ    $-ENQstr
  647.                     ; parity code translation table
  648. partab    db    5,3,1,4,2        ; even, mark, none, odd, space
  649. lpartab equ    $-partab
  650. parcode db    0            ; parity code (0-4)
  651.                     ; baud rate code translation table
  652. ; 45.5 - no VT100 code (call it 50),50,75,110,134.5,150,300,600,1200,
  653. ; 1800,2000,2400,4800,9600,19200,38400,57600,115200  extended beyond DEC
  654. baudtab db    0,0,8,16,24,32,48,56,64,72,80,88,104,112,120,128,128,128,64,8
  655. lbaudtab equ    $-baudtab-1    ; last two are 1200/75 for split speeds
  656. baudidx db    0            ; index into baud rate table
  657. datbits db    7            ; number of databits (7 or 8)
  658. wyse_grch db    0c2h,0c0h,0dah,0bfh,0c3h,0d9h,0b3h,0b2h ; Wyse-50 graphics
  659.     db    0c5h,0b4h,0c4h,0b1h,0cdh,0c1h,0bah,0b0h    ; chars (0..15) CP437
  660.  
  661. issoft    db    0            ; 0=hard char set, else soft
  662. apcstring dw    0            ; segment of apcmacro memory
  663.  
  664. ;;;;;;;;;;;;;;; start session save area
  665.     even
  666. savezoff label    word
  667. ttstate dw    offset atnrm        ; terminal automata state
  668. ttstateST dw    offset atnorm        ; state for action after ST seen
  669. bracecount db    0            ; count of curly braces in APC string
  670. att_normal db    07H            ; default normal screen coloring
  671. oldterm    dw    0            ; terminal type from previous entry
  672. tekflg    db    0            ; Tek mode active flag
  673. old8bit    db    -1            ; flags.remflg setting for D463/D470
  674. iniflgs    dw    0            ; status flags at entry time
  675. modeset db    0            ; temp for atsm/atrm
  676. anspflg    db    0            ; printer flag bits and definitions
  677. h19stat    db    0            ; H-19 extra status bits
  678. h19ctyp    db    1            ; H-19 cursor type (1=ul, 2=bk, 4=off)
  679. h19cur    dw    0            ; H-19 saved cursor position
  680. insmod    db    0            ; insert mode on (1) or off (0)
  681. belcol    db    72            ; column at which to ring margin bell
  682. kbicsr    dw    0            ; cursor when keyboard input typed
  683. kbiflg    db    0            ; set/reset for keyboard input
  684. ttkbi    db    0            ; flag for keyboard input seen
  685. atescftab dw    ansesc            ; offset of esc follower table
  686. setptr    dw    0            ; hold offset of designated char set
  687. upss    db    96,'A',0,0        ; User Preferred Supplemental Set
  688.                     ; size, ident (Latin1)
  689. ; tab stops, stored here
  690. tabs    db    (swidth+7)/8 dup (0)    ; active tab stops, one column per bit
  691. deftabs    db    (swidth+7)/8 dup (0)    ; default (setup) tab stops
  692. ; byte per line, type of line: 0=normal, 1=double wide, 2=double high
  693. linetype db    slen dup (0)        ; single/double width chars for a line
  694. linescroll db    slen dup (0)        ; horizontal scroll for each line
  695. oldscrn    dw    0            ; old screen. hi=rows-1, low=cols-1
  696.  
  697. ; Scrolling region - do not separate or change order of mar_top & mar_bot
  698. mar_top db    0            ; scrolling region top margin
  699. mar_bot db    23            ; scrolling region bottom margin
  700. mar_left db    0            ; left margin
  701. mar_right db    vswidth-1        ; right margin
  702. savdgmar dw    0            ; DG saved right/left margins
  703. dspstate db    0            ; display state (mode)line work byte
  704. dspmsave dw    0            ; saved main dsp scrolling margins
  705. dspcstat dw    0            ; saved cursor pos for status line
  706. dspcmain dw    0            ; saved cursor pos for main display
  707. G0set    db    gsize+3+1 dup (0),0    ; G0..G3 char set space
  708. G1set    db    gsize+3+1 dup (0),1    ; last byte is permanent set index
  709. G2set    db    gsize+3+1 dup (0),2    ;  and should never be changed
  710. G3set    db    gsize+3+1 dup (0),3
  711. xltkeytable db    gsize dup (0)        ; keyboard translation table
  712. doublebyte db    0            ; [HF] 93/Nov/26 storage for dbl.char.
  713. double2nd db    0            ; [HF]
  714.                     ; Start of save cursor material
  715. savelist equ    this byte        ; top of list of things to save
  716. havesaved db    0            ; if have saved anything
  717. cursor    dw    0            ; cursor position
  718. savextattr db    0            ; extended display attributes
  719. curattr db    07h            ; cursor attribute
  720. svattr_index    equ $-savelist        ; offset of saved cursor attribute
  721. savscbattr db    1            ; normal background attributes
  722. atctype    db    1            ; VTxxx cursor type (1=ul,2=bk,0/4=off)
  723. savflgs dw    0            ; saved flags for atsc/atrc
  724. atwrap    db    0            ; autowrap flag
  725. atinvisible db    0            ; invisible char attribute flag
  726. decrlm    db    0            ; host controlled right-left writing
  727. GLptr    dw    0            ; pointer to char set for GL
  728. GRptr    dw    0            ; pointer to char set for GR
  729. SSptr    dw    0            ; pointer to char set for single shift
  730. Gsetid    db    4 dup (0)        ; set numbers 0..24 of char set
  731. lsavecu equ    $-savelist        ; length of stuff to save
  732. savecu    db    lsavecu dup (0)        ; saved cursor, attr., charset, etc
  733.                     ; End of save cursor material
  734.     even                ; Control sequence storage area
  735. ansifinptr dw    anstab            ; pointer to ANSI final char dispatch
  736. dcstabptr dw    dcstab            ; pointer to DCS dispatch table
  737. dnparam    dw    0            ; number of parameters for DCS
  738. dparam    dw    maxparam dup (0)    ; Parameters for DCS
  739. dlparam    db    0            ; a single letter Parameter for DCS
  740. dninter    dw    0            ; number of DCS intermediates
  741. dinter    db    maxinter dup (0)    ; Intermediates for DCS
  742. dcsstrf    db    0            ; Final char of DCS
  743. dnldcnt dw    0            ; autodownload, chars in emubuf
  744. emubufc    dw    0            ; count of chars in string buffer
  745. emubuf    db    66 dup (0)        ; emulator string storage buffer
  746.     db    0            ; safety for string overflow
  747. emubufl    dw    $-emubuf        ; length of emulator buffer
  748. pktbuf    db    66 dup (0)        ; Kermit packet recognizer buffer
  749.     db    0
  750. pktbufl    dw    $-pktbuf
  751. pktlen    db    0            ; autodownload, declared packet LEN
  752. pkttype db    0            ; autodownload, packet TYPE
  753. pktchk    db    0            ; autodownload, running pkt chksum
  754. dgparmread dw    0            ; DG count of parameters read
  755.                     ; DG windows structure
  756. dgwindcnt dw    1            ; DG count of active windows
  757. dgwindow dw    slen dup (0)        ; DG window [mar_top,mar_bot]
  758. dgwindcomp db    slen dup (0)        ; DG window compress (0=80,1=132 cols,
  759.                     ;  2 = line has soft font chars)
  760. dgcaller dw    atnorm            ; DG hex proc callback address
  761. numdigits db    0            ; DG hex digits remaining to be done
  762. dgnum    dw    0            ; DG numerical result
  763. protectena db    0            ; DG protected mode enabled (if != 0)
  764. blinkdis db    0            ; DG blink disabled
  765. dgroll    db    1            ; DG roll (0=disabled, 1=enabled)
  766. dghscrdis db    0            ; DG horz scroll disabled (if 1)
  767. dgcursave dw    16 dup (0)        ; DG cursor position named save area
  768. dgctypesave db    16 dup (0)        ; DG cursor type named save area
  769. dgcross    db    0            ; DG crosshair activity: 0=off, 1=on
  770.                     ;   2 = track keypad, 4= track mouse
  771. dg463fore db    0            ; DG D463 Polygon fill foregnd color
  772. dgaltid    dw    0            ; DG alt term id from host (0=none)
  773. dgkbl    db    0            ; DG keyboard language
  774. dgd470mode db    0            ; DG nonzero if D470 in ANSI mode
  775. dglinepat dw    0ffffh            ; DG line drawing pattern
  776. thisline db    0            ; linetype for current line
  777. scroll    db    1            ; lines to scroll, temp worker
  778. wyse_scroll db    0            ; Wyse-50 scroll/noscroll mode flag
  779. wyse_protattr dw 0            ; Wyse-50 protected char attributes
  780.                     ;  high byte=extattr, low=scbattr
  781. savezlen dw    ($-savezoff)        ; length of z save area
  782. ;;;;;;;;;;;;;;;;; end of session save area
  783.  
  784. ;note low_rgt    dw    0        ; text screen dimensions
  785.                     ; byte low_rgt = max column (79)
  786.                     ; byte low_rgt+1 = max row (23)
  787. led_col    equ    65            ; column position for "LEDs" display
  788. led_off equ    '.'            ; "Off" LED
  789. v320leds db    'VT320 ....'        ; VT320 mode (all 10 characters)
  790. v220leds db    'VT220 ....'        ; VT220 mode
  791. v102leds db    'VT102 ....'        ; VT102 mode
  792. v100leds db    'VT100 ....'        ; VT100 mode
  793. v52leds    db    'VT52      '        ; VT52 mode
  794. h19leds    db    'Heath-19  '        ; Heath-19 mode
  795. honeyleds db    'Honey ....'        ; Honeywell VIP 7809
  796. ansileds db    'ANSI  ....'        ; ANSI-BBS
  797. pt20leds db    'PT200 ....'        ; Prime PT200
  798. d470leds db    'D470      '        ; D470 series from Data General
  799. d470model db    'D470'            ; D470 response for Read New Model ID
  800. d463leds db    'D463      '        ; D463 series from Data General
  801. d463model db    'D463'            ; D463 response for Read New Model ID
  802. d217leds db    'D217      '        ; D217 series from Data General
  803. d217model db    'D217'            ; D217 response for Read New Model ID
  804. ;;d413model db    'D413'            ; D413 response for Read New Model ID
  805. wyseleds db    'Wyse-50   '        ; Wyse-50 mode
  806. data    ends
  807.  
  808. data1    segment
  809.     extrn lccp866r:byte, k8cp866r:byte, k7cp866r:byte
  810.     extrn cp866koi7:byte, cp866koi8:byte, cp866lci:byte
  811.  
  812. ; Translation tables for byte codes 0a0h..0ffh to map DEC Multinational
  813. ; Character Set (DEC Supplemental Graphic) to Code Pages.
  814. ; Codes 00h-1fh are 7-bit controls (C0), codes 20h..7eh are ASCII, 7fh DEL is
  815. ; considered to be a control code, 80h..9fh are 8-bit controls (C1).
  816. ; Each table is 128 translatable bytes followed by the table size (94) and the
  817. ; ISO announcer ident '%5'.
  818.  
  819. MNlatin    db    0a4h,0a6h,0ach,0adh,0aeh,0afh,0b4h    ; Latin1 code points
  820.     db    0beh,0d0h,0deh,0f0h,0feh,0ffh        ; to MNlatin spaces
  821.  
  822.  
  823.                ; Dec Technical set to CP437, CP860, CP863, CP865
  824.              ; Note: CP850 lacks the symbols so expect trash
  825. dectech    db    32 dup (0)                ; columns 8 and 9
  826.     db    0h,0fbh,0dah,0c4h, 0f4h,0f5h,0b3h,0dah    ; column 10
  827.     db    0c0h,0bfh,0d9h,28h,28h,29h,29h,0b4h
  828.     db    0c3h,3ch,3eh,5ch,  2fh,0bfh,0d9h,03eh    ; column 11
  829.     db    0a8h,20h,20h,20h,  0f3h,3dh,0f2h,3fh
  830.     db    1eh,0ech,0ech,0f6h,1eh,1fh,0e8h,0e2h    ; column 12
  831.     db    0f7h,0f7h,0e9h,58h,3fh,1dh,1ah,0f0h
  832.     db    0e3h,3fh,20h,0e4h, 20h,20h,0fbh,0eah    ; column 13
  833.     db    3fh,54h,3fh,3fh,   0efh,55h,5eh,76h
  834.     db    0aah,0e0h,0e1h,78h,0ebh,0eeh,0edh,3fh    ; column 14 
  835.     db    6eh,69h,0e9h,6bh,  3fh,20h,76h,3fh
  836.     db    0e3h,3fh,70h,0e5h, 0e7h,0a8h,9fh,77h    ; column 15
  837.     db    45h,76h,3fh,1bh,   18h,1ah,19h,7fh
  838.     db    94,3eh,0            ; 94 byte set, letter ident
  839.  
  840.                 ; Data General Word Processing to CP 437
  841. dgwpcp437 db    20h,0dah,0c0h,0bfh, 0d9h,9fh,'~',8h    ; column 10
  842.     db    0e4h,0e4h,0f4h,0f5h, 0fbh,8h,0ech,8h
  843.     db    '0','1',0fdh,'3', '4','5','6','7'    ; column 11
  844.     db    '8','9',8h,0c9h, 1bh,8h,1ah,0fah
  845.     db    13h,0e0h,0e1h,8h, 0ebh,8h,8h,0fch    ; column 12
  846.     db    0e9h,8h,8h,8h, 0e6h,8h,0eeh,8h
  847.     db    8h,8h,0e5h,0e7h, 8h,0edh,8h,8h        ; column 13
  848.     db    8h,0eah,1eh,14h, 4 dup (8h)
  849.     db    0c3h,04h,010h,010h, 011h,1eh,1fh,9 dup (8h) ; column 14
  850.     db    '0','1','2','3', '4','5','6','7'    ; column 15
  851.     db    '8','9',3fh,18h, 1ah,1bh,19h,20h
  852.     db    94,'D','W'            ; 94 byte set, letter idents
  853. dgwplen    equ    $-dgwpcp437            ; table size
  854.  
  855.             ; Convert Data General International to Latin1.
  856.             ; DGI chars at these code points translate to the
  857.             ; value used as a code point in the Latin1 table.
  858.             ; Thus the second byte, 0ach, DGI not sign, in its
  859.             ; row 2 col 10 translates to Latin1 not sign in row 12
  860.             ; col 10. Columns 8 and 9 are C1 controls.
  861. dgi2lat    db    0a0h,0ach,0bdh,0b5h, 0b2h,0b3h,0a4h,0a2h ; column 10
  862.     db    0a3h,0aah,0bah,0a1h, 0bfh,0a9h,0aeh,3fh
  863.     db    0bbh,0abh,0b6h,3fh,  3fh,0a5h,0b1h,3fh     ; column 11
  864.     db    3fh,0b7h,60h,0a7h,   0b0h,0a8h,0b4h,3fh
  865.     db    0c1h,0c0h,0c2h,0c4h, 0c3h,0c5h,0c6h,0c7h ; column 12
  866.     db    0c9h,0c8h,0cah,0cbh, 0cdh,0cch,0ceh,0cfh
  867.     db    0d1h,0d3h,0d2h,0d4h, 0d6h,0d5h,0d8h,3fh     ; column 13
  868.     db    0dah,0d9h,0dbh,0dch, 0a0h,59h,0a0h,0a0h
  869.     db    0e1h,0e0h,0e2h,0e4h, 0e3h,0e5h,0e6h,0e7h ; column 14
  870.     db    0e9h,0e8h,0eah,0ebh, 0edh,0ech,0eeh,0efh
  871.     db    0f1h,0f3h,0f2h,0f4h, 0f6h,0f5h,0f8h,3fh     ; column 15
  872.     db    0fah,0f9h,0fbh,0fch, 0dfh,0ffh,0a0h,0a0h
  873. dgi2len    equ    $-dgi2lat
  874.  
  875. ; yr8l1[]   /* Hewlett Packard Roman8 to Latin-1 */
  876. ;/* This is HP's official translation, straight from iconv */
  877. ;/* It is NOT invertible. */ omits columns 0..9
  878. hr8L1    db 160,192,194,200,202,203,206,207,180, 96, 94,168,126,217,219,163
  879.     db 175,221,253,176,199,231,209,241,161,191,164,163,165,167,102,162
  880.     db 226,234,244,251,225,233,243,250,224,232,242,249,228,235,246,252
  881.     db 197,238,216,198,229,237,248,230,196,236,214,220,201,239,223,212
  882.     db 193,195,227,208,240,205,204,211,210,213,245, 83,115,218, 89,255
  883.     db 222,254,183,181,182,190, 45,188,189,170,186,171, 42,187,177,160
  884. hr8L1len equ $-hr8L1
  885.  
  886. ; yr8l1[]   /* HP Roman8 to ISO Latin-1, Invertible */ omits cols 0..9
  887. ihr8L1    db 160,192,194,200,202,203,206,207,180,166,169,168,172,217,219,173
  888.     db 175,221,253,176,199,231,209,241,161,191,164,163,165,167,174,162
  889.     db 226,234,244,251,225,233,243,250,224,232,242,249,228,235,246,252
  890.     db 197,238,216,198,229,237,248,230,196,236,214,220,201,239,223,212
  891.     db 193,195,227,208,240,205,204,211,210,213,245,178,179,218,184,255
  892.     db 222,254,183,181,182,190,185,188,189,170,186,171,215,187,177,247
  893. ihr8L1len equ $-ihr8L1
  894.  
  895.  
  896. data1    ends
  897.  
  898. ifndef    no_graphics
  899. code2    segment
  900.     extrn    tekini:far, tekemu:far, tekend:far, teksetcursor:far
  901.     extrn    dgline:far, dgbar:far, dgcrosson:far, dgcrossoff:far
  902.     extrn    dgcrossrpt:far, dgsetcrloc:far, dgarc:far, dgpoly:far
  903.     extrn    mksoftspace:far, clearsoft:far
  904. code2    ends
  905. endif    ; no_graphics
  906.  
  907. code    segment
  908.     extrn    cptchr:near, pntchr:near, pntchk:near, pntflsh:near
  909.     extrn    modlin:near, latin1:near
  910.     extrn    clrmod:near, latininv:near, trnprs:near
  911.     extrn    dgsettek:far, vtksmac:near, vtkrmac:near, product:near
  912.     extrn    jpnftox:near, jpnxtof:near    ; [HF] 93/Nov/26
  913.  
  914.     assume    ds:data, es:nothing
  915.  
  916. fmodlin    proc    far
  917.     call    modlin
  918.     ret
  919. fmodlin    endp
  920.  
  921. fclrmod    proc    far
  922.     call    clrmod
  923.     ret
  924. fclrmod    endp
  925.  
  926. fcptchr    proc    far
  927.     call    cptchr
  928.     ret
  929. fcptchr    endp
  930.  
  931. fpntchr    proc    far
  932.     call    pntchr
  933.     ret
  934. fpntchr    endp
  935.  
  936. fpntchk    proc    far
  937.     call    pntchk
  938.     ret
  939. fpntchk    endp
  940.  
  941. fpntflsh proc    far
  942.     call    pntflsh
  943.     ret
  944. fpntflsh endp
  945.  
  946. ftrnprs    proc    far
  947.     call    trnprs
  948.     ret
  949. ftrnprs    endp
  950.  
  951. fvtksmac proc    far
  952.     call    vtksmac
  953.     ret
  954. fvtksmac endp
  955.  
  956. fvtkrmac proc    far
  957.     call    vtkrmac
  958.     ret
  959. fvtkrmac endp
  960.  
  961. fproduct proc    far
  962.     call    product
  963.     ret
  964. fproduct endp
  965.  
  966. flatin1    proc    far
  967.     push    ax
  968.     push    es
  969.     push    flags.chrset
  970.     push    ds
  971.     mov    ax,seg flags
  972.     mov    ds,ax
  973.     mov    ax,ds:vtcpage        ; get current terminal Code Page
  974.     mov    ds:flags.chrset,ax    ; tell file transfer part
  975.     pop    ds
  976.     call    latin1            ; sets DS:BX
  977.     call    latininv        ; adjusts BX
  978.     mov    ax,seg flags
  979.     mov    es,ax
  980.     pop    es:flags.chrset
  981.     pop    es
  982.     pop    ax
  983.     ret
  984. flatin1    endp
  985.  
  986. fjpnxtof proc    far            ; [HF] 93/Nov/26
  987.     call    jpnxtof            ; [HF] 93/Nov/26
  988.     ret                ; [HF] 93/Nov/26
  989. fjpnxtof endp                ; [HF] 93/Nov/26
  990. code    ends
  991.  
  992. code1    segment
  993.     extrn    prtbout:near, prtnout:near, csrtype:near, atsclr:near
  994.     extrn    vtscru:near, vtscrd:near, chgdsp:near
  995.     extrn    setpos:near, setudk:near, udkclear:near, vtbell:near
  996.     extrn    setatch:near, qsetatch:near, getatch:near
  997.     extrn    revideo:near, getbold:near, setbold:near, clrbold:near
  998.     extrn    getblink:near, setblink:near, clrblink:near, getunder:near
  999.     extrn    setunder:near, clrunder:near, revscn:near, setcolor:near
  1000.     extrn    setrev:near, clrrev:near, dec2di:far
  1001.     extrn    atparse:near, atpclr:near, atdispat:near, apcmacro:near
  1002.     extrn    setprot:near, clrprot:near, frepaint:far, touchup:near
  1003.     extrn    rcvmacro:near, srvmacro:near
  1004. ifndef    no_graphics
  1005.     extrn    tekinq:near, tekpal:near, tekrpal:near
  1006. endif    ; no_graphics
  1007.  
  1008.     assume    cs:code1, ds:data, es:nothing
  1009.  
  1010. ; Terminal display routine. Call with character incoming character in AL
  1011.  
  1012. anstty    proc    near
  1013.     mov    dx,cursor        ; some routines need cursor in dx
  1014.     mov    kbiflg,0        ; clear old flag value
  1015.     test    yflags,trnctl        ; Debug mode?
  1016.     jz    anstt1            ; z = no
  1017.     jmp    atdeb            ; yes, just translate control chars
  1018. anstt1:    cmp    ttkbi,0            ; new keyboard input?
  1019.     je    anstt2            ; e = no, just continue
  1020.     mov    kbiflg,1        ; yes, set flag
  1021.     mov    kbicsr,dx        ; save old cursor
  1022.     mov    ttkbi,0            ; clear this flag
  1023.  
  1024. anstt2:    test    anspflg,vtcntp        ; print controller on?
  1025.     jz    anstt4            ; z = no
  1026.     test    flags.capflg,logses    ; capturing output?
  1027.     jz    anstt3            ; z = no, forget this part
  1028.     push    ax            ; save char
  1029.     call    fcptchr            ; give it captured character
  1030.     pop    ax            ; restore character
  1031. anstt3:    jmp    ttstate            ; print transparently
  1032.  
  1033. anstt4:    test    yflags,capt        ; capturing output?
  1034.     jz    anstt4a            ; z = no, forget this part
  1035.     call    fcptchr            ; give it captured character
  1036. anstt4a:or    al,al            ; NUL char?
  1037.     jnz    anstt5            ; nz = no
  1038.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1039.     jnz    anstt5            ; nz = yes, must pass nulls
  1040.     test    flags.vtflg,ttwyse    ; Wyse?
  1041.     jz    atign            ; z = no, ignore it
  1042.  
  1043. anstt5:    cmp    vtemu.vtdnld,0        ; autodownload disabled?
  1044.     je    anstt8            ; e = yes
  1045.     cmp    al,trans.rsoh        ; start of packet char?
  1046.     jne    anstt5c            ; ne = no
  1047.     push    ax
  1048.     call    anstt5x            ; flush current buffer
  1049.     pop    ax
  1050.     mov    dnldcnt,1        ; say recording new packet
  1051.     mov    pktbuf,al        ; store char for replay
  1052.     mov    pktchk,0        ; initialize checksum
  1053.     ret
  1054. anstt5c:cmp    dnldcnt,0        ; parsing?
  1055.     je    anstt8            ; e = no
  1056.     mov    bx,dnldcnt
  1057.     mov    pktbuf[bx],al
  1058.     inc    dnldcnt            ; count incoming bytes
  1059.     inc    bx
  1060.     cmp    bx,pktbufl        ; packet too long?
  1061.     jae    anstt5x            ; ae = too much, fail
  1062.     add    pktchk,al        ; add to running checksum
  1063.     cmp    al,trans.reol        ; premature EOL?
  1064.     je    anstt5x            ; e = yes, fail
  1065.     cmp    dnldcnt,2        ; LEN byte?
  1066.     jne    anstt5d            ; ne = no
  1067.     cmp    al,' '+3        ; minimal length packet?
  1068.     jbe    anstt5x            ; be = no, fail
  1069.     push    ax
  1070.     sub    al,' '            ; remove length ASCII bias
  1071.     mov    pktlen,al        ; packet length
  1072.     pop    ax
  1073.     ret
  1074.  
  1075. anstt5d:cmp    dnldcnt,3        ; SEQ?
  1076.     ja    anstt5e            ; a = no
  1077.     cmp    al,' '            ; SEQ of zero?
  1078.     jne    anstt5x            ; ne = no, fail
  1079.     ret
  1080. anstt5e:cmp    dnldcnt,4        ; TYPE?
  1081.     ja    anstt5g            ; a = no
  1082.     mov    pkttype,al        ; remember TYPE for macro call
  1083.     cmp    al,'S'            ; TYPE of S?
  1084.     je    anstt5h            ; e = yes, succeed
  1085.     cmp    al,'I'            ; TYPE of I?
  1086.     jne    anstt5x            ; ne = no, fail
  1087.     ret
  1088.  
  1089. anstt5g:mov    bl,pktlen        ; reported packet length
  1090.     add    bl,2            ; add SOP and LEN
  1091.     xor    bh,bh
  1092.     cmp    dnldcnt,bx        ; count matches declared pkt length?
  1093.     jb    anstt5h            ; b = no, not yet, keep looking
  1094.     ja    anstt5x            ; a = went too far, fail
  1095.     mov    bl,pktchk        ; running checksum, type 1
  1096.     sub    bl,al            ; don't add checksum byte to ours
  1097.     xor    bh,bh
  1098.     shl    bx,1            ; get top two bits into bh
  1099.     shl    bx,1
  1100.     shr    bl,1            ; restore bl
  1101.     shr    bl,1
  1102.     add    bl,bh            ; add in top two bits
  1103.     and    bl,03fh            ; chop to lower six bits
  1104.     add    bl,' '            ; add ASCII bias
  1105.     cmp    al,bl            ; compare checksum bytes
  1106.     jne    anstt5x            ; ne = no match, fail
  1107.     mov    dnldcnt,0        ; declare replay buffer empty
  1108.     cmp    pkttype,'S'        ; S packet?
  1109.     jne    anstt5i            ; ne = no
  1110.     call    rcvmacro        ; do packet Receive macro
  1111. anstt5h:ret
  1112. anstt5i:call    srvmacro        ; do packet Server macro
  1113.     ret
  1114. anstt5x:mov    cx,dnldcnt        ; bytes in buffer
  1115.     jcxz    anstt5z            ; z = empty
  1116.     mov    bx,offset pktbuf    ; buffer
  1117. anstt5y:push    cx
  1118.     push    bx
  1119.     mov    al,[bx]            ; read old byte
  1120.     call    anstt8            ; replay old byte (near call)
  1121.     pop    bx
  1122.     pop    cx
  1123.     inc    bx            ; next buffer byte
  1124.     loop    anstt5y
  1125. anstt5z:mov    dnldcnt,0
  1126.     ret
  1127.  
  1128.                     ; Direct char to processor module
  1129. anstt8:    test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1130.     jnz    anstt10            ; nz = yes
  1131.     test    flags.vtflg,ttwyse    ; Wyse?
  1132.     jnz    anstt20            ; nz = yes
  1133.     cmp    vtemu.vtchset,13    ; ASCII (0) or NRC's (1-13) active?
  1134.     ja    anstt8b            ; a = no
  1135.     cmp    vtemu.vtchset,0        ; ASCII?
  1136.     je    anstt8b            ; e = yes
  1137.     and    al,7fh            ; yes, NRCs force chars to 7-bits
  1138. anstt8b:test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  1139.     jnz    anstt9            ; nz = no
  1140.     cmp    al,20h            ; C0 control code?
  1141.     jb    anstt8c            ; b = yes
  1142.     cmp    vtemu.vtchset,15    ; TRANSPARENT?
  1143.     je    anstt9            ; e = yes, pass all others
  1144. anstt8c:jmp    atctrl            ; dispatch on control code
  1145. anstt9:    jmp    ttstate            ; dispatch according to state
  1146.  
  1147.                     ; DG D463/D470 terminal
  1148. anstt10:test    flags.remflg,d8bit    ; use high bit?
  1149.     jnz    anstt11            ; nz = yes
  1150.     and    al,7fh            ; 7 bit terminal only
  1151. anstt11:test    anspflg,vtcntp        ; controller (transparent) printing?
  1152.     jnz    anstt12            ; nz = yes, go through filter routine
  1153.     cmp    dgd470mode,0        ; ansi mode?
  1154.     jne    anstt13            ; ne = yes
  1155.     test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  1156.     jnz    anstt12            ; nz = no, do according to state
  1157.     cmp    ttstate,offset atnrm    ; normal text processing?
  1158.     jne    anstt12            ; ne = no, pass controls to state
  1159.     jmp    dgctrl            ; do DG controls
  1160. anstt12:jmp    ttstate            ; process regularly
  1161.                     ; D470 ANSI mode operations
  1162. anstt13:test    al,not 9fh        ; control chars (0-1fh, 80h-9fh)?
  1163.     jz    anstt14            ; z = yes
  1164.     jmp    ttstate            ; process regularly
  1165. anstt14:jmp    dgansctl        ; do controls
  1166.  
  1167. anstt20:and    al,7fh            ; Wyse, chop 8th bit
  1168.     cmp    ttstate,offset atnrm    ; normal state?
  1169.     je    anstt21            ; e = yes
  1170.     jmp    ttstate            ; do state
  1171.  
  1172. anstt21:cmp    al,20h            ; control code?
  1173.     jae    atnrm            ; ae = no, process as text
  1174.     xor    ah,ah            ; clear for word use below
  1175.     mov    di,ax            ; use AL as a word index
  1176.     shl    di,1
  1177.     jmp    wyc0[di]        ; dispatch on C0 control codes
  1178. anstty    endp
  1179.  
  1180. ; [HF]940130 translation procedure for Japanese
  1181. ; [HF]940130 Carry set if AL is leading byte of bouble byte char.
  1182. jpnxlat    proc    near            ; [HF]940130
  1183.     cmp    al,DEL            ;[HF] DEL?
  1184.     jne    jpnxlat4        ;[HF] ne = no
  1185.     stc                ;[HF] yes, just ignore
  1186.     ret                ;[HF]
  1187. jpnxlat4:                ;[HF]
  1188.     push    ax            ;[HF] save Char
  1189.     mov    ax,[bx+gsize+1]        ;[HF] get ident
  1190.     cmp    ax,'$B'            ;[HF] JIS-Kanji?
  1191.     je    jpnxlat1        ;[HF] e = yes
  1192.     jmp    short jpnxlat2        ;[HF]
  1193. jpnxlat1:                ;[HF]
  1194.     pop    ax            ;[HF] restore char
  1195.     cmp    doublebyte,0        ;[HF] Leading byte?
  1196.     jne    jpnxlat3        ;[HF] ne = no
  1197.     mov    doublebyte,al        ;[HF] yes save it
  1198.     stc                ;[HF] dont display
  1199.     ret                ;[HF]
  1200. jpnxlat3:                ;[HF]
  1201.     mov    ah,doublebyte        ;[HF] set leading byte
  1202.     call    fjpnxtof        ;[HF] xlat to local code
  1203.     mov    doublebyte,al        ;[HF] save 2nd byte
  1204.     mov    al,ah            ;[HF] set leading byte
  1205.     clc                ;[HF] display the char in AL
  1206.     ret                ;[HF]
  1207. jpnxlat2:                ;[HF] single byte char
  1208.     mov    doublebyte,0        ;[HF]
  1209.     pop    ax            ;[HF] restore char
  1210.     xlatb                ;[HF]
  1211.     cmp    rxtable+256,0        ;[HF] TRANSLATION INPUT turned off?
  1212.     je    jpnxlat5        ;[HF] e = yes, use ISO mechanisms
  1213.     mov    bx,offset rxtable    ;[HF] address of translate table
  1214.     mov    ah,al            ;[HF] copy char
  1215.     xlatb                ;[HF] new char is in al
  1216. jpnxlat5:                ;[HF]
  1217.     clc                ; [HF]940130 display it
  1218.     ret                ; [HF]940130
  1219. jpnxlat    endp                ; [HF]940130
  1220.  
  1221. atign:    ret                ; something to be ignored
  1222.  
  1223. atnorm: mov    ttstate,offset atnrm    ; reset state to "normal"
  1224.     mov    ttstateST,offset atnorm    ; reset state for ST seen
  1225.     ret
  1226.             
  1227. atnrm    proc    near            ; Normal character (in AL) processor
  1228.     mov    issoft,0        ; presume hard char set
  1229.     cmp    SSptr,0            ; single shift needed?
  1230.     je    atnrm10            ; e = no
  1231.     and    al,not 80h        ; strip high bit
  1232.     mov    bx,SSptr        ; pointer to desired char set
  1233.     mov    SSptr,0            ; clear single shift indicator
  1234.     jmp    short atnrm12        ; process
  1235.  
  1236. atnrm10:test    al,80h            ; high bit set for GRight?
  1237.     jnz    atnrm11            ; nz = yes
  1238.     mov    bx,GLptr        ; GL char set
  1239.     jmp    short atnrm11a        ; process
  1240.  
  1241. atnrm11:and    al,not 80h        ; strip high bit
  1242.     mov    bx,GRptr        ; GR char set
  1243.  
  1244. atnrm11a:cmp    isps55,0        ; [HF]940130 Japanese PS/55 ?
  1245.     je    atnrm12            ; [HF]940130 e = no
  1246.     call    jpnxlat            ; [HF]940130 yes, need special xlat
  1247.     jnc    atnrm14            ; [HF]940130 nc = display the char
  1248.     clc                ; [HF]940130 clear carry
  1249.     ret
  1250.  
  1251. atnrm12:mov    ch,byte ptr [bx+gsize+3] ; get hard/soft char set indicator
  1252.     or    ch,ch            ; hard character set?
  1253.     jz    atnrm12a        ; z = yes
  1254. ifndef    no_graphics
  1255.     mov    issoft,ch        ; activate soft
  1256.     cmp    tekflg,tek_active+tek_sg ; inited already?
  1257.     je    atnrm12a        ; e = yes
  1258.     push    ax
  1259.     push    bx
  1260.     call    dgsettek        ; to graphics mode
  1261.     pop    bx
  1262.     pop    ax
  1263. endif    ; no_graphics
  1264. atnrm12a:xlatb                ; translate al to new char in al
  1265. atnrm13:cmp    rxtable+256,0        ; TRANSLATION INPUT turned off?
  1266.     je    atnrm14            ; e = yes, use ISO mechanisms
  1267.     mov    bx,offset rxtable    ; address of translate table
  1268.     mov    ah,al            ; copy char
  1269.     xlatb                ; new char is in al
  1270. atnrm14:cmp    al,DEL            ; ANSI Delete char?
  1271.     jne    atnrm15            ; ne = no
  1272.     ret                ; ignore DEL
  1273. atnrm15:cmp    atinvisible,0        ; invisible char?
  1274.     je    atnrm2            ; e = no, visible
  1275.     mov    al,' '            ; invisible, write as space
  1276.                     ; use atdeb for debug simple tty dsp
  1277. atnrm2:    mov    dx,cursor        ; get cursor virtual position
  1278.     push    bx
  1279.     mov    bl,dh            ; get row
  1280.     xor    bh,bh
  1281.     mov    bl,linetype[bx]        ; line width
  1282.     mov    thisline,bl        ; save for current reference
  1283.     cmp    issoft,0        ; soft font being used?
  1284.     je    atnrm2f            ; e = no
  1285.     or    dgwindcomp[bx],2    ; say soft font on this line
  1286. atnrm2f:pop    bx
  1287.     test    vtemu.vtflgop,decawm    ; Autowrap active?
  1288.     jz    atnrm2a            ; z = no
  1289.     mov    cl,mar_right        ; logical right margin
  1290.     cmp    thisline,0        ; single width line?
  1291.     je    atnrm2c            ; e = yes, single
  1292.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1293.     jnz    atnrm2c            ; nz = yes, these double the margins
  1294.     shr    cl,1            ; halve right column # for wide chars
  1295. atnrm2c:cmp     isps55,0                ; [HF]941103 Japanese PS/55 mode?
  1296.         je      atnrm2h                 ; [HF]941103 e = no
  1297.         cmp     doublebyte,0            ; [HF]940226 doublebyte char ?
  1298.         je      atnrm2h                 ; [HF]940226 e = no
  1299.         dec     cl                      ; [HF]940226 check one more space
  1300.         cmp     dl,cl                   ; [HF]940226 enough space?
  1301.         jbe     atnrm2a                 ; [HF]940226 be = yes
  1302.         inc     cl                      ; [HF]940226 restore right margin
  1303.         mov     dl,cl                   ; [HF]940226 set it to DL
  1304.         inc     dl                      ; [HF]940226 set beyond pos for wrap
  1305.         mov     atwrap,dh               ; [HF]940226 mark wrap
  1306.         inc     atwrap                  ; [HF]940226 to next line
  1307. atnrm2h:cmp     dl,cl                   ; want to write beyond right margin?
  1308.     jb    atnrm2a            ; b = no
  1309.     cmp    atwrap,0        ; autowrap pending?
  1310.     je    atnrm2a            ; e = no
  1311.     test    anspflg,vtautop        ; printing desired?
  1312.     jz    atnrm2a            ; e = no
  1313.     push    dx
  1314.     push    ax            ; save char
  1315.     mov    dh,atwrap        ; get 1+last display line's row
  1316.     dec    dh            ; up one line
  1317.     call    pntlin            ; print line
  1318.     mov    al,LF            ; terminate in LF
  1319.     call    fpntchr
  1320.     call    fpntflsh        ; flush printer buffer
  1321.     pop    ax            ; recover char in AL
  1322.     pop    dx
  1323. atnrm2a:push    ax            ; save character
  1324.     cmp    protectena,0        ; protected mode enabled?
  1325.     je    atnrm2d            ; e = no
  1326.     call    getatch            ; check for protected field
  1327.     test    cl,att_protect        ; protected?
  1328.     jz    atnrm2d            ; z = no
  1329.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1330.     jz    atnrm2d            ; z = no
  1331.     call    dgcuf            ; do DG cursor right
  1332.     mov    dx,cursor
  1333. atnrm2d:cmp    decrlm,0        ; host right-left mode active?
  1334.     je    atnrm2e            ; e = no
  1335.     cmp    atwrap,0        ; wrap pending?
  1336.     je    atnrm2e            ; e = no
  1337.     mov    dl,mar_right
  1338.     inc    dl            ; set to wrap in normal sense
  1339.  
  1340. atnrm2e:call    atscur            ; set cursor physical position
  1341.     pop    ax
  1342.     cmp    insmod,0        ; insert mode off?
  1343.     je    atnrm3            ; e = yes
  1344.     push    ax
  1345.     call    inschr            ; open a char space in this line
  1346.     cmp    doublebyte,0        ; [HF] doublebyte display?
  1347.     jne    atnrm2g            ; [HF] ne = yes
  1348.     cmp    thisline,0        ; single width line?
  1349.     je    atnrm2b            ; e = yes
  1350. atnrm2g:call    inschr            ; open second space for double width
  1351. atnrm2b:pop    ax            ; restore char
  1352.                     ; set cursor before writing char
  1353. atnrm3:    cmp    thisline,0        ; check for double characteristic
  1354.     je    atnrm3a            ; e = normal, not doubles
  1355.     shl    dl,1            ; double the column number
  1356. atnrm3a:push    dx
  1357.     call    direction        ; set dx to desired position
  1358.     mov    ah,curattr        ; current attribute
  1359.     mov    cl,extattr        ; extended attribute
  1360.     test    cl,att_protect        ; protected?
  1361.     jz    atnrm3h            ; z = no
  1362.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1363.     jz    atnrm3h            ; z = no
  1364.     mov    ah,byte ptr wyse_protattr ; use Wyse protected char attributes
  1365.     mov    cl,byte ptr wyse_protattr+1
  1366. atnrm3h:mov    ch,issoft
  1367.     or    ch,ch            ; soft font?
  1368.     jz    atnrm3d            ; z = no
  1369.     sub    ch,100            ; remove local bias (leaves 1..31)
  1370.     shl    ch,1
  1371.     shl    ch,1
  1372.     shl    ch,1            ; move to upper 5 bits
  1373.      and    cl,not 0f8h        ; clear soft set bits
  1374.     or    cl,ch            ; new extended attribute
  1375. atnrm3d:call    setatch            ; write char (al) and attribute (ah)
  1376.     cmp    doublebyte,0        ;[HF] doublebyte display?
  1377.     je    atnrm3g            ;[HF] e = no
  1378.     pop    dx            ;[HF]
  1379.     inc    dl            ;[HF] next column
  1380.     mov    cursor,dx        ;[HF] set cursor position
  1381.     push    dx            ;[HF]
  1382.     call    direction        ;[HF] set dx to desired position
  1383.     mov    al,doublebyte        ;[HF] set 2nd byte
  1384.     mov    ah,curattr        ;[HF] current attribute
  1385.     mov    cl,extattr        ; extended attribute
  1386.  
  1387.     test    cl,att_protect        ; protected?
  1388.     jz    atnrm3i            ; z = no
  1389.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1390.     jz    atnrm3i            ; z = no
  1391.     mov    ah,byte ptr wyse_protattr ; use Wyse protected char attributes
  1392.     mov    cl,byte ptr wyse_protattr+1
  1393. atnrm3i:
  1394.     mov    ch,issoft
  1395.     or    ch,ch            ; soft font?
  1396.     jz    atnrm3f            ; z = no
  1397.     sub    ch,100            ; remove local bias (leaves 1..31)
  1398.     shl    ch,1
  1399.     shl    ch,1
  1400.     shl    ch,1            ; move to upper 5 bits
  1401.      and    cl,not 0f8h        ; clear soft set bits
  1402.     or    cl,ch            ; new extended attribute
  1403. atnrm3f:call    setatch            ;[HF] write 2nd char and attrib.
  1404.     mov    doublebyte,0        ;[HF] clear doublebyte ind
  1405. atnrm3g:mov    issoft,0
  1406.     pop    dx
  1407.     cmp    thisline,0        ; check for double characteristic
  1408.     je    atnrm4            ; e = normal, not doubles
  1409.     cmp    decrlm,0        ; host writing direction active?
  1410.     je    atnrm3b            ; e = no
  1411.     dec    dl            ; next col
  1412.     jmp    short atnrm3c
  1413. atnrm3b:inc    dl            ; next column
  1414. atnrm3c:push    dx
  1415.     call    direction        ; set dx to desired position
  1416.     mov    ah,curattr        ; current attribute
  1417.     mov    cl,extattr        ; extended attribute
  1418.     test    cl,att_protect        ; protected?
  1419.     jz    atnrm3j            ; z = no
  1420.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1421.     jz    atnrm3j            ; z = no
  1422.     mov    ah,byte ptr wyse_protattr ; use Wyse protected char attributes
  1423.     mov    cl,byte ptr wyse_protattr+1
  1424. atnrm3j:
  1425.     mov    al,' '            ; use a space for doubling
  1426.     mov    ch,issoft
  1427.     or    ch,ch            ; soft font?
  1428.     jz    atnrm3e            ; z = no
  1429.     sub    ch,100            ; remove local bias (leaves 1..31)
  1430.     shl    ch,1
  1431.     shl    ch,1
  1432.     shl    ch,1            ; move to upper 5 bits
  1433.      and    cl,not 0f8h        ; clear soft set bits
  1434.     or    cl,ch            ; new extended attribute
  1435. atnrm3e:call    setatch            ; write char (al) and attribute (ah)
  1436.     pop    dx
  1437.     shr    dl,1            ; keep "cursor" in single units
  1438.  
  1439. atnrm4:    test flags.vtflg,ttd463+ttd470+ttd217+ttheath+ttwyse; no wrap & scroll?
  1440.     jz    atnrm4d            ; z = no
  1441.     jmp    dgcuf            ; do DG cursor forward
  1442.  
  1443. atnrm4d:test    vtemu.vtflgop,decawm    ; Autowrap active?
  1444.     jz    atnrm5            ; z = no
  1445.     cmp    decrlm,0        ; host writing left to right?
  1446.     je    atnrm4e            ; e = no
  1447.     or    dl,dl            ; wrote in left most col?
  1448.     jnz    atnrm5            ; nz = no
  1449.     mov    dl,mar_right        ; set next column to the right
  1450.     jmp    short atnrm4b        ; do not move cursor now
  1451.  
  1452. atnrm4e:mov    cl,mar_right        ; logical right margin
  1453.     cmp    thisline,0        ; single width line?
  1454.     je    atnrm4a            ; e = yes, single
  1455.     shr    cl,1            ; halve right column # for wide chars
  1456. atnrm4a:cmp    dl,cl            ; wrote in right-most column?
  1457.     jb    atnrm5            ; b = no
  1458.     inc    dl            ; say want to use next column
  1459. atnrm4b:mov    atwrap,dh        ; turn on wrap flag with 1 + this row
  1460.     inc    atwrap            ;  so 0 means no wrap pending
  1461.     test    flags.vtflg,ttheath    ; H-19?
  1462.     jnz    atscur            ; nz = yes, show wrap now
  1463.     mov    cursor,dx        ; virtual cursor position
  1464.     ret                ; exit without moving cursor from eol
  1465.  
  1466. atnrm5:    mov    dx,cursor        ; restore cursor position
  1467.     cmp    decrlm,0        ; host writing direction active?
  1468.     je    atnrm5a            ; e = no
  1469.     or    dl,dl
  1470.     jz    atnrm5b
  1471.     dec    dl            ; next column
  1472.     jmp    short atnrm5b
  1473. atnrm5a:inc    dl            ; next column
  1474. atnrm5b:mov    atwrap,0        ; say not about to wrap
  1475. ;;    jmp    short atscur
  1476. atnrm    endp
  1477.  
  1478. atscur:    cmp    dl,mar_left        ; left of left margin?
  1479.     jae    atscu1            ; ae = no, continue
  1480.     mov    dl,mar_left        ; set at left margin
  1481. atscu1:    mov    cl,mar_right        ; copy logical margin; cl = right col
  1482.     push    bx
  1483.     mov    bl,dh            ; get row
  1484.     xor     bh,bh
  1485.     cmp    linetype [bx],0        ; single width lines?
  1486.     pop    bx
  1487.     je    atscu1a            ; e = yes, single width
  1488.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1489.     jnz    atscu1a            ; nz = yes, these double the margins
  1490.     shr    cl,1            ; halve column # for double wides
  1491. atscu1a:cmp    dl,cl            ; right of right margin?
  1492.     jbe    atscu3            ; be = no, continue
  1493.     mov    dl,cl            ; assume no autowrap
  1494.     test    vtemu.vtflgop,decawm    ; Autowrap?
  1495.     jz    atscu3            ; z = no
  1496.     mov    dl,mar_left        ; set to left margin
  1497.     cmp    decrlm,0        ; host right-left mode active?
  1498.     je    atscu1e            ; e = no
  1499.     mov    dl,mar_right
  1500. atscu1e:cmp    dh,byte ptr low_rgt+1    ; at bottom of screen?
  1501.     je    atscu1b            ; e = yes
  1502.     cmp    dh,mar_bot        ; at bottom of scrolling region?
  1503.     jl    atscu2            ; l = no, bump cursor and continue
  1504. atscu1b:test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  1505.     jz    atscu1d            ; z = no
  1506.     cmp    dgroll,0        ; is DG roll enabled?
  1507.     jne    atscu1d            ; ne = yes, do the scroll
  1508.     mov    dh,mar_top        ; move to top of window
  1509.     jmp    short atscu3
  1510. atscu1d:mov    scroll,1        ; scroll count = 1 line
  1511.     call    atscru            ; scroll up
  1512.     dec    dh            ; offset inc dh below
  1513. atscu2: inc    dh            ; just bump it
  1514. atscu3: or    dh,dh            ; constrain row to valid range
  1515.     jge    atscu4            ; ge = non-negative row, ok
  1516.     xor    dh,dh
  1517. atscu4: cmp    dh,byte ptr low_rgt+1    ; 25th line?
  1518.     jle    atsetcur        ; le = no
  1519.     mov    dh,byte ptr low_rgt+1    ; set to 24th line
  1520.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  1521.         je      atscu4c                 ; [HF]940227 e = yes, Heath-19
  1522.         cmp     isps55,0                ; [HF]941103 Japanese PS/55 ?
  1523.         je      atscu4a                 ; [HF]941103 e = no
  1524.         cmp     flags.modflg,2          ; [HF]940227 mode line owned by host?
  1525.         jne     atsetcur                ; [HF]940227 ne = no, don't touch
  1526.         jmp     short atscu4a           ; [HF]940227 host wants to go to 25th
  1527. atscu4c:test    h19stat,h19l25          ; Heath 25th line enabled?
  1528.     jz    atsetcur        ; z = no
  1529. atscu4a:inc    dh            ; go to line 25 [hlk]
  1530.     test    yflags,modoff        ; is mode line off?
  1531.     jnz    atscu4b            ; nz = yes
  1532.     push    dx            ; save cursor position
  1533.     call    fclrmod            ; clear the line
  1534.     or    yflags,modoff        ; now say it's off (owned by host)
  1535.     pop    dx
  1536. atscu4b:mov    flags.modflg,2        ; say mode line is owned by host
  1537.  
  1538. atsetcur:cmp    dh,slen            ; beyond last screen row we support?
  1539.     jbe    atsetcur0a        ; be = no
  1540.     mov    dh,slen            ; put on last row
  1541. atsetcur0a:cmp    dl,mar_right        ; beyond right edge?
  1542.     jbe    atsetcur0b        ; be = no
  1543.     mov    dl,mar_right        ; limit to right edge
  1544. atsetcur0b:
  1545.     mov    cursor,dx        ; set cursor and return
  1546.     push    dx
  1547.     mov    bl,dh            ; get row
  1548.     xor    bh,bh            ; clear high byte
  1549.     cmp    linetype[bx],0        ; single width line?
  1550.     je    atsetcu1        ; e = yes
  1551.     shl    dl,1            ; double the column number
  1552. atsetcu1:call    direction        ; set dx to desired position
  1553.     call    setpos            ; set cursor physical position
  1554.     pop    dx
  1555.     test    vtemu.vtflgop,vsmarginbell; do we care about margin bell?
  1556.     jz    atsetcu2        ; z = no, return if no margin bell
  1557.     cmp    kbiflg,0        ; is keyboard input flag set?
  1558.     je    atsetcu2        ; e = no, just return
  1559.     mov    bx,kbicsr        ; cursor at previous keyboard input
  1560.     cmp    bh,dh            ; same row as now?
  1561.     jne    atsetcu2        ; ne = no, just return
  1562.     cmp    bl,belcol        ; old cursor at or left of bell column?
  1563.     ja    atsetcu2        ; a = no, just return
  1564.     cmp    dl,belcol        ; new cursor past bell column?
  1565.     jbe    atsetcu2        ; be = no, just return
  1566.     push    dx
  1567.     call    vtbell            ; ring the bell
  1568.     pop    dx
  1569. atsetcu2:ret
  1570.  
  1571. ; Control-character dispatcher
  1572. atctrl:    cmp    al,escape        ; an escape sequence starting?
  1573.     je    atctrl1            ; e = yes, don't print it
  1574.     cmp    al,CSI            ; this kind of escape?
  1575.     je    atctrl1            ; e = yes
  1576.     cmp    al,18h            ; CAN (cancel)?
  1577.     je    atctrl6            ; e = yes
  1578.     cmp    al,1ah            ; SUB (treated as CAN)?
  1579.     je    atctrl6            ; e = yes
  1580.     cmp    al,9ch            ; ST?
  1581.     jne    atctrl5            ; ne = no
  1582.     jmp    ttstateST
  1583. atctrl5:cmp    ttstate,offset atesc1    ; state is second char of ST?
  1584.     jne    atctrl6            ; ne = no
  1585.     jmp    ttstate            ; go process second char
  1586. atctrl6:test    anspflg,vtcntp        ; printing desired?
  1587.     jz    atctrl1            ; z = no
  1588.     call    fpntchr            ; print char in al
  1589. atctrl1:xor    ah,ah            ; clear for word use below
  1590.     test    al,80h            ; high bit set?
  1591.     jnz    atctrl2            ; nz = yes
  1592.     mov    di,ax            ; use AL as a word index
  1593.     shl    di,1
  1594. atctrl3:jmp    ansc0[di]        ; dispatch on C0 control codes
  1595. atctrl2:and    al,not 80h        ; strip high bit
  1596.     mov    di,ax            ; use AL as a word index
  1597.     shl    di,1
  1598.     test    flags.vtflg,ttvt320+ttvt220 ; doing VT320/VT220?
  1599.     jz    atctrl3            ; z = no, trim back to C0
  1600. atctrl4:jmp    ansc1[di]        ; dispatch on C1 control codes
  1601.  
  1602. ; Control code routines
  1603. atbs:    cmp    decrlm,0        ; host writing direction active?
  1604.     jne    atbs2            ; ne = yes
  1605.     or    dl,dl            ; Backspace, too far?
  1606.     jz    atbs1            ; z = at column 0 already
  1607.     dec    dl            ; backup cursor
  1608. atbs1:    call    atccpc            ; check range
  1609.     mov    atwrap,0        ; cancel wrap pending
  1610.     jmp    atsetcur        ; set cursor and return
  1611.  
  1612. atbs2:    cmp    dl,mar_right        ; at right margin now?
  1613.     je    atbs1            ; e = yes, stop
  1614.     inc    dl
  1615.     jmp    short atbs1
  1616.  
  1617. atht:    cmp    flags.vtflg,ttheath    ; Horizontal Tab, Heath-19 mode?
  1618.     je    atht2            ; e = yes, handle specially
  1619.     xor    ch,ch
  1620.     mov    cl,mar_right
  1621.     cmp    dl,cl            ; at or beyond last column?
  1622.     jae    atht1a            ; ae = yes check range, set cursor
  1623. atht1:    inc    dl            ; tab always moves at least one column
  1624.     push    si
  1625.     mov    si,vtemu.vttbst        ; active buffer
  1626.     call    istabs            ; returns carry set if at a tabstop
  1627.     pop    si
  1628.     jc    atht1a            ; c = at a tabstop
  1629.     loopz    atht1
  1630. atht1a:    call    atccpc            ; check range
  1631. atht1b:    call    atsetcur        ; set cursor and return
  1632.     ret
  1633.  
  1634. atht2:    mov    dx,cursor        ; Heath-19. get cursor position
  1635.     add    dl,8            ; tabs are every 8 columns
  1636.     and    dl,not 7        ; do modulo 8
  1637.     cmp    dl,mar_right        ; check against right edge
  1638.     jbe    atht3            ; be = in range
  1639.     mov    dl,mar_right        ; else go to right margin
  1640. atht3:    jmp    atht1b            ; set cursor and return
  1641.  
  1642. atlf:    test    vtemu.vtflgop,anslnm    ; Line Feed, New-line mode?
  1643.     jz    atlf2            ; z = no, just move to next line down
  1644. atlf1:    mov    dl,mar_left        ; move to left margin also
  1645.     cmp    decrlm,0        ; host writing direction active?
  1646.     je    atlf2            ; e = no
  1647.     mov    dl,mar_right
  1648. atlf2:    test    anspflg,vtautop        ; printing desired?
  1649.     jz    atlf3            ; e = no
  1650.     push    dx
  1651.     push    ax            ; save char
  1652.     call    pntlin            ; print current line
  1653.     pop    ax            ; recover char in AL, print it too
  1654.     call    fpntchr
  1655.     call    fpntflsh        ; flush printer buffer
  1656.     pop    dx
  1657. atlf3:    inc    dh            ; index line down
  1658.     call    atccic            ; check indexing
  1659.     test    flags.vtflg,ttwyse    ; Wyse-50?
  1660.     jz    atlf4            ; z = no, do the scroll if any
  1661.     cmp    protectena,0        ; protected mode on?
  1662.     je    atlf4            ; e = no, can scroll
  1663.     cmp    ax,offset atign        ; scroll requested?
  1664.     je    atlf5            ; e = no
  1665.     mov    dh,mar_top        ; roll over to the top
  1666.     jmp    short atlf5
  1667. atlf4:    call    ax            ; call scrolling routine
  1668. atlf5:    jmp    atsetcur        ; set cursor
  1669.  
  1670. atcr:     mov    dl,mar_left        ; Carriage Return, go to left margin
  1671.     mov    atwrap,0        ; cancel wrap pending
  1672.     cmp    decrlm,0        ; host writing direction active?
  1673.     je    atcr2            ; e = no
  1674.     mov    dl,mar_right
  1675. atcr2:    cmp    flags.vtflg,ttheath    ; Heath-19?
  1676.     jne    atcr1            ; ne = no
  1677.     test    h19stat,h19alf        ; auto line feed on?
  1678.     jnz    atcr3            ; nz = yes, do the LF part above
  1679. atcr1:    cmp    crdisp_mode,0        ; CR-display is normal?
  1680.     jne    atlf3            ; ne = no, do CR-LF
  1681.     jmp    atsetcur        ; set cursor and return
  1682. atcr3:    test    anspflg,vtcntp        ; print controller on?
  1683.     jnz    atcr3a            ; nz = yes
  1684.     test    flags.capflg,logses    ; capturing output?
  1685.     jz    atcr4            ; z = no, forget this part
  1686. atcr3a:    push    dx            ; save char
  1687.     mov    al,LF            ; log the new LF after the CR
  1688.     call    fcptchr            ; give it captured character
  1689.     pop    dx            ; restore character
  1690. atcr4:    jmp    atlf2            ; do CR-LF
  1691.  
  1692. atff:    cmp    flags.vtflg,ttansi    ; ansi terminal?
  1693.     jne    atff2            ; ne = no
  1694.     cmp    ttstate,offset atescf    ; Form Feed, parsing escape sequence?
  1695.     je    atff1            ; e = yes
  1696.     mov    ninter,0        ; prepare for CSI 2 J simulation
  1697.     mov    lparam,0
  1698.     mov    param,2
  1699.     jmp    ated            ; erase screen, home cursor
  1700.  
  1701. atff2:    cmp    ttstate,offset atescf    ; Form Feed, parsing escape sequence?
  1702.     jne    atlf            ; ne = no, do as line feed
  1703. atff1:    test    denyflg,tekxflg        ; is auto Tek mode disabled?
  1704.     jnz    atlf            ; nz = yes, treat as line feed
  1705. ifndef    no_graphics
  1706.     call    atsc            ; save cursor and associated data
  1707.     mov    al,escape
  1708.     call    TEKEMU
  1709.     mov    al,FF
  1710.     call    TEKEMU            ; feed to Tektronix Emulator, al=FF
  1711.     jmp    atnorm
  1712. else
  1713.     jmp    atlf
  1714. endif    ; no_graphics
  1715.  
  1716. atcan:    mov    parstate,0        ; CAN, clear esc seq parser
  1717.     jmp    atnorm
  1718.  
  1719. atenq:    mov    cx,ENQhstrl-1        ; length of Honeywell string-1
  1720.     mov    si,offset ENQhstr    ; ptr to string
  1721.     mov    ttyact,0        ; start grouping for networks
  1722.     cmp    flags.vtflg,tthoney    ; ENQ, Honeywell terminal?
  1723.     je    atenq1            ; e = yes
  1724.     cmp    vtenqenable,0        ; VTxxx response enabled?
  1725.     je    atenq4            ; e = no
  1726.     cmp    enqbuf,0        ; safe?
  1727.     jne    atenq1f            ; ne = no, unsafe, no prefix
  1728.     mov    cx,ENQstrl        ; length of string
  1729.     mov    si,offset ENQstr    ; ptr to string
  1730. atenq1:    cld    
  1731.     lodsb                ; get a byte
  1732.     push    cx            ; save regs
  1733.     push    si
  1734.     call    prtbout            ; send to port WITHOUT echo
  1735.     pop     si
  1736.     pop    cx
  1737.     loop    atenq1            ; loop for all characters
  1738. atenq1f:cmp    flags.vtflg,tthoney    ; ENQ, Honeywell terminal?
  1739.     je    atenq3            ; e = yes
  1740.     mov    rdbuf,' '
  1741.     mov    di,offset rdbuf        ; place to work
  1742.     cmp    enqbuf,0        ; safe message?
  1743.     jne    atenq1b            ; ne = no, unsafe, no prefix
  1744.     inc    di            ; start with space prefix
  1745.     mov    ax,version        ; Kermit version
  1746.     call    dec2di
  1747.     mov    byte ptr [di],'_'    ; _terminal name
  1748.     inc    di
  1749.     call    getled            ; get terminal name to si
  1750.     mov    cx,8            ; max of 8 bytes
  1751. atenq1a:lodsb                ; read a byte
  1752.     cmp    al,' '            ; still in visibles?
  1753.     jbe    atenq1b            ; be = no
  1754.     mov    [di],al            ; store
  1755.     inc    di
  1756.     loop    atenq1a            ; do more
  1757.  
  1758. atenq1b:mov    si,offset enqbuf+1    ; user postfix, asciiz
  1759.     cmp    byte ptr [si],0        ; anything there?
  1760.     je    atenq1d            ; e = no
  1761.     cmp    byte ptr [si-1],0    ; safe message?
  1762.     jne    atenq1c            ; ne = no, unsafe, no prefix
  1763.     mov    byte ptr [di],'_'    ; separator
  1764.     inc    di
  1765.     dec    cx            ; one less slot
  1766. atenq1c:lodsb
  1767.     or    al,al
  1768.     jz    atenq1d            ; z = end of string
  1769.     cmp    enqbuf,0        ; safe?
  1770.     jne    atenq1e            ; ne = no, unsafe, use as-is
  1771.     cmp    al,' '            ; control code?
  1772.     jae    atenq1e            ; ae = no
  1773.     mov    al,'_'            ; force in separator
  1774. atenq1e:mov    [di],al
  1775.     inc    di
  1776.     jmp    short atenq1c        ; while there is text
  1777.  
  1778. atenq1d:mov    byte ptr [di],CR    ; CR terminator
  1779.     inc    di
  1780.     mov    cx,di
  1781.     mov    si,offset rdbuf
  1782.     sub    cx,si
  1783.     dec    cx            ; do all but last char in loop
  1784. atenq2:    lodsb
  1785.     push    cx            ; save regs
  1786.     push    si
  1787.     call    prtbout            ; send to port WITHOUT echo
  1788.     pop     si
  1789.     pop    cx
  1790.     loop    atenq2
  1791. atenq3:    lodsb                ; last char
  1792.     mov    ttstate, offset atnrm    ; reset to normal and return
  1793.     mov    ttyact,1        ; end group output for networks
  1794.     call    prtbout            ; last byte trips the group trigger
  1795. atenq4:    ret
  1796.  
  1797. atesc:    cmp    ttstate,offset atdcsnul    ; consuming a DCS?
  1798.     jne    atesc3            ; ne = no
  1799.     mov    ttstate,offset atesc1    ; stay here
  1800.     ret
  1801. atesc1:    cmp    al,'\'            ; end of ST?
  1802.     je    atesc2            ; e = yes
  1803.     jmp    atdcsnul        ; continue to consume DCS
  1804. atesc2:    jmp    atgotst            ; reset DCS processing
  1805.  
  1806. atesc3:    mov    ttstate,offset atescf    ; ESC, next state is escape follower
  1807.     ret
  1808.  
  1809. ; Respond to character following Escape, dispatch on that char
  1810. atescf:    call    atpclr            ; clear parser argument list
  1811.     mov    dcstabptr,offset dcstab    ; VT DCS dispatch table
  1812.     mov    atescftab,offset ansesc    ; ANSI escape table, for atdispat
  1813.     mov    ansifinptr,offset anstab
  1814.     mov    cx,flags.vtflg
  1815.     test    cx,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttansi ; VT320 etc?
  1816.     jnz    atescf2            ; nz = yes
  1817.     mov    atescftab,offset v52esc ; VT52 escape table
  1818.     cmp    cx,ttvt52        ; VT52?
  1819.     je    atescf1            ; e = yes
  1820.     mov    atescftab,offset h19esc ; use Heath-19 table
  1821.     cmp    cx,ttheath        ; Heath-19?
  1822.     je    atescf1            ; e = yes
  1823.     mov    atescftab,offset pt200esc
  1824.     cmp    cx,ttpt200        ; Prime PT200?
  1825.     je    atescf2            ; e = yes
  1826.     mov    atescftab,offset dgescftab ; use D470 escape follower table
  1827.     mov    dcstabptr,offset dgdcstab ; DG DCS dispatch table
  1828.     mov    ansifinptr,offset dganstab 
  1829.     cmp    cx,ttd470        ; D470?
  1830.     je    atescf2            ; e = yes
  1831.     ret                ; return on error
  1832. atescf1:mov    ttstate,offset atnrm    ; reset state to "normal"
  1833.     mov    bx,atescftab        ; get offset of escape follower table
  1834.     jmp    atdispat        ; perform dispatch via table in BX
  1835.  
  1836. atescf2:test    al,not (2fh)        ; in intermediates (column 2)?
  1837.     jnz    atescf1            ; nz = no, dispatch on this char
  1838.     mov    ttstate,offset atescf2    ; stay in this state til col 3 or more
  1839.     mov    bx,ninter        ; number of intermediates
  1840.     cmp    bx,maxinter        ; done enough already?
  1841.     jae    atescf3            ; ae = yes, ignore the excess
  1842.     mov    inter[bx],al        ; store this one
  1843.     inc    ninter            ; one more
  1844. atescf3:ret                ; get more input
  1845.  
  1846.                     ; CSI, char 9bh (ANSI CSI == ESC [)
  1847. atcsi0:    cmp    ninter,0        ; any intermediates from ESC..[?
  1848.     je    atcsi            ; e = no, else not this item
  1849.     jmp    atnorm            ; reset state to "normal"
  1850.                     ; enter here with real CSI char
  1851. atcsi:    mov    ttstate,offset atparse    ; next state is parse control seq
  1852.     mov    parfail,offset atnorm    ; where to jmp if failure
  1853.     mov    pardone,offset atcsi1    ; where to jmp when done
  1854.     jmp    atpclr            ; clear parser parameters and return
  1855.  
  1856. atcsi1:    mov    bx,ansifinptr        ; ANSI Final character table
  1857.     mov    ttstate,offset atnrm    ; reset state to "normal"
  1858.     jmp    atdispat        ; dispatch on character
  1859.  
  1860. h19csi:    test    vtemu.vtflgop,decanm    ; Heath-19 "ESC [", is ANSI mode on?
  1861.     jnz    h19csi1            ; nz = yes
  1862.     mov    ttstate,offset atnrm    ; else ignore the "[" (kbd lock)
  1863.     ret
  1864. h19csi1:mov    ttstate,offset atparse    ; H-19, ESC [ parser
  1865.     mov    pardone,offset h19csi2     ; where to jmp when done
  1866.     mov    parfail,offset atnorm    ; where to jmp if failure
  1867.     ret                ; get next char
  1868. h19csi2:mov    bx,offset h19ans    ; H-19 ANSI Final character table
  1869.     mov    ttstate,offset atnrm    ; reset state to "normal"
  1870.     jmp    atdispat        ; dispatch on character
  1871.  
  1872. ; Process Device Control Strings (DCS or ESC P lead-in chars, already read).
  1873. atdcs0:    cmp    ninter,0        ; any intermediates?
  1874.     je    atdcs            ; e = no, else not this item
  1875.     jmp    atnorm            ; reset state to normal
  1876.                     ; enter here with real DCS char
  1877. atdcs:    mov    ttstate,offset atparse    ; next state is parse control seq
  1878.     mov    pardone,offset atdcs1    ; where to jmp when done
  1879.     mov    parfail,offset atdcsnul    ; where to jmp if failure
  1880.     ret
  1881. atdcs1:    mov    dcsstrf,al        ; record Final char
  1882.     mov    emubufc,0        ; clear string count
  1883.     mov    cx,maxparam        ; number of DCS parameters
  1884.     push    si            ; copy these to the DCS area so that
  1885.     push    di            ;  they are not lost when an ST is
  1886.     push    es            ;  parsed (parser clears ESC items)
  1887.     push    ds
  1888.     pop    es
  1889.     mov    si,offset param        ; ESC paramater storage area, numeric
  1890.     mov    di,offset dparam    ; DCS parameter storage area, numeric
  1891.     cld
  1892.     rep    movsw            ; copy set to DCS storage area
  1893.     mov    cl,lparam         ; copy letter Paramter
  1894.     mov    dlparam,cl
  1895.     mov    cx,maxinter        ; number of intermediate characters
  1896.     mov    si,offset inter        ; source
  1897.     mov    di,offset dinter    ; destination
  1898.     rep    movsb
  1899.     mov    si,nparam        ; number of parameters
  1900.     mov    dnparam,si
  1901.     mov    si,ninter
  1902.     mov    dninter,si        ; number of intermediates
  1903.     pop    es
  1904.     pop    di
  1905.     pop    si
  1906.     mov    ttstateST,offset atnorm ; default ST completion state
  1907.     mov    emubufc,0        ; clear processed string length
  1908.     mov    al,dcsstrf        ; get DCS Final char
  1909.     mov    bx,dcstabptr        ; DCS dispatch table
  1910.     call    atdispat        ; go to DCS handler
  1911.     ret
  1912.  
  1913. ; Process ST or ESC \  String Terminator.
  1914. atgotst0:cmp    ninter,0        ; any intermediates in ESC..\?
  1915.     je    atgotst            ; e = no, else not this item
  1916.     jmp    atnorm            ; reset state to normal
  1917.                     ; enter here with real ST char
  1918. atgotst:jmp    ttstateST        ; go to state for ST arrival
  1919.  
  1920. ; Read and discard OSC (ESC ]), PM (ESC ^) control sequences
  1921. ; through final ST (ESC \) terminator.
  1922. atdcsnul0:cmp    ninter,0        ; any intermediates in ESC..\?
  1923.     je    atdcsnul        ; e = no, else not this item
  1924.     ret
  1925.                     ; enter here with real ST char
  1926. atdcsnul:mov    dcsstrf,0        ; simulate a null (dummy) Final char
  1927.     mov    emubufc,0        ; clear string count
  1928.     mov    ttstate,offset atdcsnul    ; keep coming here
  1929.     mov    ttstateST,offset atnorm    ; where to go when ST has been seen
  1930.     ret                ; consume chars
  1931.  
  1932. ; Process Application Process Control string (APC or ESC _ lead-in chars,
  1933. ; already read). Mallocs 1KB buffer, passes buffer to apcmacro for execution
  1934. ; as a Take file. Curly braces protect comma command separators.
  1935. atapc:    cmp    ninter,0        ; any intermediates?
  1936.     je    atapc0            ; e = no, else not this item
  1937.     jmp    atnorm            ; reset state to normal
  1938.                     ; enter here with real DCS char
  1939. atapc0:    mov    ax,apcstring        ; old string buffer segment
  1940.     or    ax,ax            ; used?
  1941.     jz    atapc1            ; z = no
  1942.     push    es
  1943.     mov    es,ax
  1944.     mov    ah,freemem        ; free that string memory
  1945.     int    dos
  1946.     pop    es
  1947.     mov    apcstring,0        ; clear pointer
  1948. atapc1:    mov    bx,(1024+3+15)/16    ; 1K buffer
  1949.     mov    cx,bx            ; remember desired paragraphs
  1950.     mov    ah,alloc        ; allocate a memory block
  1951.     int    dos
  1952.     jc    atapc2            ; c = error, not enough memory
  1953.      cmp    bx,cx            ; obtained vs wanted
  1954.     jae    atapc3            ; ae = enough
  1955.     push    es
  1956.     mov    es,ax            ; allocated segment
  1957.     mov    ah,freemem        ; free it again
  1958.     int    dos
  1959.     pop    es
  1960. atapc2:    jmp    atnorm            ; fail
  1961.  
  1962. atapc3:    mov    apcstring,ax        ; remember segment
  1963.     mov    bracecount,0        ; count of curly braces in string
  1964.     mov    emubufc,0        ; preset string buffer count
  1965.     mov    ttstate,offset atapc4    ; next state is read string
  1966.     mov    ttstateST,offset atapc5    ; where to go when ST has been seen
  1967.     ret
  1968.                     ; read bytes of APC string
  1969. atapc4:    mov    bx,emubufc        ; count of buffer chars
  1970.     cmp    bx,1024            ; too many?
  1971.     ja    atapc6            ; a = yes, ignore string
  1972.     push    es
  1973.     mov    cx,apcstring        ; segment of string buffer
  1974.     mov    es,cx
  1975.     cmp    al,braceop        ; opening brace?
  1976.     jne    atapc4a            ; ne = no
  1977.     inc    bracecount        ; count up braces
  1978. atapc4a:cmp    al,bracecl        ; closing brace?
  1979.     jne    atapc4b            ; ne = no
  1980.     sub    bracecount,1        ; count down braces
  1981.     jnc    atapc4b            ; nc = not below zero
  1982.     mov    bracecount,0        ; clamp to zero
  1983. atapc4b:cmp    al,','            ; comma command separator?
  1984.     jne    atapc4c            ; ne = no
  1985.     cmp    bracecount,0        ; in curly braces?
  1986.     jne    atapc4c            ; ne = yes, leave comma as comma
  1987.     mov    al,CR            ; replace bare comma as CR
  1988. atapc4c:xor    ah,ah
  1989.     mov    es:[bx+2],ax        ; store incoming byte + null
  1990.     pop    es
  1991.     inc    emubufc            ; count bytes in buffer
  1992.     ret                ; accumulate more bytes
  1993.  
  1994. atapc5:    mov    ax,apcstring        ; get here upon ST for APC
  1995.     or    ax,ax            ; string buffer in use?
  1996.     jz    atapc6            ; z = no, quit
  1997.     mov    ttstate,offset atnrm    ; reinit state before leaving
  1998.     mov    ttstateST,offset atnorm
  1999.     mov    bracecount,0        ; count of curly braces in string
  2000.     cmp    apcenable,0        ; is APCMACRO enabled?
  2001.     je    atapc6            ; e = no, quit
  2002.     push    es
  2003.     mov    es,ax
  2004.     mov    bx,emubufc        ; count of bytes in string
  2005.     mov    emubufc,0        ; clear for later users
  2006.     mov    byte ptr es:[bx+2],CR    ; append CR C to renter Connect mode
  2007.     mov    byte ptr es:[bx+2+1],'C'
  2008.     add    bx,2            ; two more bytes in buffer
  2009.     mov    es:[0],bx        ; length of string
  2010.     pop    es
  2011.     mov    cx,bx            ; CX used to pass string length
  2012.     call    APCMACRO        ; create and execute Take file
  2013.                     ; does not return if success
  2014. atapc6:    mov    ax,apcstring        ; segment of string buffer
  2015.     or    ax,ax            ; in use?
  2016.     jz    atapc7            ; z = no
  2017.     mov    es,ax
  2018.     mov    ah,freemem        ; free buffer
  2019.     int    dos
  2020. atapc7:    mov    apcstring,0        ; clear buffer
  2021.     mov    emubufc,0        ; clear string count
  2022.     mov    bracecount,0        ; count of curly braces in string
  2023.     jmp    atnorm            ; exit this sequence
  2024.  
  2025.  
  2026. ; User Definable Key processor of DCS strings.
  2027. atudk:    cmp    dinter,0        ; no intermediates?
  2028.     je    atudk1            ; e = correct
  2029.     mov    ninter,0        ; setup atdcsnul for proper form
  2030.     jmp    atdcsnul        ; bad, consume the rest
  2031.  
  2032. atudk1:    cmp    dparam,1        ; is initial Parameter Pc a 1?
  2033.     jae    atudk2            ; ae = yes, clear only this key
  2034.     call    udkclear        ; clear all UDKeys
  2035.     mov    dparam,1        ; and turn off Parameter
  2036. atudk2:    mov    ttstate,offset atudk3    ; next state is get a substring
  2037.     mov    ttstateST, offset atudk6 ; for when ST has been seen
  2038.     ret
  2039.  
  2040. atudk3:    cmp    al,';'            ; string separator?
  2041.     je    atudk5            ; e = yes, process string to-date
  2042.     mov    bx,emubufc        ; count of chars in string buffer
  2043.     cmp    bx,emubufl        ; too many?
  2044.     jae    atudk4            ; ae = too many, ignore extras
  2045.     mov    emubuf[bx],al        ; store the char
  2046.     inc    emubufc            ; count it
  2047. atudk4:    ret
  2048. atudk5:    mov    si,offset emubuf    ; address of string buffer is DS:SI
  2049.     mov    cx,emubufc        ; count of buffer contents
  2050.     call    setudk            ; insert string definition
  2051.     mov    emubufc,0        ; clear string buffer
  2052.     ret
  2053. atudk6:    call    atudk5            ; ST seen, process last string
  2054.     jmp    atnorm            ; reset state to normal
  2055.  
  2056. ; Call this routine to deliver Parameters in succession. Each call points to
  2057. ; a Parameter as param[si], where si is maintained here. If there are no
  2058. ; Parameters the effect is the same as one Parameter with a value of zero.
  2059. ; Enter with di = offset of action routine to be called for each Parameter.
  2060. ; cx, si, and di are preserved over the call to the action routine.
  2061.  
  2062. atreps    proc    near
  2063.     xor    si,si            ; initialize parm index
  2064.     mov    cx,nparam        ; number of Parameters
  2065.     or    cx,cx            ; zero?
  2066.     jnz    atrep1            ; nz = no
  2067.     inc    cx            ; zero parms is same as 1
  2068. atrep1: push    cx            ; save loop counter
  2069.     push    si            ; save parameter index
  2070.     push    di            ; save call vector
  2071.     call    DI            ; call indicated routine
  2072.     pop    di            ; restore registers
  2073.     pop    si
  2074.     pop    cx
  2075.     add    si,2            ; advance to next parameter
  2076.     loop    atrep1            ; loop for all
  2077.     ret
  2078. atreps    endp
  2079.  
  2080.                     ; Action routines
  2081. atind0:    cmp    ninter,0        ; any intermediates?
  2082.     je    atind            ; e = no, else not this item
  2083.     ret
  2084. atind:    inc    dh            ; IND (index), move cursor down one
  2085. atind1: call    atccic            ; check cursor position
  2086.     call    ax            ; scroll if necessary
  2087.     jmp    atsetcur        ; set cursor, etc. and return
  2088.  
  2089. atnel0:    cmp    ninter,0        ; any intermediates from ESC..E?
  2090.     je    atnel            ; e = no, else not this item
  2091.     jmp    atdgnrc            ; try Nowegian/Danish NRC designator
  2092.                     ; enter here with real NEL char
  2093. atnel:    mov    dl,mar_left        ; NEL, next line - sort of like CRLF
  2094.     inc    dh            ; ... all in one command
  2095.     jmp    short atind1        ; check cursor, etc., and return
  2096.  
  2097. atri0:    cmp    ninter,0        ; any intermediates?
  2098.     je    atri            ; e = no, else not this item
  2099.     ret
  2100. atri:    cmp    flags.vtflg,ttheath    ; Heath-19?
  2101.     jne    atri1            ; ne = no
  2102.     cmp    dh,byte ptr low_rgt+1    ; on 25th line?
  2103.     jbe    atri1            ; be = no
  2104.     ret                ; no vertical for Heath on 25th line
  2105. atri1:    dec    dh            ; RI, reverse index
  2106.     jmp    short atind1        ; check cursor, etc., and return
  2107.  
  2108.                     ; HTS, horizontal tab set in this col
  2109. athts0:    cmp    ninter,0        ; any intermediates from ESC..H?
  2110.     je    athts            ; e = no, else not this item
  2111.         cmp     isps55,0                ; [HF] Japanese mode ?
  2112.         je      athts1                  ; [HF] e = no
  2113.         jmp     atdgfJ                  ; [HF] else possible old wrong JISRoman
  2114. athts1: jmp     atdgnrc                 ; try Swedish NRC designator
  2115. athts:    call    atccpc            ; make column number valid
  2116.     mov    si,vtemu.vttbst        ; active buffer
  2117.     jmp    tabset            ; say set tab in this column (DL)
  2118.  
  2119.                     ; DECSC
  2120. atsc:    mov    si,offset savelist    ; save cursor, attribute, char set etc
  2121.     mov    di,offset savecu    ; place to save the stuff
  2122.     mov    cl,extattr        ; extended attributes
  2123.     mov    savextattr,cl        ; it's real storage is in msyibm
  2124.     mov    cl,scbattr
  2125.     mov    savscbattr,cl
  2126.     mov    havesaved,1        ; say have saved something
  2127.     mov    cx,lsavecu        ; length of save area
  2128.     push    es            ; save es
  2129.     mov    ax,data            ; seg of save area
  2130.     mov    es,ax            ; set es to data segment
  2131.     cld
  2132.     shr    cx,1            ; divide by two for word moves
  2133.     jnc    atsc1            ; nc = even number of bytes
  2134.     movsb                ; do the odd byte
  2135. atsc1:    rep    movsw            ; save it
  2136.     pop    es
  2137.     mov    cx,vtemu.vtflgop    ; save a copy of the flags
  2138.     mov    savflgs,cx
  2139.     ret
  2140.                     ; DECRC
  2141. atrc:    cmp    havesaved,0        ; saved anything yet?
  2142.     jne    atrc1            ; ne = yes
  2143.     ret
  2144. atrc1:    mov    si,offset savecu    ; restore cursor, attributes, etc
  2145.     mov    di,offset savelist    ; where stuff goes
  2146.     mov    cx,lsavecu        ; length of save area
  2147.     push    es            ; save es
  2148.     push    ds
  2149.     mov    ax,seg savecu        ; seg of savecu storage
  2150.     mov    ds,ax
  2151.     mov    ax,seg savelist        ; seg of regular storage
  2152.     mov    es,ax
  2153.     cld
  2154.     shr    cx,1            ; divide by two for word moves
  2155.     jnc    atrc2            ; nc = even number of bytes
  2156.     movsb                ; do the odd byte
  2157. atrc2:    rep    movsw            ; put the stuff back
  2158.     pop    ds
  2159.     pop    es
  2160.     mov    al,savextattr        ; extended attributes
  2161.     mov    extattr,al
  2162.     mov    al,savscbattr
  2163.     mov    scbattr,al
  2164.     mov    ax,savflgs        ; get saved flags
  2165.     xor    ax,vtemu.vtflgop    ; exclusive-or with current flags
  2166.     mov    al,atctype        ; get cursor shape
  2167.     call    csrtype            ; restore it
  2168. atrc3:    mov    ax,vtemu.vtflgop    ; reset flags in case called again
  2169.     and    ax, not(decckm+deckpam+decom)  ; remove old bits [dlk]
  2170.     and    savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
  2171.     or    ax,savflgs        ; restore saved bits [dlk]
  2172.     or    vtemu.vtflgop,ax    ; update these flags
  2173.     mov    savflgs,ax
  2174.     mov    bx,offset Gsetid    ; restore character sets
  2175.     call    chrsetup        ; go remake G0..G3
  2176.     mov    dx,cursor        ; get cursor
  2177.     mov    kbiflg,0        ; don't bother them with beeps here
  2178.     jmp    atsetcur        ; set cursor
  2179.  
  2180. atkpam:    cmp    ninter,0        ; any intermediates?
  2181.     jne    atkpam1            ; ne = yes, not this item
  2182.     or    vtemu.vtflgop,deckpam    ; turn on keypad applications mode
  2183.     ret
  2184. atkpam1:jmp    atdgnrc            ; try Swiss NRC designator
  2185.  
  2186. atkpnm: and    vtemu.vtflgop,not deckpam ; turn off keypad applications mode
  2187.     ret                ; (to numeric mode)
  2188.  
  2189.                     ; Privileged sequence, ignore it
  2190. atpriv:    cmp    ninter,0        ; any intermediates?
  2191.     jne    atpriv1            ; ne = yes, not this item
  2192.     mov    ttstate,offset atnorm    ; ignore next char
  2193. atpriv1:ret                ; and return to normal afterward
  2194.  
  2195. ; ISO 2022 three byte Announcer Summary    <ESC> <space> <final char>
  2196. ;Esc Sequence  7-Bit Environment          8-Bit Environment
  2197. ;----------    ------------------------   ----------------------------------
  2198. ;<ESC><SP>A    G0->GL                     G0->GL
  2199. ;<ESC><SP>B    G0-(SI)->GL, G1-(SO)->GL   G0-(LS0)->GL, G1-(LS1)->GL
  2200. ;<ESC><SP>C    (not used)                 G0->GL, G1->GR
  2201. ;<ESC><SP>D    G0-(SI)->GL, G1-(SO)->GL   G0->GL, G1->GR
  2202. ;<ESC><SP>E    Full preservation of shift functions in 7 & 8 bit environments
  2203. ;<ESC><SP>F    C1 represented as <ESC>F   C1 represented as <ESC>F
  2204. ;<ESC><SP>G    C1 represented as <ESC>F   C1 represented as 8-bit quantity
  2205. ;<ESC><SP>H    All graphic character sets have 94 characters
  2206. ;<ESC><SP>I    All graphic character sets have 94 or 96 characters
  2207. ;<ESC><SP>J    In a 7 or 8 bit environment, a 7 bit code is used
  2208. ;<ESC><SP>K    In an 8 bit environment, an 8 bit code is used
  2209. ;<ESC><SP>L    Level 1 of ISO 4873 is used
  2210. ;<ESC><SP>M    Level 2 of ISO 4873 is used
  2211. ;<ESC><SP>N    Level 3 of ISO 4873 is used
  2212. ;<ESC><SP>P    G0 is used in addition to any other sets:
  2213. ;              G0 -(SI)-> GL              G0 -(LS0)-> GL
  2214. ;<ESC><SP>R    G1 is used in addition to any other sets:
  2215. ;              G1 -(SO)-> GL              G1 -(LS1)-> GL
  2216. ;<ESC><SP>S    G1 is used in addition to any other sets:
  2217. ;              G1 -(SO)-> GL              G1 -(LS1R)-> GR
  2218. ;<ESC><SP>T    G2 is used in addition to any other sets:
  2219. ;              G2 -(LS2)-> GL             G2 -(LS2)-> GL
  2220. ;<ESC><SP>U    G2 is used in addition to any other sets:
  2221. ;              G2 -(LS2)-> GL             G2 -(LS2R)-> GR
  2222. ;<ESC><SP>V    G3 is used in addition to any other sets:
  2223. ;              G3 -(LS2)-> GL             G3 -(LS3)-> GL
  2224. ;<ESC><SP>W    G3 is used in addition to any other sets:
  2225. ;              G3 -(LS2)-> GL             G3 -(LS3R)-> GR
  2226. ;<ESC><SP>Z    G2 is used in addition to any other sets:
  2227. ;              SS2 invokes a single character from G2
  2228. ;<ESC><SP>[    G3 is used in addition to any other sets:
  2229. ;              SS3 invokes a single character from G3
  2230. ;
  2231. ; ISO Escape Sequences for Alphabet Designation ("F" = Final char)
  2232. ; Sequence     Function                                         Invoked By
  2233. ;  <ESC>(F     assigns 94-character graphics set "F" to G0.     SI  or LS0
  2234. ;  <ESC>)F     assigns 94-character graphics set "F" to G1.     SO  or LS1
  2235. ;  <ESC>*F     assigns 94-character graphics set "F" to G2.     SS2 or LS2
  2236. ;  <ESC>+F     assigns 94-character graphics set "F" to G3.     SS3 or LS3
  2237. ;  <ESC>-F     assigns 96-character graphics set "F" to G1.     SO  or LS1
  2238. ;  <ESC>.F     assigns 96-character graphics set "F" to G2.     SS2 or LS2
  2239. ;  <ESC>/F     assigns 96-character graphics set "F" to G3.     SS3 or LS3
  2240. ;  <ESC>$(F    assigns multibyte character set "F" to G0.       SI  or LS0
  2241. ;  <ESC>$)F    assigns multibyte character set "F" to G1.       SO  or LS1
  2242. ;  <ESC>$*F    assigns multibyte character set "F" to G2.       SS2 or LS2
  2243. ;  <ESC>$+F    assigns multibyte character set "F" to G3.       SS3 or LS3
  2244. ;     
  2245. ; Designate character sets, AL has final character, inter has all preceeding.
  2246. ;
  2247. ;  <ESC> $ B       designate JIS X 208 code set (ISO(ECMA)#87) to G0 (old)
  2248. ;  <ESC> $ <char> B  designates JIS X 208 code set (ISO(ECMA)#87)
  2249. ;
  2250. ;  The following sequences are for JIS C 6226-1978 code set (ISO(ECMA)#42), but
  2251. ;  treated as the same as the above in this version of MS-Kermit, becuase that the
  2252. ;  diffrence is quite small.
  2253. ;
  2254. ;  <ESC> $ @
  2255. ;  <ESC> $ <char> @
  2256. ;
  2257. ;  <ESC> <char> J  designates JIS X 201 Roman code set (ISO(ECMA)#14)
  2258. ;
  2259. ;  Note: The ESC sequences for U.S. ASCII code set are treated as the same
  2260. ;        as above because there is no fonts are available for U.S. ASCII .
  2261. ;        The differences between U.S. ASCII and JIS X 201 Roman are only
  2262. ;        backslash and tilde.
  2263. ;
  2264. atdgfA:    call    atdgset            ; 'A' ISO Latin-1, UK-ASCII
  2265.     jc    atdgfA1            ; c = no matching pointer
  2266.     cmp    inter,'+'        ; in the 94 byte set?
  2267.     ja    atdgfA2            ; a = no, 96 'A' is Latin1
  2268.     mov    ax,flags.vtflg        ; terminal type
  2269.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttansi ; VTxxx?
  2270.     jz    atdgfA1            ; z = no
  2271.     jmp    mkukascii        ; make UK ASCII table
  2272. atdgfA1:ret
  2273.  
  2274. atdgfA2:jmp    mklatin1        ; make Latin1 char set
  2275.  
  2276. atdgfA3:jmp    atdgnrc            ; try British NRC
  2277.  
  2278. atdgfB:    cmp    inter,'$'        ; [HF] 940130 multibyte set?
  2279.     je    atdgfB2            ; [HF] 940130 e = yes
  2280.     call    atdgset            ; 'B' ASCII, get setptr from inter
  2281.     jc    atdgfA1            ; c = no matching pointer
  2282.     cmp    inter,'+'        ; in the 94 byte set?
  2283.     ja    atdgfB1            ; a = no, do Latin2
  2284.     jmp    mkascii            ; make US ASCII set
  2285.  
  2286. atdgfB1:jmp    mklatin2        ; make Latin2 ("B"/96)
  2287.  
  2288. atdgfB2:cmp    ninter,1        ; [HF] any intermediates?
  2289.     jne    atdgfB3            ; [HF] ne = yes we have
  2290.     mov    inter,'('        ; [HF] implicit G0 /94
  2291.     jmp    short atdgfB4        ; [HF]
  2292. atdgfB3:push    ax            ; [HF]
  2293.     mov    al,inter[1]        ; [HF]
  2294.     mov    inter,al        ; [HF]
  2295.     mov    ninter,1        ; [HF]
  2296.     pop    ax            ; [HF]
  2297. atdgfB4:call    atdgset            ; [HF]
  2298.     jc    atdgfA1            ; [HF]
  2299.     jmp    mkjiskanji        ; [HF]
  2300.  
  2301. ;[HF] Japanese JIS-Katakana and JIS-Roman
  2302. ;[HF]
  2303. atdgfI:    call    atdgset            ; [HF] JIS-Katakana
  2304.     jc    atdgfI1            ; [HF] c = no matching pointer
  2305.     cmp    inter,'+'        ; [HF] in the 94 byte set?
  2306.     ja    atdgfI1            ; [HF] a = no, just ignore
  2307.     mov    ax,flags.vtflg        ; [HF] terminal type
  2308.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; [HF] VTxxx?
  2309.     jz    atdgfI1            ; [HF] z = no
  2310.     jmp    mkjiskana        ; [HF] make JIS Katakana table
  2311. atdgfI1:ret                ; [HF]
  2312.  
  2313. atdgfJ:    call    atdgset            ; [HF] JIS-Roman
  2314.     jc    atdgfJ1            ; [HF] c = no matching pointer
  2315.     cmp    inter,'+'        ; [HF] in the 94 byte set?
  2316.     ja    atdgfJ1            ; [HF] a = no, just ignore
  2317.     test    ax,ttvt320+ttvt220+ttvt102+ttvt100+tthoney ; [HF] VTxxx?
  2318.     jz    atdgfJ1            ; [HF] z = no
  2319.     jmp    mkascii            ; [HF] treat as US ASCII
  2320. atdgfJ1:ret                ; [HF]
  2321.  
  2322. atdgf0:    call    atdgset            ; '0', '2', DEC Special Graphics
  2323.     jc    atdgfA1            ; c = no matching pointer
  2324.     cmp    inter,'+'        ; in the 94 byte set?
  2325.     ja    atdgfA1            ; a = no, ignore
  2326.     jmp    mkdecspec        ; init set to DEC Special Graphics
  2327.  
  2328. atdgf1:    call    atdgset            ; '1' ALT-ROM
  2329.     jc    atdgf1b            ; c = no matching pointer
  2330.     jmp    mkaltrom        ; make ALT-ROM set
  2331.  
  2332. atdgf1b:
  2333. ;    cmp    ninter,0        ; ESC 1? (Special enter Tek mode)
  2334. ;    jne    atdgf1c            ; ne = some, not ESC 1
  2335. ;    cmp    nparam,0
  2336. ;    jne    atdgf1c            ; ne = some, not ESC 1
  2337. ;    jmp    atff1            ; treat the same as ESC ^L
  2338. atdgf1c:ret
  2339.  
  2340. atdgft:    call    atdgset            ; '>' Dec Technical Set
  2341.     jc    atdgft1            ; c = no matching pointer
  2342.     cmp    inter,'+'        ; in the 94 byte set?
  2343.     ja    atdgft1            ; a = no
  2344.     jmp    mkdectech        ; make DEC Tech set
  2345.  
  2346. atdgft1:cmp    ninter,0        ; ESC > DECKNPNM set numeric keypad?
  2347.     jne    atdgft2            ; ne = no
  2348.     and    vtemu.vtflgop,not deckpam ; turn off application keypad bit
  2349. atdgft2:ret                ;  (to numeric)
  2350.                     ; '<' User Preferred Supplemental Set
  2351. atdgfu:    call    atdgset            ; get set pointer
  2352.     jc    atdgfu2            ; c = no matching pointer
  2353.     test    flags.vtflg,ttvt220    ; in VT220 mode?
  2354.     jnz    atdgfu1b        ; nz = yes, force DEC Supplemental
  2355. ; DEC VT320's ignore the set size designator when picking UPSS sets here
  2356.     cmp    word ptr upss+1,0+'A'    ; is ISO Latin-1 the preferred set?
  2357.     jne    atdgfu0a        ; ne = no
  2358.     jmp    mklatin1        ; make Latin1 set
  2359. atdgfu0a:cmp    word ptr upss+1,0+'H'    ; is Hebrew-ISO preferred?
  2360.     jne    atdgfu1            ; ne = no
  2361.     jmp    mklatin_Hebrew        ; make Hebrew-ISO
  2362.  
  2363. atdgfu1:cmp    word ptr upss+1,'5%'    ; DEC Supplemental Graphics?
  2364.     jne    atdgfu1a        ; ne = no
  2365. atdgfu1b:jmp    mkdecmn            ; make DEC Multinat/Supp Graphics
  2366. atdgfu1a:cmp    word ptr upss+1,'4"'    ; DEC Hebrew?
  2367.     jne    atdgfu2
  2368.     jmp    mkdec_Hebrew        ; make DEC Hebrew 
  2369. atdgfu2:ret
  2370.  
  2371. atdgfq:    call    atdgset            ; '?' Transparent
  2372.     jc    atdgfu2            ; c = no matching pointer
  2373.     jmp    mkxparent        ; make transparent table
  2374.  
  2375.                     ; ESC <...> <1-8>  series
  2376. atsdhl:    cmp    ninter,1        ; just one intermediate?
  2377.     jne    atsdh0            ; ne = no
  2378.     cmp    inter,'#'        ; this intermediate?
  2379.     jne    atdgnrc            ; ne = no, try NRC char set designator
  2380.     cmp    al,'3'            ; Double high lines. Top half?
  2381.     je    atsdh2            ; e = yes
  2382.     cmp    al,'4'            ; bottom half?
  2383.     je    atsdh2            ; e = yes
  2384.     cmp    al,'5'            ; restore line to single width?
  2385.     je    atsdh1            ; e = yes
  2386.     cmp    al,'6'            ; double width single height?
  2387.     je    atsdh2            ; e = yes
  2388.     cmp    al,'8'            ; screen alignment?
  2389.     je    atsdh8            ; e = yes
  2390. atsdhx:    ret                ; else ignore
  2391.  
  2392. atsdh1:    jmp    linesgl            ; set line to single width
  2393. atsdh2:    jmp    linedbl            ; expand the line to double width
  2394. atsdh8:    jmp    atalign            ; do screen alignment
  2395.  
  2396. atsdh0:    cmp    ninter,0        ; zero intermediates?
  2397.     jne    atdgf5            ; ne = no, try for more
  2398.     cmp    al,'7'            ; save cursor?
  2399.     jne    atsdh0a            ; ne = no
  2400.     jmp    atsc            ; do save cursor, ESC 7
  2401. atsdh0a:cmp    al,'8'            ; restore cursor?
  2402.     jne    atsdh0b            ; ne = no
  2403.     jmp    atrc            ; do restore cursor, ESC 8
  2404. atsdh0b:ret
  2405.  
  2406. atdgf5:    cmp    ninter,2        ; two intermediates?
  2407.     jne    atdgf5a            ; ne = no, ignore remainder
  2408.     cmp    al,'6'            ; '%6' NRC designator?
  2409.     je    atdgnrc            ; e = yes, do that above
  2410.     cmp    al,'5'            ; '%5' DEC Supplemental Graphic?
  2411.     jne    atdgf5a            ; ne = no
  2412.     cmp    inter,'+'        ; in the 94 byte set?
  2413.     ja    atdgf5a            ; a = no, ignore
  2414.     cmp    inter[1],'%'        ; '%5'?
  2415.     jne    atdgf5a            ; ne = no
  2416.     mov    ninter,1        ; help atdgset find our set
  2417.     call    atdgset            ; get set pointer
  2418.     jc    atdgf5a            ; c = no matching pointer
  2419.     jmp    mkdecmn            ; make DEC Multinat/Supp Gr
  2420. atdgf5a:ret
  2421.  
  2422. ; Enter with Final esc char in al, others in array inter. Setup Gn if success.
  2423. atdgnrc    proc    near            ; check for NRC set designator
  2424.     cmp    ninter,0        ; ESC Z?
  2425.     jne    atdgnr1            ; ne = no
  2426.     cmp    al,'Z'            ; the Z?
  2427.     jne    atdgnrx            ; ne = not ESC Z
  2428.     jmp    atda            ; process ident request
  2429. atdgnr1:cmp    inter,'+'        ; in the 94 byte set?
  2430.     ja    atdgnrx            ; a = no, ignore
  2431.     call    findctry        ; find NRC country number in CX
  2432.     jc    atdgnrx            ; c = not found, ignore
  2433.     mov    ninter,1        ; help atdgset find our set
  2434.     call    atdgset            ; check for Gn designator
  2435.     jc    atdgnrx            ; c = not found
  2436.     jmp    mknrc            ; make NRC set
  2437. atdgnrx:ret                ; ignore
  2438. atdgnrc    endp
  2439.  
  2440. ; Find NRC country number, putting it into CX, given Final char in AL and
  2441. ; intermediates in array inter. Return carry set if not found.
  2442. findctry proc    near
  2443.     cmp    ninter,2        ; second intermediate (%)?
  2444.     jb    findct1            ; b = no
  2445.     ja    findct3            ; a = three or more, no match
  2446.     mov    ah,inter+1        ; get NRC intermediate
  2447.     cmp    ax,'%6'            ; Portugese NRC?
  2448.     jne    findct4            ; ne = no, try Hebrew
  2449.     mov    cx,9            ; Portuguese NRC is number 9
  2450.     clc
  2451.     ret
  2452. findct4:cmp    ax,'%='            ; Hebrew NRC?
  2453.     jne    findct3            ; ne = no, fail
  2454.     mov    cx,13            ; Hebrew NRC is number 13
  2455.     clc
  2456.     ret
  2457. findct1:cmp    ninter,0        ; no intermediate?
  2458.     je    findct3            ; e = yes, no designator, fail
  2459.     mov    cx,nrcflen        ; number of NRC letters to consider
  2460.     cld
  2461.     push    di            ; save regs
  2462.     push    es
  2463.     push    ds
  2464.     pop    es
  2465.     mov    di,offset nrcfinal    ; list of NRC final chars
  2466.     repne    scasb            ; look for a match
  2467.     pop    es            ; recover reg
  2468.     jne    findct2            ; ne = failed
  2469.     dec    di            ; compenstate for auto-inc
  2470.     sub    di,offset nrcfinal    ; get distance covered
  2471.     mov    cl,nrcnum[di]        ; country number from parallel list
  2472.     xor    ch,ch            ; return number in CX
  2473.     pop    di
  2474.     clc                ; success
  2475.     ret
  2476. findct2:pop    di            ; carry set = failure
  2477. findct3:stc
  2478.     ret
  2479. findctry endp
  2480.  
  2481. ; Worker for atdgf routines. Return setptr looking at Gnset (n=0..3) and
  2482. ; carry clear, based on ninter=1, inter = Gn designator. Carry set if fail.
  2483. ; Modifies AL
  2484. atdgset    proc    near
  2485.     cmp    ninter,1        ; one intermediate?
  2486.     jne    atdgsex            ; ne = no, ignore
  2487.     mov    al,inter        ; inter, from parser
  2488.     cmp    al,'('            ; 94 char sets, designate G0?
  2489.     je    atdgse0            ; e = yes
  2490.     cmp    al,')'            ; G1?
  2491.     je    atdgse1
  2492.     cmp    al,'*'            ; G2?
  2493.     je    atdgse2
  2494.     cmp    al,'+'            ; G3?
  2495.     je    atdgse3
  2496.     cmp    al,'-'            ; 96 char sets, designate G1?
  2497.     je    atdgse1
  2498.     cmp    al,'.'            ; G2?
  2499.     je    atdgse2
  2500.     cmp    al,'/'            ; G3?
  2501.     je    atdgse3
  2502. atdgsex:stc                ; carry set for failure
  2503.     ret
  2504. atdgse0:mov    setptr,offset G0set    ; designate G0 set
  2505.     clc
  2506.     ret
  2507. atdgse1:mov    setptr,offset G1set    ; designate G1 set
  2508.     clc
  2509.     ret
  2510. atdgse2:mov    setptr,offset G2set    ; designate G2 set
  2511.     clc
  2512.     ret
  2513. atdgse3:mov    setptr,offset G3set    ; designate G3 set
  2514.     clc
  2515.     ret
  2516. atdgset endp
  2517.                     ; S7C1T/S8C1T select 7/8-bit controls
  2518. ats7c:    test    flags.vtflg,ttvt320+ttvt220 ; in VT320/VT220 mode?
  2519.     jz    atdgsex            ; z = no, ignore command
  2520.     cmp    ninter,1        ; one intermediate?
  2521.     jne    ats7ca            ; ne = no
  2522.     cmp    inter,' '        ; proper intermediate?
  2523.     jne    ats7ca            ; ne = no
  2524.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls bit
  2525. ats7ca:ret                ; done
  2526.  
  2527. ats8c:    cmp    inter,' '        ; proper intermediate?
  2528.     jne    ats8ca            ; ne = no
  2529.     cmp    ninter,1        ; just one?
  2530.     jne    ats8ca            ; ne = no
  2531.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls bit
  2532. ats8ca:    ret
  2533.  
  2534. ; Designate User Preferred Supplemental Set as
  2535. ;  'A' ISO Latin-1  or '%','5' DEC Supplemental Graphics, or
  2536. ;  'H' Hebrew-ISO,  or '"','4' DEC-Hebrew
  2537. ; Store the selection letters in array upss for later use by ESC <char> '<'
  2538. atupss:    cmp    word ptr dinter,0+'!'    ; "!u" proper intermediate?
  2539.     je    atupss0            ; e = yes
  2540.     mov    ninter,0        ; set up atdcsnul for proper form
  2541.     jmp    atdcsnul        ; consume unknown command
  2542. atupss0:mov    ah,94            ; assume 94 byte set
  2543.     cmp    dparam,1        ; 96 byte char size indicator?
  2544.     jb    atupss1            ; b = no, 94
  2545.     ja    atupss2            ; a = illegal Parameter
  2546.     mov    ah,96            ; say 96
  2547. atupss1:mov    upss,ah            ; store char set size
  2548.     mov    ttstateST,offset atupss4; where to go when ST has been seen
  2549.     mov    emubufc,0        ; clear buffer count
  2550.     mov    ttstate,offset atupss2    ; next state is get string
  2551.     ret
  2552. atupss2:mov    bx,emubufc        ; count of chars in string buffer
  2553.     cmp    bx,emubufl        ; too many?
  2554.     jae    atupss3            ; ae = too many, ignore extras
  2555.     mov    emubuf[bx],al        ; store the char
  2556.     inc    emubufc            ; count it
  2557. atupss3:ret
  2558. atupss4:mov    si,emubufc        ; count of chars in string
  2559.     mov    emubuf[si],0        ; terminate string in null
  2560.     mov    ax,word ptr emubuf    ; copy two chars from string to
  2561.     mov    word ptr upss+1,ax    ;  upss char set ident storage area
  2562.     mov    emubufc,0        ; clear the string count
  2563.     ret
  2564.  
  2565. ; Select/map character sets
  2566. atls0:    test    flags.vtflg,ttansi    ; ANSI-BBS?
  2567.     jnz    atlsx            ; nz = yes, avoid BBS stupidities
  2568.     mov    GLptr,offset G0set    ; LS0,  map G0 char set into GLeft
  2569.     ret                ; Control-O
  2570. atls1:    test    flags.vtflg,ttansi    ; ANSI-BBS?
  2571.     jnz    atlsx            ; nz = yes, avoid BBS stupidities
  2572.     mov    GLptr,offset G1set    ; LS1,  map G1 char set into GLeft
  2573.     ret                ; Control-N
  2574. atls1r:    cmp    ninter,0        ; any intermediate chars?
  2575.     jne    atlsx            ; ne = yes, not a Locking Shift
  2576.     mov    GRptr,offset G1set    ; LS1R, map G1 char set into GRight
  2577.     ret
  2578. atss2:    cmp    ninter,0        ; any intermediate chars?
  2579.     jne    atlsx            ; ne = yes, not a Single Shift
  2580.     mov    SSptr,offset G2set    ; SS2,  use G2 for next graphics only
  2581.     ret
  2582. atls2:    cmp    ninter,0        ; any intermediate chars?
  2583.     jne    atlsx            ; ne = yes, not a Locking Shift
  2584.     mov    GLptr,offset G2set    ; LS2,  map G2 char set into GLeft
  2585.     ret
  2586. atls2r:    cmp    ninter,0        ; any intermediate chars?
  2587.     jne    atlsx            ; ne = yes, not a Locking Shift
  2588.     mov    GRptr,offset G2set    ; LS2R, map G2 char set into GRight
  2589.     ret
  2590. atss3:    cmp    ninter,0        ; any intermediate chars?
  2591.     jne    atlsx            ; ne = yes, not a Single Shift
  2592.     mov    SSptr,offset G3set    ; SS3,  use G3 for next graphics only
  2593.     ret
  2594. atls3:    cmp    ninter,0        ; any intermediate chars?
  2595.     jne    atlsx            ; ne = yes, not a Locking Shift
  2596.     mov    GLptr,offset G3set    ; LS3,  map G3 char set into GLeft
  2597.     ret
  2598. atls3r:    cmp    ninter,0        ; any intermediate chars?
  2599.     jne    atlsx            ; ne = yes, not a Locking Shift
  2600.     mov    GRptr,offset G3set    ; LS3R, map G3 char set into GRight
  2601. atlsx:    ret
  2602.  
  2603.  
  2604. ; Routine to set default character set.
  2605. chrdef    proc    near
  2606.       mov    GLptr,offset G0set    ; map G0 set to GLeft
  2607.     mov    GRptr,offset G2set    ; map G2 set to GRight
  2608.     mov    SSptr,0            ; clear single shift
  2609.     mov    bx,offset emubuf    ; temp table of char set idents
  2610.     mov    word ptr [bx],C_ASCII    ; G0 and G1 to ASCII
  2611.     mov    al,vtemu.vtchset    ; user specifed char set for GL
  2612.     mov    byte ptr [bx+2],al    ; set G2 and G3 to user selected set
  2613.     mov    byte ptr [bx+3],al
  2614.     cmp    al,C_SHORT_KOI        ; Short KOI?
  2615.     jne    chrdef0b        ; ne = no
  2616.     mov    byte ptr [bx],al    ; force into all sets, as if an NRC
  2617.     mov    byte ptr [bx+1],al
  2618. chrdef0b:test    flags.vtflg,ttvt320+ttvt220
  2619.     jnz    chrdef1            ; nz = yes, 8-bit terminals
  2620.     mov    GRptr,offset G1set    ; map G1 set to GRight
  2621.     mov    byte ptr [bx+1],C_DECTECH ; assume Dec Special Graphics in G1
  2622.     test    flags.vtflg,ttansi    ; ANSI-BBS?
  2623.     jz    chrdef0a        ; z = no
  2624.     mov    byte ptr [bx+1],C_XPARENT ; set TRANSPARENT
  2625.     jmp    short chrdef1
  2626. chrdef0a:test    flags.vtflg,ttwyse    ; Wyse-50?
  2627.     jz    chrdef1            ; z = no
  2628.     mov    byte ptr [bx+1],C_WYSEGR ; Wyse-50 graphics to G1
  2629.  
  2630. chrdef1:cmp     vtemu.vtchset,C_JISKANJI        ;[HF] JIS-Kanji?
  2631.         jne     chrdef1a                        ;[HF] ne = no
  2632.         mov     byte ptr [bx+2],C_JISKAT        ;[HF] G2 = JIS-Katakana
  2633.         mov     byte ptr [bx+3],al              ;[HF] G3 = JIS-Kanji
  2634.         mov     GRptr,offset G3set              ;[HF] GR = G3 (as VT382)
  2635.         jmp     short chrdef2                   ;[HF]
  2636. chrdef1a:test   vtemu.vtflgop,vsnrcm    ; doing National Replacement Chars?
  2637.     jz    chrdef2            ; z = no
  2638.     mov    al,vtemu.vtchset    ; get country number
  2639.     mov    dgkbl,al        ; keyboard language
  2640.     cmp    al,C_DHEBNRC        ; max NRC country
  2641.     ja    chrdef2            ; a = out of bounds, ignore
  2642.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  2643.     mov    ah,al            ; country number 1..12
  2644.     mov    [bx],al            ; set G0
  2645.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  2646.     jnz    chrdef2            ; nz = yes, don't touch G1..G3 here
  2647.     mov    [bx+1],ah
  2648.     mov    word ptr [bx],ax    ; same char set in G0..G3
  2649.     mov    word ptr [bx+2],ax
  2650.  
  2651. chrdef2:test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  2652.     jz    chrdef5            ; z = no (should have all cases now)
  2653.     mov    al,C_DGINT        ; D463/D470 DG International to G1
  2654.     test    flags.remflg,d8bit    ; 8 bit mode?
  2655.     jnz    chrdef4            ; nz = yes
  2656. chrdef3:mov    al,C_DGWP        ; D463/D470 DG Word Processing to G1
  2657. chrdef4:mov    [bx+1],al        ; D463/D470 G1 default
  2658.     mov    dgkbl,al        ; DG keyboard language
  2659.     mov    vtemu.vtchset,al
  2660.     mov    ah,[bx]            ; G0
  2661.     or    ah,ah            ; using NRCs?
  2662.     jz    chrdef5            ; z = no
  2663.     mov    dgkbl,ah        ; yes, state NRC in use for kbd
  2664.     jmp    short chrdef5
  2665.  
  2666. chrdef5:call    chrsetup        ; worker to setup G0..G3
  2667.                     ; do table of Gn overrides
  2668.     mov    bx,offset vtemu.vttable    ; table of char set overrides
  2669. chrdef6:call    chrsetup                ; worker to setup G0..G3
  2670.     ret
  2671. chrdef    endp
  2672.  
  2673. ; Load G0..G3 with character sets whose idents (0..24) are in byte array 
  2674. ; pointed to by BX. Update Gsetid with those byte idents enroute.
  2675. chrsetup proc    near
  2676.     push    ninter            ; preserve these
  2677.     mov    ch,inter
  2678.     push    cx            ; save them
  2679.     mov    ninter,1        ; one intermediate
  2680.     mov    inter,'('        ; init inter for atdgset
  2681.     xor    cx,cx            ; count sets from 0
  2682. chrset1:push    cx            ; save loop counter
  2683.     push    bx
  2684.     call    atdgset            ; get setptr = offset Gnset (n=0..3)
  2685.     mov    al,[bx]            ; get char set ident from 4 byte list
  2686.     cmp    al,0ffh            ; none?
  2687.     je    chrset90        ; e = none
  2688.     mov    bx,cx            ; update Gsetid table with set ident
  2689.     mov    Gsetid[bx],al
  2690.     cmp    al,C_ASCII        ; ASCII (0)?
  2691.     jne    chrset13        ; ne = no
  2692.     call    mkascii            ; make ASCII
  2693.     jmp    chrset90
  2694.  
  2695. chrset13:cmp    al,C_DHEBNRC        ; in NRC's?
  2696.     ja    chrset14              ; a = no
  2697.     mov    cl,al            ; put country number in cx
  2698.     xor    ch,ch
  2699.     call    mknrc            ; setup an NRC, using cx and setptr
  2700.     jmp    chrset90
  2701.  
  2702. chrset14:cmp    al,C_ALTROM        ; want ALT-ROM?
  2703.     jne    chrset15        ; ne = no
  2704.     call    mkaltrom        ; do ALT-ROM setup
  2705.     jmp    chrset90
  2706.  
  2707. chrset15:cmp    al,C_XPARENT        ; Transparent (15)?
  2708.     jne    chrset16        ; ne = no
  2709.     call    mkxparent        ; do Transparent setup
  2710.     jmp    chrset90
  2711.  
  2712. chrset16:cmp    al,C_LATIN1        ; Latin1 (16)?
  2713.     jne    chrset17
  2714.     cmp    setptr,offset G0set    ; want 96 byte set in G0?
  2715.     je    chrset90        ; e = yes, can not do this
  2716.     call    mklatin1        ; make Latin1
  2717.     jmp    chrset90
  2718.  
  2719. chrset17:cmp    al,C_DMULTINAT        ; DEC-MCS (17)?
  2720.     jne    chrset18        ; ne = no
  2721.     call    mkdecmn            ; make DEC Supplement Graph (DEC-MCS)
  2722.     jmp    chrset90
  2723.  
  2724. chrset18:cmp    al,C_DECTECH        ; DEC-Technical (18)?
  2725.     jne    chrset19        ; ne = no
  2726.     call    mkdectech        ; make DEC Technical
  2727.     jmp    chrset90
  2728.  
  2729. chrset19:cmp    al,C_DECSPEC        ; DEC-Special-Graphics?
  2730.     jne    chrset20        ; ne = no
  2731.     call    mkdecspec        ; make DEC Special Graphics
  2732.     jmp    chrset90
  2733.  
  2734. chrset20:cmp    al,C_DGINT        ; DG International?
  2735.     jne    chrset21        ; ne = no
  2736.     call    mkdgint            ; make DG International
  2737.     jmp    short chrset90
  2738.  
  2739. chrset21:cmp    al,C_DGLINE        ; DG Line Drawing?
  2740.     jne    chrset22        ; ne = no
  2741.     call    mkdgld            ; make DG line drawing
  2742.     jmp    short chrset90
  2743.  
  2744. chrset22:cmp    al,C_DGWP        ; DG Word Processing?
  2745.     jne    chrset23        ; ne = no
  2746.     call    mkdgwp            ; make DG Word Procssing
  2747.     jmp    short chrset90
  2748.     
  2749. chrset23:cmp    al,C_LATIN2        ; Latin2/CP852?
  2750.     jne    chrset24        ; ne = no
  2751.     call    mklatin2
  2752.     jmp    short chrset90
  2753.  
  2754. chrset24:cmp    al,C_HEBREWISO        ; Hebrew-ISO (CP862)?
  2755.     jne    chrset26        ; ne = no
  2756.     call    mklatin_hebrew
  2757.     jmp    short chrset90
  2758.  
  2759. chrset26:cmp    al,C_WYSEGR        ; Wyse-50 graphics chars?
  2760.     jne    chrset27        ; ne = no
  2761.     call    mkwyse
  2762.     jmp    short chrset90
  2763.  
  2764. chrset27:cmp    al,C_HPROMAN8        ; HP-Roman8?
  2765.     jne    chrset28        ; ne = no
  2766.     call    mkhpr8
  2767.     jmp    short chrset90
  2768.  
  2769. chrset28:cmp    al,C_CYRILLIC_ISO    ; Cyrillic to CP866?
  2770.     jne    chrset29        ; ne = no
  2771.     call    mkcyiso
  2772.     jmp    short chrset90
  2773.  
  2774. chrset29:cmp    al,C_KOI8        ; Cyrillic KOI8 to CP866?
  2775.     jne    chrset30        ; ne = no
  2776.     call    mkkoi8
  2777.     jmp    short chrset90
  2778.  
  2779. chrset30:cmp    al,C_SHORT_KOI        ; Cyrillic Short-KOI to CP866?
  2780.     jne    chrsetj13        ; ne = no
  2781.     call    mkkoi7
  2782.     jmp    short chrset90
  2783.  
  2784.  
  2785. chrsetj13:cmp   al,C_JISKAT             ; [HF] JIS-Katakana?
  2786.         jne     chrsetj87               ; [HF] ne = no
  2787.         call    mkjiskana               ; [HF]
  2788.         jmp     short chrset90          ; [HF]
  2789.  
  2790. chrsetj87:cmp    al,C_JISKANJI        ; [HF] JIS-Kanji?
  2791.     jne    chrset100        ; [HF] ne = no
  2792.     call    mkjiskanji        ; [HF]
  2793.     jmp    short chrset90        ; [HF]
  2794.  
  2795. chrset100:cmp    al,100+1        ; possible DG soft set?
  2796.     jb    chrset90        ; ne = no
  2797.     cmp    al,100+31        ; in range of soft sets?
  2798.     ja    chrset90        ; a = no
  2799.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  2800.     jz    chrset90        ; z = no
  2801.     call    mkdgsoft        ; do it (softset # + 100+1 is in al)
  2802.  
  2803. chrset90:pop    bx
  2804.     pop    cx
  2805.     inc    bx            ; next byte of table
  2806.     inc    inter            ; next set pointer
  2807.     inc    cx
  2808.     cmp    cx,4            ; done all sets?
  2809.     jae    chrset92        ; ae = yes
  2810.     jmp    chrset1            ; b = no (counting sets as 0..3)
  2811. chrset92:pop    cx            ; recover saved parsing items
  2812.     mov    inter,cl        ; restore
  2813.     pop    ninter            ; this too
  2814.     ret
  2815. chrsetup endp
  2816.  
  2817. ; Make Data General International to Gn table. 
  2818. ; Enter with destination in setptr
  2819. mkdgint    proc    near
  2820.     push    si
  2821.     push    di
  2822.     push    es
  2823.     mov    di,setptr
  2824.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  2825.     xor    ah,ah
  2826.     mov    si,ax
  2827.     mov    Gsetid[si],C_DGINT    ; store our char set ident
  2828.     mov    ax,ds
  2829.     mov    es,ax
  2830.     PUSH    DS
  2831.     call    flatin1        ; get DS:BX to Code Page dependent Latin1
  2832.     mov    si,bx
  2833.     cld
  2834.     push    di
  2835.     mov    cx,gsize        ; gsize chars
  2836.     rep    movsb            ; copy appropriate Latin1 xlat table
  2837.     pop    di
  2838.     mov    cx,dgi2len        ; number of new chars
  2839.     mov    si,offset dgi2lat    ; source of chars to be translated
  2840.     add    di,20h            ; where new chars start
  2841.  
  2842. mkdgin1:PUSH    DS
  2843.     mov    ax,seg dgi2lat
  2844.     mov    ds,ax
  2845.     lodsb                ; read Latin1 code point from dgi2lat
  2846.     POP    DS
  2847.     cmp    al,80h            ; "?" unknown indicator or ASCII?
  2848.     jb    mkdgin2            ; b = yes, reproduce it literally
  2849.     sub    al,80h            ; map down to indexable value
  2850.     xlatb                ; translate through Latin1 table
  2851. mkdgin2:stosb                ; store in active table
  2852.     loop    mkdgin1            ; do all necessary
  2853.     POP    DS
  2854.     mov    di,setptr
  2855.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2856.     mov    word ptr[di+gsize+1],'ID' ; set ident code
  2857.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2858.     pop    es
  2859.     pop    di
  2860.     pop    si
  2861.     call    invcopy            ; create keyboard table by inversion
  2862.     ret
  2863. mkdgint    endp
  2864.  
  2865. ; Make Data General line drawing graphics to Gn table. 
  2866. ; Enter with destination in setptr
  2867. mkdgld    proc    near
  2868.     push    si
  2869.     push    di
  2870.     mov    di,setptr
  2871.     mov    al,[di+gsize+3+1]        ; get Gn number (0..3)
  2872.     xor    ah,ah
  2873.     mov    si,ax
  2874.     mov    Gsetid[si],C_DGLINE        ; store our char set ident
  2875.     mov    cx,gsize        ; first fill with spaces
  2876.     mov    al,20h
  2877.     push    es
  2878.     push    ds
  2879.     pop    es
  2880.     push    di            ; save starting location
  2881.     cld
  2882.     rep    stosb            ; spaces
  2883.     pop    di
  2884.     add    di,20h            ; where new chars start
  2885.     mov    si,offset dgldc        ; replacement chars
  2886.     mov    cx,dgldclen        ; number of new chars
  2887.     rep    movsb            ; copy them to the table
  2888.     mov    di,setptr
  2889.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2890.     mov    word ptr[di+gsize+1],'LD' ; set ident code
  2891.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2892.     pop    es
  2893.     pop    di
  2894.     pop    si
  2895.     call    invcopy            ; create keyboard table by inversion
  2896.     ret
  2897. mkdgld    endp
  2898.  
  2899. ; Make Data General word processing to Gn table. 
  2900. ; Enter with destination in setptr
  2901. mkdgwp    proc    near
  2902.     push    si
  2903.     push    di
  2904.     mov    di,setptr
  2905.     mov    al,[di+gsize+3+1]        ; get Gn number (0..3)
  2906.     xor    ah,ah
  2907.     mov    si,ax
  2908.     mov    Gsetid[si],C_DGWP    ; store our char set ident
  2909.     mov    cx,gsize        ; first fill with spaces
  2910.     mov    al,20h
  2911.     push    es
  2912.     push    ds
  2913.     pop    es
  2914.     push    di            ; save starting location
  2915.     cld
  2916.     rep    stosb            ; spaces
  2917.     pop    di
  2918.     add    di,20h            ; where new chars start
  2919.     mov    si,offset dgwpcp437    ; replacement chars
  2920.     mov    cx,dgwplen        ; number of new chars
  2921.     push    ds
  2922.     mov    ax,seg dgwpcp437
  2923.     mov    ds,ax
  2924.     rep    movsb            ; copy them to the table
  2925.     pop    ds
  2926.     mov    di,setptr
  2927.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  2928.     mov    word ptr[di+gsize+1],'WD' ; set ident code
  2929.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2930.     pop    es
  2931.     pop    di
  2932.     pop    si
  2933.     call    invcopy            ; create keyboard table by inversion
  2934.     ret
  2935. mkdgwp    endp
  2936.  
  2937. ; Make Data General soft set to Gn table. 
  2938. ; Enter with destination in setptr, reg AL holding 100d + softset-20h+1
  2939. mkdgsoft proc    near
  2940.     push    ax
  2941.     call    mkascii
  2942.     pop    ax
  2943. ifndef    no_graphics
  2944.     push    ax
  2945.     call    mksoftspace        ; create space for soft set, uses AL
  2946.     pop    ax
  2947.     jnc    mkdgsoft1        ; nc = got the memory
  2948.     ret                ; c = failed, use ASCII
  2949. endif    ; no_graphics
  2950. mkdgsoft1:push    bx
  2951.     mov    bx,setptr
  2952.     mov    byte ptr[bx+gsize],94    ; say this is a 94 byte set
  2953.     mov    word ptr[bx+gsize+1],'UD' ; set ident code
  2954.     mov    byte ptr[bx+gsize+3],al    ; say hard char set (101..131)
  2955.     mov    bl,[bx+gsize+3+1]    ; get Gn number (0..3)
  2956.     xor    bh,bh
  2957.     mov    Gsetid[bx],al        ; store our char set ident
  2958.     pop    bx
  2959.     call    invcopy            ; create keyboard table by inversion
  2960.     ret
  2961. mkdgsoft endp
  2962.  
  2963. ; Make DEC Alt-ROM to Gn table.
  2964. ; Enter with destination in setptr
  2965. mkaltrom proc    near
  2966.     call    mkascii            ; init set to ASCII
  2967.     push    si
  2968.     push    di
  2969.     push    es
  2970.     push    ds
  2971.     pop    es            ; point es at data segment
  2972.     mov    di,setptr
  2973.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  2974.     xor    ah,ah
  2975.     mov    si,ax
  2976.     mov    Gsetid[si],C_ALTROM    ; store our char set ident
  2977.     add    di,60h            ; replace a..z with 20h + (a..z)
  2978.     mov    si,di            ; special graphics table
  2979.     mov    cx,27            ; number of chars to do (a..z)
  2980.     cld
  2981. decalt1:lodsb                ; get a char
  2982.     add    al,20h            ; map up by 20h
  2983.     stosb
  2984.     loop    decalt1
  2985.     mov    di,setptr
  2986.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  2987.     mov    word ptr[di+gsize+1],0+'1' ; set ident code
  2988.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  2989.     pop    es
  2990.     pop    di
  2991.     pop    si
  2992.     call    invcopy            ; create keyboard table by inversion
  2993.     ret
  2994. mkaltrom endp
  2995.  
  2996. ; Make DEC special graphics to Gn table.
  2997. ; Enter with destination in setptr
  2998. mkdecspec proc    near
  2999.     call    mkascii            ; init set to ASCII
  3000.     push    si
  3001.     push    di
  3002.     mov    di,setptr
  3003.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3004.     xor    ah,ah
  3005.     mov    si,ax
  3006.     mov    Gsetid[si],C_DECSPEC    ; store our char set ident
  3007.     add    di,95            ; replace chars 95-126
  3008.     mov    si,offset sgrtab    ; use DEC special graphics table
  3009.     mov    cx,sgrtabl        ; table length
  3010.     test    flags.vtflg,ttheath    ; Heath rather than VT?
  3011.     jz    mkdecsp1        ; z = no
  3012.     mov    si,offset hgrtab    ; use Heath table
  3013.     mov    cx,hgrtabl
  3014.     dec    di            ; work from 94 rather than 95
  3015. mkdecsp1:push    es
  3016.     push    ds
  3017.     pop    es
  3018.     push    ds
  3019.     mov    ax,seg sgrtab
  3020.     mov    ds,ax
  3021.     cld
  3022.     rep    movsb            ; replace chars with sgrtab items
  3023.     pop    ds
  3024.     mov    di,setptr
  3025.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3026.     mov    word ptr[di+gsize+1],0+'0' ; set ident code
  3027.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3028.     pop    es
  3029.     pop    di
  3030.     pop    si
  3031.     call    invcopy            ; create keyboard table by inversion
  3032.     clc
  3033.     ret
  3034. mkdecspec endp
  3035.  
  3036. ; Make Dec Technical to Gn table
  3037. ; Enter with destination in setptr
  3038. mkdectech proc    near
  3039.     push    si
  3040.     push    di
  3041.     mov    di,setptr
  3042.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3043.     xor    ah,ah
  3044.     mov    si,ax
  3045.     mov    Gsetid[si],C_DECTECH    ; store our char set ident
  3046.     push    es
  3047.     push    ds
  3048.     pop    es
  3049.     cld
  3050.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3051.     mov    di,setptr        ; destination
  3052.     mov    si,offset dectech    ; source data
  3053.     push    ds
  3054.     mov    ax,seg dectech
  3055.     mov    ds,ax
  3056.     rep    movsb
  3057.     pop    ds
  3058.     pop    es
  3059.     mov    di,setptr
  3060.     mov    byte ptr[di+gsize],94    ; say this is a 96 byte set
  3061.     mov    word ptr[di+gsize+1],0+'>' ; set ident code
  3062.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3063.     pop    di
  3064.     pop    si
  3065.     call    invcopy            ; create keyboard table by inversion
  3066.     clc
  3067.     ret
  3068. mkdectech endp
  3069.  
  3070. ; Make Cyrillic_ISO to CP866
  3071. ; Enter with destination in setptr
  3072. mkcyiso proc    near
  3073.     push    si
  3074.     push    di
  3075.     mov    di,setptr
  3076.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3077.     xor    ah,ah
  3078.     mov    si,ax
  3079.     mov    Gsetid[si],C_CYRILLIC_ISO ; store our char set ident
  3080.     push    es
  3081.     push    ds
  3082.     pop    es
  3083.     cld
  3084.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3085.     mov    di,setptr        ; destination
  3086.     mov    si,offset lccp866r    ; source data
  3087.     push    ds
  3088.     mov    ax,seg lccp866r
  3089.     mov    ds,ax
  3090.     rep    movsb
  3091.     pop    ds
  3092.     pop    es
  3093.     mov    di,setptr
  3094.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3095.     mov    word ptr[di+gsize+1],'CI' ; set ident code
  3096.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3097.     push    es
  3098.     mov    cx,gsize
  3099.     mov    di,seg cp866lci
  3100.     mov    es,di
  3101.     mov    di,offset cp866lci
  3102.     call    tblcopy            ; create keyboard table
  3103.     pop    es
  3104.     pop    di
  3105.     pop    si
  3106.     clc
  3107.     ret
  3108. mkcyiso endp
  3109.  
  3110. ; Make Cyrillic KOI8 to CP866
  3111. ; Enter with destination in setptr
  3112. mkkoi8 proc    near
  3113.     push    si
  3114.     push    di
  3115.     mov    di,setptr
  3116.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3117.     xor    ah,ah
  3118.     mov    si,ax
  3119.     mov    Gsetid[si],C_KOI8    ; store our char set ident
  3120.     push    es
  3121.     push    ds
  3122.     pop    es
  3123.     cld
  3124.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3125.     mov    di,setptr        ; destination
  3126.     mov    si,offset k8cp866r    ; source data
  3127.     push    ds
  3128.     mov    ax,seg k8cp866r
  3129.     mov    ds,ax
  3130.     rep    movsb
  3131.     pop    ds
  3132.     pop    es
  3133.     mov    di,setptr
  3134.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3135.     mov    word ptr[di+gsize+1],'CK' ; set ident code
  3136.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3137.     push    es
  3138.     mov    cx,gsize
  3139.     mov    di,seg cp866koi8
  3140.     mov    es,di
  3141.     mov    di,offset cp866koi8
  3142.     call    tblcopy            ; create keyboard table
  3143.     pop    es
  3144.     pop    di
  3145.     pop    si
  3146.     clc
  3147.     ret
  3148. mkkoi8 endp
  3149.  
  3150. ; Make Short-KOI (7 bit) to CP866
  3151. ; Enter with destination in setptr
  3152. mkkoi7 proc    near
  3153.     push    si
  3154.     push    di
  3155.     mov    di,setptr
  3156.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3157.     xor    ah,ah
  3158.     mov    si,ax
  3159.     mov    Gsetid[si],C_SHORT_KOI    ; store our char set ident
  3160.     push    es
  3161.     push    ds
  3162.     pop    es
  3163.     cld
  3164.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3165.     mov    di,setptr        ; destination
  3166.     mov    si,offset k7cp866r    ; source data
  3167.     push    ds
  3168.     mov    ax,seg k7cp866r
  3169.     mov    ds,ax
  3170.     rep    movsb
  3171.     pop    ds
  3172.     pop    es
  3173.     mov    di,setptr
  3174.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3175.     mov    word ptr[di+gsize+1],'CS' ; set ident code
  3176.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3177.     push    es
  3178.     mov    cx,gsize
  3179.     mov    di,seg cp866koi7
  3180.     mov    es,di
  3181.     mov    di,offset cp866koi7
  3182.     call    tblcopy            ; create keyboard table
  3183.     pop    es
  3184.     pop    di
  3185.     pop    si
  3186.     clc
  3187.     ret
  3188. mkkoi7 endp
  3189.  
  3190. ; Make Heath-19 special graphics to Gn table. Enter with dest of setptr.
  3191.  
  3192. ; Initialize a char set to ASCII values 0..127 and ident of 94/B
  3193. ; Enter with setptr holding offset of G0set, G1set, G2set, or G3set char set
  3194. mkascii    proc    near
  3195.     push    ax
  3196.     push    cx
  3197.     push    di
  3198.     push    es
  3199.     mov    di,setptr        ; char set to init (G0..G3)
  3200.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3201.     xor    ah,ah
  3202.     mov    si,ax
  3203.     mov    Gsetid[si],C_ASCII    ; store our char set ident
  3204.     mov    cx,gsize        ; number of bytes to do
  3205.     xor    al,al            ; initial value
  3206.     push    ds
  3207.     pop    es            ; set es to data segment
  3208.     cld
  3209. mkascii1:stosb                ; copy value to char set table
  3210.     inc    al
  3211.     loop    mkascii1
  3212.     mov    di,setptr
  3213.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3214.     mov    word ptr[di+gsize+1],0+'B' ; set ident code to ASCII "B"
  3215.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3216.     pop    es
  3217.     pop    di
  3218.     pop    cx
  3219.     pop    ax
  3220.     call    invcopy            ; create keyboard table by inversion
  3221.     ret
  3222. mkascii    endp
  3223.  
  3224. ; Make UK ASCII to table Gn
  3225. ; Enter with destination in setptr
  3226. mkukascii proc    near
  3227.     call    mkascii            ; make US ASCII table
  3228.     push    di
  3229.     mov    di,setptr        ; get set pointer
  3230.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3231.     xor    ah,ah
  3232.     mov    si,ax
  3233.     mov    Gsetid[si],C_UKNRC    ; store our char set ident
  3234.     mov    byte ptr[di+23h],156    ; replace sharp 2/3 with Sterling sign
  3235.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3236.     mov    word ptr[di+gsize+1],0+'A' ; set ident code
  3237.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3238.     pop    di
  3239.     call    invcopy            ; create keyboard table by inversion
  3240.     ret
  3241. mkukascii endp
  3242.  
  3243. ; Make DEC Multinational Char Set (DEC-MCS/DEC Supplemental Graphics)
  3244. ; and put into Gn table indicated by AL = 0..3
  3245. ; Enter with destination in setptr
  3246. mkdecmn    proc    near
  3247.     push    si
  3248.     push    di
  3249.     mov    di,setptr        ; get set pointer
  3250.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3251.     xor    ah,ah
  3252.     mov    si,ax
  3253.     mov    Gsetid[si],C_DMULTINAT ; store our char set ident
  3254.     push    es
  3255.     mov    ax,seg G0set        ; segment of Gn's
  3256.     mov    es,ax
  3257.     PUSH    DS
  3258.     call    flatin1            ; get Latin1 to DS:BX
  3259.     mov    si,bx
  3260.     cld
  3261.     mov    cx,gsize+3+1        ; gsize chars plus three ident bytes
  3262.     rep    movsb
  3263.     POP    DS
  3264.     mov    di,setptr
  3265.     mov    al,[di+24h]        ; 10/4 Latin1 (currency) to
  3266.     mov    [di+28h],al        ; 10/8 DEC-MCS
  3267.     mov    byte ptr [di+57h],3fh     ; 13/7 OE to ?
  3268.     mov    al,[di+7fh]        ; 15/15 Latin1 (lower y umlate) to
  3269.     mov    [di+7dh],al        ; 15/13 DEC-MCS
  3270.     mov    cx,13            ; number of updates
  3271.     xor    bh,bh
  3272.     mov    ax,seg MNlatin
  3273.     mov    es,ax
  3274.     mov    si,offset MNlatin    ; get update table
  3275. mkdecmn1:mov    bl,es:[si]        ; get Latin1 code point to be changed
  3276.     and    bl,not 80h        ; map down to 0..127 range
  3277.     mov    byte ptr [di+bx],20h    ; store new value (space)
  3278.     inc    si
  3279.     loop    mkdecmn1
  3280.     pop    es
  3281.     mov    di,setptr
  3282.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3283.     mov    word ptr[di+gsize+1],'5%' ; set ident code
  3284.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3285.     pop    di
  3286.     pop    si
  3287.     call    invcopy            ; create keyboard table by inversion
  3288.     ret
  3289. mkdecmn    endp
  3290.  
  3291. ;[HF] Put JIS Katakana char set (128..255) into Gn table.
  3292. ;[HF] Enter with destination in setptr
  3293. mkjiskana proc    near
  3294.     call    mkascii            ; init set to ASCII
  3295.     push    si
  3296.     push    di
  3297.     mov    di,setptr        ; point at character set
  3298.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3299.     xor    ah,ah
  3300.     mov    si,ax
  3301.     mov    Gsetid[si],C_JISKAT    ; store our char set ident
  3302.     add    di,33        ;[HF]941227 start position
  3303.     mov    cx,63        ;[HF]941227 number of chars to do (16 x 4 - 1)
  3304.     mov    al,(33+128)    ;[HF]941227 start with 8th bit on
  3305.     cld
  3306.     push    es
  3307.     push    ds
  3308.     pop    es            ; point es at data segment
  3309. mkjiskana2:stosb            ; store codes 128..223
  3310.     inc    al
  3311.     loop    mkjiskana2
  3312.     mov    di,setptr
  3313.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3314.     mov    word ptr[di+gsize+1],0+'I' ; set ident code
  3315.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3316.     pop    es
  3317.     pop    di
  3318.     pop    si
  3319.     call    invcopy            ; create keyboard table by inversion
  3320.     ret
  3321. mkjiskana endp
  3322.  
  3323. ; [HF] Construct JIS-Kanji table to Gn table.
  3324. ; [HF] Enter with destination in setptr
  3325. ; [HF] Actually, because the JIS-Kanji set is double byte charater set,
  3326. ; [HF] this procedure simply sets only the ident code.
  3327. ; [HF] Actual translation is done by (f)jpnxtof.
  3328. mkjiskanji proc    near
  3329.     push    si            ; [HF]
  3330.     push    di            ; [HF]
  3331.     mov    di,setptr        ; [HF]
  3332.     mov    al,[di+gsize+3+1]    ; [HF] get Gn number (0..3)
  3333.     xor    ah,ah            ; [HF] clear high byte
  3334.     mov    si,ax            ; [HF] set SI reg.
  3335.     mov    Gsetid[si],C_JISKANJI    ; [HF] set our char set ident
  3336.     mov    byte ptr[di+gsize],94    ; [HF] say this is 94 x 94 byte set
  3337.     mov    word ptr[di+gsize+1],'$B' ; [HF] set ident code
  3338.     pop    di            ; [HF]
  3339.     pop    si            ; [HF]
  3340.     call    invcopy            ; create keyboard table by inversion
  3341.     ret                ; [HF]
  3342. mkjiskanji endp
  3343.  
  3344. ; Put transparent char set (128..255) into Gn table.
  3345. ; Enter with destination in setptr
  3346. mkxparent proc    near
  3347.     call    mkascii            ; init set to ASCII
  3348.     push    si
  3349.     push    di
  3350.     mov    di,setptr        ; point at character set
  3351.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3352.     xor    ah,ah
  3353.     mov    si,ax
  3354.     mov    Gsetid[si],C_XPARENT    ; store our char set ident
  3355.     mov    cx,gsize        ; number of chars to do, 128
  3356.     cld
  3357.     mov    al,cl            ; start with 128 char value
  3358.     push    es
  3359.     push    ds
  3360.     pop    es            ; point es at data segment
  3361. mkxpar2:stosb                ; store codes 128..255
  3362.     inc    al
  3363.     loop    mkxpar2
  3364.     mov    di,setptr
  3365.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3366.     mov    word ptr[di+gsize+1],0+'?' ; set ident code
  3367.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3368.     pop    es
  3369.     pop    di
  3370.     pop    si
  3371.     call    invcopy            ; create keyboard table by inversion
  3372.     ret
  3373. mkxparent endp
  3374.  
  3375. ; Construct NRC table.
  3376. ; Enter with destination in setptr
  3377. ; and CX holding the desired country code (1..13).
  3378. mknrc    proc near
  3379.     call    mkascii            ; init set to ASCII
  3380.     push    bx
  3381.     push    cx
  3382.     push    si
  3383.     push    di
  3384.     push    word ptr emubuf
  3385.     push    word ptr emubuf+2
  3386.     push    es
  3387.     mov    di,setptr
  3388.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3389.     xor    ah,ah
  3390.     mov    si,ax
  3391.     mov    Gsetid[si],cl        ; store our char set ident
  3392.     mov    emubuf+2,cl        ; local copy
  3393.     cmp    cl,13            ; DEC Hebrew case?
  3394.     je    mknrc10            ; e = yes
  3395.         ; copy from NRC table (si) to set pointed at by di, cx chars
  3396.                     ;  plus 3 ident bytes at table end
  3397.     mov    word ptr emubuf,offset nrclat ; start of NRC to Latin1 table
  3398.     mov    ax,cx            ; country code 1..12
  3399.     mov    bl,15            ; 15 bytes per entry
  3400.     mul    bl            ; distance down the table to country
  3401.     add    word ptr emubuf,ax    ; point at country line
  3402.     mov    cx,12            ; do 12 bytes of new chars
  3403.     push    ds
  3404.     pop    es
  3405.     cld
  3406.     PUSH    DS
  3407.     call    flatin1            ; returns DS:BX = Latin1 to CPnnn
  3408.     xor    si,si
  3409. mknrc2:    mov    al,ES:nrclat[si]    ; get code point to change
  3410.     xor    ah,ah
  3411.     mov    di,ES:setptr        ; start of destination table
  3412.     mov    byte ptr ES:[di+gsize+3],0    ; say hard char set
  3413.     add    di,ax            ; destination of new char
  3414.     push    bx
  3415.     mov    bx,word ptr ES:emubuf    ; ptr to country entries
  3416.     mov    al,ES:[bx+si]        ; read char from NRC table
  3417.     pop    bx
  3418.     inc    si
  3419.     test    al,80h            ; in GR Latin1 area?
  3420.     jz    mknrc3            ; z = no, in ASCII GL area
  3421.     and    al,not 80h        ; trim high bit for xlat
  3422.     xlatb                  ; translate through Latin1 Code Page
  3423. mknrc3:    stosb                ; move replacement char from nrc list
  3424.     loop    mknrc2
  3425.     POP    DS
  3426.  
  3427.     mov    di,setptr
  3428.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  3429.     jz    mknrc8            ; z = no
  3430.     mov    cl,emubuf+2        ; country code again
  3431.     cmp    cl,3            ; French NRC?
  3432.     jne    mknrc4            ; ne = no
  3433.     mov    al,07fh            ; apply DG French NRC patch
  3434.     jmp    short mknrc7
  3435. mknrc4:    cmp    cl,6            ; Spanish NRC?
  3436.     jne    mknrc5            ; ne = no
  3437.     mov    al,07fh            ; apply DG Spanish NRC patch
  3438.     jmp    short mknrc7
  3439. mknrc5:    cmp    cl,7            ; DG Danish/Norweigen NRC?
  3440.     jne    mknrc6            ; ne = no
  3441.     mov    al,0fch            ; apply DG Danish/Norweigen NRC patch
  3442.     jmp    short mknrc7
  3443. mknrc6:    cmp    cl,8            ; Swiss NRC?
  3444.     jne    mknrc7            ; ne = no
  3445.     mov    al,0e9h            ; apply DG Swiss NRC patch
  3446. mknrc7:    and    al,not 80h
  3447.     xlatb                ; push through Latin1 translation
  3448.     mov    [di+7fh],al        ; new value
  3449. mknrc8:    add    di,gsize        ; look at end of set, to id bytes
  3450.     movsb                ; copy set size and two ident chars
  3451.     movsw
  3452.     jmp    short mknrc11
  3453.  
  3454. mknrc10:mov    vtcpage,862        ; Hebrew NRC CP862
  3455.     mov    di,ds
  3456.     mov    es,di
  3457.     mov    di,setptr
  3458.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3459.     add    di,6*16
  3460.     mov    cx,27            ; number of characters
  3461.     PUSH    DS
  3462.     call    flatin1            ; get SI appropriate for Code Page
  3463.     mov    si,bx            ; point to Latin 1 for this code page
  3464.     add    si,6*16            ; get Hebrew part of CP862
  3465.     cld
  3466.     rep    movsb
  3467.     POP    DS
  3468. mknrc11:pop    es
  3469.     pop    word ptr emubuf+2
  3470.     pop    word ptr emubuf
  3471.     pop    di
  3472.     pop    si
  3473.     pop    cx
  3474.     pop    bx
  3475.     call    invcopy            ; create keyboard table by inversion
  3476.     ret
  3477. mknrc    endp
  3478.     
  3479. ; Construct Latin1 table to Gn table.
  3480. ; Enter with destination in setptr
  3481. mklatin1 proc    near
  3482.     push    si
  3483.     push    di
  3484.     mov    di,setptr        ; destination
  3485.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3486.     xor    ah,ah
  3487.     mov    si,ax
  3488.     mov    Gsetid[si],C_LATIN1    ; store our char set ident
  3489.     mov    cx,gsize        ; bytes
  3490.     push    es
  3491.     push    ds
  3492.     pop    es
  3493.     PUSH    DS
  3494.     call    flatin1            ; get DS:BX appropriate for Code Page
  3495.     mov    si,bx
  3496.     cld
  3497.     rep    movsb            ; copy bytes
  3498.     POP    DS
  3499.     mov    di,setptr
  3500.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3501.     mov    word ptr[di+gsize+1],0+'A' ; set ident code
  3502.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3503.     pop    es
  3504.     pop    di
  3505.     pop    si
  3506.     call    invcopy            ; create keyboard table by inversion
  3507.     ret
  3508. mklatin1 endp
  3509.  
  3510. ; Construct Latin2 table to Gn table.
  3511. ; Enter with destination in setptr
  3512. mklatin2 proc    near
  3513.     push    si
  3514.     push    di
  3515.     mov    di,setptr        ; destination
  3516.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3517.     xor    ah,ah
  3518.     mov    si,ax
  3519.     mov    Gsetid[si],C_LATIN2    ; store our char set ident
  3520.     mov    vtcpage,852        ; set emulator's CP to CP852
  3521.     mov    cx,gsize        ; bytes
  3522.     push    es
  3523.     push    ds
  3524.     pop    es
  3525.     PUSH    DS
  3526.     call    flatin1            ; get BX appropriate for Code Page
  3527.     mov    si,bx
  3528.     cld
  3529.     rep    movsb            ; copy bytes
  3530.     POP    DS
  3531.     mov    di,setptr
  3532.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3533.     mov    word ptr[di+gsize+1],0+'B' ; set ident code
  3534.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3535.     pop    es
  3536.     pop    di
  3537.     pop    si
  3538.     call    invcopy            ; create keyboard table by inversion
  3539.     ret
  3540. mklatin2 endp
  3541.  
  3542. ; Make DEC Hebrew (94) 8-bit Supplemental
  3543. ; Same code points as Hebrew-ISO at this time
  3544. mkdec_Hebrew    proc    near
  3545.     call    mklatin_hebrew
  3546.     push    es
  3547.     push    ds
  3548.     pop    es
  3549.     mov    di,setptr
  3550.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3551.     mov    word ptr[di+gsize+1],'4"' ; set ident code
  3552.     pop    es
  3553.     call    invcopy            ; create keyboard table by inversion
  3554.     ret
  3555. mkdec_Hebrew    endp
  3556.  
  3557. ; Make Hebrew-ISO (96) 8-bit Supplemental to Gn pointer
  3558. ; Enter with destination in setptr
  3559. ; Presumes CP 862 is loaded
  3560. mklatin_Hebrew    proc    near
  3561.     push    si
  3562.     push    di
  3563.     mov    di,setptr        ; destination
  3564.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3565.     xor    ah,ah
  3566.     mov    si,ax
  3567.     mov    Gsetid[si],C_HEBREWISO    ; store our char set ident
  3568.     mov    cx,gsize        ; bytes
  3569.     mov    vtcpage,862        ; set emulator's CP to CP862
  3570.     push    es
  3571.     push    ds
  3572.     pop    es
  3573.     PUSH    DS
  3574.     call    flatin1            ; get DS:BX appropriate for Code Page
  3575.     mov    si,bx
  3576.     cld
  3577.     rep    movsb            ; copy bytes
  3578.     POP    DS
  3579.     mov    di,setptr
  3580.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3581.     mov    word ptr[di+gsize+1],0+'H' ; set ident code
  3582.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3583.     pop    es
  3584.     pop    di
  3585.     pop    si
  3586.     call    invcopy            ; create keyboard table by inversion
  3587.     ret
  3588. mklatin_Hebrew    endp
  3589.  
  3590.  
  3591. ; Make HP-Roman8 to Gn table. 
  3592. ; Enter with destination in setptr
  3593. mkhpr8    proc    near
  3594.     push    si
  3595.     push    di
  3596.     push    es
  3597.     mov    di,setptr
  3598.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3599.     xor    ah,ah
  3600.     mov    si,ax
  3601.     mov    Gsetid[si],C_HPROMAN8    ; store our char set ident
  3602.     mov    ax,ds
  3603.     mov    es,ax
  3604.     PUSH    DS
  3605.     call    flatin1        ; get DS:BX to Code Page dependent Latin1
  3606.     mov    si,bx
  3607.     cld
  3608.     push    di
  3609.     mov    cx,gsize        ; gsize chars
  3610.     rep    movsb            ; copy appropriate Latin1 xlat table
  3611.     pop    di
  3612.     add    di,20h            ; where new chars start
  3613.     mov    cx,hr8L1len        ; number of new chars
  3614.     mov    si,offset hr8L1    ; source of chars to be translated
  3615.     push    DS
  3616.     mov    ax,seg trans
  3617.     mov    ds,ax
  3618.     cmp    trans.xchri,0        ; readable (vs invertible)?
  3619.     pop    ds
  3620.     je    mkhpr81            ; e = yes, do nothing
  3621.     mov    cx,ihr8L1len        ; number of new chars
  3622.     mov    si,offset ihr8L1    ; source of chars to be translated
  3623.  
  3624. mkhpr81:PUSH    DS
  3625.     mov    ax,seg ihr8L1        ; same seg for readable and invertable
  3626.     mov    ds,ax
  3627.     lodsb                ; read Latin1 code point from dgi2lat
  3628.     POP    DS
  3629.     cmp    al,80h            ; "?" unknown indicator or ASCII?
  3630.     jb    mkhpr82            ; b = yes, reproduce it literally
  3631.     sub    al,80h            ; map down to indexable value
  3632.     xlatb                ; translate through Latin1 table
  3633. mkhpr82:stosb                ; store in active table
  3634.     loop    mkhpr81            ; do all necessary
  3635.     POP    DS
  3636.     mov    di,setptr
  3637.     mov    byte ptr[di+gsize],96    ; say this is a 96 byte set
  3638.     mov    word ptr[di+gsize+1],'HP' ; set ident code
  3639.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3640.     pop    es
  3641.     pop    di
  3642.     pop    si
  3643.     call    invcopy            ; create keyboard table by inversion
  3644.     ret
  3645. mkhpr8    endp
  3646.  
  3647. ; Make Wyse-50 graphics character set. Enter with setptr ready.
  3648. mkwyse    proc    near
  3649.     push    si
  3650.     push    di
  3651.     push    es
  3652.     call    mkascii            ; make US ASCII table
  3653.     mov    di,setptr        ; get set pointer
  3654.     mov    byte ptr[di+gsize],94    ; say this is a 94 byte set
  3655.     mov    word ptr[di+gsize+1],'YW' ; set ident code
  3656.     mov    byte ptr[di+gsize+3],0    ; say hard char set
  3657.     mov    al,[di+gsize+3+1]    ; get Gn number (0..3)
  3658.     xor    ah,ah
  3659.     mov    si,ax
  3660.     mov    Gsetid[si],C_WYSEGR    ; store our char set ident
  3661.     mov    si,offset wyse_grch    ; Wyse chars, from "0"
  3662.     mov    cx,16            ; qty of them
  3663.     add    di,'0'            ; index table
  3664.     cld
  3665. mkwyse1:lodsb                ; read replacement byte
  3666.     mov    [di],al            ; store new graphics char
  3667.     inc    di
  3668.     loop    mkwyse1
  3669.     pop    es
  3670.     pop    di
  3671.     pop    si
  3672.     call    invcopy            ; create keyboard table by inversion
  3673.     ret
  3674. mkwyse    endp
  3675.  
  3676. ; Get output byte in AL from keyboard raw reader and convert through active
  3677. ; character set translation. Return final output byte in AL.
  3678. ; Uses table xltkeytable for translation.
  3679. xltkey    proc    FAR
  3680.     cmp    al,80h            ; regular ASCII key?
  3681.     jb    xltkey1            ; b = yes, do not translate
  3682.     cmp    flags.xltkbd,0        ; keyboard translation is off?
  3683.     jne    xltkey2            ; ne = no
  3684. xltkey1:ret
  3685.  
  3686. xltkey2:push    bx
  3687.     mov    bx,offset xltkeytable    ; translation table
  3688.     and    al,not 80h        ; strip high bit to use as index
  3689.     xlatb                ; table replaces high bit
  3690.     pop    bx
  3691.     ret
  3692. xltkey    endp
  3693.  
  3694. ; Create keyboard translation table by inverse lookup of wire to screen
  3695. ; table. Effective only if setptr equals GRptr.
  3696. invcopy    proc    near
  3697.     push    es
  3698.     push    ds
  3699.     pop    es
  3700.     push    di
  3701.     mov    di,setptr
  3702.     cmp    di,GRptr        ; points to GR?
  3703.     jne    invcopy4        ; ne = no, not our condition
  3704.     mov    si,offset xltkeytable    ; output table
  3705.     mov    al,80h            ; start here
  3706.     mov    cx,gsize        ; loop counter
  3707. invcopy2:push    ax
  3708.     push    cx
  3709.     mov    di,GRptr        ; high bit is where GR points
  3710.     mov    cx,gsize
  3711.     add    di,cx
  3712.     std
  3713.     repne    scasb            ; scan looking for this code
  3714.     cld
  3715.     jne    invcopy3        ; ne = not found
  3716.     inc    di            ; backup to found code
  3717.     sub    di,GRptr        ; minus start
  3718.     mov    ax,di
  3719.     or    al,80h            ; put back high bit
  3720.     cmp    vtemu.vtchset,13    ; ASCII (0) or NRC's (1-13) active?
  3721.     ja    invcopy3        ; a = no
  3722.     cmp    vtemu.vtchset,0        ; ASCII?
  3723.     je    invcopy3        ; e = yes
  3724.     and    al,7fh            ; yes, NRCs force chars to 7-bits
  3725. invcopy3:mov    [si],al            ; want only lower byte
  3726.     pop    cx
  3727.     pop    ax
  3728.     inc    si
  3729.     inc    al
  3730.     loop    invcopy2
  3731. invcopy4:pop    di
  3732.     pop    es
  3733.     ret
  3734. invcopy    endp
  3735.  
  3736. ; Copy table pointed to be es:di to xltkeytable, cx values.
  3737. ; If es:di is NULL then create identity table, cx values.
  3738. tblcopy    proc    near
  3739.     push    si
  3740.     push    di
  3741.     push    es
  3742.     push    ds
  3743.     mov    si,setptr
  3744.     cmp    si,GRptr        ; points to GR?
  3745.     jne    tblcopy3        ; ne = no, not our condition
  3746.     mov    si,es
  3747.     mov    ax,seg xltkeytable
  3748.     mov    es,ax
  3749.     mov    ds,si
  3750.     mov    si,di
  3751.     mov    di,offset xltkeytable
  3752.     mov    ax,ds
  3753.     or    ax,si            ; null pointer?
  3754.     jz    tblcopy1        ; z = yes, create identity
  3755.     cld
  3756.     rep    movsb            ; copy table
  3757.     jmp    short tblcopy3
  3758.  
  3759. tblcopy1:mov    al,80h            ; create identity table 80h..cx+80h
  3760. tblcopy2:stosb
  3761.     inc    al
  3762.     loop    tblcopy2
  3763.  
  3764. tblcopy3:pop    ds
  3765.     pop    es
  3766.     pop    di
  3767.     pop    si
  3768.     ret
  3769. tblcopy    endp
  3770.  
  3771. ; cursor movements
  3772. atcup:    test    dspstate,dsptype    ; on VT320 status line?
  3773.     jz    atcup0            ; z = no
  3774.     mov    param,0            ; yes, do not change rows
  3775. atcup0:    mov    ax,param        ; get row
  3776.     or    ah,ah            ; too large?
  3777.     jz    atcup0a            ; z = not too too large
  3778.     mov    al,200            ; limit row
  3779. atcup0a:mov    dh,al            ; temp row
  3780.     mov    ax,param+2        ; get column
  3781.     or    ah,ah            ; too large?
  3782.     jz    atcup0b            ; z = not yet
  3783.     mov    al,mar_right        ; limit column
  3784.     inc    al
  3785. atcup0b:mov    dl,al
  3786.     or    dh,dh            ; zero row number?
  3787.     jz    atcup1            ; z = yes, continue
  3788.     dec    dh            ; normalize to 0,0 system
  3789. atcup1:    or    dl,dl            ; ditto for column
  3790.     jz    atcup2
  3791.     dec    dl
  3792. atcup2:    test    vtemu.vtflgop,decom    ; Origin mode?
  3793.     jz    atcup3            ; z = no, skip this stuff
  3794.     add    dh,mar_top        ; yes, it was relative to top margin
  3795.     jno    atcup2a            ; if no overflow, continue
  3796.     mov    dh,byte ptr low_rgt+1    ; otherwise just set to screen bottom
  3797. atcup2a:cmp    dh,mar_bot        ; going below bottom margin?
  3798.     jbe    atcup3            ; be = no
  3799.     mov    dh,mar_bot        ; clip to bottom margin
  3800. atcup3:    mov    al,mar_right        ; right margin
  3801.     cmp    dl,al            ; too far to the right?
  3802.     jbe    atcup4            ; ne = no
  3803.     mov    dl,al            ; limit to right margin
  3804. atcup4:    mov    ah,byte ptr low_rgt+1    ; last regular text line
  3805.     cmp    dh,ah            ; going to 25th line?
  3806.     jbe    atcup7            ; be = no
  3807.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  3808.     je    atcup5            ; e = yes
  3809.     mov    dh,ah            ; VTxxx: clamp to bottom line
  3810.     jmp    short atcup7
  3811. atcup5:    inc    ah            ; "25th" status line
  3812.     cmp    dh,ah            ; going too far?
  3813.     ja    atcup6            ; a = yes
  3814.     test    h19stat,h19l25        ; Heath 25th mode line enabled?
  3815.     jnz    atcup8            ; nz = yes
  3816. atcup6:    mov    dh,byte ptr cursor+1    ; do not change rows
  3817. atcup7: call    atccpc            ; check position
  3818. atcup8:    jmp    atsetcur        ; set cursor position and return
  3819.  
  3820. atcuarg:mov    al,byte ptr param    ; worker, get cursor movement argument
  3821.     or    al,al            ; zero?
  3822.     jnz    atcua1            ; nz = no
  3823.     inc    al            ; default to one
  3824. atcua1: ret
  3825.                     ; cursor up
  3826. atcuu:    cmp    dh,byte ptr low_rgt+1    ; on 25th line?
  3827.     jbe    atcuu1            ; be = no
  3828.     cmp    flags.vtflg,ttansi    ; emulating ANSI?
  3829.     je    atcuu1            ; e = yes
  3830.     ret                ; no vertical on 25th line
  3831. atcuu1:    call    atcuarg            ; get cursor move up argument into al
  3832.     sub    dh,al            ; compute new cursor position
  3833.     jnc    atcuu2            ; nc = ok [dlk]
  3834.     xor    dh,dh            ; overflow, restrict range. [dlk]
  3835. atcuu2:    call    atccic            ; check indexing, ignore action in ax
  3836.     jmp    atsetcur        ; set the cursor at its new position
  3837.  
  3838. atcud:    call    atcuarg            ; cursor down
  3839.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  3840.     jbe    atcud1            ; be = no
  3841.     ret                ; else leave it on status line
  3842. atcud1:    add    dh,al            ; compute new cursor position
  3843.     jnc    atcud2            ; nc = ok [dlk]
  3844.     mov    dh,byte ptr low_rgt+1    ; default bottom [dlk]
  3845. atcud2:    call    atccic            ; check indexing, ignore action in ax
  3846.     jmp    atsetcur        ; set the cursor at its new position
  3847.  
  3848.                     ; Allow horiz movement on 25th line
  3849. atcuf:    call    atcuarg            ; cursor forward
  3850.     add    dl,al            ; compute new cursor position
  3851.     jnc    atcup3            ; nc = no problem
  3852.     mov    dl,byte ptr low_rgt    ; else set to right margin
  3853.     jmp    atcup3            ; check/set cursor, return
  3854.  
  3855. atcub:    call    atcuarg            ; cursor back
  3856.     sub    dl,al            ; compute new cursor position
  3857.     jnc    atcub1            ; nc = no problem
  3858.     xor    dl,dl            ; else set to left margin
  3859. atcub1:    jmp    atcup3            ; check/set cursor, return
  3860.  
  3861. atcha:    call    atcuarg            ; absolute horizontal address
  3862.     mov    dl,al            ; new column, counted from 1
  3863.     sub    dl,1            ; column, count from 0 internally
  3864.     jns    atcha1            ; ns = no problem
  3865.     xor    dl,dl            ; else set to left margin
  3866. atcha1:    jmp    atcup3            ; check/set cursor, return
  3867.  
  3868. atcht:    call    atcuarg            ; move cursor forward # horiz tabs
  3869.     inc    dl            ; next column
  3870.     mov    cl,al            ; number of tabstops to locate
  3871.     xor    ch,ch
  3872.     mov    si,offset tabs        ; active tabs buffer
  3873. atcht1:    cmp    dl,mar_right        ; at end of line?
  3874.     jae    atcht2            ; ae = yes, stop here
  3875.     call    istabs            ; is dl column a tabstop?
  3876.     inc    dl            ; try next column, preserves carry
  3877.     jnc    atcht1            ; nc = no, find one
  3878.     loop    atcht1            ; do cx tabstops
  3879. atcht2:    jmp    atcup3            ; set cursor
  3880.  
  3881. atcva:    inc    dl            ; count columns from 1 here
  3882.     mov    byte ptr param+2,dl    ; set column in second parameter
  3883.     mov    param+3,0        ; high byte
  3884.     jmp    atcup            ; do absolute vertical positioning
  3885.  
  3886. atcnl:    call    atcuarg            ; do # Next-Lines
  3887.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  3888.     jbe    atcnl1            ; be = no
  3889.     ret                ; else leave it on status line
  3890. atcnl1:    mov    cl,al            ; number to do
  3891.     xor    ch,ch
  3892. atcnl2:    push    cx
  3893.     inc    dh            ; number to do
  3894.     mov    dl,mar_left
  3895.     call    atccic            ; check cursor position
  3896.     call    ax            ; scroll if necessary
  3897.     call    atsetcur        ; set cursor, etc. and return
  3898.     pop    cx
  3899.     loop    atcnl2
  3900.     ret
  3901. atcpl:    call    atcuarg            ; do # Previous-Lines
  3902.     cmp    dh,byte ptr low_rgt+1    ; on 25th line now?
  3903.     jbe    atcpl1            ; be = no
  3904.     ret                ; else leave it on status line
  3905. atcpl1:    mov    cl,al            ; number to do
  3906.     xor    ch,ch
  3907.     mov    dl,mar_left
  3908. atcpl2:    dec    dh            ; do one line
  3909.     push    cx            ; save counter
  3910.     call    atccic            ; check cursor position
  3911.     call    ax            ; scroll if necessary
  3912.     call    atsetcur        ; set cursor
  3913.     pop    cx
  3914.     loop    atcpl2            ; do cx times
  3915.     ret
  3916.  
  3917. ; Screen erasure commands
  3918.                     ; Erase in display
  3919. ated:    cmp    ninter,0        ; zero intermediates?
  3920.     je    ated0            ; e = yes, else try protected mode
  3921.     ret
  3922.  
  3923. ated0:    cmp    lparam,0
  3924.     je    ated0a
  3925.     jmp    atedsel
  3926. ated0a:    cmp    param,0            ; was arg zero?
  3927.     jne    ated1            ; ne = no
  3928.     jmp    ereos            ; do erase cursor to end of screen
  3929.  
  3930. ated1:    cmp    param,1            ; was arg one?
  3931.     jne    ated2            ; ne = no
  3932.     jmp    ersos            ; do erase start of screen to cursor
  3933.  
  3934. ated2:    cmp    param,2            ; was arg two?
  3935.     je    ated2a            ; e = yes, erase entire screen
  3936.     ret                ; else ignore
  3937. ated2a:    push    dx            ; save dynamic cursor
  3938.     push    word ptr mar_top
  3939.     mov    mar_bot,dh
  3940.     mov    mar_top,0        ; row of cursor
  3941.     inc    dh            ; number of lines to scroll
  3942.     mov    scroll,dh
  3943.     call    atscru            ; scroll them up before erasure
  3944.     pop    word ptr mar_top
  3945.     pop    dx
  3946.     call    ersos            ; erase start of screen to cursor
  3947.     call    ereos            ; erase cursor to end of screen
  3948.     cmp    flags.vtflg,ttansi    ; ANSI-BBS terminal?
  3949.     je    ated2b            ; e = yes, home the cursor
  3950.     ret
  3951. ated2b:    xor    dx,dx
  3952.     jmp    atsetcur
  3953.  
  3954. atedsel    proc    near            ; DECSED selective erase in display
  3955.     cmp    lparam,'?'        ; proper intermediate?
  3956.     jne    atedsel3        ; ne = no
  3957.     mov    ax,param        ; get parameter
  3958.     or    ax,ax            ; 0?
  3959.     jnz    atedsel1        ; nz = no
  3960.     mov    al,mar_top        ; 0: erase cursor to end of screen
  3961.     mov    ah,mar_bot        ; save margins
  3962.     push    ax
  3963.     mov    mar_top,dh        ; use current row
  3964.     mov    ah,byte ptr low_rgt+1    ; bottom screen row for text
  3965.     mov    mar_bot,ah
  3966.     call    erprot            ; do protected mode erasure
  3967.     pop    ax
  3968.     mov    mar_top,al        ; restore margins
  3969.     mov    mar_bot,ah
  3970.     jmp    short atedsel3
  3971. atedsel1:cmp    al,1            ; 1? erase start of line to cursor
  3972.     jne    atedsel2        ; ne = no
  3973.     mov    al,mar_top        ; 1: erase start to cursor
  3974.     mov    ah,mar_bot        ; save margins
  3975.     push    ax
  3976.     mov    al,mar_right
  3977.     mov    ah,dl            ; save right margin and cursor col
  3978.     push    ax
  3979.     mov    mar_right,dl        ; stop at current cursor
  3980.     mov    dl,mar_left        ; start at this pseudo cursor
  3981.     mov    mar_top,dh        ; use current row
  3982.     mov    mar_bot,dh
  3983.     call    erprot            ; do protected mode erasure
  3984.     pop    ax
  3985.     mov    mar_right,al        ; restore right margin
  3986.     mov    dl,ah            ; restore cursor row
  3987.     pop    ax
  3988.     mov    mar_top,al        ; restore margins
  3989.     mov    mar_bot,ah
  3990.     jmp    short atedsel3
  3991. atedsel2:cmp    al,2            ; 2? erase whole screen
  3992.     jne    atedsel3        ; ne = no
  3993.     mov    al,mar_top        ; 2: erase whole screen
  3994.     mov    ah,mar_bot        ; save margins
  3995.     push    ax
  3996.     mov    ah,mar_right
  3997.     mov    al,mar_left
  3998.     push    ax
  3999.     push    dx            ; save cursor
  4000.     xor    dx,dx            ; set to top left corner
  4001.     mov    mar_right,dl        ; starting point
  4002.     mov    mar_top,dh
  4003.     mov    ax,low_rgt        ; lower right corner of text area
  4004.     mov    mar_right,al        ; end here
  4005.     mov    mar_bot,ah
  4006.     call    erprot            ; do protected mode erasure
  4007.     pop    dx            ; restore cursor
  4008.     pop    ax
  4009.     mov    mar_left,al
  4010.     mov    mar_right,ah
  4011.     pop    ax
  4012.     mov    mar_top,al        ; restore margins
  4013.     mov    mar_bot,ah
  4014. atedsel3:ret
  4015. atedsel    endp
  4016.  
  4017.  
  4018. p20ed:    xor    dx,dx            ; Prime PT200, set cursor to 0,0
  4019.     call    ereos            ; erase cursor to end of screen
  4020.     jmp    atsetcur            ; put cursor at 0,0 and return
  4021.  
  4022.                     ; Erase in current line
  4023. atel:    cmp    ninter,0        ; zero intermediates?
  4024.     je    atel0            ; e = yes
  4025.     ret
  4026.  
  4027. atel0:    cmp    lparam,0        ; letter parameter?
  4028.     je    atel0a
  4029.     jmp    atelsel            ; try protected mode erasure
  4030. atel0a:    cmp    param,0            ; was arg zero?
  4031.     jne    atel1            ; ne = no
  4032.     mov    al,dl            ; erase from cursor
  4033.     mov    bl,byte ptr low_rgt    ;  to end of line, inclusive
  4034.     jmp    erinline        ; do the erasure
  4035.  
  4036. atel1:    cmp    param,1            ; was arg one?
  4037.     jne    atel2            ; ne = no
  4038.     xor    al,al            ; erase from start of line
  4039.     mov    bl,dl            ;  to cursor, inclusive
  4040.     jmp    erinline        ; do the erasure
  4041.  
  4042. atel2:    cmp    param,2            ; was arg two?
  4043.     jne    atel3            ; ne = no, ignore
  4044.     xor    al,al            ; erase entire line
  4045.     mov    bl,byte ptr low_rgt
  4046.     jmp    erinline        ; clear it
  4047. atel3:    ret
  4048.  
  4049.  
  4050. atelsel    proc    near            ; DECSEL selective erase in line
  4051.     cmp    lparam,'?'        ; proper intermediate?
  4052.     jne    atelsel3        ; ne = no
  4053.     mov    ax,param        ; get parameter
  4054.     or    ax,ax            ; 0?
  4055.     jnz    atelsel1        ; nz = no
  4056.     mov    al,mar_top        ; 0: erase cursor to end of line
  4057.     mov    ah,mar_bot        ; save margins
  4058.     push    ax
  4059.     mov    mar_top,dh        ; use current row
  4060.     mov    mar_bot,dh
  4061.     call    erprot            ; do protected mode erasure
  4062.     pop    ax
  4063.     mov    mar_top,al        ; restore margins
  4064.     mov    mar_bot,ah
  4065.     ret
  4066. atelsel1:cmp    al,1            ; 1? erase start of line to cursor
  4067.     jne    atelsel2        ; ne = no
  4068.     mov    al,mar_top        ; 1: erase start to cursor
  4069.     mov    ah,mar_bot        ; save margins
  4070.     push    ax
  4071.     mov    al,mar_right
  4072.     mov    ah,dl            ; save right margin and cursor col
  4073.     push    ax
  4074.     mov    mar_right,dl        ; stop at current cursor
  4075.     mov    dl,mar_left        ; start at this pseudo cursor
  4076.     mov    mar_top,dh        ; use current row
  4077.     mov    mar_bot,dh
  4078.     call    erprot            ; do protected mode erasure
  4079.     pop    ax
  4080.     mov    mar_right,al        ; restore right margin
  4081.     mov    dl,ah            ; restore cursor row
  4082.     pop    ax
  4083.     mov    mar_top,al        ; restore margins
  4084.     mov    mar_bot,ah
  4085.     ret
  4086. atelsel2:cmp    al,2            ; 2? erase whole line
  4087.     jne    atelsel3        ; ne = no
  4088.     mov    al,mar_top        ; 2: erase whole line
  4089.     mov    ah,mar_bot        ; save margins
  4090.     push    ax
  4091.     mov    ah,dl            ; save right margin and cursor col
  4092.     mov    al,mar_right
  4093.     push    ax
  4094.     mov    mar_right,dl        ; stop at current cursor
  4095.     mov    dl,mar_left        ; start at this pseudo cursor
  4096.     mov    mar_top,dh        ; use current row
  4097.     mov    mar_bot,dh
  4098.     call    erprot            ; do protected mode erasure
  4099.     pop    ax
  4100.     mov    mar_right,al        ; restore right margin
  4101.     mov    dl,ah            ; restore cursor row
  4102.     pop    ax
  4103.     mov    mar_top,al        ; restore margins
  4104.     mov    mar_bot,ah
  4105. atelsel3:ret
  4106. atelsel    endp
  4107.  
  4108.                     ; ECH, erase chars in this line
  4109. atech:    mov    ax,dx            ; get cursor position
  4110.     mov    bx,ax            ; erase ax to bx
  4111.     cmp    byte ptr param,0    ; 0 argument
  4112.     je    atech1            ; e = yes
  4113.     dec    bl            ; count from 1
  4114. atech1:    add    bl,byte ptr param    ; number of characters
  4115.     jmp    erinline        ; erase in this line
  4116.  
  4117.  
  4118. ; Set Graphics Rendition commands (video attributes)
  4119.  
  4120. atsgr:    cmp    lparam,0        ; any letter parameter?
  4121.     jne    atsgr0            ; ne = yes, fail
  4122.     mov    ah,curattr        ; get current cursor attribute
  4123.     mov    di,offset atsgr1    ; routine to call
  4124.     call    atreps            ; repeat for all parms
  4125.     mov    curattr,ah        ; store new attribute byte
  4126.     test    flags.vtflg,ttwyse    ; Wyse-50?
  4127.     jz    atsgr0a            ; z = no
  4128.     mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attribute
  4129. atsgr0a:cmp     isps55,0                ; [HF]941103 Japanese PS/55 ?
  4130.     je      atsgr0                  ; [HF]941103 e = no
  4131.     mov     scbattr,ah              ; [HF]940225 and background also
  4132. atsgr0:    ret
  4133.  
  4134. atsgr1:    mov    bx,param[si]        ; fetch an argument
  4135.     or    bl,bl            ; 0, clear all attributes?
  4136.     jnz    atsgr2            ; nz = no, do selectively below
  4137.     call    clrbold            ; clear bold attribute
  4138.     call    clrblink        ; clear blink attribute
  4139.     call    clrrev            ; clear reverse video attribute
  4140.     call    clrunder        ; clear underline attribute
  4141.     mov    atinvisible,0        ; clear invisible attribute
  4142.     mov    cl,extattr
  4143.     and    cl,att_protect        ; preserve protected attribute
  4144.     mov    extattr,cl        ; clear extended attributes
  4145.     cmp    reset_color,0        ; reset colors?
  4146.     je    atsgr1a            ; e = no
  4147.     mov    ah,scbattr
  4148. atsgr1a:ret
  4149.  
  4150. atsgr2:    cmp    lparam,0        ; letter parameter?
  4151.     jne    atsgr9            ; ne = yes, go directly to colors
  4152.     cmp    bl,1            ; 1, set bold?
  4153.     jne    atsgr2a            ; ne = no
  4154.     jmp    setbold            ; set bold attribute
  4155.  
  4156. atsgr2a:cmp    bl,2            ; D470 / PT200 - 2, set dim?
  4157.     jne    atsgr3            ; ne = no
  4158.     cmp    flags.vtflg,ttd470    ; DG d470?
  4159.     je    atsgr2b            ; e = yes
  4160.     cmp    flags.vtflg,ttpt200    ; PT200 '2' = half intensity
  4161.     jne    atsgr3              ; ne = no, do next attrib test
  4162.     jmp    setbold            ; set half intensity
  4163.  
  4164. atsgr2b:mov    ah,scbattr        ; D470, "set dim" get default coloring
  4165.     jmp    clrbold            ; make it dim
  4166.  
  4167. atsgr3: cmp    bl,4            ; 4, set underline?
  4168.     jne    atsgr4            ; ne = no
  4169.     jmp    setunder        ; set underline attribute
  4170.  
  4171. atsgr4: cmp    bl,5            ; 5, set blink?
  4172.     jne    atsgr5            ; ne = no
  4173.     jmp    setblink        ; set blink attribute
  4174.  
  4175. atsgr5: cmp    bl,7            ; 7, reverse video for chars?
  4176.     jne    atsgr5a            ; ne = no, try coloring
  4177.     jmp    setrev            ; set reversed video attribute (AH)
  4178.  
  4179. atsgr5a:cmp    bl,8            ; 8, invisbile on?
  4180.     jne    atsgr6            ; ne = no, try coloring
  4181.     mov    atinvisible,1        ; set invisible coloring
  4182.     ret
  4183.  
  4184. atsgr6:    cmp    flags.vtflg,ttheath    ; Heath-19?
  4185.     jne    atsgr9            ; ne = no
  4186.     cmp    bl,10            ; 10, enter graphics mode?
  4187.     jne    atsgr7            ; ne = no
  4188.     push    ax            ; save ah
  4189.     mov    al,'F'            ; simulate final char of 'F'
  4190.     call    v52sgm            ; do character setup like VT52
  4191.     pop    ax
  4192.     ret
  4193. atsgr7:    cmp    bl,11            ; 11, exit graphics mode?
  4194.     jne    atsgr8            ; ne = no, ignore
  4195.     push    ax            ; save ah
  4196.     mov    al,'G'            ; simulate final char of 'G'
  4197.     call    v52sgm            ; do character setup like VT52
  4198.     pop    ax
  4199. atsgr8:    ret
  4200.  
  4201. atsgr9:    cmp    flags.vtflg,ttd470    ; DG D470?
  4202.     je    atsgr15            ; e = yes
  4203.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  4204.     jz    atsgr14            ; z = no, 22-27 are VT220/320 only
  4205.     cmp    bl,22            ; 22, bold off?
  4206.     jne    atsgr10            ; ne = no
  4207.     jmp    clrbold
  4208. atsgr10:cmp    bl,24            ; 24, underline off?
  4209.     jne    atsgr11            ; ne = no
  4210.     jmp    clrunder
  4211. atsgr11:cmp    bl,25            ; 25, blinking off?
  4212.     jne    atsgr12            ; ne = no
  4213.     jmp    clrblink
  4214. atsgr12:cmp    bl,27            ; 27, reverse video off?
  4215.     jne    atsgr13            ; ne = no
  4216.     jmp    clrrev            ; clear reversed video attribute (AH)
  4217. atsgr13:cmp    bl,28            ; 28, invisible off?
  4218.     jne    atsgr14            ; ne = no
  4219.     mov    atinvisible,0        ; clear invisible attribute
  4220.     ret
  4221. atsgr14:jmp    setcolor        ; BL = color, AH = attribute byte
  4222.  
  4223.  
  4224. atsgr15:cmp    bl,30            ; in foreground colors?
  4225.     jae    atsgr16            ; ae = yes, make bold
  4226.     cmp    lparam,'<'        ; DG dim code?
  4227.     jb    atsgr17            ; b = no, do nothing
  4228.     call    clrbold            ; assume dim
  4229.     mov    al,lparam
  4230.     sub    al,'<'+30h
  4231.     add    bl,al            ; compose dim color
  4232.     jmp    setcolor
  4233.  
  4234. atsgr16:call    setbold            ; then make it bold
  4235.     jmp    setcolor
  4236. atsgr17:ret
  4237.  
  4238. ; Tabulation char commands
  4239. attbc:    call    atccpc            ; make sure cursor is kosher
  4240.     cmp    ninter,0        ; zero intermediates?
  4241.     je    attbc0            ; e = yes, else quit
  4242.     ret
  4243.                     ; Tabstop set/clears
  4244. attbc0: cmp    param,0            ; was argument zero?
  4245.     jne    attbc1            ; ne = no
  4246.     push    si
  4247.     mov    si,vtemu.vttbst        ; active buffer
  4248.     call    tabclr            ; clear tabstop in column DL
  4249.     pop    si
  4250.     ret
  4251.  
  4252. attbc1: cmp    param,3            ; was arg 3 (clear all tab stops)?
  4253.     je    attbc2            ; e = yes
  4254.     ret                ; else ignore
  4255. attbc2:    mov    cx,(swidth+7)/8        ; get ready to zap swidth columns
  4256.     mov    di,offset tabs        ; point to the tab stop table
  4257.     xor    al,al            ; zero indicates no tab stop
  4258.     push    es            ; save es
  4259.     push    ds
  4260.     pop    es            ; use data segment for es:di below
  4261.     cld                ; set direction forward
  4262.     rep    stosb            ; clear all bits
  4263.     pop    es
  4264.     ret
  4265.                     ; set scrolling margins
  4266. atstbm:    test    dspstate,dsptype    ; on status line?
  4267.     jnz    atstb3            ; nz = yes, ignore this command
  4268.     mov    al,byte ptr param    ; get the two line number args
  4269.     mov    ah,byte ptr param+2
  4270.     or    al,al            ; was first zero?
  4271.     jnz    atstb1            ; nz = no, continue
  4272.     inc    al            ; default is one
  4273. atstb1: or    ah,ah            ; was second zero?
  4274.     jnz    atstb2            ; nz = no
  4275.     mov    ah,byte ptr low_rgt+1    ; yes, default is last line on screen
  4276.     inc    ah
  4277. atstb2: dec    al            ; normalize to 0,0 coordinate system
  4278.     dec    ah
  4279.     cmp    ah,al            ; size of region at least two lines?
  4280.     jbe    atstb3            ; be = no, indicate an error
  4281.     or    al,al            ; check against screen limits
  4282.     jl    atstb3            ; l = out of range
  4283.     cmp    ah,byte ptr low_rgt+1
  4284.     ja    atstb3            ; a = too far down
  4285.     mov    mar_top,al        ; set the limits
  4286.     mov    mar_bot,ah
  4287.     xor    dx,dx            ; Home cursor
  4288.     jmp    atsetcur        ; set cursor position and return
  4289. atstb3:    ret                ; ignore bad requests
  4290.  
  4291. ; Device attributes commands
  4292. atda:    cmp    param,0            ; was argument zero?
  4293.     je    decid            ; e = send the i.d. string
  4294.     ret                ; no, only an echo
  4295. decid:    cmp    ninter,0        ; any intermediates?
  4296.     je    decid1            ; e = no, else not this item
  4297.     jmp    atdgnrc            ; try Spanish NRC designator
  4298. decid1:    mov    ax,flags.vtflg        ; get terminal ident type
  4299.     mov    cx,36            ; assumed length of asciiz string
  4300.     mov    ttyact,0        ; group output for networks
  4301.     mov    si,offset v32str    ; VT320 ident string
  4302.     cmp    ax,ttvt320        ; VT320?
  4303.     je    decid2            ; e = yes
  4304.     mov    si,offset v22str
  4305.     cmp    ax,ttvt220        ; VT220?
  4306.     je    decid2            ; e = yes
  4307.     mov    si,offset v102str
  4308.     cmp    ax,ttvt102        ; VT102?
  4309.     je    decid2            ; e = yes
  4310.     mov    si,offset v100str
  4311.     cmp    ax,ttvt100        ; VT100?
  4312.     je    decid2            ; e = yes
  4313.     cmp    ax,ttansi        ; ANSI-BBS?
  4314.     je    decid2            ; e = yes
  4315.     cmp    ax,tthoney        ; Honeywell?
  4316.     je    decid2            ; e = yes
  4317.     mov    si,offset v52str
  4318.     cmp    ax,ttvt52        ; VT52?
  4319.     je    decid2            ; e = yes
  4320.     mov    si,offset h19str
  4321.     cmp    ax,ttheath        ; Heath-19 mode?
  4322.     je    decid2            ; e = yes
  4323.     mov    si,offset pt20str    ; Prime PT200 string
  4324. decid2:    cmp    lparam,'>'        ; this letter parameter?
  4325.     jne    decid3            ; ne = no
  4326.     test    ax,ttvt320+ttvt220    ; VT320/VT220 mode?
  4327.     jz    decid4            ; z = no, ignore
  4328.     mov    si,offset v32sda    ; Secondary DA response string
  4329. decid3:    cld
  4330.     lodsb                ; read string
  4331.     or    al,al            ; end of string?
  4332.     jz    decid4            ; z = yes
  4333.     push    cx
  4334.     push    si
  4335.     cmp    byte ptr [si],0        ; last byte to be sent?
  4336.     je    decid3a            ; e = yes
  4337.     cmp    cx,1            ; last possible byte?
  4338.     ja    decid3b            ; a = no
  4339. decid3a:mov    ttyact,1        ; finished grouping output for net
  4340. decid3b:call    prtbout            ; send it to port with no local echo
  4341.     pop    si
  4342.     pop    cx
  4343.     loop    decid3            ; do all characters
  4344. decid4:    mov    ttyact,1        ; finished grouping output for net
  4345.     ret
  4346.                     ; Display LED's
  4347. atll:    mov    di,offset atleds    ; get pointer to routine to call
  4348.     call    atreps            ; repeat for selective parameters
  4349.     ret
  4350.  
  4351. atleds:    push    si            ; set LED indicators
  4352.     call    getled            ; set si to term type (led) string
  4353.     mov    di,si
  4354.     pop    si
  4355.     jc    atled2            ; c = no leds 1..4, ignore
  4356. atled4:    cmp    param[si],0        ; zero argument?
  4357.     jne    atled3            ; ne = no, check further
  4358.     mov    al,led_off        ; set all off
  4359.     mov    ah,al
  4360.     mov    [di+6],ax        ; where dots go after name
  4361.     mov    [di+6+2],ax
  4362. atled1:    test    yflags,modoff        ; mode line supposed to be off?
  4363.     jnz    atled2            ; nz = yes
  4364.     push    dx
  4365.     call    fmodlin            ; update status line
  4366.     pop    dx
  4367. atled2: ret
  4368. atled3: mov    ax,param[si]        ; get the argument
  4369.     cmp    al,1            ; must be 1 to 4
  4370.     jb    atled2            ; b = out of range
  4371.     cmp    al,4
  4372.     ja    atled2            ; a = out of range
  4373.     dec    ax            ; zero base it
  4374.     push    di
  4375.     add    di,ax
  4376.     add    al,'1'            ; add ascii offset for digit
  4377.     mov    [di+6],al         ; turn the "LED" on by storing digit
  4378.     pop    di
  4379.     jmp    short atled1        ; update display and return
  4380.  
  4381. decsca    proc    near            ; DEC Select Character Attributes
  4382.     cmp    ninter,1        ; one intermediate?
  4383.     jne    atll            ; no, try led routine
  4384.     cmp    inter,'"'        ; CSI Pn " q ?
  4385.     jne    decsca2            ; ne = no
  4386.     cmp    param,1            ; 0, 2 mean protected mode goes off
  4387.     jne    decsca1            ; ne = not 1, protected mode goes on
  4388.     call    setprot            ; start protecting
  4389.     ret
  4390. decsca1:call    clrprot            ; end protecting
  4391. decsca2:ret
  4392. decsca    endp
  4393.  
  4394.  
  4395. ; Set/Reset mode commands
  4396.                     ; ESC [ ? xxx h/l Set/Reset series
  4397. atrm:    mov    modeset,0        ; say we are resetting modes
  4398.     mov    di,offset atrsm        ; Reset/Set modes
  4399.     call    atreps            ; repeat for all parms
  4400.     test    vtemu.vtflgop,decanm    ; did ansi mode get reset?
  4401.     jnz    atrm1            ; nz = no, return
  4402.     cmp    flags.vtflg,ttheath    ; were we a Heath-19?
  4403.     je    atrm0            ; e = yes, don't change terminal types
  4404.     cmp    flags.vtflg,ttpt200    ; were we a PT200?
  4405.     je    atrm0            ; e = yes, don't change terminal types
  4406.     mov    flags.vtflg,ttvt52    ; say VT52 now
  4407. atrm0:    call    chrdef            ; set default char sets
  4408.     call    atsc            ; save cursor status
  4409.     test    yflags,modoff        ; mode line supposed to be off?
  4410.     jnz    atrm1            ; nz = yes
  4411.     call    fmodlin            ; update mode line
  4412. atrm1:    ret
  4413.  
  4414. atsm:    mov    modeset,1        ; say we are setting modes
  4415.     mov    di,offset atrsm        ; Reset/Set modes
  4416.     jmp    atreps            ; repeat for all parms
  4417.  
  4418. atrsm:    mov    ax,param[si]        ; pick up the argument
  4419.     cmp    lparam,'?'        ; DEC private mode? ESC [ ?
  4420.     je    atrsm1            ; e = yes, do DEC specific things
  4421.     cmp    lparam,'>'        ; Heath-19 private mode? ESC [ >
  4422.     jne    atrsma            ; ne = no
  4423.     jmp    htrsm1            ; do Heath specific things
  4424.                     ; ANSI level
  4425. atrsma:    cmp    al,20            ; 20, ANSI new-line mode?
  4426.     jne    atrsm0            ; ne = no, try insert mode
  4427.     and    vtemu.vtflgop,not vsnewline ; assume resetting
  4428.     cmp    modeset,0        ; resetting?
  4429.     je    atrsmb            ; e = yes
  4430.     or    vtemu.vtflgop,vsnewline    ; setting
  4431. atrsmb:    mov    ax,anslnm        ; get the flag bit
  4432.     jmp    atrsflg            ; set or reset it
  4433. atrsm0:    cmp    al,4            ; toggle insert mode?
  4434.     jne    atrsmc            ; ne = no
  4435.     mov    al,modeset        ; set/reset insert mode
  4436.     mov    insmod,al        ; store it
  4437.     ret
  4438. atrsmc:    cmp    al,12            ; 12? Control local echo
  4439.     jne    atrsmx            ; ne = no
  4440.     cmp    modeset,0        ; resetting mode (ESC [ 12 l)?
  4441.     jne    atrsmc1            ; ne = no
  4442.     or    yflags,lclecho        ; (l) turn on local echoing
  4443.     jmp    short atrsmc2
  4444. atrsmc1:and    yflags,not lclecho    ; (h) turn off local echoing
  4445. atrsmc2:test    yflags,modoff        ; is mode line off?
  4446.     jnz    atrsmx            ; nz = yes
  4447.     push    dx            ; save cursor position
  4448.     call    fmodlin            ; write mode line
  4449.     pop    dx
  4450. atrsmx:    ret
  4451.                     ; DEC specifics
  4452. atrsm1: cmp    al,1            ; cursor keys mode?
  4453.     jne    atrsm2            ; ne = no
  4454.     mov    ax,decckm        ; get the bit
  4455.     jmp    atrsflg            ; set or reset it and return
  4456.  
  4457. atrsm2: cmp    al,7            ; Auto-wrap?
  4458.     jne    atrsm3            ; ne = no
  4459.     and    vtemu.vtflgop,not vswrap ; assume resetting line wrap
  4460.     cmp    modeset,0        ; resetting?
  4461.     je    atrsm2a            ; e = yes
  4462.     or    vtemu.vtflgop,vswrap    ; set the bit
  4463. atrsm2a:mov    ax,decawm        ; get the bit
  4464.     jmp    atrsflg            ; set or reset it and return
  4465.  
  4466. atrsm3: cmp    al,6            ; Origin mode?
  4467.     jne    atrsm4            ; ne = no
  4468.     jmp    atrsom            ; change decom and return
  4469.  
  4470. atrsm4: cmp    al,5            ; change the video?
  4471.     jne    atrsm5            ; ne = no
  4472.     jmp    atrsscnm        ; yes, change it if necessary
  4473.  
  4474. atrsm5: cmp    al,2            ; Change VT52 compatibility mode?
  4475.     jne    atrsm6            ; ne = no
  4476.     test    dspstate,dsptype    ; on status line?
  4477.     jnz    atrsm5b            ; nz = yes, ignore switch
  4478.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  4479.     jne    atrsm5a            ; ne = no
  4480.     mov    modeset,0        ; Heath  ESC [ ? 2 h  resets ANSI mode
  4481. atrsm5a:mov    ax,decanm        ; get ansi mode flag
  4482.     call    atrsflg            ; set or reset it
  4483.     test    yflags,modoff        ; mode line supposed to be off?
  4484.     jnz    atrsm5b            ; nz = yes
  4485.     push    dx            ; save cursor position
  4486.     call    fmodlin            ; write mode line
  4487.     pop    dx
  4488. atrsm5b:ret
  4489.  
  4490. atrsm6:    cmp    al,3            ; 132/80 column mode change?
  4491.     jne    atrsm7            ; ne = no
  4492.     mov    al,curattr        ; save current video attributes
  4493.     mov    ah,extattr        ; and extended attributes
  4494.     push    ax
  4495.     xor    ah,ah            ; high byte: not exiting Connect mode
  4496.     and    vtemu.vtflgop,not deccol; assume mode is reset
  4497.     mov    al,modeset        ; pass set/reset request to chgdsp
  4498.     or    al,al
  4499.     jz    atrsm6a            ; z = set 80 columns
  4500.     or    vtemu.vtflgop,deccol    ; assume it will work (tell msy)
  4501. atrsm6a:call    chgdsp            ; call Change Display proc in msy
  4502.     and    vtemu.vtflgop,not deccol; assume mode is reset
  4503.     cmp    modeset,0        ; want 80 cols?
  4504.     je    atrsm6n            ; e = yes, else 132 cols
  4505.     cmp    byte ptr low_rgt,79
  4506.     jbe    atrsm6b
  4507.     or    vtemu.vtflgop,deccol    ; set the status bit
  4508.     mov    byte ptr low_rgt,132-1    ; screen capability
  4509.     jmp    short atrsm6e
  4510. atrsm6b:and    vtemu.vtflgst,not deccol; turn off setup 132 col bit too
  4511. atrsm6n:cmp    byte ptr low_rgt,79    ; want 80 cols, is it wider?
  4512.     jbe    atrsm6e            ; be = no
  4513.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  4514. atrsm6e:test    flags.vtflg,ttd463+ttd470+ttd217+ttwyse ; D463/D470 or Wyse?
  4515.     jnz    atrsm6f            ; nz = yes, no reset for them
  4516.     CALL    ATRES2            ; do partial reset of emulator
  4517. atrsm6f:pop    ax
  4518.     mov    curattr,al        ; restore saved items
  4519.     mov    extattr,ah
  4520.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  4521.     jz    atrsm6g            ; z = no
  4522. atrsm6h:call    frepaint        ; repaint new screen
  4523.     ret                ; D463/D470 gets no other changes
  4524. atrsm6g:mov    dx,low_rgt        ; text lines (leave status line intact)
  4525.     mov    mar_top,0
  4526.     mov    mar_bot,dh        ; reset scrolling region
  4527.     mov    dl,byte ptr low_rgt    ; right margin
  4528.     mov    mar_right,dl
  4529.     mov    mar_left,0
  4530.     test    flags.vtflg,ttwyse     ; Wyse?
  4531.     jnz    atrsm6h            ; nz = yes, leave cursor alone, repaint
  4532.     xor    dx,dx            ; new cursor position is 0,0
  4533.     mov    cursor,dx
  4534.     jmp    atsetcur        ; place it there and return
  4535.  
  4536. atrsm7:    cmp    al,18            ; 18?  18 & 19 = printer support
  4537.     jne    atrsm8            ; ne = no
  4538.     cmp    modeset,0        ; resetting?
  4539.     jne    atrsm7a            ; ne = no, setting
  4540.     and    anspflg,not vtffp    ; no form feed after printing
  4541.     ret
  4542. atrsm7a:or    anspflg,vtffp        ; use form feed after printing
  4543.     ret
  4544.  
  4545. atrsm8:    cmp    al,19            ; 19, print region?
  4546.     jne    atrsm9            ; ne = no
  4547.     cmp    modeset,0        ; resetting?
  4548.     jne    atrsm8a            ; ne = no, setting
  4549.     and    anspflg,not vtextp    ; reset print region to scrolling reg
  4550.     ret
  4551. atrsm8a:or    anspflg,vtextp        ; set print region to whole screen
  4552.     ret
  4553.  
  4554. atrsm9:    cmp    al,25            ; ESC [ ? 25 h/l? cursor on/off
  4555.     jne    atrsm10            ; ne = no
  4556.     mov    al,4            ; assume cursor to be turned off (4)
  4557.     cmp    modeset,0        ; resetting (invisible cursor)?
  4558.     je    atrsm9a            ; e = yes
  4559.     mov    al,1            ; assume underline (1)
  4560.     test    vtemu.vtflgop,vscursor    ; underline?
  4561.     jnz    atrsm9a            ; nz = yes
  4562.     inc    al            ; block (2)
  4563. atrsm9a:mov    atctype,al        ; save VTxxx cursor type here
  4564.     jmp    atsctyp            ; set the cursor type
  4565.  
  4566.                     ; DECRLM (alt VT320 right/left write)
  4567. atrsm10:cmp    al,34            ; ESC [ ? 34 h/l? Invoke special macro
  4568.     jne    atrsm10b        ; ne = no
  4569.     and    vtemu.vtflgop,not vswdir; writing direction to normal
  4570.     and    vtemu.vtflgst,not vswdir; writing direction to normal
  4571.     cmp    modeset,0        ; resetting?
  4572.     jne    atrsm10a        ; ne = no, setting
  4573.     mov    decrlm,0        ; writing direction to left to right
  4574.     ret
  4575. atrsm10a:mov    decrlm,1        ; writing direction to right to left
  4576.     ret
  4577.                     ; DECHEBM (alt VT320 keyboard map)
  4578. atrsm10b:cmp    al,35            ; ESC [ ? 35 h/l? Invoke special macro
  4579.     jne    atrsm10d        ; ne = no
  4580.     cmp    modeset,0        ; resetting?
  4581.     jne    atrsm10c        ; ne = no, setting
  4582.     call    fvtkrmac        ; perform on-line macro
  4583.     ret
  4584.                     ;  code is located in file msy
  4585. atrsm10c:call    fvtksmac        ; do set macro
  4586.     ret
  4587.  
  4588. atrsm10d:cmp    al,36            ; DECHEM Hebrew encoding mode?
  4589.     jne    atrsm11            ; ne = no
  4590.     cmp    modeset,0        ; resetting?
  4591.     jne    atrsm10e        ; ne = no
  4592.     mov    al,13            ; Hebrew NRC
  4593.     mov    ah,al            ; GR = GL = 13
  4594.     or    vtemu.vtflgop,vsnrcm    ; set NRC active bit
  4595.     or    vtemu.vtflgst,vsnrcm
  4596.     and    vtemu.vtflgop,not vscntl ; no 8-bit controls
  4597.     jmp    short atrsm10f
  4598. atrsm10e:mov    al,17            ; DEC Multinational set (17)
  4599.     xor    ah,ah            ; GLeft is ASCII (0)
  4600.     and    vtemu.vtflgop,not vsnrcm ; clear NRC active bit
  4601.     and    vtemu.vtflgst,not vsnrcm
  4602. atrsm10f:mov    vtemu.vtchset,al
  4603.     mov    bx,offset emubuf    ; temp table of char set idents
  4604.     xchg    ah,al            ; order correctly
  4605.     mov    [bx],ax            ; char sets for G0..G3
  4606.     mov    [bx+2],ax
  4607.     call    chrsetup        ; invoke NRC
  4608.     ret
  4609.  
  4610. atrsm11:cmp    al,38            ; 38? Enter Tek sub-mode. VT340 seq
  4611.     jne    atrsm12            ; ne = no
  4612.     cmp    modeset,1        ; setting mode (ESC [ ? 38 h)?
  4613.     jne    atrsm12            ; ne = no, ignore sequence
  4614. ifndef    no_graphics
  4615.     test    denyflg,tekxflg        ; is auto Tek mode disabled?
  4616.     jnz    atrsm12            ; nz = yes, just ignore command
  4617.     call    atsc            ; save cursor and associated data
  4618.     xor    al,al            ; enter with this received character
  4619.     call    TEKEMU            ; go to Tektronix Emulator, al=null
  4620.     jmp    atnorm
  4621. endif    ; no_graphics
  4622. atrsm12:cmp    al,42            ; 42, use NRC 7-bit command?
  4623.     jne    atrsm15            ; ne = no
  4624.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
  4625.     jz    atrsm14            ; z = no
  4626.     cmp    vtemu.vtchset,0        ; ASCII?
  4627.     je    atrsm14            ; e = yes, no NRC
  4628.     cmp    vtemu.vtchset,13    ; highest NRC ident?
  4629.     ja    atrsm14            ; a = not NRC
  4630.     cmp    modeset,0        ; resetting?
  4631.     je    atrsm13            ; e = yes
  4632.     or    vtemu.vtflgop,vsnrcm    ; set NRC flag bit
  4633.     jmp    chrdef            ; and set NRC characters
  4634. atrsm13:mov    ax,vtemu.vtflgop    ; run time flags
  4635.     and    vtemu.vtflgop,not vsnrcm ; turn off NRC flag bit
  4636.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  4637.     jmp    chrdef
  4638. atrsm14:ret
  4639. atrsm15:cmp    al,66            ; 66, keypad to applications mode?
  4640.     jne    atrsm16            ; ne = no
  4641.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220 mode?
  4642.     jz    atrsm16            ; z = no
  4643.     mov    ax,deckpam        ; bit to control
  4644.     jmp    atrsflg            ; control the flag and return
  4645. atrsm16:ret
  4646.  
  4647. ; VT340  CSI number $ |   number is 0 or 80 for 80 cols, 132 for 132 columns
  4648. ; DECSCPP, set columns per page
  4649. atscpp:    cmp    inter,'$'        ; correct intermediate letter?
  4650.     jne    atscpp2            ; ne = no, ignore
  4651.     cmp    ninter,1        ; one intermediate?
  4652.     jne    atscpp2            ; ne = no, ignore
  4653.     mov    modeset,1        ; assume 132 columns wanted
  4654.     cmp    param,80        ; 80 or 132 columns?
  4655.     ja    atscpp1            ; a = 132 columns
  4656.     mov    modeset,0        ; set to 80 columns
  4657. atscpp1:mov    al,3            ; set up CSI ? 3 h/l command
  4658.     jmp    atrsm6            ; process that command
  4659. atscpp2:ret
  4660.  
  4661.         ; Heath-19  ESC [ > Ps h or l where Ps = 1, 4, 7, or 9
  4662. htrsm1:    cmp    al,1            ; 25th line?
  4663.     jne    htrsm4            ; ne = no
  4664.     and    h19stat,not h19l25    ; clear 25th line bit
  4665.     cmp    modeset,0        ; clearing?
  4666.     je    htrsm1a            ; e = yes
  4667.     or    h19stat,h19l25        ; set bit
  4668.     jmp    htrsmx            ; we are done
  4669. htrsm1a:mov    ah,byte ptr low_rgt+1    ; point to status (25th) line
  4670.     inc    ah            ;  which is here
  4671.     xor    al,al            ; from column 0
  4672.     mov    bh,ah            ; to same line
  4673.     mov    bl,byte ptr low_rgt    ; physical width
  4674.     call    vtsclr            ; disabling status line clears it
  4675.     ret
  4676.  
  4677. htrsm4:    cmp    al,4            ; 4, block/line cursor?
  4678.     jne    htrsm5            ; ne = no
  4679.     and    h19ctyp,4        ; save on/off bit (4)
  4680.     cmp    modeset,0        ; reset?
  4681.     je    htrsm4a            ; e = yes
  4682.     or    h19ctyp,2        ; remember block kind here
  4683.     jmp    atsctyp
  4684. htrsm4a:or    h19ctyp,1        ; remember underline kind here
  4685.     jmp    atsctyp
  4686.      
  4687. htrsm5: cmp     al,5                    ; 5, on/off cursor?
  4688.         jne     htrsm7                  ; ne = no
  4689.         cmp     modeset,0               ; on?
  4690.         je      htrsm5a                 ; e = yes
  4691.     or    h19ctyp,4        ; remember off state in this bit
  4692.         jmp     atsctyp
  4693. htrsm5a:and    h19ctyp,not 4        ; set cursor on
  4694.         jmp     atsctyp
  4695.  
  4696. htrsm7:    cmp    al,7            ; 7, alternate application keypad?
  4697.     jne    htrsm8            ; ne = no
  4698.     mov    ax,deckpam        ; get keypad application mode bit
  4699.     jmp    atrsflg            ; set or reset appl keypad mode
  4700.  
  4701. htrsm8:    cmp    al,8            ; 8, received CR => CR/LF?
  4702.     jne    htrsm9
  4703.     and    h19stat,not h19alf    ; clear autoline feed bit
  4704.     cmp    modeset,0        ; resetting?
  4705.     je    htrsmx            ; yes
  4706.     or    h19stat,h19alf        ; turn on the mode
  4707.     ret
  4708.  
  4709. htrsm9:    cmp    al,9            ; 9, auto newline mode? (add cr to lf)
  4710.     jne    htrsmx            ; ne = no
  4711.     mov    ax,anslnm        ; get the bit
  4712.     jmp    atrsflg            ; set or reset newline mode
  4713. htrsmx:    ret                ; ignore the code
  4714.  
  4715. atrsflg:cmp    modeset,0        ; reset?
  4716.     je    atrsf1            ; e = yes, reset it
  4717.     or    vtemu.vtflgop,ax    ; set, OR in the flag
  4718.     test    ax,decanm        ; changing ansi mode?
  4719.     jz    atrsfx            ; z = no
  4720.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  4721.     je    atrsfx            ; e = yes, don't flip terminal kinds
  4722.     mov    ax,oldterm        ; terminal type at startup
  4723.     mov    flags.vtflg,ax        ; restore it
  4724.     ret
  4725. atrsf1: not    ax            ; reset bit, complement
  4726.     and    vtemu.vtflgop,ax    ; clear the bit
  4727.     not    ax            ; recover the bit
  4728.     test    ax,decanm        ; changing ansi mode?
  4729.     jz    atrsfx            ; z = no
  4730.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  4731.     je    atrsfx            ; e = yes, don't flip terminal kinds
  4732.     mov    flags.vtflg,ttvt52    ; say VT52 now
  4733. atrsfx:    ret
  4734.                     ; Set/Clear Origin mode
  4735. atrsom:    test    dspstate,dsptype    ; on status line?
  4736.     jz    atrsom1            ; z = no
  4737.     ret                ; else ignore this command
  4738. atrsom1:cmp    modeset,0        ; clearing DEC origin mode?
  4739.     jne    atrsom2            ; ne = no, setting
  4740.     and    vtemu.vtflgop,not decom ; reset Origin mode
  4741.     xor    dx,dx            ; go to the home position
  4742.     jmp    atsetcur        ; set cursor and return
  4743. atrsom2:or    vtemu.vtflgop,decom    ; set Origin mode
  4744.     mov    dx,cursor        ; get the cursor
  4745.     xor    dl,dl            ; go to right margin
  4746.     mov    dh,mar_top        ; go to home of scrolling region
  4747.     jmp    atsetcur        ; set the cursor and return
  4748.  
  4749. atrsscnm:cmp    modeset,0        ; resetting?
  4750.     je    atrss1            ; e = yes, reset
  4751.     test    vtemu.vtflgop,vsscreen    ; setting, set already?
  4752.     jnz    atrss3            ; nz = yes, don't do it again
  4753.     or    vtemu.vtflgop,vsscreen    ; set and tell Status display
  4754.     jmp    short atrss2        ; do it
  4755.  
  4756. atrss1: test    vtemu.vtflgop,vsscreen    ; resetting, reset already?
  4757.     jz    atrss3            ; z = yes, don't do it again
  4758.     and    vtemu.vtflgop,not vsscreen ; clear and tell Status
  4759.                     ; fall through to atrss2
  4760.  
  4761. ; Note: This is also called from the stblmds initialization routine.
  4762. ; Reverse video the entire screen, update scbattr and curattr to match.
  4763. atrss2:    push    ax
  4764.     mov    ah,scbattr        ; current screen attributes
  4765.     call    revideo            ; reverse them
  4766.     mov    scbattr,ah        ; set screen background attribute
  4767.     mov    ah,curattr        ; get current cursor attribute
  4768.     call    revideo            ; reverse it
  4769.     mov    curattr,ah        ; store it
  4770.     call    revscn            ; reverse everything on the screen
  4771.     pop    ax
  4772. atrss3:    ret
  4773.  
  4774.                     ; Self tests DECTST
  4775. atctst:    cmp    inter,0            ; any intermediate char?
  4776.     jne    atcts3            ; ne = yes, not a selftest command
  4777.     cmp    param,2            ; VT102 selftest?
  4778.     je    atcts1            ; e = yes
  4779.     cmp    param,4            ; VT320 selftest?
  4780.     jne    atcts6            ; ne = no
  4781. atcts1:    test    dspstate,dsptype    ; cursor is on status line?
  4782.     jz    atcts2            ; z = no
  4783.     push    param            ; save first parameter
  4784.     mov    ah,inter        ;  and first intermediate char
  4785.     push    ax
  4786.     mov    param,0            ; select main display
  4787.     mov    inter,'$'        ; setup proper intermediate
  4788.     call    atssdt            ; select status line of off
  4789.     call    atsasd            ; select main display
  4790.     pop    ax
  4791.     pop    param            ; restore parameter
  4792.     mov    inter,ah        ;  and intermediate char
  4793. atcts2:    xor    al,al            ; init test weight
  4794.     mov    di,offset atcts4    ; routine to call
  4795.     call    atreps            ; repeat for all parms
  4796.     test    al,80H            ; reset?
  4797.     jz    atcts3            ; z = no, return
  4798.     jmp    atreset            ; reset everything
  4799. atcts3: ret
  4800.  
  4801. atcts4:    or    si,si            ; initial arg?
  4802.     jz    atcts5            ; z = yes, skip it (examined above)
  4803.     cmp    param[si],1        ; power up test (0, 1) included?
  4804.     ja    atcts5            ; a = no, ignore printer/comms/repeats
  4805.     or    al,80H            ; say we want reset
  4806. atcts5: ret
  4807.  
  4808. atcts6:    cmp    nparam,0        ; absence of parameters?
  4809.      jne    atcts5            ; ne = no, ignore sequence
  4810.     jmp    athoney            ; try Honeywell ESC [ y  ident response
  4811.  
  4812. atalign    proc    near            ; Align screen, fill screen with 'E's
  4813.     mov    al,'E'            ; char to use as filler
  4814.     test    dspstate,dsptype    ; is cursor on status line?
  4815.     jz    atalig1            ; z = no
  4816.     ret                ; yes, ignore the command
  4817. atalig1:cmp    flags.modflg,0        ; is mode line off?
  4818.     je    atalig2            ; e = yes
  4819.     and    yflags,not modoff    ; say it's on
  4820.     mov    flags.modflg,1        ;  and owned by us
  4821. atalig2:push    ax            ; save displayed char
  4822.     push    vtemu.vtflgst        ; save setup flags
  4823.     mov    ax,vtemu.vtflgop    ; operational flags
  4824.     and    ax,deccol        ; get 80/132 column indicator
  4825.     and    vtemu.vtflgst,not deccol ; clear for set below
  4826.     or    vtemu.vtflgst,ax    ; set it so reset preserves it
  4827.     call    atreset            ; clear system
  4828.     pop    vtemu.vtflgst        ; recover setup flags
  4829.     or    vtemu.vtflgop,decawm    ; set wrap
  4830.     mov    cl,byte ptr low_rgt    ; number of columns-1
  4831.     inc    cl
  4832.     mov    al,byte ptr low_rgt+1    ; number of rows-1
  4833.     inc    al
  4834.     mul    cl            ; ax = number of chars on screen
  4835.     mov    cx,ax
  4836.     pop    ax            ; recover displayed char in AL
  4837.     mov    emubuf,al        ; keep it here while looping
  4838. atalig3:push    cx
  4839.     mov    al,emubuf        ; write screen full of this char
  4840.     call    atnrm            ; write the 'E' or whatever
  4841.     pop    cx
  4842.     loop    atalig3            ; cx times
  4843.     ret
  4844. atalign    endp
  4845.  
  4846.  
  4847. ; Reports
  4848. atreqt: cmp    param,1            ; want report?
  4849.     jbe    atreq1            ; be = yes
  4850. atreq0:    ret                ; Gee, must have been an echo (> 1)
  4851.  
  4852. atreq1:    test    flags.vtflg,ttvt102+ttvt100+tthoney+ttansi ; VT102 etc?
  4853.     jz    atreq0            ; z = no, ignore
  4854.     mov    ttyact,0        ; group output for networks
  4855.     mov    al,Escape
  4856.     call    prtbout
  4857.     mov    al,'['
  4858.     call    prtbout
  4859.     mov    al,'3'            ; we report only upon request
  4860.     cmp    param,0            ; was argument a zero?
  4861.     jne    atreq1b            ; ne = no
  4862.     mov    al,'2'            ; yes
  4863. atreq1b:call    prtbout
  4864.     mov    al,';'            ; separate
  4865.     call    prtbout
  4866.     mov    bl,parcode        ; get the parity code
  4867.     xor    bh,bh
  4868.     mov    al,partab[bx]        ; get VT100 parity code
  4869.     push    ax            ; save parity code
  4870.     call    prtnout            ; send number to the port
  4871.     mov    al,';'            ; separate
  4872.     call    prtbout
  4873.     mov    al,'2'            ; assume 7 data bits
  4874.     pop    bx            ; get parity code into bl
  4875.     cmp    bl,1            ; is parity none?
  4876.     jne    atreq2            ; ne = no, so 7 data bits
  4877.     test    flags.remflg,d8bit    ; 8 bit display?
  4878.     jz    atreq2            ; z = no
  4879.     mov    al,'1'            ; must be eight
  4880. atreq2: call    prtbout            ; send it to the port
  4881.     mov    al,';'
  4882.     call    prtbout
  4883.     mov    bl,baudidx        ; baud rate index
  4884.     xor    bh,bh
  4885.     mov    al,baudtab[bx]        ; get DEC baud rate code
  4886.     push    ax
  4887.     call    prtnout            ; sending speed index
  4888.     mov    al,';'
  4889.     call    prtbout
  4890.     pop    ax
  4891.     cmp    bl,lbaudtab-1        ; using the split speed entry?
  4892.     jne    atreq2a            ; ne = no
  4893.     mov    al,[bx+1]        ; get trailing receive speed (75 baud)
  4894. atreq2a:call    prtnout            ; receiving speed index
  4895.     mov    al,';'
  4896.     call    prtbout
  4897.     mov    al,'1'            ; clock rate multiplier is always 1
  4898.     call    prtbout
  4899.     mov    al,';'
  4900.     call    prtbout
  4901.     mov    al,'0'            ; Flags are always zero (no STP)
  4902.     call    prtbout
  4903.     mov    ttyact,1        ; end group output for networks
  4904.     mov    al,'x'
  4905.     call    prtbout
  4906.     ret
  4907.  
  4908.                     ; Single Controls
  4909. ; Note DEC manual incorrectly says DECSCL's do a hard rather than soft reset
  4910. decscl:    cmp    inter,'!'        ; "CSI ! p" soft reset?
  4911.     jne    decsc0            ; ne = no
  4912.     jmp    atsres            ; do a soft reset
  4913.  
  4914. decsc0:    cmp    inter,'"'        ; "CSI Psc; Ps1 " p"  operating level?
  4915.     je    decsc1            ; e = yes
  4916.     cmp    inter,'$'        ; "CSI Pn $ p"  DECRQM?
  4917.     jne    decsc0a            ; ne = no, ignore others
  4918.     jmp    decsc5            ; do isolated controls report
  4919. decsc0a:ret                ; else ignore
  4920. decsc1:    cmp    param,61        ; Psc, select VT100?
  4921.     jne    decsc2            ; ne = no
  4922.     mov    flags.vtflg,ttvt102    ; set VT102
  4923.     mov    oldterm,ttvt102        ; and remember it
  4924.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  4925.     mov    al,anspflg        ; preserve screen print flag
  4926.     push    ax
  4927.     call    atsres            ; do soft reset of emulator
  4928.     pop    ax
  4929.     mov    anspflg,al
  4930.     ret
  4931. decsc2:    cmp    param,62        ; go to VT2xx level?
  4932.     jne    decsc3            ; ne = no
  4933.     test    flags.vtflg,ttvt320+ttvt102 ; at VT300/VT102 level now?
  4934.     jnz    decsc3a            ; nz = yes, don't change types
  4935.     mov    flags.vtflg,ttvt220    ; set VT220 mode
  4936.     mov    oldterm,ttvt220
  4937.     jmp    short decsc3b        ; finish up
  4938.     
  4939. decsc3:    cmp    param,63        ; go to VT300 level?
  4940.     jne    decsc4            ; ne = no
  4941. decsc3a:mov    flags.vtflg,ttvt320    ; set VT320 mode
  4942.     mov    oldterm,ttvt320
  4943. decsc3b:cmp    param[2],2        ; Ps1, range here is 0, 1, 2
  4944.     ja    decsc4            ; a = out of range, ignore
  4945.     mov    al,anspflg        ; preserve screen print flag
  4946.     push    ax
  4947.     call    atsres            ; do soft reset of emulator
  4948.     pop    ax
  4949.     mov    anspflg,al
  4950.     and    vtemu.vtflgop,not vscntl ; turn off 8-bit controls
  4951.     cmp    param[2],1        ; select 7-bit controls?
  4952.     je    decsc4            ; e = yes, we have done so
  4953.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  4954. decsc4:    ret
  4955.                            ; single controls report request
  4956. decsc5:    cmp    lparam,'?'        ; want DEC Private modes?
  4957.     jne    decsc5a            ; ne = no
  4958.     call    decscpre        ; do standard prefix
  4959.     mov    al,'2'            ; assume mode is reset
  4960.     call    decsc20            ; do DEC Private mode report
  4961.     jmp    decscend        ; do end of sequence
  4962. decsc5a:cmp    inter,0            ; intermediate char?
  4963.     je    decsc5b            ; e = no, ignore
  4964.     call    decscpre        ; do standard prefix
  4965.     mov    al,'2'            ; assume mode is reset
  4966.     call    decsc5c            ; do ANSI report
  4967.     jmp    decscend        ; do end of sequence
  4968. decsc5b:ret                ; else return failure
  4969.                     
  4970. decsc5c:mov    cx,param        ; ANSI report:
  4971.     cmp    cx,2            ; 2, Keyboard action?
  4972.     jne    decsc6            ; ne = no
  4973.     ret
  4974. decsc6:    cmp    cx,3            ; control representation?
  4975.     jne    decsc7            ; ne = no
  4976.     ret                ; say reset(acting on controls)
  4977. decsc7:    cmp    cx,4            ; 4, Insert/Replace mode?
  4978.     jne    decsc8            ; ne = no
  4979.     cmp    insmod,0        ; insert mode off?
  4980.     je    decsc7a            ; e = yes, off
  4981.     dec    al            ; say is on
  4982. decsc7a:ret
  4983. decsc8:    cmp    cx,10            ; 10, Horizontal editing?
  4984.     jne    decsc9            ; ne = no
  4985.     mov    al,'4'            ; permanently reset
  4986.     ret
  4987. decsc9:    cmp    cx,12            ; 12, Send/Receive (local echo)?
  4988.     jne    decsc11            ; ne = no
  4989.     test    yflags,lclecho        ; echoing on?
  4990.     jz    decsc12            ; z = no
  4991.     dec    al            ; say set
  4992.     ret
  4993. decsc11:cmp    cx,20            ; 20, new line mode?
  4994.     jne    decsc13            ; ne = no
  4995.     test    vtemu.vtflgop,anslnm    ; new line set?
  4996.     jz    decsc12            ; z = no, reset
  4997.     dec    al            ; say set
  4998. decsc12:ret
  4999. decsc13:mov    al,'0'            ; say not recognized
  5000.     ret
  5001.  
  5002.                            ; DEC Private mode report
  5003. decsc20:mov    cx,param
  5004.     cmp    cx,1            ; 1, cursor keys?
  5005.     jne    decsc22            ; ne = no
  5006.     test    vtemu.vtflgop,decckm    ; set?
  5007.     jz    decsc31            ; z = no, reset
  5008.     dec    al
  5009.     ret
  5010. decsc22:cmp    cx,2            ; 2, ANSI mode
  5011.     jne    decsc24            ; ne = no
  5012.     test    vtemu.vtflgop,decanm    ; set?
  5013.     jz    decsc31            ; z = no, reset
  5014.     dec    al
  5015.     ret
  5016. decsc24:cmp    cx,3            ; 3, column
  5017.     jne    decsc26            ; ne = no
  5018.     test    vtemu.vtflgop,deccol    ; 132 column mode set?
  5019.     jz    decsc31            ; z = no, reset (80 columns)
  5020.     dec    al
  5021.     ret
  5022. decsc26:cmp    cx,4            ; 4, scrolling mode
  5023.     je    decsc31            ; e = yes always say reset (jump)
  5024.                     ;
  5025.     cmp    cx,5            ; 5, screen
  5026.     jne    decsc28            ; ne = no
  5027.     test    vtemu.vtflgop,decscnm    ; set (light background)?
  5028.     jz    decsc31            ; z = no, reset
  5029.     dec    al
  5030.     ret
  5031. decsc28:cmp    cx,6            ; 6, Origin mode?
  5032.     jne    decsc30            ; ne = no
  5033.     test    dspstate,dsptype    ; on status line?
  5034.     jz    decsc29            ; z = no, main display
  5035.     test    dspstate,dspdecom    ; main display Origin mode set?
  5036.     jz    decsc31            ; z = no, reset
  5037.     dec    al
  5038.     ret
  5039. decsc29:test    vtemu.vtflgop,decom    ; Origin mode set?
  5040.     jz    decsc31            ; z = no, reset
  5041.     dec    al
  5042.     ret
  5043. decsc30:cmp    cx,7            ; 7, autowrap?
  5044.     jne    decsc32            ; ne = no
  5045.     test    vtemu.vtflgop,decawm    ; set?
  5046.     jz    decsc31            ; z = no, reset
  5047.     dec    al
  5048. decsc31:ret                ; common return point
  5049. decsc32:cmp    cx,8            ; 8, autorepeat?
  5050.     jne    decsc34            ; ne = no
  5051.     dec    al
  5052.     ret                ; say set
  5053. decsc34:cmp    cx,18            ; 18, print Form Feed?
  5054.     jne    decsc36            ; ne = no
  5055.     test    anspflg,vtffp        ; set?
  5056.     jz    decsc31            ; z = no, reset
  5057.     dec    al
  5058.     ret
  5059. decsc36:cmp    cx,19            ; 19, printer extent?
  5060.     jne    decsc38            ; ne = no
  5061.     test    anspflg,vtextp        ; set?
  5062.     jz    decsc31            ; z = no, reset
  5063.     dec    al
  5064.     ret
  5065. decsc38:cmp    cx,25            ; 25, text cursor enabled?
  5066.     jne    decsc40            ; ne = no
  5067.     test    atctype,4        ; 4 is off
  5068.     jnz    decsc31            ; nz = off/disabled
  5069.     dec    al            ; say enabled
  5070.     ret
  5071. decsc40:cmp    cx,42            ; 42, NRC's
  5072.     jne    decsc42            ; ne = no
  5073.     test    flags.vtflg,ttvt320+ttvt220 ; VT320/VT220?
  5074.     jz    decsc31            ; z = no
  5075.     test    vtemu.vtflgop,vsnrcm    ; NRC's active?
  5076.     jz    decsc31            ; z = no
  5077.     dec    al            ; say enabled
  5078.     ret
  5079. decsc42:cmp    cx,66            ; 66, numeric keypad?
  5080.     jne    decsc44            ; ne = no
  5081.     test    vtemu.vtflgop,deckpam    ; set?
  5082.     jz    decsc31            ; z = no, reset
  5083.     dec    al            ; say set
  5084.     ret
  5085. decsc44:cmp    cx,68            ; 68, keyboard usage?
  5086.     jne    decsc45            ; ne = no
  5087.     mov    al,'4'            ; say always typewriter mode
  5088.     ret
  5089. decsc45:mov    al,'0'            ; say unknown kind
  5090.     ret
  5091.  
  5092. decscpre:mov    ttyact,0        ; group output for networks
  5093.     mov    al,Escape        ; do standard report beginning
  5094.     call    prtbout
  5095.     mov    al,'['
  5096.     call    prtbout
  5097.     mov    al,lparam        ; with query mark
  5098.     or    al,al            ; any letter param?
  5099.     jz    decscpre1        ; z = no
  5100.     call    prtbout
  5101. decscpre1:
  5102.     mov    al,byte ptr param    ; get parameter
  5103.     call    prtnout            ; send the number
  5104.     mov    al,';'
  5105.     call    prtbout
  5106.     ret
  5107.  
  5108. decscend:call    prtbout            ; do standard rpt end, send char in al
  5109.     mov    al,'$'
  5110.     call    prtbout
  5111.     mov    ttyact,1        ; end group output for networks
  5112.     mov    al,'y'
  5113.     call    prtbout
  5114.     ret
  5115.  
  5116. ; DEC style Soft Reset
  5117. ; Note: graphics rendition is NOT changed by soft reset, DEC manual is wrong.
  5118. atsres    proc    near            ; do soft reset of terminal
  5119.     test    dspstate,dsptype    ; on status line?
  5120.     jz    atsres1            ; z = no, on main display
  5121.     mov    param,0
  5122.     mov    inter,'$'        ; setup entry for atsasd
  5123.     call    atsasd            ; select main display
  5124. atsres1:and    vtemu.vtflgop,not(decawm+decckm+deckpam+decom) ; these go off
  5125.     mov    insmod,0        ; insert mode off
  5126.     mov    mar_top,0        ; reset scrolling margins
  5127.     mov    al,byte ptr low_rgt+1
  5128.     mov    mar_bot,al        ; to full screen
  5129.     mov    anspflg,0        ; clear printer flag
  5130.     mov    al,1            ; restore cursor, assume underline (1)
  5131.     test    vtemu.vtflgop,vscursor    ; underline?
  5132.     jnz    atsres2            ; nz = yes
  5133.     inc    al            ; block (2)
  5134. atsres2:mov    atctype,al        ; save VTxxx cursor type here
  5135.     call    atsctyp            ; set the cursor type
  5136.     push    cursor
  5137.     mov    cursor,0        ; set save cursor to Home
  5138.     call    atsc            ; save attributes
  5139.     pop    cursor            ; restore active cursor
  5140.     call    chrdef            ; set default character set
  5141.         cmp     isps55,0                ; [HF]941103 Japanese PS/55?
  5142.         je      atsres4                 ; [HF]941103 e = no
  5143.         cmp     flags.modflg,0          ; [HF]940227 mode line is off?
  5144.         je      atsres3                 ; [HF]940227 e = yes
  5145.         mov     flags.modflg,1          ; [HF]940227 mode line is owned by us
  5146.         jmp     short atsres5           ; [HF]941103
  5147. atsres4:test    yflags,modoff           ; mode line is to be off?
  5148.     jnz    atsres3            ; nz = yes
  5149. atsres5:call    fmodlin            ; rewrite mode line
  5150. atsres3:ret
  5151. atsres    endp
  5152.                     ; DECRQSS/DECRPSS Control Settings
  5153.  
  5154.                     ; Handle DCS ... q string ST
  5155. atcrq:    cmp    ninter,1        ; one intermediate?
  5156.     je    atcrq1            ; e = yes
  5157.     ja    atcrq0            ; a = too many
  5158.     jmp    atcrqq            ; none, do Sixel DCS params q...ST
  5159. atcrq0:    mov    ninter,0        ; set up atdcsnul for proper form
  5160.     mov    ttstate,offset atdcsnul    ; not understood, consume til ST
  5161.     ret
  5162.  
  5163. atcrq1:    cmp    inter,'$'        ; correct intermediate?
  5164.     jne    atcrq0            ; ne = no
  5165.     cmp    nparam,0        ; and no parameters?
  5166.     jne    atcrq0            ; ne = have some, not ours
  5167.     mov    ttstateST,offset atcrq4    ; set state for ST arrival
  5168.     mov    ttstate,offset atcrq2    ; next state gets string contents
  5169.     mov    emubufc,0        ; clear buffer counter
  5170.     mov    word ptr emubuf,0    ; empty start of buffer
  5171.     ret
  5172. atcrq2:    mov    bx,emubufc        ; count of chars in string buffer
  5173.     cmp    bx,emubufl        ; too many?
  5174.     jae    atcrq3            ; ae = too many, ignore extras
  5175.     mov    emubuf[bx],al        ; store the char
  5176.     inc    emubufc            ; count it
  5177. atcrq3:    ret
  5178.                     ; here after ST has been seen
  5179. atcrq4:    cmp    emubufc,2        ; max string chars we want
  5180.     jbe    atcrq4a            ; be = ok
  5181.     jmp    atnorm            ; a = too many, ignore
  5182. atcrq4a:mov    ax,word ptr emubuf    ; get first two chars
  5183.     cmp    ax,'}$'            ; select active display?
  5184.     jne    atcrq5            ; ne = no
  5185.     jmp    atcrqd            ; do the routine
  5186. atcrq5:    cmp    ax,'p"'            ; set conformance level?
  5187.     jne    atcrq7            ; ne = no
  5188.     jmp    atcrqp
  5189. atcrq7:    cmp    ax,'~$'            ; set status line type
  5190.     jne    atcrq8
  5191.     jmp    atcrqt
  5192. atcrq8:    cmp    ax,'r'            ; set top and bottom margins?
  5193.     jne    atcrq9
  5194.     jmp    atcrqr
  5195. atcrq9:    cmp    ax,'m'            ; set graphic rendition?
  5196.     jne    atcrq10
  5197.     jmp    atcrqm
  5198. atcrq10:jmp    atcrqxx            ; unknown command
  5199.                     ; DCS $ q  response routines
  5200. atcrqr:    call    atcrqbeg        ; 'r', top/bottom margins
  5201.     test    dspstate,dsptype    ; doing status line display?
  5202.     jz    atcrqr2            ; z = no
  5203.     mov    al,byte ptr dspmsave    ; get saved top margin
  5204.     inc    al
  5205.     call    prtnout
  5206.     mov    al,';'
  5207.     call    prtbout
  5208.     mov    al,byte ptr dspmsave+1    ; get saved bottom margin
  5209.     jmp    short atcrqr3        ; finish up
  5210. atcrqr2:mov    al,mar_top        ; top margin
  5211.     inc    al            ; move to 1,1 system
  5212.     call    prtnout
  5213.     mov    al,';'
  5214.     call    prtbout
  5215.     mov    al,mar_bot
  5216. atcrqr3:inc    al            ; move to 1,1 system
  5217.     call    prtnout
  5218.     mov    al,'r'            ; final char
  5219.     jmp    atcrqend        ; do epilogue
  5220.  
  5221. atcrqm:    call    atcrqbeg        ; 'm', graphics rendition
  5222.     mov    al,'0'            ; say start with all attributes off
  5223.     call    prtbout
  5224.     call    getbold            ; returns ah with bold attr or 0
  5225.     or    ah,ah            ; bold set?
  5226.     jz    atcrqm2            ; z = no
  5227.     mov    al,';'
  5228.     call    prtbout
  5229.     mov    al,'1'            ; say bold is on
  5230.     call    prtbout
  5231. atcrqm2:call    getunder        ; underline
  5232.     or    cl,cl            ; underline on?
  5233.     jz    atcrqm3            ; z = no, do next
  5234.     mov    al,';'
  5235.     call    prtbout
  5236.     mov    al,'4'            ; say underlining is on
  5237.     call    prtbout
  5238. atcrqm3:mov    ah,scbattr
  5239.     call    getblink        ; blinking
  5240.     or    ah,ah            ; blinking on?
  5241.     jz    atcrqm4            ; z = no
  5242.     mov    al,';'
  5243.     call    prtbout
  5244.     mov    al,'5'            ; say blinking is on
  5245.     call    prtbout
  5246. atcrqm4:test    extattr,att_rev        ; chars in reversed video?
  5247.     jz    atcrqm5            ; z = no
  5248.     mov    al,';'
  5249.     call    prtbout
  5250.     mov    al,'7'            ; say underlining is on
  5251.     call    prtbout
  5252. atcrqm5:mov    al,'m'            ; final char
  5253.     jmp    atcrqend        ; do epilogue
  5254.  
  5255. atcrqd:    call    atcrqbeg        ; '$}', writing to screen/status line
  5256.     mov    al,'0'            ; assume writing to main display
  5257.     test    dspstate,dsptype    ; get type of display
  5258.     jz    atcrqd2            ; z = main display
  5259.     inc    al            ; say writing to mode line
  5260. atcrqd2:call    prtbout
  5261.     mov    al,'$'            ; final chars
  5262.     call    prtbout
  5263.     mov    al,7dh            ; right curly brace
  5264.     jmp    atcrqend        ; do epilogue
  5265.  
  5266. atcrqt:    call    atcrqbeg        ; '$~', status line
  5267.     mov    al,'0'            ; assume mode line is off
  5268.     test    yflags,modoff        ; is mode line off?
  5269.     jnz    atcrqt2            ; nz = yes
  5270.     mov    al,'2'            ; mode line is on and host writable
  5271. atcrqt2:call    prtbout
  5272.     mov    al,'c'            ; final chars
  5273.     call    prtbout
  5274.     mov    al,7eh            ; tilde
  5275.     jmp    atcrqend        ; do epilogue
  5276.                     ; '"p' set conformance level
  5277. atcrqp:    cmp    oldterm,ttvt100        ; main-mode terminal is VT100?
  5278.     je    atcrqp2            ; e = yes
  5279.     cmp    oldterm,tthoney        ; Honeywell?
  5280.     je    atcrqp2            ; e = yes
  5281.     cmp    oldterm,ttansi        ; ANSI-BBS?
  5282.     je    atcrqp2            ; e = yes
  5283.     cmp    oldterm,ttvt102        ; VT102?
  5284.     je    atcrqp2            ; e = yes
  5285.     cmp    oldterm,ttvt320        ; how about VT320?
  5286.     je    atcrqp2            ; e = yes
  5287.     jmp    atcrqxx            ; say invalid request
  5288. atcrqp2:mov    ttyact,0        ; group output for networks
  5289.     mov    al,Escape        ; '"p', conformance level
  5290.     call    prtbout
  5291.     mov    al,'P'            ; DCS, ESC P
  5292.     call    prtbout
  5293.     mov    al,'0'            ; valid request
  5294.     call    prtbout
  5295.     mov    al,'$'
  5296.     call    prtbout
  5297.     mov    al,61            ; assume VT102
  5298.     cmp    oldterm,ttvt100        ; VT100?
  5299.     je    atcrqp2a        ; e = yes
  5300.     cmp    oldterm,tthoney        ; Honeywell
  5301.     je    atcrqp2a        ; e = yes
  5302.     cmp    oldterm,ttansi        ; ANSI-BBS?
  5303.     je    atcrqp2a        ; e = yes
  5304.     cmp    oldterm,ttvt102        ; are we a VT102?
  5305.     jne    atcrqp3            ; ne = no
  5306. atcrqp2a:call    prtnout
  5307.     jmp    short atcrqp5        ; finish the report
  5308.  
  5309. atcrqp3:mov    al,63            ; say VT320
  5310.     call    prtnout
  5311.     mov    al,';'
  5312.     call    prtbout
  5313.     mov    al,'2'            ; assume 8-bit controls are on
  5314.     test    vtemu.vtflgop,vscntl    ; 8-bit controls active?
  5315.     jnz    atcrqp4            ; nz = yes
  5316.     mov    al,'1'            ; else say only 7-bit controls
  5317. atcrqp4:call    prtbout
  5318. atcrqp5:mov    al,'"'            ; final characters
  5319.     call    prtbout
  5320.     mov    al,'p'
  5321.     jmp    atcrqend        ; do epilogue
  5322.  
  5323. atcrqbeg:mov    ttyact,0        ; group output for networks
  5324.     mov    al,Escape        ; report prologue
  5325.     call    prtbout
  5326.     mov    al,'P'            ; DCS, ESC P
  5327.     call    prtbout
  5328.     mov    al,'0'            ; valid request
  5329.     call    prtbout
  5330.     mov    al,'$'
  5331.     jmp    prtbout
  5332.  
  5333. atcrqend:call    prtbout            ; report epilogue, al has char
  5334.     mov    ttyact,1        ; end group output for networks
  5335.     mov    emubufc,0        ; clear work buffer count
  5336.     mov    al,Escape
  5337.     call    prtbout
  5338.     mov    al,'\'            ; string terminator ST (ESC \)
  5339.     jmp    prtbout
  5340.  
  5341. atcrqxx:mov    ttyact,0        ; group output for networks
  5342.     mov    al,Escape        ; report invalid request
  5343.     call    prtbout
  5344.     mov    al,'P'            ; DCS, ESC P
  5345.     call    prtbout
  5346.     mov    al,'1'            ; invalid request
  5347.     call    prtbout
  5348.     mov    al,'$'
  5349.     cmp    emubufc,1        ; any first char?
  5350.     jb    atcrqend        ; b = no
  5351.     call    prtbout
  5352.     mov    al,emubuf        ; first string char
  5353.     cmp    emubufc,2        ; two string chars?
  5354.     jne    atcrqend        ; ne = no
  5355.     call    prtbout
  5356.     mov    al,emubuf+1        ; second string char
  5357.     jmp    atcrqend        ; do epilogue
  5358.  
  5359.                     ; DCS P1; P2; P3 <char> Sixel command
  5360. atcrqq:    cmp    dcsstrf,'q'        ; final char of 'q'? Sixel draw
  5361.     je    atcrqq1            ; e = yes
  5362.     cmp    dcsstrf,'p'        ; 'p', restore palette?
  5363.     jne    atcrqq0            ; ne = no
  5364.     cmp    dinter,'$'        ; DCS 2 $ p?
  5365.     jne    atcrqq0            ; ne = no
  5366.     cmp    param,2            ; this too?
  5367.     jne    atcrqq1            ; ne = no
  5368. ifndef    no_graphics
  5369.     call    tekinq            ; get Tek screen state
  5370.     jmp    tekrcol            ; restore palette
  5371. endif    ; no_graphics
  5372.  
  5373. atcrqq0:mov    ninter,0        ; setup atdcsnul for proper form
  5374.     jmp    atdcsnul        ; consume unknown command
  5375.  
  5376. atcrqq1:test    denyflg,tekxflg        ; is auto Tek mode disabled?
  5377.     jnz    atcrqq0            ; nz = yes, consume
  5378. ifndef    no_graphics
  5379.     mov    di,offset emubuf    ; temp buffer
  5380.     mov    byte ptr [di],escape    ; do ESC ^L to erase screen
  5381.     inc    di
  5382.     mov    byte ptr [di],FF
  5383.     inc    di
  5384.     mov    byte ptr [di],escape    ; start DCS
  5385.     inc    di
  5386.     mov    byte ptr [di],'P'
  5387.     inc    di
  5388.     mov    ax,dparam[0]        ; get first parameter
  5389.     call    dec2di
  5390.     mov    byte ptr [di],';'
  5391.     inc    di
  5392.     mov    ax,dparam[2]        ; get second parameter
  5393.     call    dec2di            ; write ascii value
  5394.     mov    byte ptr [di],';'
  5395.     inc    di
  5396.     mov    ax,dparam[4]        ; get third parameter
  5397.     call    dec2di            ; write ascii value
  5398.     mov    al,dcsstrf
  5399.     mov    byte ptr [di],al    ; final char
  5400.     mov    byte ptr [di+1],0    ; terminator
  5401.     mov    di,offset emubuf
  5402.     mov    al,yflags        ; get yflags
  5403.     and    al,capt            ; save logging bit
  5404.     push    ax
  5405.     and    yflags,not capt        ; turn off logging bit
  5406. atcrqq2:mov    al,[di]
  5407.     inc    di
  5408.     or    al,al            ; at the end?
  5409.     jz    atcrqq3            ; z = yes
  5410.     push    di
  5411.     call    tekemu            ; feed Tek emulator this string
  5412.     pop    di
  5413.     jmp    short atcrqq2        ; do another string member
  5414. atcrqq3:mov    chcontrol,1        ; turn on full cell char writing
  5415.     pop    ax            ; recover logging bit
  5416.     or    yflags,al        ; restate logging bit
  5417. endif    ; no_graphics
  5418.     jmp    atnorm
  5419.  
  5420. ifndef    no_graphics
  5421. ; State machine to process DCS strings of type "p" (restore color palette)
  5422. ; Enter with "p" char in AL.
  5423. tekrcol    proc    near
  5424.     mov    ttstate,offset tekrco1    ; next state is get parameter
  5425.     mov    ttstateST,offset tekrcost ; go here on ST
  5426.     push    es
  5427.     push    ds
  5428.     pop    es
  5429.     mov    cx,5            ; five words
  5430.     xor    ax,ax
  5431.     mov    di,offset param        ; clear parameters Pc,Pu,Px,Py,Pz
  5432.     cld
  5433.     rep    stosw
  5434.     pop    es
  5435.     mov    nparam,0        ; work on initial parameter first
  5436.     ret
  5437. tekrco1:push    bx
  5438.     mov    bx,nparam        ; parameter number
  5439.     shl    bx,1            ; make it a word index
  5440.     mov    cx,param[bx]        ; accumulated parameter
  5441.     call    getdec            ; accumulate decimal value
  5442.     mov    param[bx],cx        ; remember accumulation
  5443.     pop    bx
  5444.     jnc    tekrcos1        ; nc = got a digit char
  5445.     inc    nparam            ; say have another complete parameter
  5446.     cmp    al,'/'            ; this kind of separator?
  5447.     je    tekrco3            ; e = yes, finish
  5448.     cmp    al,';'            ; break char is separator?
  5449.     jne    tekrco4            ; ne = no, decode current sequence
  5450. tekrco3:cmp    nparam,5        ; have 5 params already?
  5451.     jb    tekrcos1        ; n = no, continue reading
  5452. tekrco4:call    tekrpal            ; process parameters in msgibm file
  5453.     jmp    tekrcol            ; start over on next field
  5454.  
  5455. tekrcost:mov    ttstate,offset atnrm    ; get here on ST
  5456.     mov    ttstateST,offset atnorm ; default ST completion state
  5457.     cmp    nparam,5        ; enough parameters to finish cmd?
  5458.     jb    tekrcos1        ; b = no, abandon it
  5459.     call    tekrpal            ; update from last data item
  5460. tekrcos1:ret
  5461. tekrcol    endp
  5462. endif    ; no_graphics
  5463.  
  5464. ; Accumulate decimal value in CX using ascii char in al.
  5465. ; Return with value in CX. Return carry clear if ended on a digit,
  5466. ; return carry set and ascii char in al if ended on a non-digit.
  5467. getdec    proc    near
  5468.     cmp    al,'0'            ; a number?
  5469.     jb    getdecx            ; b = no, quit
  5470.     cmp    al,'9'
  5471.     ja    getdecx            ; a = not a number, quit
  5472.     sub    al,'0'            ; remove ascii bias
  5473.     xchg    cx,ax            ; put char in cx, decimal value in ax
  5474.     push    dx            ; save reg
  5475.     push    bx
  5476.     mov    bx,10
  5477.     mul    bx            ; times ten for a new digit
  5478.     pop    bx
  5479.     pop    dx            ; recover reg, ignore overflow
  5480.     add    al,cl            ; add current digit
  5481.     adc    ah,0            ; 16 bits worth
  5482.     xchg    ax,cx            ; rpt cnt back to cx
  5483.     clc                ; say found a digit
  5484.     ret
  5485. getdecx:stc                ; say non-digit (in al)
  5486.     ret
  5487. getdec    endp
  5488.                     ; Device Status Reports
  5489. atdsr:    mov    di,offset atdsr1    ; routine to call
  5490.     call    atreps            ; do for all parms
  5491.     ret
  5492.                     ; DSR workers
  5493. atdsr1:    mov    ax,param[si]
  5494.     cmp    lparam,0        ; any intermediate?
  5495.     jne    atdsr2            ; ne = yes, an intermediate
  5496.     cmp    ax,5            ; operating status report?
  5497.     je    rpstat            ; e = yes
  5498.     cmp    ax,6            ; cursor position report?
  5499.     je    rpcup            ; e = yes
  5500.     ret
  5501. atdsr2:    cmp    lparam,'?'        ; DEC mode queries for below?
  5502.     jne    atdsr3            ; no, skip them
  5503.     cmp    ax,6            ; VT340 cursor report?
  5504.     je    rpcup            ; e = yes
  5505.     cmp    ax,15            ; printer status report?
  5506.     je    rpstap            ; e = yes
  5507.     cmp    ax,25            ; UDK status?
  5508.     jne    atdsr3            ; ne = no
  5509.     jmp    rpudk            ; do udk status rpt
  5510. atdsr3:    cmp    ax,26            ; keyboard type?
  5511.     jne    atdsr4            ; ne = no
  5512.     jmp    rpkbd            ; do keyboard type report
  5513. atdsr4:    cmp    ax,256            ; WordPerfect Tek screen query?
  5514.     jne    atdsr5            ; ne = no
  5515. ifndef    no_graphics
  5516.     jmp    tekrpt            ; do Tek report
  5517. endif    ; no_graphics
  5518. atdsr5:    ret                ; must have been an echo
  5519.  
  5520. rpstat:    mov    ttyact,0        ; group output for networks
  5521.     mov    al,Escape        ; operating status query
  5522.     call    prtbout
  5523.     mov    al,'['
  5524.     call    prtbout
  5525.     mov    al,'0'            ; tell them we think we are OK
  5526.     call    prtbout
  5527.     mov    ttyact,1        ; end group output for networks
  5528.     mov    al,'n'
  5529.     call    prtbout
  5530.     ret
  5531.  
  5532. rpcup:    mov    ttyact,0        ; group output for networks
  5533.     mov    al,Escape        ; cursor position report
  5534.     call    prtbout
  5535.     mov    al,'['
  5536.     call    prtbout
  5537.     mov    al,byte ptr cursor+1    ; get row
  5538.     inc    al            ; map to origin at 1,1 system
  5539.     test    vtemu.vtflgop,decom    ; Origin mode set?
  5540.     jz    rpcup1            ; z = no
  5541.     sub    al,mar_top        ; subtract off top margin
  5542. rpcup1: call    prtnout            ; output the number
  5543.     mov    al,';'
  5544.     call    prtbout
  5545.     mov    al,byte ptr cursor    ; column number
  5546.     inc    al            ; map to origin at 1,1 system
  5547.     call    prtnout
  5548.     mov    ttyact,1        ; end group output for networks
  5549.     mov    al,'R'            ; final char
  5550.     call    prtbout
  5551.     ret
  5552.  
  5553. rpstap:    mov    ttyact,0        ; group output for networks
  5554.     mov    al,Escape        ; printer port query
  5555.     call    prtbout
  5556.     mov    al,'['
  5557.     call    prtbout
  5558.     mov    al,'?'            ;  10 = printer ready, 13 = not ready
  5559.     call    prtbout
  5560.     mov    al,'1'
  5561.     call    prtbout
  5562.     mov    ah,ioctl        ; get printer status, via DOS
  5563.     mov    al,7            ; status for output
  5564.     push    bx
  5565.     mov    bx,4            ; std handle for system printer
  5566.     int    dos
  5567.     pop    bx
  5568.     jc    rpstap1            ; c = call failed
  5569.     cmp    al,0ffh            ; code for Ready
  5570.     jne    rpstap1            ; ne = not ready
  5571.     mov    al,'0'            ; ready, send final digit
  5572.     jmp    short rpstap2
  5573. rpstap1:mov    al,'3'            ; not ready, say printer disconnected
  5574. rpstap2:call    prtbout
  5575.     mov    ttyact,1        ; end group output for networks
  5576.     mov    al,'n'            ; final char of response
  5577.     call    prtbout
  5578.     ret
  5579.  
  5580. rpudk:    mov    ttyact,0        ; group output for networks
  5581.     mov    al,Escape        ; response to UDK locked query
  5582.     call    prtbout
  5583.     mov    al,'['
  5584.     call    prtbout
  5585.     mov    al,'?'
  5586.     call    prtbout
  5587.     mov    al,20            ; say keys are unlocked (locked=21)
  5588.     call    prtnout
  5589.     mov    ttyact,1        ; end group output for networks
  5590.     mov    al,'n'            ; final char
  5591.     call    prtbout
  5592.     ret
  5593.  
  5594. rpkbd:    mov    ttyact,0        ; group output for networks
  5595.     mov    al,Escape        ; response to kbd type query
  5596.     call    prtbout
  5597.     mov    al,'['
  5598.     call    prtbout
  5599.     mov    al,'?'
  5600.     call    prtbout
  5601.     mov    al,27            ; keyboard dialect follows
  5602.     call    prtnout
  5603.     mov    al,';'
  5604.     call    prtbout
  5605.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  5606.     xor    bh,bh
  5607.     mov    al,nrckbd[bx]        ; get DEC keyboard code from table
  5608.     call    prtnout
  5609.     mov    ttyact,1        ; end group output for networks
  5610.     mov    al,'n'
  5611.     call    prtbout
  5612.     ret
  5613.  
  5614. ifndef    no_graphics
  5615. tekrpt:    call    tekinq            ; get Tek screen size and num colors
  5616.     push    cx            ; screen colors
  5617.     push    bx            ; screen width
  5618.     push    ax            ; screen height
  5619.     mov    ttyact,0        ; group output for networks
  5620.     mov    al,Escape        ; response to Tek query
  5621.     call    prtbout
  5622.     mov    al,'['
  5623.     call    prtbout
  5624.     mov    al,'?'
  5625.     call    prtbout
  5626.     mov    di,offset emubuf    ; working buffer
  5627.     mov    byte ptr [di],0        ; insert terminator
  5628.     mov    ax,256            ; first parameter
  5629.     call    dec2di            ; write ascii digits
  5630.     mov    byte ptr [di],';'    ; separator
  5631.     inc    di
  5632.     pop    ax            ; get screen height
  5633.     call    dec2di
  5634.     mov    byte ptr [di],';'    ; separator
  5635.     inc    di
  5636.     pop    ax            ; get screen width
  5637.     call    dec2di
  5638.     mov    byte ptr [di],';'    ; separator
  5639.     inc    di
  5640.     pop    ax            ; get number screen color (0, 1 or 16)
  5641.     call    dec2di
  5642.     mov    byte ptr[di],'n'    ; end of sequence
  5643.     inc    di
  5644.     mov    cx,di            ; compute string length
  5645.     mov    di,offset emubuf
  5646.     sub    cx,di
  5647. tekrpt1:mov    al,[di]            ; get a string char
  5648.     inc    di
  5649.     cmp    cx,1            ; last char?
  5650.     ja    tekrpt2            ; a = no
  5651.     mov    ttyact,1        ; end group output for networks
  5652. tekrpt2:call    prtbout            ; send it
  5653.     loop    tekrpt1
  5654.     ret
  5655. endif    ; no_graphics
  5656.  
  5657. atrqtsr:cmp    flags.vtflg,ttheath    ; Heath-19? ESC [ u
  5658.     jne    atrqts1            ; ne = no
  5659.     cmp    nparam,0        ; ought to have no parameters
  5660.     jne    atrqts2            ; ne = oops, not H-19 command, ignore
  5661.     jmp    atrc            ; H19, restore cursor pos and attrib
  5662.     
  5663. atrqts1:cmp    inter,'$'        ; VT320 Terminal State Rpt DECRQTSR?
  5664.     jne    atrqts2            ; ne = no
  5665.     cmp    param,1            ; report required?
  5666.     je    atrqts4            ; e = yes
  5667.     cmp    param,2            ; VT340 color palette report?
  5668.     jne    atrqts1a        ; ne = no
  5669. ifndef    no_graphics
  5670.     call    tekinq            ; get Tek screen state
  5671.     call    tekpal            ; do palette report in Tek emulator
  5672. endif    ; no_graphics
  5673. atrqts1a:ret
  5674. atrqts2:cmp    inter,'&'        ; DECRQUPSS, User preferred Supp Set?
  5675.     je    atrqts5            ; e = yes
  5676.     cmp    ninter,0        ; any intermediates?
  5677.     jne    atrqts3            ; ne = yes
  5678.     jmp    atrc            ; ANSI restore cursor ESC [ s
  5679. atrqts3:ret                ; else ignore
  5680. atrqts4:mov    al,Escape        ; Terminal state report
  5681.     call    prtbout
  5682.     mov    al,'P'            ; DCS, ESC P
  5683.     call    prtbout
  5684.     mov    al,byte ptr param
  5685.     call    prtnout            ; output as ascii digits, no echo
  5686.     mov    al,'$'
  5687.     call    prtbout            ; output char, no echo
  5688.     mov    al,'s'            ; Final char to main DCS part
  5689.     call    prtbout
  5690.     mov    al,Escape
  5691.     call    prtbout
  5692.     mov    al,'\'            ; string terminator ST (ESC \)
  5693.     call    prtbout
  5694.     ret
  5695.  
  5696. atrqts5:mov    al,Escape        ; User Preferred Supplemental Set
  5697.     call    prtbout
  5698.     mov    al,'P'            ; DCS, ESC P
  5699.     call    prtbout            ;  report
  5700.     mov    al,'0'            ; assume 94 byte set
  5701.     cmp    upss,94            ; 94 byte set?
  5702.     je    atrqts6            ; e = yes
  5703.     inc    al            ; change to 96 byte size
  5704. atrqts6:call    prtbout
  5705.     mov    al,'!'
  5706.     call    prtbout
  5707.     mov    al,'u'
  5708.     call    prtbout
  5709.     mov    al,upss+1        ; first ident char
  5710.     call    prtbout
  5711.     mov    al,upss+2        ; second char, if any
  5712.     or    al,al
  5713.     jz    atrqts7            ; z = no second char
  5714.     call    prtbout
  5715. atrqts7:mov    al,Escape
  5716.     call    prtbout
  5717.     mov    al,'\'            ; string terminator ST (ESC \)
  5718.     call    prtbout
  5719.     ret
  5720.                     ; Request Presentation State Report
  5721. atrqpsr:cmp    inter,'$'        ; proper form?
  5722.     jne    atrqps1            ; ne = no, ignore
  5723.     cmp    param,1            ; cursor report?
  5724.     je    atrqps2            ; e = yes
  5725.     cmp    param,2            ; tabstop report?
  5726.     jne    atrqps1            ; ne = no, ignore
  5727.     jmp    atrqps40        ; do tabstop report
  5728. atrqps1:ret                ; else ignore
  5729.  
  5730. atrqps2:mov    al,Escape        ; cursor report, start
  5731.     call    prtbout
  5732.     mov    al,'P'            ; DCS, ESC P
  5733.     call    prtbout
  5734.     mov    al,'1'
  5735.     call    prtbout
  5736.     mov    al,'$'
  5737.     call    prtbout
  5738.     mov    al,'u'
  5739.     call    prtbout
  5740.     mov    al,dh            ; row of cursor
  5741.     inc    al            ; count from 1,1
  5742.     call    prtnout            ; output number
  5743.     mov    al,';'
  5744.     call    prtbout
  5745.     mov    al,dl            ; column of cursor
  5746.     inc    al            ; count from 1,1
  5747.     call    prtnout            ; output number
  5748.     mov    al,';'
  5749.     call    prtbout
  5750.     mov    al,'1'            ; video page, always 1 for VT320
  5751.     call    prtbout
  5752.     mov    al,';'
  5753.     call    prtbout
  5754.     mov    al,40h            ; start bit field template
  5755.     test    extattr,att_rev        ; reverse video char writing on?
  5756.     jz    atrqps3            ; z = no
  5757.     or    al,8            ; set the bit
  5758. atrqps3:call    getblink        ; ah will be non-zero if blinking
  5759.     or    ah,ah            ; blinking?
  5760.     jz    atrqps4            ; z = no
  5761.     or    al,4            ; set the bit
  5762. atrqps4:call    getunder        ; ah will be non-zero if underlining
  5763.     or    cl,cl            ; underlining?
  5764.     jz    atrqps5            ; z = no
  5765.     or    al,2            ; set the bit
  5766. atrqps5:call    getbold            ; ax will be non-zero if bolding
  5767.     or    ah,ah            ; bold?
  5768.     jz    atrqps6            ; z = no
  5769.     or    al,1            ; set the bit
  5770. atrqps6:call    prtbout
  5771.     mov    al,';'
  5772.     call    prtbout
  5773.     mov    al,40h            ; Satt (Selective params)
  5774.     test    extattr,att_protect    ; is char protected?
  5775.     jz    atrqps6a        ; z = no
  5776.     or    al,1            ; say char is protected
  5777. atrqps6a:call    prtbout            ; output required skeleton
  5778.     mov    al,';'
  5779.     call    prtbout
  5780.     mov    al,40h            ; Sflag (shift/wrap/origin mode)
  5781.     cmp    atwrap,0        ; wrap pending?
  5782.     je    atrqps7            ; e = no
  5783.     or    al,8            ; set the bit
  5784. atrqps7:cmp    SSptr,offset G3set    ; SS3: G3 mapped to GL for next char?
  5785.     jne    atrqps8            ; ne = no
  5786.     or    al,4            ; set the bit
  5787. atrqps8:cmp    SSptr,offset G2set    ; SS2: G2 mapped to GL for next char?
  5788.     jne    atrqps9            ; ne = no
  5789.     or    al,2            ; set the bit
  5790. atrqps9:test    vtemu.vtflgop,decom    ; Origin mode set?
  5791.     jz    atrqps10        ; z = no
  5792.     or    al,1            ; set the bit
  5793. atrqps10:call    prtbout
  5794.     mov    al,';'
  5795.     call    prtbout
  5796.     mov    al,'0'            ; Pgl, say which set is in GL
  5797.     mov    si,GLptr        ; setup for worker
  5798.     call    atrqps30        ; worker returns proper al
  5799.     call    prtbout
  5800.     mov    al,';'
  5801.     call    prtbout
  5802.     mov    al,'0'            ; Pgr, say which set is in GR
  5803.     mov    si,GRptr        ; setup for worker
  5804.     call    atrqps30        ; worker returns proper al
  5805.     call    prtbout
  5806.     mov    al,';'
  5807.     call    prtbout
  5808.     mov    al,40h            ; Scss, char set size bit field
  5809.     call    atrqp15            ; call worker to fill in al
  5810.     call    prtbout    
  5811.     mov    al,';'
  5812.     call    prtbout
  5813.     mov    bx,offset G0set        ; Sdesig, get 1-2 letter ident
  5814.     call    atrqps20        ; G0, let worker fill in response
  5815.     mov    bx,offset G1set
  5816.     call    atrqps20        ; G1, let worker fill in response
  5817.     mov    bx,offset G2set
  5818.     call    atrqps20        ; G2, let worker fill in response
  5819.     mov    bx,offset G3set
  5820.     call    atrqps20        ; G3, let worker fill in response
  5821.     mov    al,Escape
  5822.     call    prtbout
  5823.     mov    al,'\'            ; string terminator ST (ESC \)
  5824.     call    prtbout
  5825.     ret
  5826.  
  5827. ; worker for Character set size reporting
  5828. atrqp15:cmp    G0set+gsize,96        ; is G0 a 96 byte set?
  5829.     jne    atrqp16            ; ne = no
  5830.     or    al,1            ; say 96
  5831. atrqp16:cmp    G1set+gsize,96        ; is G1 a 96 byte set?
  5832.     jne    atrqp17            ; ne = no
  5833.     or    al,2            ; say 96
  5834. atrqp17:cmp    G2set+gsize,96        ; G2 set?
  5835.     jne    atrqp18
  5836.     or    al,4            ; say 96
  5837. atrqp18:cmp    G3set+gsize,96        ; G3 set?
  5838.     jne    atrqp19
  5839.     or    al,8            ; say 96
  5840. atrqp19:ret                ; return with al setup
  5841.  
  5842. ; worker for Character set ident reporting at atrqps16: et seq
  5843. atrqps20:mov    al,[bx+gsize+1]        ; Gn set pointer, first letter
  5844.     call    prtbout
  5845.     mov    al,[bx+gsize+2]        ; second letter
  5846.     or    al,al            ; is there one?
  5847.     jz    atrqps21        ; z = no, nothing there
  5848.     call    prtbout
  5849. atrqps21:ret
  5850.  
  5851. ; worker. Enter with SI holding GLptr or GRptr and al = '0'
  5852. ; Returns al = '0' .. '3' to match set pointed at
  5853. atrqps30:cmp    si,offset G0set        ; si points at G0?
  5854.     je    atrqps31        ; e = yes
  5855.     inc    al            ; try next set
  5856.     cmp    si,offset G1set        ; si points at G1?
  5857.     je    atrqps31
  5858.     inc    al
  5859.     cmp    si,offset G2set        ; si points at G2?
  5860.     je    atrqps31
  5861.     inc    al            ; must be G3
  5862. atrqps31:ret
  5863.  
  5864. atrqps40:mov    al,Escape        ; start tabstop report
  5865.     call    prtbout
  5866.     mov    al,'P'            ; DCS, ESC P
  5867.     call    prtbout
  5868.     mov    al,'2'            ; tabs
  5869.     call    prtbout
  5870.     mov    al,'$'
  5871.     call    prtbout
  5872.     mov    al,'u'
  5873.     call    prtbout
  5874.     mov    cl,mar_right        ; right most column number
  5875.     inc    cl            ; number of columns
  5876.     xor    ch,ch
  5877.     push    dx            ; save dx
  5878.     xor    dx,dx            ; dh for done one output, dl = column
  5879.     mov    si,offset tabs        ; active tabs buffer
  5880. atrqps41:call    istabs            ; tab inquiry routine, column is in dl
  5881.     jnc    atrqps43        ; nc = no tab
  5882.     or    dh,dh            ; sent one value already?
  5883.     je    atrqps42        ; e = no, so no separator
  5884.     mov    al,';'            ; separator (DEC used '/')
  5885.     call    prtbout
  5886. atrqps42:mov    al,dl            ; get column
  5887.     inc    al            ; count columns from 1 for host
  5888.     call    prtnout            ; output the number
  5889.     inc    dh            ; say sent a number
  5890. atrqps43:inc    dl            ; next column, say sent one output
  5891.     loop    atrqps41        ; do the rest
  5892.     pop    dx            ; recover dx
  5893.     mov    al,Escape
  5894.     call    prtbout
  5895.     mov    al,'\'            ; string terminator ST (ESC \)
  5896.     call    prtbout
  5897.     ret
  5898.     
  5899. ; Process Restore Presentation Reports, for cursor and tab stops
  5900. ; Uses bytes dinter+5 and dinter+6 as internal variables
  5901. atrp:    cmp    dinter,0+'$'        ; correct intermediate?
  5902.     je    atrp1            ; e = yes
  5903.     jmp    atcrqxx            ; send back "illegal restore" response
  5904. atrp1:    cmp    dparam,1        ; cursor info?
  5905.     je    atrp4            ; e = yes
  5906.     mov    modeset,1        ; say setting tabs
  5907.     call    atrpw            ; call worker to do ascii to binary
  5908.     dec    dl            ; count internally from col 0
  5909.     call    tabset            ; set tab in column dl
  5910. atrp3:    mov    emubufc,0        ; clear the string count
  5911.     ret
  5912.                       ; start cursor info report playback
  5913. atrp4:    cmp    dinter+5,0        ; our internal counter in vacant byte
  5914.     jne    atrp5            ; not initial byte
  5915.     inc    dinter+5        ; point to next item next time
  5916.     call    atrpw            ; ascii to binary worker
  5917.     xchg    dh,dl            ; get row to correct byte
  5918.     mov    dl,byte ptr cursor+1    ; get column
  5919.     jmp    atsetcur        ; set the cursor
  5920. atrp5:    cmp    dinter+5,1        ; column?
  5921.     jne    atrp6
  5922.     inc    dinter+5        ; point to next item next time
  5923.     call    atrpw            ; ascii to binary worker
  5924.     mov    dh,byte ptr cursor    ; get row
  5925.     jmp    atsetcur        ; set the cursor
  5926. atrp6:    cmp    dinter+5,2        ; page?
  5927.     jne    atrp7
  5928.     inc    dinter+5        ; omit page byte
  5929.     ret
  5930. atrp7:    cmp    dinter+5,3
  5931.     jne    atrp8
  5932.     inc    dinter+5        ; Srend
  5933.     mov    al,emubuf        ; string byte
  5934.     mov    ah,curattr        ; attributes field
  5935.                     ; ought to clear attributes first
  5936.     test    al,1            ; set bold?
  5937.     jz    atrp7a            ; z = no
  5938.     call    setbold
  5939. atrp7a:    test    al,2            ; set underline?
  5940.     jz    atrp7b            ; z = no
  5941.     call    setunder
  5942. atrp7b:    test    al,4            ; set blink?
  5943.     jz    atrp7c            ; z = no
  5944.     call    setblink
  5945. atrp7c:    mov    curattr,ah        ; attributes so far
  5946.     test    al,8            ; set per char rev video?
  5947.     jz    atrp7d            ; z = no
  5948.     call    setrev            ; set reversed video
  5949.     mov    curattr,ah        ; gather main attributes
  5950. atrp7d:    ret
  5951. atrp8:    cmp    dinter+5,4
  5952.     jne    atrp9
  5953.     inc    dinter+5        ; Satt, skip it
  5954.     ret
  5955. atrp9:    cmp    dinter+5,5
  5956.     jne    atrp10
  5957.     inc    dinter+5
  5958.     mov    al,emubuf        ; string byte
  5959.     mov    ah,al
  5960.     and    ah,8            ; autowrap bit
  5961.     mov    atwrap,ah        ; set it
  5962.     mov    SSptr,0            ; say no single shift needed
  5963.     test    al,4            ; SS3 bit?
  5964.     jz    atrp9a            ; z = no
  5965.     mov    SSptr,offset G3set    ; set the pointer
  5966. atrp9a:    test    al,2            ; SS2 bit?
  5967.     jz    atrp9b            ; z = no
  5968.     mov    SSptr,offset G2set    ; set the pointer
  5969. atrp9b:    and    vtemu.vtflgop,not decom ; clear origin bit
  5970.     test    al,1            ; origin mode?
  5971.     jz    atrp9c            ; z = no
  5972.     or    vtemu.vtflgop,decom    ; set origin mode
  5973. atrp9c:    ret
  5974. atrp10:    cmp    dinter+5,6        ; Pgl
  5975.     jne    atrp11
  5976.     inc    dinter+5
  5977.     mov    al,emubuf        ; string byte
  5978.     call    atrpw5            ; call worker to setup bx with ptr
  5979.     mov    GLptr,bx
  5980.     ret
  5981. atrp11:    cmp    dinter+5,7        ; Pgr
  5982.     jne    atrp12
  5983.     inc    dinter+5
  5984.     mov    al,emubuf        ; string byte
  5985.     call    atrpw5            ; call worker to setup bx with ptr
  5986.     mov    GRptr,bx
  5987.     ret
  5988. atrp12:    cmp    dinter+5,8        ; Scss
  5989.     jne    atrp13            ; ne = no
  5990.     inc    dinter+5
  5991.     mov    al,emubuf        ; string byte
  5992.     and    al,0fh            ; strip ascii bias
  5993.     mov    dinter+6,al        ; save here for Sdesig byte, next
  5994.     ret
  5995. atrp13:    cmp    dinter+5,9        ; Sdesig
  5996.     jne    atrp14
  5997.     inc    dinter+5
  5998.     mov    si,offset emubuf    ; string
  5999.     xor    cx,cx            ; init loop counter to 0
  6000. atrp13a:mov    al,'('            ; assume G0 is 94 byte set
  6001.     add    al,cl            ; plus loop index to get set pointer
  6002.     shr    dinter+6,1        ; get set size bit
  6003.     jnc    atrp13b            ; e = correct
  6004.     add    al,4            ; map to 96 byte indicator
  6005. atrp13b:mov    inter,al        ; store size byte as intermediate
  6006.     mov    ninter,1        ; one char
  6007.     cld
  6008. atrp13c:lodsb                ; next string byte
  6009.     test    al,not 2fh        ; is there a second intermediate byte?
  6010.     jnz    atrp13d            ; nz = no
  6011.     mov    inter+1,al        ; store intermediate
  6012.     inc    ninter            ; count them
  6013.     jmp    short atrp13c        ; try again for a Final char
  6014. atrp13d:push    si
  6015.     push    cx
  6016.     mov    bx,offset ansesc    ; table to use
  6017.     call    atdispat        ; dispatch on final char to set ptr
  6018.     pop    cx
  6019.     pop    si
  6020.     inc    cx
  6021.     cmp    cx,3            ; doing last one?
  6022.     jbe    atrp13a            ; be = no, do all four
  6023.     ret
  6024. atrp14:    jmp    atcrqxx            ; send back "illegal restore" response
  6025.  
  6026.                     ; worker, ascii string to decimal byte
  6027. atrpw:    mov    cx,emubufc        ; length of this string
  6028.     jcxz    atrpw3            ; nothing there
  6029.     mov    si,offset emubuf    ; address of string
  6030.     xor    dl,dl            ; init final value
  6031.     cld
  6032. atrpw2:    lodsb                ; read a digit
  6033.     sub    al,'0'            ; ascii to numeric
  6034.     jc    atrpw3            ; c = trouble
  6035.     shl    dl,1            ; previous contents times 10
  6036.     mov    dh,dl
  6037.     shl    dl,1
  6038.     shl    dl,1
  6039.     add    dl,dh
  6040.     add    dl,al            ; plus new value
  6041.     loop    atrpw2            ; do all digits
  6042. atrpw3:    ret
  6043.                        ; char set selector worker
  6044. atrpw5:    cmp    al,'0'            ; bx gets G0set...G3set, based on AL
  6045.     jne    atrpw5a
  6046.     mov    bx,offset G0set
  6047.     ret
  6048. atrpw5a:cmp    al,'1'
  6049.     jne    atrpw5b
  6050.     mov    bx,offset G1set
  6051.     ret
  6052. atrpw5b:cmp    al,'2'
  6053.     jne    atrpw5c
  6054.     mov    bx,offset G2set
  6055.     ret
  6056. atrpw5c:mov    bx,offset G3set
  6057.     ret
  6058.  
  6059. ; Select Active Display. When selecting the status line make new scrolling
  6060. ; margins be just the status line and force on Origin mode. Save the regular
  6061. ; margins and origin mode for restoration when regular display is re-selected.
  6062. ; Also CSI Pn; Pn; Pn; Pn ~ invokes Lotus macro PRODUCT
  6063. atsasd    proc    near
  6064.     cmp    inter,'$'        ; correct intermediate?
  6065.     jne    atsasd1            ; ne = no
  6066.     cmp    param,1            ; select which display
  6067.     jb    atsasd4            ; b = select main display
  6068.     ja    atsasd1            ; a = illegal value
  6069.     cmp    flags.modflg,2        ; mode line host owned?
  6070.     jne    atsasd1            ; ne = no, ignore command
  6071.     test    dspstate,dsptype    ; was previous display = status line?
  6072.     jz    atsasd2            ; z = no
  6073. atsasd1:ret                ; else do nothing
  6074.  
  6075. atsasd2:push    word ptr mar_top    ; save scrolling margins
  6076.     pop    dspmsave        ; save scrolling margins
  6077.     or    dspstate,dsptype    ; say status line is active
  6078.     mov    al,byte ptr low_rgt+1    ; get last text line
  6079.     inc    al            ; status line
  6080.     mov    mar_top,al
  6081.     mov    mar_bot,al        ; new scrolling margins
  6082.     and    dspstate,not dspdecom    ; clear remembered origin mode
  6083.     test    vtemu.vtflgop,decom    ; was origin mode active?
  6084.     jz    atsasd3            ; z = no
  6085.     or    dspstate,dspdecom    ; remember origin mode was active
  6086. atsasd3:or    vtemu.vtflgop,decom    ; set origin mode
  6087.     call    atsc            ; save cursor material
  6088.     call    chrdef            ; reinit char sets from master setup
  6089.     mov    dx,dspcstat        ; get status line cursor
  6090.     mov    dh,mar_top        ; set row
  6091.     jmp    atsetcur        ; set cursor
  6092.  
  6093. atsasd4:test    dspstate,dsptype    ; was previous display = status line?
  6094.     jnz    atsasd5            ; nz = yes
  6095.     ret                ; else do nothing    
  6096. atsasd5:push    dspmsave        ; restore scrolling margins
  6097.     pop    word ptr mar_top
  6098.     and    vtemu.vtflgop,not decom    ; clear origin mode bit
  6099.     test    dspstate,dspdecom    ; was origin mode on for main screen?
  6100.     jz    atsasd6            ; z = no
  6101.     or    vtemu.vtflgop,decom    ; set it now
  6102. atsasd6:push    cursor            ; get status line cursor position
  6103.     pop    dspcstat        ; save it
  6104.     mov    dspstate,0        ; say now doing main screen
  6105.     jmp    atrc            ; restore cursor material
  6106. atsasd    endp
  6107.  
  6108. atssdt    proc    near            ; Select Status Line Type, DECSSDT
  6109.     cmp    inter,'$'        ; correct intermediate char?
  6110.     je    atssdt1            ; e = yes
  6111.     cmp    ninter,0        ; no intermediates?
  6112.     jne    atssdt0            ; ne = no
  6113.     call    fproduct        ; do PRODUCT macro
  6114. atssdt0:ret
  6115. atssdt1:test    dspstate,dsptype    ; on mode line already?
  6116.     jnz    atssdt4            ; nz = yes, cannot reselect now
  6117.     cmp    param,0            ; turn off status line?
  6118.     jne    atssdt2            ; ne = no
  6119.     push    dx            ; save cursor position
  6120.     call    fclrmod            ; clear the line
  6121.     pop    dx
  6122.     or    yflags,modoff        ; now say it's off
  6123.     mov    flags.modflg,1        ; say mode line is owned by us
  6124.     ret
  6125. atssdt2:cmp    param,1            ; regular status line?
  6126.     jne    atssdt3            ; ne = no
  6127.     push    dx
  6128.     call    fmodlin            ; turn on regular mode line
  6129.     pop    dx
  6130.     and    yflags,not modoff    ; and say it's on
  6131.     mov    flags.modflg,1        ; say mode line is owned by us
  6132.     ret
  6133. atssdt3:cmp    param,2            ; host writable?
  6134.     jne    atssdt4            ; ne = no
  6135.     mov    flags.modflg,2        ; say mode line is owned by host
  6136. atssdt4:ret
  6137. atssdt    endp
  6138.  
  6139. ; VT52 compatibility mode routines.
  6140.  
  6141. ; Return to ANSI mode.
  6142.  
  6143. v52ans: or    vtemu.vtflgop,decanm    ; turn on ANSI flag
  6144.     mov    ax,oldterm        ; terminal type at startup
  6145.     cmp    ax,ttvt52        ; was VT52 the prev kind?
  6146.     jne    v52ans1            ; ne = no
  6147.     mov    ax,ttvt320        ; use VT320
  6148. v52ans1:mov    oldterm,ax
  6149.     mov    flags.vtflg,ax        ; restore it
  6150.     call    chrdef            ; set default char sets
  6151.     call    atsc            ; save cursor status
  6152.     test    yflags,modoff        ; mode line supposed to be off?
  6153.     jnz    v52ans2            ; nz = yes
  6154.     call    fmodlin            ; rewrite mode line
  6155. v52ans2:ret
  6156.     
  6157. ; VT52 cursor positioning.
  6158.  
  6159. v52pos: mov    ttstate,offset v52pc1    ; next state
  6160.     ret
  6161. v52pc1: sub    al,' '-1        ; minus offset
  6162.     xor    ah,ah
  6163.     mov    param,ax        ; stash it here
  6164.     mov    ttstate,offset v52pc2    ; next state
  6165.     ret
  6166. v52pc2: sub    al,' '-1        ; minus offset
  6167.     xor    ah,ah
  6168.     mov    param+2,ax        ; stash here
  6169.     mov    ttstate,offset atnrm    ; reset state to "normal"
  6170.     jmp    atcup            ; position and return
  6171.  
  6172. ; VT52 print controls
  6173.  
  6174. v52ps:    mov    param,0            ; print screen
  6175.     mov    lparam,0
  6176.     jmp    ansprt            ; simulate ESC [ 0 i
  6177. v52pl:    mov    param,1            ; print line
  6178.     jmp    short v52pcom        ; simulate ESC [ ? 1 i
  6179. v52pcb:    mov    param,5            ; Enter printer controller on
  6180.     jmp    short v52pcom        ; simulate ESC [ ? 5 i
  6181. v52pce:    mov    param,4            ; Exit printer controller on
  6182. ;    jmp    short v52pcom        ; simulate ESC [ ? 4 i
  6183. v52pcom:mov    lparam,'?'        ; simulate ESC [ ? <number> i
  6184.     jmp    ansprt            ; process command
  6185.  
  6186. v52sgm:    mov    setptr,offset G0set    ; enter/exit special graphics mode
  6187.     cmp    al,'F'            ; enter VT52 graphics mode?
  6188.     jne    v52sgm1            ; ne = no, exit and return to ASCII
  6189.     jmp    mkdecspec        ; 'G' make DEC special graphics in G0
  6190. v52sgm1:jmp    mkascii            ; make ASCII in G0
  6191.  
  6192. ; Heath-19 special functions
  6193.  
  6194. h19sans:or    vtemu.vtflgop,decanm    ; Turn on ANSI flag. ESC <
  6195.     jmp    chrdef            ; set default char sets
  6196.                     ; clear screen and go home
  6197.  
  6198. h19ed:    cmp    param,0            ; Erase cursor to end of screen?
  6199.     jne    h19ed2            ; ne = no
  6200.     mov    ax,dx            ; start at cursor
  6201.     mov    bx,low_rgt        ; lower right corner
  6202.     cmp    bh,dh            ; on status line?
  6203.     jae    h19ed1            ; ae = no
  6204.     mov    bh,dh            ; put end on status line
  6205. h19ed1:    call    vtsclr            ; clear it
  6206.     ret
  6207. h19ed2:    cmp    param,1            ; erase start of display to cursor?
  6208.     je    h19esos            ; e = yes
  6209.     cmp    param,2            ; erase entire screen?
  6210.     je    h19clrs            ; e = yes
  6211.     ret                ; else ignore
  6212.  
  6213.                     ; erase entire screen
  6214. h19clrs:cmp    dh,byte ptr low_rgt+1    ; on status line?
  6215.     ja    h19erl            ; a = yes, do just erase in line
  6216.     xor    dx,dx            ; go to upper left corner
  6217.     call    atsetcur        ; do it
  6218.     xor    ax,ax            ; clear screen from (0,0)
  6219.     mov    bx,low_rgt        ; to lower right corner
  6220.     call    vtsclr            ; clear it
  6221.     ret
  6222.  
  6223. h19erl:    xor    al,al            ; erase whole line
  6224.     mov    bl,byte ptr low_rgt    ; physical width
  6225.     jmp    erinline        ; erase whole line, cursor stays put
  6226.  
  6227. h19ero:    xor    al,al            ; erase start of line to cursor
  6228.     mov    bl,dl
  6229.     jmp    erinline        ; clear that part of line
  6230.  
  6231.                     ; erase start of screen to cursor
  6232. h19esos:cmp    dh,byte ptr low_rgt+1    ; on status line?
  6233.     ja    h19ero            ; a = yes, do just erase in line
  6234.     jmp    ersos            ; do regular erase start of screen
  6235.  
  6236. h19wrap:or    vtemu.vtflgop,decawm    ; turn on line wrapping
  6237.     ret
  6238. h19nowrp:and    vtemu.vtflgop,not decawm ; turn off line wrapping
  6239.     ret
  6240.  
  6241. h19herv:mov    ah,curattr        ; get current cursor attribute
  6242.     mov    cl,extattr
  6243.     call    setrev            ; ESC p set reversed video
  6244.     mov    curattr,ah        ; store new attribute byte
  6245.     ret
  6246.  
  6247. h19hxrv:mov    ah,curattr        ; get current cursor attribute
  6248.     mov    cl,extattr
  6249.     call    clrrev            ; ESC q set normal video
  6250.     mov    curattr,ah        ; store new attribute byte
  6251.     ret
  6252.  
  6253. h19sc:    mov    dx,cursor
  6254.     mov    h19cur,dx        ; save cursor position
  6255.     ret
  6256.  
  6257. h19rc:    mov    dx,h19cur        ; saved cursor position
  6258.     jmp    atsetcur            ; set cursor and return
  6259.  
  6260.                     ; Heath-19 set mode "ESC x "
  6261. h19smod:mov    ttstate,offset hsmod    ; setup to parse rest of seq
  6262.     ret
  6263. hsmod:    mov    modeset,1        ; say set mode
  6264.     mov    ttstate,offset atnrm
  6265.     sub    al,'0'            ; remove ascii bias
  6266.     jmp    htrsm1            ; perform mode set
  6267.  
  6268. h19cmod:mov    ttstate,offset hcmod    ; setup to parse rest of seq
  6269.     ret
  6270.  
  6271. hcmod:    mov    modeset,0        ; say reset mode
  6272.     mov    ttstate,offset atnrm
  6273.     sub    al,'0'            ; remove ascii bias
  6274.     jmp    htrsm1            ; perform mode reset
  6275.  
  6276. hrcup:    mov    al,escape        ; send "ESC Y row col" cursor report
  6277.     call    prtbout            ; send with no local echo
  6278.     mov    al,'Y'
  6279.     call    prtbout
  6280.     mov    al,byte ptr cursor+1    ; get row
  6281.     add    al,' '            ; add ascii bias
  6282.  
  6283.     call    prtbout            ; send it
  6284.     mov    al,byte ptr cursor    ; get column
  6285.     add    al,' '            ; add ascii bias
  6286.     call    prtbout            ; and send it too
  6287.     ret
  6288.  
  6289. ; Insert/Delete characters and lines
  6290. inslin    proc    near
  6291.     mov    ax,param        ; insert line
  6292.     or    ax,ax            ; any args?
  6293.     jne    insli1            ; ne = yes
  6294.     inc    ax            ; insert one line
  6295. insli1:    mov    scroll,al        ; lines to scroll
  6296.     mov    dx,cursor        ; current position
  6297.     cmp    dh,mar_bot        ; below bottom margin?
  6298.     ja    insli3            ; a = below bottom margin
  6299.     push    word ptr mar_top
  6300.     mov    mar_top,dh        ; call present position the top
  6301.     call    atscrd            ; scroll down
  6302.     pop    word ptr mar_top    ; restore margins
  6303.     xor    dl,dl            ; go to left margin
  6304.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6305.     jz    insli2            ; z = no
  6306.     jmp    dgsetcur        ; DG set cursor with protection
  6307. insli2:    jmp    atsetcur        ; reposition cursor and return
  6308. insli3: ret
  6309. inslin    endp
  6310.  
  6311. dellin    proc    near
  6312.     mov    ax,param        ; delete line(s)
  6313.     or    ax,ax            ; any args?
  6314.     jne    delli1            ; ne = yes
  6315.     inc    ax            ; insert one line
  6316. delli1:    mov    scroll,al        ; line count
  6317.     mov    dx,cursor        ; where we are presently
  6318.     cmp    dh,mar_bot        ; at or below bottom margin?
  6319.     jae    delli3            ; ae = yes, do not scroll
  6320.     push    word ptr mar_top    ; save current scrolling margins
  6321.     mov    mar_top,dh        ; temp top margin is here
  6322.     call    atscru            ; scroll up
  6323.     pop    word ptr mar_top    ; restore scrolling margins
  6324.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6325.     jz    delli2            ; z = no
  6326.     jmp    dgsetcur        ; DG set cursor with protection
  6327. delli2:    jmp    atsetcur        ; restore cursor
  6328. delli3: ret
  6329. dellin    endp
  6330.  
  6331. ansich    proc    near            ; ANSI insert characters ESC [ Pn @
  6332.     mov    cx,param
  6333.     or    cx,cx            ; any arguments?
  6334.     jne    ansic1            ; ne = no, ignore
  6335.     inc    cx            ; use one
  6336. ansic1:    push    bx            ; use this as insert/delete flag
  6337.     mov    bh,1            ; do an insert operation
  6338. ansic2:    call    insdel            ; do common insert/delete code
  6339.     pop    bx
  6340.     ret
  6341. ansich    endp
  6342.  
  6343. inschr    proc    near            ; insert open (space) char at cursor
  6344.     push    bx            ; use this as insert/delete flag
  6345.     mov    bh,1            ; do an insert operation
  6346.     mov    cx,1            ; do one character
  6347.     call    insdel            ; do common insert/delete code
  6348.     pop    bx
  6349.     ret
  6350. inschr    endp
  6351.  
  6352. atdelc    proc    near
  6353.     mov    cx,param        ; Delete characters(s)
  6354.     or    cx,cx            ; zero becomes one operation
  6355.     jnz    atdelc1
  6356.     inc    cx            ; delete one char. Heath ESC N
  6357. atdelc1:push    bx            ; use this as insert/delete flag
  6358.     mov    bh,-1            ; do a delete operation
  6359. atdelc2:call    insdel            ; do common insert/delete code
  6360.     pop    bx
  6361.     ret
  6362. atdelc    endp
  6363.  
  6364.                     ; Common code for insert/delete char
  6365. insdel    proc    near            ; BH has insert/delete code
  6366.     mov    dx,cursor        ; logical cursor
  6367.     cmp    decrlm,0        ; host writing direction active?
  6368.     je    insdel11        ; e = no
  6369.     call    hldirection
  6370. insdel11:
  6371.     push    bx
  6372.     mov    bl,dh            ; row
  6373.     xor    bh,bh
  6374.     mov    bl,linetype[bx]
  6375.     mov    thisline,bl
  6376.     or    bl,bl            ; single width line?
  6377.     pop    bx
  6378.     jz    insdel1            ; z = yes
  6379.     add    dl,dl            ; double the cursor column
  6380.     add    cx,cx            ; double repeat count
  6381.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6382.     jz    insdel1            ; z = no
  6383.     shl    mar_right,1        ; this one doubles the margins
  6384. insdel1:mov    bl,mar_right
  6385.     inc    bl            ; number of screen columns
  6386.     sub    bl,dl            ; width - cursor
  6387.     cmp    cl,bl            ; skipping more than screen width?
  6388.     jbe    insdel2            ; be = no
  6389.     mov    cl,bl            ; limit to screen width please
  6390. insdel2:
  6391. ; dh=logical cursor row, dl= logical cursor column, cx has repeat count
  6392. ; bl = logical screen width - 1, bh = +1 for insert, -1 for delete chars.
  6393.     mov    bl,cl            ; offset
  6394.     xor    ch,ch
  6395.     or    bh,bh            ; ins or del?
  6396.     jl    insdel5            ; l = delete
  6397.                     ; Insert processor
  6398.     mov    cl,mar_right        ; right margin
  6399.     sub    cl,dl            ; minus cursor location
  6400.     mov    dl,mar_right        ; start at right margin
  6401.     jcxz    insdel7            ; z = nothing to do
  6402. insdel4:push    cx
  6403.     push    dx
  6404.     sub    dl,bl            ; back up by offset
  6405.     call    hldirection
  6406.     call    getatch            ; read char from vscreen
  6407.     pop    dx
  6408.     push    dx
  6409.     call    hldirection
  6410.     call    qsetatch        ; write it farther to the right
  6411.     pop    dx
  6412.     pop    cx
  6413.     dec    dl            ; backup one column
  6414.     loop    insdel4
  6415.     jmp    short insdel7
  6416.                       ; Delete processor
  6417. insdel5:mov    cl,mar_right        ; right margin
  6418.     sub    cl,dl            ; minus starting position
  6419.     sub    cl,bl            ; minus displacement (num deletes)
  6420.     inc    cl            ; count column 0
  6421. insdel6:push    cx
  6422.     push    dx
  6423.     add    dl,bl            ; look to right
  6424.     call    hldirection
  6425.     call    getatch            ; read char from vscreen
  6426.     pop    dx
  6427.     push    dx
  6428.     call    hldirection
  6429.     call    qsetatch        ; write it farther to the left
  6430.     pop    dx
  6431.     pop    cx
  6432.     inc    dl            ; next column
  6433.     loop    insdel6
  6434.  
  6435. insdel7:mov    cl,bl            ; fill count
  6436.     xor    ch,ch
  6437.     jcxz    insdel9            ; z = empty
  6438.     mov    ah,scbattr        ; get fill
  6439.     mov    al,' '
  6440. insdel8:push    cx
  6441.     xor    cl,cl            ; extended attributes
  6442.     push    dx
  6443.     call    hldirection
  6444.     call    qsetatch        ; write new char
  6445.     pop    dx
  6446.     inc    dl            ; next column
  6447.     pop    cx
  6448.     loop    insdel8
  6449.  
  6450. insdel9:mov    dx,cursor        ; logical cursor again
  6451.     push    cursor
  6452.     cmp    thisline,0        ; is line already single width?
  6453.     je    insde10            ; e = yes
  6454.     add    dl,dl            ; move to double char cell
  6455.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  6456.     jz    insde10            ; z = no
  6457.     shr    mar_right,1        ; this one doubles the margins
  6458. insde10:call    atsetcur        ; set it to current char
  6459.     mov    dl,dh            ; rows to update
  6460.     call    touchup
  6461.     pop    cursor
  6462.     mov    dx,cursor        ; in case we are called indirectly
  6463.     ret
  6464. insdel    endp
  6465.  
  6466. noins:    mov    insmod,0        ; turn off insert mode
  6467.     ret
  6468.  
  6469. entins:    mov    insmod,0ffh        ; enter insert mode
  6470.     ret
  6471.  
  6472. ; Line type to/from single or double
  6473. linesgl    proc    near            ; convert line to single width char
  6474.     push    ax
  6475.     push    bx
  6476.     push    cx
  6477.     push    dx
  6478.     mov    bx,dx            ; cursor
  6479.     mov    bl,bh
  6480.     xor    bh,bh            ; bx now holds row
  6481.     cmp    linetype [bx],0        ; is line already single width?
  6482.     je    linsglx            ; e = yes
  6483.     mov    linetype [bx],0        ; say will be single now
  6484.     mov    dh,byte ptr cursor+1    ; row
  6485.     xor    dl,dl            ; start in column 0
  6486.     mov    cl,mar_right        ; number of columns on screen - 1
  6487.     inc    cl
  6488.     shr    cl,1            ; number of columns to do
  6489.     xor    ch,ch
  6490.     push    cx            ; save around loop below
  6491. linsgl1:push    cx            ; save loop counter
  6492.     push    dx
  6493.     shl    dl,1            ; double column number
  6494.     call    direction        ; set dx to desired position
  6495.     call    getatch            ; read char (al) and attribute (ah)
  6496.     pop    dx            ; logical attribute to cl
  6497.     push    dx
  6498.     call    direction        ; set dx to desired position
  6499.     call    qsetatch        ; write char (al) and attribute (ah)
  6500.     pop    dx            ; and logical attribute is in cl
  6501.     inc    dl            ; next column
  6502.     pop    cx
  6503.     loop    linsgl1
  6504.     pop    cx            ; recover column counter
  6505.     mov    dl,cl
  6506. linsgl2:push    cx            ; save counter
  6507.     push    dx
  6508.     call    direction        ; set dx to desired position
  6509.     mov    ah,scbattr        ; screen background
  6510.     xor    cl,cl            ; extended attribute
  6511.     mov    al,' '
  6512.     call    qsetatch        ; write char
  6513.     pop    dx
  6514.     pop    cx
  6515.     inc    dl            ; next column
  6516.     loop    linsgl2            ; repeat for all characters
  6517.     mov    dl,dh            ; rows to touchup
  6518.     call    touchup
  6519. linsglx:pop    dx
  6520.     pop    cx
  6521.     pop    bx
  6522.     pop    ax
  6523.     push    cursor
  6524.     call    atsetcur        ; set visible cursor
  6525.     pop    cursor
  6526.     ret
  6527. linesgl    endp
  6528.  
  6529. linedbl    proc    near            ; convert line to double width char
  6530.     push    ax            ; must reset physical cursor
  6531.     push    bx            ; to same char as before expansion
  6532.     push    cx            ; but does not modify variable cursor
  6533.     push    dx
  6534.     mov    bx,dx            ; cursor
  6535.     mov    bl,bh
  6536.     xor    bh,bh            ; bx now holds row
  6537.     cmp    linetype [bx],0        ; is line single width?
  6538.     jne    lindblx            ; ne = no. nothing to do
  6539.     mov    linetype [bx],1        ; say will be double width now
  6540.     mov    cl,mar_right        ; number of columns on the screen - 1
  6541.     inc    cl
  6542.     xor    ch,ch
  6543.     shr    cl,1            ; number of items to do
  6544.     mov    dl,cl
  6545.     dec    dl
  6546. lindbl1:push    cx            ; save loop counter
  6547.     push    dx
  6548.     call    direction        ; set dx to desired position
  6549.     call    getatch            ; read char (al) and attribute (ah)
  6550.     pop    dx            ; extended attribute is in cl
  6551.     shl    dl,1            ; double the column number
  6552.     push    dx
  6553.     call    direction        ; set dx to desired position
  6554.     call    qsetatch        ; write char and attribute
  6555.     pop    dx
  6556.     inc    dl            ; move to second column of double
  6557.     push    dx
  6558.     call    direction        ; set dx to desired position
  6559.     mov    al,' '            ; space as filler
  6560.     call    qsetatch        ; write that char
  6561.     pop    dx
  6562.     dec    dl
  6563.     shr    dl,1
  6564.     dec    dl
  6565.     pop    cx
  6566.     loop    lindbl1
  6567.     mov    dl,dh            ; rows to touchup
  6568.     call    touchup
  6569. lindblx:pop    dx
  6570.     pop    cx
  6571.     pop    bx
  6572.     pop    ax
  6573.     push    cursor
  6574.     call    atsetcur        ; set visible cursor
  6575.     pop    cursor
  6576.     ret
  6577. linedbl    endp
  6578.  
  6579. ; Printer support routines
  6580. ansprt    proc near
  6581.     mov    di,offset ansprt0    ; routine to process arguments
  6582.     call    atreps            ; repeat for all parms
  6583.     ret
  6584.  
  6585. ansprt0:mov    ax,param[si]        ; pick up the argument
  6586.     or    ax,ax            ; 0 (print all/part of screen)?
  6587.     jnz    ansprt1            ; nz = no
  6588.     cmp    ninter,0        ; unwanted intermediates?
  6589.     jne    anspr4a            ; ne = got one, illegal here
  6590.     call    fpntchk            ; check printer
  6591.     call    pntext            ; do whole screen or scrolling extent
  6592.     jmp    atsetcur        ; reposition cursor and return
  6593.  
  6594. ansprt1:cmp    ax,1            ; 1 (print current line)?
  6595.     jne    ansprt4            ; ne = no
  6596.     call    fpntchk            ; check for printer ready
  6597.     call    pntlin            ; print current line
  6598.     mov    al,LF
  6599.     call    fpntchr
  6600.     call    fpntflsh        ; flush printer buffer
  6601.     jmp    atsetcur        ; reposition cursor and return
  6602.  
  6603. ansprt4:cmp    ax,4            ; 4 (auto print disable)?
  6604.     jne    ansprt5            ; ne = no
  6605.     cmp    lparam,'?'        ; was it ESC [ ? 4 i
  6606.     jne    anspr4a            ; ne = no, so it was ESC [ 4 i
  6607.     test    anspflg,vtautop        ; check state of print flag
  6608.     jz    anspr4a            ; z = off already
  6609.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  6610.     call    ftrnprs            ; toggle mode line PRN indicator
  6611. anspr4a:ret
  6612.  
  6613. ansprt5:cmp    ax,5            ; 5 (auto print enable)?
  6614.     jne    ansprtx            ; ne = no
  6615.     call    fpntchk            ; check printer, ignore carry ret
  6616.     cmp    lparam,'?'        ; was it ESC [ ? 5 i
  6617.     jne    anspr5a            ; ne = no
  6618.     test    anspflg,vtautop        ; is print already enabled?
  6619.     jnz    ansprtx            ; nz = yes, leave trnprs intact
  6620.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  6621.     call    ftrnprs            ; toggle on mode line PRN indicator
  6622.     ret
  6623. anspr5a:test    anspflg,vtcntp        ; controller print already enabled?
  6624.     jnz    ansprtx            ; nz = yes
  6625.     mov    emubufc,0        ; clear string buffer
  6626.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  6627.     call    ftrnprs            ; toggle on mode line PRN indicator
  6628.     jc    ansprtx            ; c = printer not ready failure
  6629.     or    anspflg,vtcntp        ; controller print enabled
  6630.     mov    ttstate,offset ansmc    ; do transparent print
  6631. ansprtx:ret
  6632. ansprt    endp
  6633.  
  6634. ; State machine active while Media Copy On (Print Controller ON). Copies all
  6635. ; chars to the printer until and excluding Media Copy Off (ESC [ 4 i) or a
  6636. ; repeated Media Copy On (ESC [ 5 i) has been received or the emulator reset.
  6637. ; New char is in al.
  6638. ansmc    proc    near
  6639.     mov    ttstate,offset ansmc    ; stay in this state
  6640.     cmp    al,ESCAPE        ; start a new sequence?
  6641.     je    ansmc1            ; e = yes
  6642.     cmp    al,CSI            ; start a new sequence?
  6643.     je    ansmc0a            ; e = yes
  6644.     mov    emubufc,0        ; say no matched chars
  6645.     call    fpntchr            ; print char in al, ignore errors
  6646.     ret
  6647.                     ; CSI seen
  6648. ansmc0a:call    ansmc5            ; playback previous matches
  6649.     call    atpclr            ; clear parser
  6650.     mov    pardone,offset ansmc4    ; where to go when done
  6651.     mov    parfail,offset ansmc5    ; where to go when fail, playback
  6652.     mov    ttstate,offset ansmc3    ; get numeric arg
  6653.     mov    emubuf,CSI        ; stuff CSI
  6654.     mov    emubufc,1
  6655.     ret
  6656.                     ; Escape seen
  6657. ansmc1:    call    ansmc5            ; playback previous matches
  6658.     mov    ttstate,offset ansmc2    ; get left square bracket
  6659.     mov    emubufc,1        ; one char matched
  6660.     mov    emubuf,al        ; store it
  6661.     ret
  6662.  
  6663. ansmc2:    cmp    al,'['            ; left square bracket?
  6664.     je    ansmc2a            ; e = yes
  6665.     cmp    al,ESCAPE        ; ESC?
  6666.     je    ansmc1            ; e = yes, start over
  6667.     cmp    al,CSI            ; CSI?
  6668.     je    ansmc0a            ; e = yes, start over
  6669.     call    ansmc5            ; playback previous matches
  6670.     call    fpntchr            ; print char in al, ignore errors
  6671.     ret
  6672.  
  6673. ansmc2a:inc    emubufc            ; say matched "ESC ["
  6674.     mov    emubuf+1,al        ; store left square brace
  6675.     call    atpclr            ; clear parser
  6676.     mov    pardone,offset ansmc4    ; where to go when done
  6677.     mov    parfail,offset ansmc4c    ; where to go when fail, playback
  6678.     mov    ttstate,offset ansmc3    ; get numeric arg
  6679.     ret
  6680.                     ; CSI or ESC [ seen
  6681. ansmc3:    cmp    al,ESCAPE        ; ESC?
  6682.     je    ansmc1            ; e = yes, start over
  6683.     cmp    al,CSI            ; CSI?
  6684.     je    ansmc0a            ; e = yes, start over
  6685.     inc    emubufc            ; another char
  6686.     mov    bx,emubufc        ; qty stored
  6687.     mov    emubuf[bx-1],al        ; store it
  6688.     mov    ah,al            ; check for C0 and C1 controls
  6689.     and    ah,not 80h
  6690.     cmp    ah,20h            ; control range?
  6691.     jb    ansmc5            ; b = yes, mismatch, playback
  6692.     jmp    atparse            ; parse control sequence
  6693.                     ; parse succeeded, al has Final char
  6694. ansmc4:    cmp    al,'i'            ; correct Final char?
  6695.     jne    ansmc5            ; ne = no, playback previous matches
  6696.     cmp    lparam,0        ; missing letter parameter?
  6697.     jne    ansmc5            ; ne = no, mismatch
  6698.     cmp    ninter,0        ; missing intermediates?
  6699.     jne    ansmc5            ; ne = no, mismatch
  6700.     mov    cx,nparam        ; number of parameters
  6701.     xor    bx,bx            ; subscript
  6702. ansmc4a:mov    ax,param[bx]
  6703.     add    bx,2            ; next param
  6704.     cmp    ax,4            ; CSI 4 i  MC OFF?
  6705.     je    ansmc4b            ; e = yes, stop printing
  6706.     loop    ansmc4a            ; keep trying all parameters
  6707.     jmp    short ansmc7        ; forget this one, start over
  6708.  
  6709.                     ; Media OFF found
  6710. ansmc4b:mov    ttstate,offset atnrm    ; return to normal state
  6711.     call    fpntflsh        ; flush printer buffer
  6712.     test    anspflg,vtcntp        ; was printing active?
  6713.     jz    ansmc7            ; z = no
  6714.     and    anspflg,not vtcntp    ; yes, disable print controller
  6715.     call    ftrnprs            ; toggle mode line PRN indicator
  6716.     ret
  6717.                     ; atparse exited failure, char in AL
  6718. ansmc4c:cmp    al,ESCAPE        ; ESC?
  6719.     je    ansmc1            ; e = yes, start over
  6720.     cmp    al,CSI            ; CSI?
  6721.     je    ansmc0a            ; e = yes, start over, else playback
  6722.  
  6723.                     ; playback emubufc matched chars
  6724. ansmc5:    mov    cx,emubufc        ; matched char count
  6725.     jcxz    ansmc7            ; z = none
  6726.     push    ax            ; save current char in al
  6727.     push    si
  6728.     mov    si,offset emubuf    ; matched sequence, cx chars worth
  6729.     cld
  6730. ansmc6:    lodsb                ; get a char
  6731.     call    fpntchr            ; print it, ignore errors
  6732.     loop    ansmc6            ; do all matched chars
  6733.     pop    si
  6734.     pop    ax
  6735.     mov    emubufc,cx        ; clear this counter
  6736. ansmc7:    mov    ttstate,offset ansmc    ; reset state to the beginning
  6737.     ret
  6738. ansmc    endp
  6739.  
  6740. dgprt    proc    near            ; RS F ? <char>     DG Print routines
  6741.     mov    ttstate,offset dgprt1    ; get the <char>
  6742.     ret
  6743. dgprt1:    mov    ttstate,offset atnrm    ; reset state
  6744.     and    al,0fh
  6745.     cmp    al,0            ; Simulprint off?
  6746.     jne    dgprt2            ; ne = no
  6747.     mov    al,7            ; reform to be VT autoprint off
  6748.  
  6749. dgprt2:    cmp    al,1            ; Simulprint on?
  6750.     jne    dgprt3            ; ne = no
  6751.     mov    al,8            ; reform to be VT autoprint on
  6752.  
  6753. dgprt3:    cmp    al,3            ; Print Pass Through on?
  6754.     jne    dgprt4            ; ne = no
  6755. dgprt3a:                ; RS F `   alternative to RS F ? 3
  6756.     test    anspflg,vtcntp        ; controller print already enabled?
  6757.     jnz    dgprt7            ; nz = yes
  6758.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  6759.     or    anspflg,vtcntp        ; controller print enabled
  6760.     mov    emubufc,0        ; clear string buffer
  6761.     mov    ttstate,offset dgmc    ; do transparent print
  6762.     call    ftrnprs            ; toggle on mode line PRN indicator
  6763.     ret
  6764.  
  6765. dgprt4:    cmp    al,8            ; VT-style autoprint on?
  6766.     jne    dgprt5            ; ne = no
  6767.     call    fpntchk            ; check printer, ignore carry ret
  6768.     test    anspflg,vtautop        ; is print already enabled?
  6769.     jnz    dgprt7            ; nz = yes, leave trnprs intact
  6770.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  6771.     call    ftrnprs            ; toggle on mode line PRN indicator
  6772.     ret
  6773.  
  6774. dgprt5:    cmp    al,7            ; VT-style autoprint off?
  6775.     jne    dgprt6            ; ne = no
  6776.     test    anspflg,vtautop        ; check state of print flag
  6777.     jz    dgprt7            ; z = off already
  6778.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  6779.     call    ftrnprs            ; toggle mode line PRN indicator
  6780.     ret
  6781.  
  6782. dgprt6:    cmp    al,':'            ; Print Screen?
  6783.     jne    dgprt7            ; ne = no
  6784.     mov    ah,mar_bot        ; save margins
  6785.     mov    al,mar_top
  6786.     push    ax
  6787.     mov    mar_top,0        ; set to full screen height
  6788.     mov    al,byte ptr low_rgt+1    ; bottom text row
  6789.     mov    mar_bot,al
  6790.     push    cursor
  6791.     xor    dx,dx            ; cursor to home
  6792.     call    dgprtwn            ; print this window
  6793.     pop    cursor
  6794.     pop    ax
  6795.     mov    mar_top,al        ; restore margins
  6796.     mov    mar_bot,ah
  6797. dgprt7:    ret
  6798. dgprt    endp
  6799.  
  6800. dgppb    proc    near            ; RS F x <n> Printer Pass back to host
  6801.     mov    bx,offset dgppb1    ; call back routine
  6802.     jmp    get1n            ; setup consume one <n>
  6803. dgppb1:    mov    al,dgescape        ; send RS R x 0  cannot set
  6804.     call    prtbout            ; out, no echo
  6805.     mov    al,'R'
  6806.     call    prtbout
  6807.     mov    al,'x'
  6808.     call    prtbout
  6809.     mov    al,'0'            ; say cannot set NRC printer mode
  6810.     call    prtbout
  6811.     ret
  6812. dgppb    endp
  6813.  
  6814. ; State machine active while DG Simulprint is  On. Copies all chars to the 
  6815. ; printer until and excluding Simulprint Off (RS F ? 0) has been received 
  6816. ; or the emulator reset.
  6817. ; New char is in al.
  6818. dgmc    proc    near
  6819.     mov    ttstate,offset dgmc    ; stay in this state
  6820.     cmp    al,dgescape        ; start a new sequence?
  6821.     je    dgmc1            ; e = yes
  6822.     mov    emubufc,0        ; say no matched chars
  6823.     call    fpntchr            ; print char in al, ignore errors
  6824.     ret
  6825.                     ; RS seen
  6826. dgmc1:    call    ansmc5            ; playback previous matches
  6827.     mov    ttstate,offset dgmc2    ; get next char
  6828.     mov    emubufc,1        ; one char matched
  6829.     mov    emubuf,al        ; store it
  6830.     ret
  6831.  
  6832. dgmc2:    cmp    al,'F'            ; 'F' part of RS F ? 2
  6833.     jne    dgmc7            ; ne = no
  6834.     inc    emubufc            ; say matched "RS F"
  6835.     mov    emubuf+1,al        ; store it
  6836.     mov    ttstate,offset dgmc3    ; get query char
  6837.     ret
  6838.                     ; RS F seen
  6839. dgmc3:    cmp    al,'?'            ; 'F' part of RS F ? 2
  6840.     jne    dgmc4            ; ne = no
  6841.     inc    emubufc            ; say matched "RS F ?"
  6842.     mov    emubuf+1,al        ; store it
  6843.     mov    ttstate,offset dgmc5    ; get final char
  6844.     ret
  6845.  
  6846. dgmc4:    cmp    al,'a'            ; RS F a  alternative?
  6847.     jne    dgmc7            ; ne = no
  6848.     jmp    short dgmc8        ; finish up
  6849.  
  6850. dgmc5:    and    al,0fh
  6851.     cmp    al,2            ; RS F ? seen, correct final char?
  6852.     je    dgmc8            ; e = yes
  6853.     
  6854. dgmc7:    call    ansmc5            ; playback previous matches
  6855.     call    fpntchr            ; print char in al, ignore errors
  6856.     mov    ttstate,offset dgmc    ; start over
  6857.     ret
  6858.  
  6859. dgmc8:    mov    ttstate,offset atnrm    ; return to normal state
  6860.     call    fpntflsh        ; flush printer buffer
  6861.     test    anspflg,vtcntp        ; was printing active?
  6862.     jz    dgmc9            ; z = no
  6863.     and    anspflg,not vtcntp    ; yes, disable print controller
  6864.     mov    al,6            ; send Control-F to host
  6865.     call    prtbout            ; output, no echo
  6866.     call    ftrnprs            ; toggle mode line PRN indicator
  6867. dgmc9:    ret
  6868. dgmc    endp
  6869.  
  6870. pntlin    proc    near            ; print whole line given by dx
  6871.     push    ax
  6872.     push    bx
  6873.     push    cx
  6874.     push    dx
  6875.     xor    ch,ch
  6876.     mov    cl,mar_right        ; number of columns - 1
  6877.     mov    dl,cl            ; Bios column counter, dh = row
  6878.     inc    cl            ; actual line length, count it down
  6879.     test    vtemu.vtflgop,vswdir    ; writing right to left?
  6880.     jnz    pntlin2            ; nz = yes, do not trim spaces
  6881.     cmp    decrlm,0        ; host writing direction active?
  6882.     jne    pntlin2            ; ne = yes
  6883. pntlin1:push    cx
  6884.     call    getatch            ; read char (al) and attribute (ah)
  6885.     pop    cx            ;  and extended bit pair to cl
  6886.     cmp    al,' '            ; is this a space?
  6887.     jne    pntlin2            ; no, we have the end of the line
  6888.     dec    dl            ; else move left one column
  6889.     loop    pntlin1            ; and keep looking for non-space
  6890.  
  6891. pntlin2:jcxz    pntlin4            ; z = empty line
  6892.     xor    dl,dl            ; start in column 0, do cl chars
  6893. pntlin3:push    cx
  6894.     call    getatch            ; read char (al) and attribute (ah)
  6895.     pop    cx
  6896.     inc    dl            ; inc to next column
  6897.     call    fpntchr            ; print the char (in al)
  6898.     jc    pntlin5            ; c = printer error
  6899.     loop    pntlin3            ; do cx columns
  6900. pntlin4:mov    al,cr            ; add trailing cr for printer
  6901.     call    fpntchr
  6902. pntlin5:pop    dx
  6903.     pop    cx
  6904.     pop    bx
  6905.     pop    ax
  6906.     ret                ; C bit controlled by pntchr
  6907. pntlin    endp
  6908.  
  6909. pntext    proc    near            ; print an extent of lines, depending
  6910.     push    ax            ; on flag bit vtextp
  6911.     push    bx
  6912.     push    dx
  6913.     xor    dx,dx            ; assume starting at top left
  6914.     mov    bx,low_rgt        ;  and extending to lower right
  6915.     test    anspflg,vtextp        ; full screen wanted?
  6916.     jnz    pntext1            ; nz = yes, else scrolling region
  6917.     mov    dh,mar_top        ; top of scrolling region
  6918.     mov    bh,mar_bot        ; bottom of scrolling region
  6919. pntext1:call    pntlin            ; print a line
  6920.     jc    pntext2            ; c = printer error
  6921.     mov    al,LF
  6922.     call    fpntchr
  6923.     jc    pntext2
  6924.     inc    dh
  6925.     cmp    dh,bh            ; done all requested lines?
  6926.     jbe    pntext1            ; be = not yet, do another
  6927.     test    anspflg,vtffp        ; form feed needed at end?
  6928.     jz    pntext2            ; z = no
  6929.     mov    al,ff
  6930.     call    fpntchr            ; print the form feed char
  6931. pntext2:pop    dx
  6932.     pop    bx
  6933.     pop    ax
  6934.     ret
  6935. pntext    endp
  6936.  
  6937. ; Set cursor coordinate DL (row) with consideration for writing direction.
  6938. ; Active only under local writing direction control
  6939. direction proc    near
  6940.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  6941.     jz    direct1            ; z = yes, no changes needed
  6942.     sub    dl,mar_right        ; right margin column number
  6943.     neg    dl            ; make a positive value again
  6944. direct1:ret
  6945. direction endp
  6946.  
  6947. ; Like direction, but functions if host writing direction decrlm is active
  6948. ; as well as local control
  6949. hldirection proc near
  6950.     cmp    decrlm,0        ; host mode inactive?
  6951.     jne    hldirect1        ; ne = no, obey
  6952.     test    vtemu.vtflgop,vswdir    ; writing left to right?
  6953.     jz    hldirect2        ; z = yes, no changes needed
  6954. hldirect1:sub    dl,mar_right        ; right margin column number
  6955.     neg    dl            ; make a positive value again
  6956. hldirect2:ret
  6957. hldirection endp
  6958.  
  6959. ; Erase from cursor (DX, inclusive) to end of screen
  6960. ; sense double width/height
  6961. ereos    proc    near
  6962.     mov    ax,dx            ; erase from cursor to end of screen
  6963.     or    dx,dx            ; cursor at home position?
  6964.     jnz    ereos1            ; nz = no
  6965.                     ; e = yes, roll screen before clear
  6966.     push    word ptr mar_top
  6967.     mov    al,byte ptr low_rgt+1    ; bottom row number
  6968.     mov    mar_bot,al
  6969.     mov    mar_top,dh        ; row of cursor
  6970.     inc    al            ; number of lines to scroll
  6971.     mov    scroll,al
  6972.     call    atscru            ; scroll them up before erasure
  6973.     pop    word ptr mar_top
  6974.                     ; removes double w/h lines too
  6975.     xor    ax,ax            ; erase from here (home)
  6976.     mov    bx,low_rgt        ; bh = bottom row number
  6977.     mov    cl,scbattr
  6978.     mov    ch,curattr
  6979.     push    cx
  6980.     cmp     vtclrflg,0        ; use scbattr?
  6981.     je    ereos0a            ; e = yes
  6982.     mov    scbattr,ch        ; use curattr
  6983. ereos0a:call    vtsclr            ; clear screen
  6984.     pop    cx
  6985.     mov    scbattr,cl        ; restore scbattr
  6986.     ret
  6987. ereos1:    push    dx            ; save dx
  6988.     mov    bl,dh            ; get row number
  6989.     xor    bh,bh
  6990.     cmp    linetype [bx],0        ; single width line?
  6991.     je    ereos2            ; e = yes
  6992.     shl    dl,1            ; physical column is twice logical
  6993. ereos2:    or    dl,dl            ; starting at left margin?
  6994.     je    ereos3            ; e = yes, this goes to single width
  6995.     inc    bl            ; else start on next line
  6996. ereos3:    cmp    bl,byte ptr low_rgt+1    ; at the end of the screen?
  6997.     ja    ereos4            ; a = yes, stop singling-up
  6998.     mov    byte ptr linetype [bx],0 ; set to single width
  6999.     inc    bx
  7000.     jmp    short ereos3        ; loop, reset lines to end of screen
  7001. ereos4:    mov    ax,dx            ; cursor
  7002.     pop    dx
  7003.     mov    bx,low_rgt        ; erase from cursor to end of screen
  7004.     cmp    dh,bh            ; on status line?
  7005.     jbe    ereos5            ; be = no
  7006.     mov    bh,dh            ; use status line
  7007. ereos5:    mov    cl,scbattr
  7008.     mov    ch,curattr
  7009.     push    cx
  7010.     cmp     vtclrflg,0        ; use scbattr?
  7011.     je    ereos5a            ; e = yes
  7012.     mov    scbattr,ch        ; use curattr
  7013. ereos5a:call    vtsclr            ; clear it
  7014.     pop    cx
  7015.     mov    scbattr,cl        ; restore scbattr
  7016.     ret
  7017. ereos    endp
  7018.  
  7019. ; Erase from start of screen to cursor (inclusive), sense double width/height
  7020. ersos    proc    near
  7021.     xor    ax,ax            ; erase from start of screen
  7022.                     ;  to cursor, inclusive
  7023.     xor    bx,bx            ; start at top row (0)
  7024. ersos1:    cmp    bl,dh            ; check rows from the top down
  7025.     jae    ersos2            ; ae = at or below current line
  7026.     mov    byte ptr linetype [bx],0; set line to single width
  7027.     inc    bx            ; inc row
  7028.     jmp    short ersos1        ; look at next line
  7029. ersos2:    or    dl,dl            ; at left margin of current line?
  7030.     jne    ersos3            ; ne = no, leave line width intact
  7031.     mov    byte ptr linetype [bx],0 ; convert to single width    
  7032. ersos3:    mov    bl,dh            ; get row number
  7033.     xor    bh,bh
  7034.     cmp    linetype [bx],0        ; single width line?
  7035.     je    ersos4            ; e = yes
  7036.     shl    dl,1            ; physical column is twice logical
  7037. ersos4:    mov    bx,dx            ; cursor position to bx
  7038.     mov    cl,scbattr
  7039.     mov    ch,curattr
  7040.     push    cx
  7041.     cmp     vtclrflg,0        ; use scbattr?
  7042.     je    ersos5            ; e = yes
  7043.     mov    scbattr,ch        ; use curattr
  7044. ersos5:    call    vtsclr            ; clear it
  7045.     pop    cx
  7046.     mov    scbattr,cl        ; restore scbattr
  7047.     ret
  7048. ersos    endp
  7049.  
  7050. ; Erase in line, from column AL to column BL, in row DH
  7051. erinline proc    near
  7052.     mov    ah,dh            ; set row
  7053.     mov    bh,dh
  7054.     mov    cl,byte ptr low_rgt    ; screen width
  7055.     push    bx
  7056.     mov    bl,dh            ; get row
  7057.     xor    bh,bh
  7058.     cmp    linetype [bx],0        ; single width line?
  7059.     pop    bx            ; pop does not affect flags
  7060.     pushf                ; save a copy of the flags for al
  7061.     je    erinli1            ; e = yes
  7062.     shl    bl,1            ; physical column is twice logical
  7063.     jc    erinli2            ; c = overflow
  7064. erinli1:cmp    bl,cl            ; wider than the physical screen?
  7065.     jb    erinli3            ; b = no, not wider than screen
  7066. erinli2:mov    bl,cl            ; physical width
  7067. erinli3:popf                ; recover copy of flags
  7068.     je    erinli4            ; e = single width line
  7069.     shl    al,1
  7070.     jc    erinli5
  7071. erinli4:cmp    al,cl
  7072.     jb    erinli6
  7073. erinli5:mov    al,cl
  7074. erinli6:mov    cl,scbattr
  7075.     mov    ch,curattr
  7076.     push    cx
  7077.     cmp     vtclrflg,0        ; use scbattr?
  7078.     je    erinli7            ; e = yes
  7079.     mov    scbattr,ch        ; use curattr
  7080. erinli7:call    vtsclr            ; clear it
  7081.     pop    cx
  7082.     mov    scbattr,cl        ; restore scbattr
  7083.     ret
  7084. erinline endp
  7085.  
  7086. ; General erasure command which skips over protected chars.
  7087. ; Preset margins and cursor to obtain all three erasure kinds.
  7088. erprot    proc    near            ; erase cursor to end of region
  7089.     mov    cursor,dx        ; preserve cursor
  7090. erprot1:push    dx
  7091.     call    direction
  7092.     call    getatch            ; read a char, get attributes
  7093.     pop    dx
  7094.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7095.     jz    erprot6            ; z = no
  7096.     cmp    protectena,0        ; is protected mode enabled?
  7097.     je    erprot4            ; e = no, erase all
  7098. erprot6:test    cl,att_protect        ; protected?
  7099.     jnz    erprot2            ; nz = yes, retain it
  7100. erprot4:xor    cl,cl            ; clear extended attributes
  7101.     mov    ah,scbattr        ; background attributes
  7102.     cmp     vtclrflg,0        ; use scbattr?
  7103.     je    eprot5            ; e = yes
  7104.     mov    ah,curattr        ; use current colors
  7105. eprot5:    mov    al,' '
  7106.     push    dx
  7107.     call    direction
  7108.     call    qsetatch        ; quietly update char
  7109.     pop    dx
  7110. erprot2:inc    dl            ; next column
  7111.     cmp    dl,mar_right        ; did right margin?
  7112.     jbe    erprot1            ; be = no
  7113.     mov    dl,mar_left        ; rest to left margin
  7114.     inc    dh            ; next line down
  7115.     cmp    dh,mar_bot        ; did the last row?
  7116.     jbe    erprot1            ; be = no
  7117. erprot3:mov    dl,byte ptr cursor+1    ; starting line, dh is ending line
  7118.     mov    dh,mar_bot
  7119.     call    touchup            ; repaint part of screen
  7120.     mov    dx,cursor
  7121.     ret
  7122. erprot    endp
  7123.  
  7124. ; Clear screen from AX to BX, where AH = row, AL = column, ditto for BX.
  7125. ; This routine accomodates right to left writing. BX >= AX.
  7126. vtsclr    proc    near
  7127.     cmp    ax,bx            ; proper order?
  7128.     jbe    vtsclr7            ; be = yes
  7129.     xchg    ax,bx            ; reverse
  7130. vtsclr7:test    vtemu.vtflgop,vswdir    ; writing left to right?
  7131.     jz    vtsclr4            ; z = yes
  7132.     cmp    bh,ah            ; same row?
  7133.     je    vtsclr2            ; e = yes
  7134.     push    ax            ; multiple lines
  7135.     push    bx            ; save both coordinates
  7136.     mov    bl,mar_right
  7137.     mov    bh,ah            ; pick just top line
  7138.     call    vtsclr2            ; delete fraction of top line
  7139.     pop    bx            ; recover ending position
  7140.     push    bx
  7141.     inc    ah            ; omit top row, now done
  7142.     dec    bh            ; omit last line, could be fractional
  7143.     cmp    bh,ah            ; any whole lines remaining to delete?
  7144.     jb    vtsclr1            ; b = no, finish up
  7145.     mov    bl,mar_right        ; get right most physical column
  7146.     xor    al,al            ; to end of line (on left)
  7147.     call    atsclr            ; clear top line and whole remainders
  7148. vtsclr1:pop    bx            ; setup for last line to be cleared
  7149.     push    bx            ; get last row again
  7150.     xor    al,al            ; start at logical left margin
  7151.     jmp    short vtsclr3        ; ax and bx are already pushed
  7152.  
  7153. vtsclr2:push    ax            ; erase single line, whole or part
  7154.     push    bx
  7155. vtsclr3:mov    ah,mar_right        ; borrow reg ah (same as bh)
  7156.     sub    ah,bl            ; reflect right to left
  7157.     mov    bl,ah
  7158.     or    bl,bl            ; overflow?
  7159.     jns    vtsclr5            ; ns = no, is ok
  7160.     xor    bl,bl            ; limit to logical screen
  7161. vtsclr5:mov    ah,mar_right
  7162.     sub    ah,al
  7163.     mov    al,ah
  7164.     jns    vtsclr6
  7165.     mov    al,mar_right        ; limit to logical screen
  7166. vtsclr6:mov    ah,bh            ; restore ah
  7167.     xchg    al,bl            ; reverse to get physical ax < bx
  7168.     call    atsclr            ; erase part/all of single line
  7169.     pop    bx
  7170.     pop    ax
  7171.     ret
  7172.                     ; for writing left to right
  7173. vtsclr4:jmp    atsclr            ; do normal erasure and return
  7174. vtsclr    endp
  7175.  
  7176. ; routines supporting scrolling and double width/height chars
  7177. ; scroll has number of lines to scroll
  7178. atscru    proc    near            ; scroll screen up one line
  7179.     test    vtemu.vtflg,ttwyse    ; Wyse-50?
  7180.     jz    atscru9            ; z = no
  7181.     cmp    wyse_scroll,0        ; ok to scroll?
  7182.     je    atscru9            ; e = yes
  7183.     ret
  7184. atscru9:push    ax            ; assumes dx holds cursor position
  7185.     push    bx            ; returns with dx = old row, new col
  7186.     push    cx
  7187.     push    si
  7188.     xor    bh,bh
  7189.     mov    bl,mar_top        ; top line to move
  7190.     xor    ch,ch
  7191.     mov    cl,scroll        ; number of lines to move
  7192.     mov    al,mar_bot        ; bottom line to scroll
  7193.     sub    al,bl            ; number of lines minus 1
  7194.     inc    al            ; number of lines
  7195.     cmp    al,cl            ; scrolling region smaller than scroll?
  7196.     jge    atscru1            ; ge = no, is ok
  7197.     mov    scroll,al        ; limit to region
  7198.     cmp    al,1            ; at least one line to scroll?
  7199.     jge    atscru1            ; ge = yes
  7200.     mov    scroll,1        ; no, force one
  7201. atscru1:mov    al,scroll
  7202.     mov    ah,byte ptr low_rgt+1    ; last text line on screen
  7203.     inc    ah            ; number of screen lines
  7204.     cmp    al,ah            ; exceeds number of lines on screen?
  7205.     jbe    atscru8            ; be = scrolling not more than that
  7206.     mov    al,ah            ; limit to screen length
  7207.     mov    scroll,al
  7208. atscru8:xor    ah,ah
  7209.     mov    si,ax            ; scroll interval
  7210.     mov    bl,mar_top
  7211.     mov    cl,mar_bot
  7212.     sub    cl,bl
  7213.     inc    cl            ; number  of lines in region
  7214.     sub    cl,scroll        ; cx = those needing movement
  7215.     cmp    cl,0
  7216.     jle    atscru3
  7217. atscru2:mov    al,linetype[bx+si]    ; get old type
  7218.     mov    linetype[bx],al        ; copy to new higher position
  7219.     mov    al,linescroll[bx+si]    ; get horizontal scroll value
  7220.     mov    linescroll[bx],al    ; copy too
  7221.     inc    bx
  7222.     loop    atscru2
  7223. atscru3:mov    bl,mar_bot        ; set fresh lines to single attribute
  7224.     mov    cl,scroll        ; number of fresh lines (qty scrolled)
  7225.     xor    ch,ch
  7226. atscru4:mov    linetype[bx],0
  7227.     mov    linescroll[bx],0
  7228.     dec    bx
  7229.     loop    atscru4            ; clear old bottom lines
  7230.     mov    bl,dh            ; get row of cursor
  7231.     xor    bh,bh
  7232.     cmp    linetype[bx],0        ; single width?
  7233.     je    atscru5            ; e = yes
  7234.     shr    dl,1            ; reindex to single width columns
  7235. atscru5:pop    si
  7236.     pop    cx
  7237.     pop    bx
  7238.     pop    ax
  7239.     test    anspflg,vtcntp        ; controller print active?
  7240.     jz    atscru6            ; z = no, ok to change screen
  7241.     ret                ;  else keep screen intact
  7242. atscru6:jmp    vtscru            ; call & ret the msy scroll routine
  7243. atscru    endp
  7244.  
  7245. atscrd    proc    near            ; scroll screen down scroll lines
  7246.     test    vtemu.vtflg,ttwyse    ; Wyse-50?
  7247.     jz    atscrd7            ; z = no
  7248.     cmp    wyse_scroll,0        ; ok to scroll?
  7249.     je    atscrd7            ; e = yes
  7250.     ret
  7251. atscrd7:push    ax            ; assumes dx holds cursor position
  7252.     push    bx            ; returns with dx = old row, new col
  7253.     push    cx
  7254.     push    si
  7255.     xor    ch,ch
  7256.     mov    cl,scroll        ; number of lines to scroll
  7257.     xor    bh,bh
  7258.     mov    bl,mar_bot        ; bottom line to move
  7259.     mov    al,bl
  7260.     xor    ah,ah
  7261.     sub    al,mar_top        ; number of lines minus 1
  7262.     inc    al            ; number of lines
  7263.     cmp    al,cl            ; scrolling region smaller than scroll?
  7264.     jge    atscrd1            ; ge = no, is ok
  7265.     mov    scroll,al        ; limit to region
  7266.     cmp    al,1            ; at least one line to scroll?
  7267.     jge    atscrd1            ; ge = yes
  7268.     mov    scroll,1        ; no, force one
  7269. atscrd1:mov    al,scroll
  7270.     mov    si,ax            ; si = scroll
  7271.     mov    bl,dh            ; get row of cursor
  7272.     xor    bh,bh            ; make into an index
  7273.     sub    bl,scroll        ; si + this bx will be new bottom line
  7274.     mov    cl,bl
  7275.     sub    cl,mar_top
  7276.     inc    cl
  7277.     cmp    cl,0
  7278.     jle    atscrd3
  7279. atscrd2:mov    al,linetype[bx]        ; get old line's type
  7280.     mov    linetype[bx+si],al    ; copy to new lower position
  7281.     mov    al,linescroll[bx]    ; get per line horizontal scroll
  7282.     mov    linescroll[bx+si],al    ; copy too
  7283.     dec    bx
  7284.     loop    atscrd2
  7285. atscrd3:mov    bl,mar_top        ; start with this line
  7286.     xor    bh,bh
  7287.     mov    cl,scroll        ; number of lines scrolled
  7288.     xor    ch,ch
  7289. atscrd4:mov    linetype[bx],0        ; clear new top lines
  7290.     mov    linescroll[bx],0
  7291.     inc    bx
  7292.     loop    atscrd4
  7293.     mov    bl,dh            ; get row of cursor
  7294.     xor    bh,bh
  7295.     cmp    linetype[bx],0        ; single width?
  7296.     je    atscrd5            ; e = yes
  7297.     shr    dl,1            ; reindex to single width columns
  7298. atscrd5:pop    si
  7299.     pop    cx
  7300.     pop    bx
  7301.     pop    ax
  7302.     test    anspflg,vtcntp        ; controller print active?
  7303.     jz    atscrd6            ; z = no, ok to change screen
  7304.     ret                ;  else keep screen intact
  7305. atscrd6:jmp    vtscrd            ; call & ret the msy scroll routine
  7306. atscrd    endp
  7307.  
  7308. ; Returns carry set if column in DL is a tab stop, else carry clear.
  7309. ; Enter with column number in DL (starts at column 0, max of swidth-1)
  7310. ; and tabstop buffer offset in SI.
  7311. istabs    proc    near
  7312.     push    bx
  7313.     push    cx
  7314.     mov    cl,dl            ; column number (0 to swidth-1)
  7315.     and    cl,00000111b        ; keep bit in byte (0-7)
  7316.     inc    cl            ; map to 1-8
  7317.     mov    bl,dl            ; column
  7318.     shr    bl,1            ; bl / 8 to get byte
  7319.     shr    bl,1
  7320.     shr    bl,1
  7321.     xor    bh,bh            ; clear high byte
  7322.     mov    bl,[si+bx]        ; get a byte of tab bits
  7323.     ror    bl,cl            ; rotate to put tab-set bit into carry
  7324.     pop    cx
  7325.     pop    bx
  7326.     ret
  7327. istabs    endp
  7328.  
  7329. ; Modify (set/clear) a tabstop. Enter with DL holding column (0 to swidth-1)
  7330. ; Set a tabstop into buffer pointed at by SI.
  7331. tabset    proc    near
  7332.     mov    modeset,1        ; set a tabstop
  7333.     jmp    short modtabs
  7334. tabset    endp
  7335.  
  7336. ; Clear a tabstop
  7337. tabclr    proc    near
  7338.     mov    modeset,0        ; clear a tabstop
  7339.     jmp    short modtabs
  7340. tabclr    endp
  7341.  
  7342. ; Worker for set/clear tabstop, si has pointer to tabstops array
  7343. modtabs:push    bx
  7344.     push    cx
  7345.     mov    cl,dl            ; column number (0 to swidth-1)
  7346.     and    cl,00000111b        ; keep bit in byte (0-7)
  7347.     mov    ch,1            ; tab bit to change
  7348.     shl    ch,cl            ; shift to bit-in-byte position
  7349.     mov    bl,dl            ; column
  7350.     shr    bl,1            ; bl / 8 to get byte
  7351.     shr    bl,1
  7352.     shr    bl,1
  7353.     xor    bh,bh            ; clear high byte
  7354.     mov    cl,[si+bx]        ; get byte of tabs bits
  7355.     not    ch            ; invert bit marker to create hole
  7356.     and    cl,ch            ; clear the tab bit
  7357.     not    ch            ; recover setting pattern
  7358.     cmp    modeset,0        ; clear the tab bit?
  7359.     jz    modtab1            ; z = yes
  7360.     or    cl,ch            ; set the tab bit
  7361. modtab1:mov    [si+bx],cl        ; store tab byte
  7362.     pop    cx
  7363.     pop    bx
  7364.     ret
  7365.  
  7366. ; This routine initializes the VT  setups at startup. It is called from
  7367. ; procedure lclyini in module msyibm.
  7368. vsinit    proc    near
  7369.     mov    vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
  7370.     mov    vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
  7371.     mov    savflgs,vsdefaults
  7372.     mov    iniflgs,vsdefaults
  7373.     xor    al,al
  7374.     mov    insmod,al        ; turn off insert mode
  7375.     mov    atinvisible,al
  7376.     xor    dl,dl            ; Column 1 has no tab stop
  7377.     mov    si,vtemu.vttbs        ; from the cold-start buffer
  7378.     call    tabclr            ; clear that tabstop
  7379.     push    es
  7380.     push    ds
  7381.     pop    es
  7382.     cld
  7383.     mov    al,1            ; set tabs at columns 9, spaced by 8
  7384.     mov    cx,(swidth-1)/8        ; bytes to do, at 8 bits/byte
  7385.     mov    di,offset deftabs+1    ; starting byte for column 9 (1...)
  7386.     rep    stosb
  7387.     xor    al,al            ; get a zero
  7388.     mov    cx,slen            ; clear linetype array
  7389.     mov    di,offset linetype
  7390.     rep    stosb
  7391.     mov    cx,slen
  7392.     mov    di,offset linescroll    ; clear horiz scroll per line
  7393.     rep    stosb
  7394.     pop    es
  7395.     mov    vtemu.vttbst,offset tabs ; addrs of active tabs for STATUS
  7396.     mov    vtemu.vttbs,offset deftabs  ; addrs of tabs for setup (SET)
  7397.     call    cpytabs            ; copy default to active
  7398.     mov    vtemu.att_ptr,offset att_normal  ; ptr to video attributes
  7399.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  7400.     sub    ah,8            ; place marker 9 columns from margin
  7401.     mov    belcol,ah        ; store column number to ring bell
  7402.         cmp     isps55,0                ; [HF]940221 Japanese PS/55?
  7403.         je      vsinix                  ; [HF]940221 e=no
  7404.         mov     vtemu.vtchset,C_JISKANJI ; [HF]940221 def = JIS-Kanji
  7405. vsinix: ret
  7406. vsinit    endp
  7407.  
  7408. ; Initialization routine.
  7409. ; Enter with dl = index for baud rate table
  7410. ; dh = parity in bits 4-7, number of data bits in bits 0-3
  7411. ansini    proc    near
  7412.     mov    ax,vtemu.vtflgst    ; setup flags
  7413.     mov    vtemu.vtflgop,ax
  7414.     mov    iniflgs,ax
  7415.     mov    savflgs,ax
  7416.     mov    ax,flags.vtflg        ; get current terminal type
  7417.     cmp    ax,tttek        ; non-text?
  7418.     je    ansin3            ; e = yes
  7419.     mov    oldterm,ax        ; remember it here for soft restarts
  7420. ansin3:    mov    anspflg,0        ; clear printing flag
  7421.     mov    al,byte ptr low_rgt    ; right most column (counted from 0)
  7422.     sub    al,8            ; place marker 9 columns from margin
  7423.     mov    belcol,al        ; store column number to ring bell
  7424.     cmp    dl,lbaudtab        ; out of range index?
  7425.     jb    ansin1            ; b = no, store it
  7426.     mov    dl,lbaudtab-2        ; yes, make it the maximum (128)
  7427. ansin1: mov    baudidx,dl        ; save baud rate index
  7428.     mov    al,dh            ; get parity/number of databits
  7429.     and    al,0FH            ; isolate number of databits
  7430.     mov    datbits,al        ; save
  7431.     mov    cl,4
  7432.     shr    dh,cl            ; isolate parity code
  7433.     cmp    dh,lpartab        ; out of range code?
  7434.     jb    ansin2            ; b = no, store it
  7435.     mov    dh,lpartab-1        ; make it the maximum
  7436. ansin2: mov    parcode,dh        ; save
  7437.     mov    cx,low_rgt
  7438.     mov    oldscrn,cx        ; remember old screen dimensions
  7439.     jmp    atreset            ; reset everything
  7440. ansini    endp
  7441.  
  7442. atxreset proc    near            ; Reset via host command
  7443.     cmp    nparam,0        ; need no Parameters, no Intermediates
  7444.     jne    atxres1            ; ne = not a reset
  7445.     cmp    ninter,0        ; any intermediates?
  7446.     je    atreset            ; e = none, it is a reset
  7447. atxres1:ret                ; ignore command
  7448. atxreset endp
  7449.  
  7450. atreset    proc    near            ; Reset-everything routine
  7451.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7452.     jnz    atres9            ; nz = yes
  7453. ifndef    no_graphics
  7454.     test    tekflg,tek_sg         ; special graphics active?
  7455.     jz    atres9            ; z = no
  7456.     call    tekend            ; exit special graphics
  7457. endif    ; no_graphics
  7458. atres9:    mov    ax,apcstring        ; seg of apcmacro memory area
  7459.     or    ax,ax            ; empty?
  7460.     jz    atres10            ; z = yes
  7461.     mov    es,ax
  7462.     mov    ah,freemem
  7463.     int    dos            ; free that memory
  7464. atres10:xor    ax,ax            ; get a zero
  7465.     mov    apcstring,ax
  7466.     mov    bracecount,al        ; APC-macro worker variables
  7467.     mov    cursor,ax        ; cursor is at 0,0
  7468.     mov    h19cur,ax        ; Heath-19 saved cursor
  7469.     mov    wyse_scroll,al        ; Wyse-50, no-scroll mode to off
  7470.     mov    decrlm,al        ; host writing direction to left-right
  7471.     mov    havesaved,al        ; unmark saved cursor section
  7472.     mov    atinvisible,al        ; clear invisible attribute
  7473.     mov    dspstate,al        ; saved modeline state
  7474.     mov    al,1            ; assume underline cursor
  7475.     test    vtemu.vtflgst,vscursor    ; kind of cursor in setup
  7476.     jnz    atres0            ; nz = underline
  7477.     inc    al            ; else say block
  7478. atres0:    mov    atctype,al        ; VTxxx cursor type
  7479.     call    udkclear        ; clear User Definable Key contents
  7480.     push    vtemu.vtflgst        ; setup flags
  7481.     pop    vtemu.vtflgop        ; operational flags
  7482.     and    vtemu.vtflgop,not vscntl ; assume no 8-bit controls
  7483.     mov    ax,oldterm        ; get terminal at entry time
  7484.     or    ax,ax            ; inited yet? (initing Tek too)
  7485.     jnz    atres0a            ; nz = yes
  7486.     mov    ax,ttvt320        ; pretend initing VT320
  7487.     jmp    short atres0b
  7488. atres0a:mov    flags.vtflg,ax        ; use it again
  7489. atres0b:test    ax,ttvt102+ttvt100+tthoney+ttpt200+ttansi ; VT100 class?
  7490.     jnz    atres1            ; nz = yes, turn on ansi mode
  7491.     test    ax,ttvt320+ttvt220    ; VT320/VT220?
  7492.     jz    atres1a            ; z = no, no ansi, no 8-bit controls
  7493.     test    vtemu.vtflgst,vscntl    ; want 8-bit controls?
  7494.     jz    atres1            ; z = no
  7495.     or    vtemu.vtflgop,vscntl    ; turn on 8-bit controls
  7496. atres1:    or    vtemu.vtflgop,decanm    ; turn on ANSI mode
  7497.     or    vtemu.vtflgst,decanm    ; and in permanent setup too
  7498.  
  7499. atres1a:mov    mar_top,0        ; reset scrolling region
  7500.     mov    ax,low_rgt        ; virtual screen lower right corner
  7501.     mov    mar_bot,ah        ; logical bottom of screen
  7502.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7503.     jz    atres1d            ; z = no
  7504. ifndef    no_graphics
  7505.     call    clearsoft        ; clear soft font storage, saves ax
  7506. endif    ; no_graphics
  7507.     mov    al,79            ; trim to 80 col screen
  7508. atres1d:mov    mar_right,al        ; logical right edge of screen
  7509.     mov    mar_left,0        ; DG left/right margins
  7510.     mov    old8bit,-1        ; flags.remflg d8bit status, clear
  7511.     xor    al,al            ; ax is top/bottom margin
  7512.     mov    dgwindow,ax        ; init to first window to full screen
  7513.     mov    dgwindcnt,1        ; DG window count, 1 = full screen
  7514.     mov    cx,slen
  7515.     xor    bx,bx
  7516. atres1i:mov    dgwindcomp[bx],al    ; set lines to uncompressed, no soft
  7517.     inc    bx
  7518.     loop    atres1i
  7519.     xor    ax,ax
  7520.     mov    savdgmar,ax        ; clear DG saved margins
  7521.     mov    protectena,al        ; disable protected fields
  7522.     mov    blinkdis,al        ; disable blink disable
  7523.     mov    dgroll,1        ; DG roll enabled
  7524.     mov    dgaltid,ax        ; DG alternate model id, clear it
  7525.     mov    dghscrdis,al        ; DG horz scroll disable is disabled
  7526.     mov    cx,16
  7527.     xor    bx,bx
  7528. atres1e:mov    dgcursave[bx],ax    ; clear DG cursor named save area
  7529.     add    bx,2
  7530.     loop    atres1e
  7531.     mov    cx,slen/2
  7532.     xor    bx,bx
  7533. atres1f:mov    word ptr linescroll[bx],ax ; clear DG per line horiz scroll
  7534.     add    bx,2
  7535.     loop    atres1f
  7536.     mov    dgnum,ax        ; DG worker word, to be safe
  7537. ifndef    no_graphics
  7538.     call    dgcrossoff        ; DG turn off crosshair
  7539. endif    ; no_graphics
  7540.     mov    dgcross,al        ; DG crosshair activity, off
  7541.     mov    dglinepat,0ffffh    ; DG line pattern, default all dots
  7542.     mov    dgcaller,offset atign    ; DG default callback, ignorance
  7543.     mov    numdigits,al        ; more DG stuff
  7544.     mov    param[0],ax        ; setup call to atleds
  7545.     mov    doublebyte,al        ; Japanese doublebyte state values
  7546.     mov    double2nd,al
  7547.     mov    param[0],ax        ; setup call to atleds
  7548.     xor    si,si
  7549.     call    atleds            ; clear the LED indicators
  7550.     call    cpytabs            ; initialize tab stops
  7551.  test flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttd463+ttd217+ttd470+ttansi
  7552.     jz    atres1c            ; z = no
  7553.     mov    al,vtemu.vtchset    ; setup char set
  7554.     cmp    al,1            ; in range for NRCs?
  7555.     jb    atres1c            ; b = no
  7556.     cmp    al,13            ; highest NRC ident?
  7557.     ja    atres1c            ; a = not NRC
  7558.     or    vtemu.vtflgop,vsnrcm    ; set NRC flag bit to activate NRCs
  7559. atres1c:mov    vtemu.vtchop,al        ; remember char set
  7560.     call    chrdef            ; set default character sets
  7561.     call    vtbell            ; ring bell like VT100
  7562.     cmp    flags.modflg,2        ; mode line owned by host?
  7563.     jne    atres1h            ; ne = no
  7564.     mov    flags.modflg,1        ; say now owned by us
  7565. atres1h:xor    ax,ax            ; not exiting connect mode, 80 col
  7566.     test    vtemu.vtflgst,deccol    ; need 132 columns?
  7567.     jz    atres1g            ; z = no, use 80 columns
  7568.     inc    al            ; say set 132 column mode
  7569. atres1g:call    chgdsp            ; call Change Display proc in msy
  7570.     and    vtemu.vtflgop,not deccol; assume mode is reset (80 cols)
  7571.     cmp    byte ptr low_rgt,79    ; is screen narrow now?
  7572.     jbe    atres2            ; be = yes
  7573.     or    vtemu.vtflgop,deccol    ; set the status bit
  7574.  
  7575.                     ; ATRES2 used in 80/132 col resetting
  7576. ATRES2:    mov    cx,slen            ; typically 24 but do max lines
  7577.     xor    di,di
  7578.     xor    al,al
  7579. atres3:    mov    linetype[di],al        ; clear the linetype array to single
  7580.     mov    linescroll[di],al    ; horizontal scroll per line
  7581.     inc    di
  7582.     loop    atres3
  7583.            mov    ah,att_normal        ; get present normal coloring
  7584.     test    vtemu.vtflgop,vsscreen    ; want reverse video?
  7585.     jz    atres4            ; z = no
  7586.     call    revideo            ; reverse them
  7587. atres4:    mov    scbattr,ah        ; set background attributes
  7588.     mov    curattr,ah        ; and cursor attributes
  7589.     test    flags.vtflg,ttwyse    ; Wyse-50?
  7590.     jz    atres4a            ; z = no
  7591.     mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attributes
  7592.     mov    byte ptr wyse_protattr+1,att_protect
  7593. atres4a:
  7594.     mov    extattr,0        ; no reverse video, no underline etc
  7595.     mov    dx,cursor        ; get cursor
  7596.     call    atsetcur        ; set cursor
  7597.     call    atsctyp            ; set right cursor type
  7598.     xor    ax,ax            ; starting location
  7599.     mov    bx,low_rgt        ; ending location
  7600.     call    vtsclr            ; clear the whole screen
  7601.     cmp    flags.modflg,1        ; mode line on and owned by us?
  7602.     jne    atres5            ; ne = no, leave it alone
  7603.     test    yflags,modoff        ; mode line supposed to be off?
  7604.     jnz    atres5            ; nz = yes
  7605.     push    dx
  7606.     call    fmodlin            ; write normal mode line
  7607.     pop    dx
  7608. atres5:    test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7609.     jz    atres6            ; z = no
  7610.     or    vtemu.vtflgop,decawm    ; Autowrap active
  7611.     or    vtemu.vtflgst,decawm    ; Autowrap active
  7612. atres6:    call    atpclr            ; clear parser work area
  7613.     xor    ax,ax
  7614.     mov    parstate,ax        ; reset parser
  7615.     mov    emubufc,ax        ; clear work buffer
  7616.     mov    atwrap,al        ; clear wrap flag
  7617.     mov    SSptr,ax        ; clear single shift flag
  7618.     mov    insmod,al        ; reset insert mode
  7619.     mov    h19stat,al        ; clear heath extended status byte
  7620.     mov    h19ctyp,1        ; Heath-19 cursor to underline
  7621.     mov    anspflg,al        ; clear printer flag
  7622.     call    atsc            ; save cursor information
  7623.     jmp    atnorm            ; set normal state
  7624. atreset    endp
  7625.  
  7626. ; Re-initialization routine. Called when Term was called but screen was
  7627. ; restored from a previously saved screen, etc.
  7628. ansrei    proc    near
  7629.     mov    dx,cursor
  7630.     call    atsctyp            ; set cursor type [rbv]
  7631.     mov    ax,vtemu.vtflgst    ; setup
  7632.     or    ax,vtemu.vtflgop    ; operational
  7633.     test    ax,deccol        ; want 80 columns?
  7634.     jnz    ansre2            ; nz = no
  7635.     cmp    byte ptr low_rgt,79    ; want 80 cols. Is active screen wider?
  7636.     jbe    ansre2            ; be = no
  7637.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  7638.     and    vtemu.vtflgop,not deccol
  7639. ansre2:    jmp    stblmds            ; check settable modes, set flags
  7640. ansrei    endp
  7641.  
  7642. ; This routine checks to see whether any of the settable modes have changed
  7643. ; (things that can be changed in both SETUP and by host commands), and
  7644. ; changes those that need to be changed.  TMPFLAGS has the new VT100 setup
  7645. ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
  7646. ; Revised to allow MSY to reset scbattr when not in connect mode,
  7647. ; to do "soft reset" if terminal type has changed, and to do a screen clear
  7648. ; reset if the actual screen colors have changed.
  7649.  
  7650. stblmds proc    near
  7651.     mov    ax,flags.vtflg        ; get current terminal type
  7652.     cmp    ax,tttek        ; non-text?
  7653.     je    stblm10            ; e = yes
  7654.     cmp    ax,oldterm        ; same as before?
  7655.     je    stblm10            ; e = yes, skip over soft reset
  7656.     mov    oldterm,ax        ; remember current terminal type
  7657.     mov    insmod,0        ; reset insert mode flag
  7658.     and    iniflgs,not vsnrcm    ; turn off NRC bit from last time
  7659.     mov    mar_top,0        ; reset top scrolling margin
  7660.     mov    al,byte ptr low_rgt+1    ; and scrolling margin
  7661.     mov    mar_bot,al        ; to last normal line on screen
  7662.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  7663.     sub    ah,8            ; place marker 9 columns from margin
  7664.     mov    belcol,ah        ; store column number to ring bell
  7665.     push    es
  7666.     push    ds
  7667.     pop    es
  7668.     xor    al,al            ; get a zero
  7669.     mov    di,offset linetype    ; line type to single width chars
  7670.     mov    cx,slen            ; screen length
  7671.     cld
  7672.     rep    stosb            ; clear
  7673.     mov    di,offset linescroll    ; line horizontal scroll to none
  7674.     mov    cx,slen
  7675.     rep    stosb
  7676.     pop    es
  7677.     and    vtemu.vtflgop,not decanm
  7678.  test    flags.vtflg,ttvt320+ttvt220+ttvt102+ttvt100+tthoney+ttpt200+ttansi
  7679.     jz    stblm10            ; z = no, not ansi class
  7680.     or    vtemu.vtflgop,decanm    ; set ansi flag bit
  7681.     or    vtemu.vtflgst,decanm    ; and in permanent setup too
  7682.  
  7683. stblm10:test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217 mode?
  7684.     jz    stblm10a        ; z = no
  7685.     mov    cx,slen-1        ; emulation screen lines
  7686.     xor    al,al
  7687.     xor    bx,bx
  7688. stblm10b:or    al,dgwindcomp[bx]    ; is any line compressed (!= 0)?
  7689.     inc    bx            ; if so remember as non-zero
  7690.     loop    stblm10b
  7691.     or    al,al            ; found any compressed/soft lines?
  7692.     jz    stblm10e        ; z = no
  7693.     test    al,2            ; any soft fonts in use?
  7694.     jnz    stblm10c        ; nz = yes, force graphics mode
  7695.     test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  7696.     jnz    stblm10d        ; nz = no, use 132 column text mode
  7697.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  7698.     jnz    stblm10e        ; nz = yes
  7699. stblm10c:
  7700. ifndef    no_graphics
  7701.     call    dgsettek        ; setup special graphics mode
  7702. endif    ; no_graphics
  7703.     jmp    short stblm10e
  7704. stblm10d:mov    al,3            ; prep call on atrsm6, 132/80 col
  7705.     mov    modeset,1        ; say want 132 columns
  7706.     call    atrsm6            ; common worker
  7707.     cmp    byte ptr low_rgt,79
  7708.     jbe    stblm10c        ; did not work, use graphics anyway
  7709. stblm10e:mov    al,flags.remflg        ; get 7/8 bit configuration
  7710.     and    al,d8bit        ; select the control bit
  7711.     cmp    old8bit,al        ; changed?
  7712.     je    stblm10a        ; e = no
  7713.     mov    old8bit,al        ; save new state
  7714.     mov    vtemu.vtchop,-1        ; force change below
  7715. stblm10a:mov    al,vtemu.vtchset    ; setup character set
  7716.     cmp    al,vtemu.vtchop        ; operational character set
  7717.     je    stblm3            ; e = same, no changes needed
  7718.     mov    vtemu.vtchop,al        ; remember this set
  7719.     and    vtemu.vtflgop,not vsnrcm ; clear NRC active bit
  7720.     and    vtemu.vtflgst,not vsnrcm
  7721.     cmp    al,1            ; in range for NRC?
  7722.     jb    stblm11            ; b = no
  7723.     cmp    al,13            ; above NRCs?
  7724.     ja    stblm11            ; a = yes
  7725.     or    vtemu.vtflgop,vsnrcm    ; set NRC active bit
  7726.     or    vtemu.vtflgst,vsnrcm
  7727.     and    vtemu.vtflgop,not vscntl ; no 8-bit controls
  7728. stblm11:call    chrdef            ; init char sets
  7729.  
  7730. stblm3:    test    vtemu.vtflgst,vswdir    ; writing direction set?
  7731.     jz    stblm3c            ; z = no
  7732.     mov    decrlm,0        ; yes, suppress host indicator
  7733. stblm3c:mov    ax,iniflgs        ; flags at last entry
  7734.     xor    ax,vtemu.vtflgst    ; find which setup ones have changed
  7735.     test    ax,deccol        ; screen width?
  7736.     jz    stblm3b            ; z = no, don't touch it
  7737.     mov    ax,vtemu.vtflgst    ; Setup bits
  7738.     and    ax,deccol        ; select screen width
  7739.     and    vtemu.vtflgop,not deccol ; clear operational flag bit
  7740.     or    vtemu.vtflgop,ax    ; set current width desired
  7741.     or    al,ah            ; collapse all bits
  7742.     mov    modeset,al        ; non-zero if 132 columns
  7743.     mov    al,3            ; setup call to atrsm6
  7744.     call    atrsm6            ; adjust display width
  7745.  
  7746. stblm3b:cmp    vtclear,1        ; screen need updating?
  7747.     mov    vtclear,0        ; preserves cpu status bits
  7748.     jb    stblm9            ; b = no
  7749.     ja    stblm3a            ; 2 or more means do a reset
  7750.     mov    ah,att_normal        ; 1, get new normal attributes setting
  7751.     mov    scbattr,ah        ; store new values
  7752.     test    flags.vtflg,ttwyse    ; Wyse-50?
  7753.     jz    stblm3d            ; z = no
  7754.     mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attributes
  7755.     mov    byte ptr wyse_protattr+1,att_protect
  7756. stblm3d:
  7757.     mov    curattr,ah
  7758.     jmp    short stblm9
  7759. stblm3a:mov    cursor,0        ; reset cursor position
  7760.     jmp    atres2            ; go to semi-reset
  7761.  
  7762.                     ; check on screen normal/reversed
  7763. stblm9:    mov    ax,iniflgs        ; flags at last entry
  7764.     xor    ax,vtemu.vtflgst    ; find which setup ones have changed
  7765.     test    ax,vsscreen        ; screen background?
  7766.     jz    stblm8            ; z = no, don't touch it
  7767.     test    vtemu.vtflgop,vsscreen    ; reverse video flag set?
  7768.     jnz    stblm5            ; nz = yes, do it
  7769.     and    vtemu.vtflgop,not vsscreen ; cleared (normal video)
  7770.     jmp    short stblm6        ; reverse everything
  7771. stblm5: or    vtemu.vtflgop,vsscreen    ; set (reverse video)
  7772. stblm6: call    atrss2            ; reverse screen and cursor attribute
  7773.     mov    ah,scbattr        ; reset saved attribute also
  7774.     mov    savecu+svattr_index,ah
  7775. stblm8:    cmp    flags.modflg,2        ; mode line enabled and owned by host?
  7776.     je    stblm9a            ; e = yes, leave it alone
  7777.     call    fclrmod            ; clear the mode line
  7778.     test    yflags,modoff        ; mode line supposed to be off?
  7779.     jnz    stblm9a            ; nz = yes
  7780.     call    fmodlin            ; write normal mode line
  7781.     and    yflags,not modoff    ; say modeline is not toggled off
  7782. stblm9a:mov    dx,cursor        ; logical cursor
  7783.     push    dx
  7784.     call    direction        ; set cursor for writing direction
  7785.     call    setpos            ; set the cursor physical position
  7786.     pop    dx
  7787.     push    vtemu.vtflgst
  7788.     pop    iniflgs            ; remember setup flags at this entry
  7789.     call    frepaint
  7790.     ret
  7791. stblmds endp
  7792.  
  7793. ; Routine called when something is typed on the keyboard
  7794.  
  7795. anskbi    proc    near
  7796.     mov    ttkbi,0FFH        ; just set a flag
  7797.     ret
  7798. anskbi    endp
  7799.  
  7800.  
  7801. ; This routine copies the new tab stops when they have changed.
  7802. ; Copies all 132 columns.
  7803. cpytabs proc    near
  7804.     mov    cx,(swidth+7)/8        ; number of bytes in screen width
  7805.     jcxz    cpytab1            ; z = none to do
  7806.     mov    si,offset deftabs    ; source is setup array
  7807.     mov    di,offset tabs        ; destination is active array
  7808.     push    es            ; save es
  7809.     push    ds
  7810.     pop    es            ; set es to data segment
  7811.     cld
  7812.     rep    movsb            ; do the copy
  7813.     pop    es            ; recover es
  7814. cpytab1:ret
  7815. cpytabs endp
  7816.  
  7817. ; Routine to toggle between text and Tek graphics modes. No arguments.
  7818. ; Text terminal type remembered in byte OLDTERM.
  7819. ans52t    proc    FAR
  7820.     mov    ax,flags.vtflg
  7821.     cmp    ax,tttek        ; in Tek mode now?
  7822.     je    ans52b            ; e = yes, exit Tek mode
  7823.     test    tekflg,tek_active    ; doing Tek sub mode?
  7824.     jnz    ans52b            ; nz = yes
  7825.     test    ax,ttd463+ttd470+ttd217    ; DG 463/D470/D217?
  7826.     jnz    ans52e            ; nz = yes, go into DG graphics mode
  7827.  
  7828. ifndef    no_graphics
  7829.     test    denyflg,tekxflg        ; is Tek mode disabled?
  7830.     jnz    ans52a            ; nz = yes, disabled
  7831.     mov    oldterm,ax        ; save text terminal type here
  7832.     call    atsc            ; save cursor and associated data
  7833.     mov    flags.vtflg,tttek    ; set Tek mode
  7834.     mov    tekflg,tek_tek        ; not a sub mode
  7835.     call    tekini            ; init Tek to switch screens
  7836. endif    ; no_graphics
  7837. ans52a:    call    atnorm
  7838.     ret
  7839.  
  7840. ans52b:
  7841. ifndef    no_graphics
  7842.     call    tekend            ; exit Tek graphics mode
  7843. endif    ; no_graphics
  7844.     mov    ax,oldterm
  7845.     or    ax,ax            ; inited yet?
  7846.     jnz    ans52c            ; nz = yes
  7847.     mov    ax,ttvt320        ; fall back for initing
  7848. ans52c:    mov    flags.vtflg,ax        ; say text terminal now
  7849.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  7850.     jnz    ans52f            ; nz = yes, cursor is ok already
  7851.     call    atrc            ; restore cursor etc
  7852.     call    atsc            ; save cursor etc
  7853. ans52f:    mov    tekflg,0        ; say not doing tek submode now
  7854.     mov    al,atctype
  7855.     call    atsctyp            ; set correct cursor type
  7856.     test    yflags,modoff        ; is mode line off?
  7857.     jnz    ans52d            ; nz = yes
  7858.     push    dx            ; save cursor position
  7859.     call    frepaint        ; restore text screen
  7860.     call    fmodlin            ; write mode line
  7861.     pop    dx
  7862. ans52d:    call    atnorm
  7863.     ret
  7864.                     ; DG D473 graphics mode entry
  7865. ans52e:    mov    oldterm,ax        ; save text terminal type here
  7866. ifndef    no_graphics
  7867.     call    dgsettek        ; switch to DG graphics
  7868. endif    ; no_graphics
  7869.     jmp    short ans52d
  7870. ans52t    endp
  7871.  
  7872. ;  Honeywell VIP 3.1 i.d. string [FD]
  7873. athoney proc    near
  7874.     cmp    flags.vtflg,tthoney    ; Honeywell mode?
  7875.     jne    athone3            ; ne = no, ignore
  7876.     mov    ttyact,0        ; group for networks
  7877.     mov    cx,VIPstrl        ; length of string
  7878.     mov    si,offset VIPstr    ; ptr to string
  7879.     cld
  7880. athone1:lodsb                ; get a byte
  7881.     push    cx            ; save regs
  7882.     push    si
  7883.     call    prtbout            ; print WITHOUT echo
  7884.     pop    si
  7885.     pop    cx
  7886.     cmp    cx,1            ; last char?
  7887.     ja    athone2            ; a = not yet
  7888.     mov    ttyact,1        ; end of network grouping
  7889. athone2:loop    athone1            ; loop for all characters
  7890. athone3:jmp    atnorm
  7891. athoney endp
  7892.  
  7893. athoncls proc    near            ; Honeywell ESC accent  screen clear
  7894.     cmp    nparam,0        ; absence of parameters?
  7895.     jne    athoncl1        ; ne = no, fail
  7896.     cmp    ninter,0        ; any intermediates?
  7897.     jne    athoncl2        ; ne = yes, not this item
  7898.     cmp    flags.vtflg,tthoney    ; doing Honeywell emulation?
  7899.     jne    athoncl1        ; ne = no
  7900.     xor    dx,dx            ; move cursor to Home position
  7901.     call    ereos            ; erase to end of screen
  7902.     xor    dx,dx
  7903.     jmp    atsetcur        ; set cursor and return
  7904. athoncl1:ret
  7905. athoncl2:jmp    atdgnrc            ; try Norwegian/Danish NRC designation
  7906. athoncls endp
  7907.  
  7908.     ; Data General D463/D470 support routines
  7909.  
  7910.                     ; Data General mode C0 control codes
  7911. dgctrl    proc    near
  7912.     test    anspflg,vtcntp        ; printing desired?
  7913.     jz    dgctrl1            ; z = no
  7914.     call    fpntchr            ; print char in al
  7915. dgctrl1:and    ax,001fh        ; clear for word use below
  7916.     mov    di,ax            ; use AL as a word index
  7917.     shl    di,1
  7918.     jmp    dgc0[di]        ; dispatch on DG C0 control codes
  7919. dgctrl    endp
  7920.  
  7921. ; Control-character dispatcher for DG ANSI mode
  7922. dgansctl proc    near
  7923.     cmp    al,escape        ; an escape sequence starting?
  7924.     jne    dgansctl1        ; ne = no
  7925.     jmp    atesc
  7926. dgansctl1:cmp    al,CSI            ; this kind of escape?
  7927.     jne    dgansctl2        ; ne = no
  7928.     jmp    atcsi0
  7929. dgansctl2:cmp    al,9ch            ; end of DCS?
  7930.     jne    dgansctl3        ; ne = no
  7931.     jmp    atgotst            ; terminate DCS
  7932. dgansctl3:cmp    ttstate,offset atdcsnul    ; consuming a DCS?
  7933.     jne    dgansctl4        ; ne = no
  7934.     ret                ; consume
  7935. dgansctl4:cmp    ttstate,offset atesc1    ; state is second char of ST?
  7936.     jne    dgansctl5        ; ne = no
  7937.     jmp    ttstate            ; go process second char
  7938. dgansctl5:test    anspflg,vtcntp        ; printing desired?
  7939.     jz    dgansctl6        ; z = no
  7940.     call    fpntchr            ; print char in al
  7941. dgansctl6:cmp    al,BELL
  7942.     jne    dgansctl7
  7943.     jmp    vtbell            ; beep
  7944. dgansctl7:cmp    al,BS
  7945.     jne    dgansctl8
  7946.     jmp    dgcub            ; do DG Backspace
  7947. dgansctl8:cmp    al,LF
  7948.     je    dgansctl9        ; e = yes
  7949.     cmp    al,FF
  7950.     jne    dgansctl10
  7951. dgansctl9:jmp    dglf            ; do DG Line Feed
  7952. dgansctl10:ret
  7953. dgansctl endp
  7954.  
  7955. dgesc    proc    near            ; Parse Data General RS commands
  7956.     mov    dgnum,0            ; clear numerical result
  7957.     mov    ttstate,offset dgesc1    ; set up to get next char
  7958.     ret
  7959. dgesc1:    mov    bx,offset dgesctab    ; dispatch table
  7960.     mov    ttstate,offset atnrm    ; reset state
  7961.     jmp    atdispat        ; dispatch on char in AL
  7962. dgesc    endp
  7963.  
  7964. ; Parse RS F/G <letter><DGnumber>(repeated)
  7965. ; F/G has been read, letter is next
  7966. dgFSERIES:mov    ttstate,offset Fdisp    ; dispatcher for incoming RS F
  7967.     ret
  7968. Fdisp:    mov    ttstate,offset atnrm    ; normal state
  7969.     mov    bx,offset fltable    ; table of letters
  7970.     jmp    atdispat        ; dispatch to action routine
  7971.  
  7972. dgGSERIES:mov    ttstate,offset Gdisp    ; dispatcher for incoming RS G
  7973.     ret
  7974. Gdisp:    mov    ttstate,offset atnrm    ; normal state
  7975.     mov    bx,offset gltable    ; table of letters
  7976.     jmp    atdispat        ; dispatch to action routine
  7977.  
  7978. dgRSERIES:test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  7979.     jz    dgnoR            ; z = no
  7980.     mov    ttstate,offset Rdisp    ; dispatcher for incoming RS R
  7981.     ret
  7982. dgnoR:    jmp    atnorm            ; no RS R series in D470
  7983.  
  7984. Rdisp:    mov    ttstate,offset atnrm    ; normal state
  7985.     mov    bx,offset rltable    ; table of letters
  7986.     jmp    atdispat        ; dispatch to action routine
  7987.  
  7988. ; DG <n>,<nn>,<nnn> processors. Enter with BX holding callback address.
  7989. ; Returns number in dgnum and resets state to atnrm.
  7990.                     ; get one DG numeric
  7991. get1n:    mov    ttstate,offset getnum    ; worker routine
  7992.     mov    dgnum,0            ; clear numerical result
  7993.     mov    numdigits,1        ; wanted qty of digits
  7994.     mov    dgcaller,bx        ; call back address
  7995.     ret
  7996.                     ; get two DG hex digits
  7997. get2n:    mov    ttstate,offset getnum    ; worker routine
  7998.     mov    dgnum,0            ; clear numerical result
  7999.     mov    numdigits,2        ; wanted qty of digits
  8000.     mov    dgcaller,bx        ; call back address
  8001.     ret
  8002.                     ; get three DG hex digits
  8003. get3n:    mov    ttstate,offset getnum    ; worker routine
  8004.     mov    dgnum,0            ; clear numerical result
  8005.     mov    numdigits,3        ; wanted qty of digits
  8006.     mov    dgcaller,bx        ; call back address
  8007.     ret
  8008.  
  8009. get3loc:mov    ttstate,offset getloc    ; get three DG Location digits
  8010.     mov    dgnum,0
  8011.     mov    numdigits,3
  8012.     mov    dgcaller,bx
  8013.     ret
  8014.  
  8015. ; get number from lower 5 bits of each byte
  8016. getdd:    mov    ttstate,offset get5num    ; worker routine
  8017.     mov    dgnum,0            ; clear numerical result
  8018.     mov    numdigits,2        ; wanted qty of digits
  8019.     mov    dgcaller,bx        ; call back address
  8020.     ret
  8021.  
  8022. getloc    proc    near
  8023.     or    al,al            ; is it truely null (RS L cmd stuff)?
  8024.     jz    getloc3            ; z = yes, exit now
  8025.     and    al,00011111b        ; keep only five lower bits
  8026.     mov    cl,5
  8027.     mov    bx,dgnum
  8028.     shl    bx,cl
  8029.     or    bl,al
  8030.     mov    dgnum,bx
  8031.     dec    numdigits        ; say one more digit done
  8032.     jz    getloc1            ; z = have done all
  8033.     ret                ; else stay in state getloc
  8034.  
  8035. getloc3:stc                ; set carry to say ended on NULL
  8036. getloc1:call    atnorm            ; set normal state
  8037.     mov    bx,dgcaller        ; get callback address
  8038.     mov    dgcaller,offset atign    ; reset default DG callback processor
  8039.     jmp    bx            ; go to callback address
  8040. getloc    endp
  8041.  
  8042. ; Return binary number in dgnum. When done it resets state to atnrm, 
  8043. ; clears callback address. Note that this proc accepts ALL bytes and uses
  8044. ; only the four lower bits, regardless of what the DG manuals suggest.
  8045. getnum    proc    near
  8046.     and    al,0fh            ; keep lower four bits
  8047.     mov    cl,4
  8048.     mov    bx,dgnum        ; get current value
  8049.     shl    bx,cl            ; times 16
  8050.     or    bl,al            ; add current digit
  8051.     mov    dgnum,bx        ; keep result
  8052.     dec    numdigits        ; say one more digit done
  8053.     jz    getnum2            ; z = have done all digits
  8054.     ret                ; else stay in this state
  8055. getnum2:call    atnorm            ; set normal state
  8056.     mov    bx,dgcaller        ; get callback address
  8057.     mov    dgcaller,offset atign    ; reset default DG callback processor
  8058.     jmp    bx            ; go to callback address
  8059. getnum    endp
  8060.  
  8061. ; Return binary number in dgnum. When done it resets state to atnrm, 
  8062. ; clears callback address. Note that this proc accepts ALL bytes and uses
  8063. ; only the five lower bits, regardless of what the DG manuals suggest.
  8064. get5num    proc    near
  8065.     and    al,1fh            ; keep lower five bits
  8066.     mov    cl,5
  8067.     mov    bx,dgnum        ; get current value
  8068.     shl    bx,cl            ; times 32
  8069.     add    bl,al            ; add current digit
  8070.     adc    bh,0
  8071.     mov    dgnum,bx        ; keep result
  8072.     dec    numdigits        ; say one more digit done
  8073.     cmp    numdigits,0        ; done all?
  8074.     jz    get5num2        ; z = yes
  8075.     ret                ; else stay in this state
  8076. get5num2:call    atnorm            ; set normal state
  8077.     mov    bx,dgcaller        ; get callback address
  8078.     mov    dgcaller,offset atign    ; reset default DG callback processor
  8079.     jmp    bx            ; go to callback address
  8080. get5num    endp
  8081.  
  8082. ; Provide binary number in dgnum from ANSI params, simulating get<kinds>
  8083. ; Enter with bx holding offset of main routine to call first.
  8084. ; Return carry set when no more parameters
  8085. dec2getn proc    near
  8086.     mov    dgparmread,0        ; parameter read
  8087.     call    bx            ; call main routine
  8088.  
  8089. dec2getn1:cmp    ttstate,offset atnrm    ; want to return to normal state?
  8090.     je    dec2getnx        ; e = yes
  8091.     mov    bx,dgparmread        ; number of parameters read
  8092.     cmp    bx,nparam        ; read all parameters?
  8093.     jae    dec2getnx        ; ae = yes
  8094.     shl    bx,1            ; convert to word index
  8095.     mov    bx,param[bx]        ; get parameter
  8096.     inc    dgparmread        ; say have read it
  8097.     mov    dgnum,bx        ; return value
  8098.     clc
  8099.     mov    bx,dgcaller
  8100.     call    bx
  8101.     jmp    short dec2getn1
  8102. dec2getnx:
  8103.     call    atnorm            ; reset state
  8104.     mov    dgnum,0
  8105.     stc                ; return carry set
  8106.     ret
  8107. dec2getn endp
  8108.  
  8109. out2n    proc    near            ; send <nn> report from value in AL
  8110.     push    cx
  8111.     mov    ch,al            ; preserve a copy
  8112.     mov    cl,4
  8113.     shr    al,cl            ; get high nibble
  8114.     and    al,0fh
  8115.     add    al,'0'            ; ascii bias
  8116.     call    prtbout
  8117.     mov    al,ch            ; recover copy
  8118.     and    al,0fh            ; get low nibble
  8119.     add    al,'0'
  8120.     call    prtbout
  8121.     pop    cx
  8122.     ret
  8123. out2n    endp
  8124.  
  8125. out2na    proc    near            ; send <nn> report from value in AL
  8126.     push    cx
  8127.     mov    ch,al            ; preserve a copy
  8128.     mov    cl,4
  8129.     shr    al,cl            ; get high nibble
  8130.     and    al,0fh
  8131.     add    al,'@'            ; ascii bias
  8132.     call    prtbout
  8133.     mov    al,ch            ; recover copy
  8134.     and    al,0fh            ; get low nibble
  8135.     add    al,'@'
  8136.     call    prtbout
  8137.     pop    cx
  8138.     ret
  8139. out2na    endp
  8140.  
  8141. dgign1n    proc    near            ; ignore a <n> command
  8142.     mov    bx,offset atnorm    ; ignore the <n>
  8143.     jmp    get1n
  8144. dgign1n    endp
  8145.  
  8146. dgign2n    proc    near            ; ignore a <nn> command
  8147.     mov    bx,offset atnorm    ; ignore the <nn>
  8148.     jmp    get2n
  8149. dgign2n    endp
  8150.  
  8151. dgprtfm    proc    near            ; Control-A  DG print form
  8152.     mov    cursor,dx        ; save cursor location
  8153. dgprtf1:mov    dl,mar_right        ; start at right margin
  8154.     mov    cl,dl
  8155.     sub    cl,mar_left        ; minus left
  8156.     inc    cl
  8157.     xor    ch,ch            ; number of columns to do
  8158. dgprtf3:push    cx
  8159.     call    dgprta            ; get char which would be printed
  8160.     pop    cx
  8161.     cmp    al,' '            ; space?
  8162.     jne    dgprtf4            ; ne = no, end scan here
  8163.     dec    dl            ; scan backward another column
  8164.     loop    dgprtf3
  8165. dgprtf4:jcxz    dgprtf6            ; z = empty line
  8166.     mov    dl,mar_left        ; start at left margin
  8167. dgprtf5:push    cx
  8168.     push    dx
  8169.     call    dgprta            ; get printable
  8170.     call    fpntchr            ; print char in al
  8171.     pop    dx
  8172.     pop    cx
  8173.     jc    dgprtf7            ; c = printer error
  8174.     inc    dl
  8175.     loop    dgprtf5            ; do count
  8176.  
  8177. dgprtf6:mov    al,CR            ; line terminator for printer
  8178.     push    dx
  8179.     call    fpntchr
  8180.     pop    dx
  8181.     jc    dgprtf7            ; c = printer error
  8182.     mov    al,LF
  8183.     push    dx
  8184.     call    fpntchr
  8185.     pop    dx
  8186.     jc    dgprtf7            ; c = printer error
  8187.     inc    dh            ; next row down
  8188.     cmp    dh,mar_bot        ; below window now?
  8189.     jbe    dgprtf1            ; be = no
  8190. dgprtf7:mov    al,6            ; Control-F to host when done
  8191.     call    prtbout            ; output, no echo
  8192.     mov    dx,cursor
  8193.     ret
  8194. dgprtfm    endp
  8195.  
  8196. dgprta    proc    near            ; worker, report printable char at dx
  8197.     call    getatch            ; read char (al) and attribute (ah)
  8198.     cmp    protectena,0        ; protected mode enabled?
  8199.     je    dgprta1            ; e = no
  8200.     test    cl,att_protect        ; protected mode?
  8201.     jnz    dgprta2            ; nz = yes, use a space
  8202.     ret                ; else use as-is
  8203. dgprta1:test    ah,att_bold        ; bold?
  8204.     jnz    dgprta3            ; nz = yes, use as-is
  8205. dgprta2:mov    al,' '            ; replace with space
  8206. dgprta3:ret
  8207. dgprta    endp
  8208.  
  8209. dgprtwn    proc    near            ; Control-Q  DG print window
  8210.     mov    cursor,dx        ; save cursor location
  8211. dgprtw1:mov    dl,mar_right        ; start at right margin
  8212.     mov    cl,dl
  8213.     sub    cl,mar_left
  8214.     inc    cl
  8215.     xor    ch,ch            ; number of columns to do
  8216. dgprtw3:push    cx
  8217.     call    dgprtb            ; get char which would be printed
  8218.     pop    cx
  8219.     cmp    al,' '            ; space?
  8220.     jne    dgprtw4            ; ne = no, end scan here
  8221.     dec    dl            ; scan backward another column
  8222.     loop    dgprtw3
  8223. dgprtw4:jcxz    dgprtw6            ; z = empty line
  8224.     mov    dl,mar_left        ; start at left margin
  8225. dgprtw5:push    cx
  8226.     push    dx
  8227.     call    dgprtb            ; get printable
  8228.     call    fpntchr            ; print char in al
  8229.     pop    dx
  8230.     pop    cx
  8231.     jc    dgprtw7            ; c = printer error
  8232.     inc    dl
  8233.     loop    dgprtw5            ; do count
  8234. dgprtw6:mov    al,CR            ; line terminator for printer
  8235.     push    dx
  8236.     call    fpntchr
  8237.     pop    dx
  8238.     jc    dgprtw7            ; c = printer error
  8239.     mov    al,LF
  8240.     push    dx
  8241.     call    fpntchr
  8242.     pop    dx
  8243.     jc    dgprtw7            ; c = printer error
  8244.     inc    dh            ; next row down
  8245.     cmp    dh,mar_bot        ; below window now?
  8246.     jbe    dgprtw1            ; be = no
  8247. dgprtw7:mov    al,6            ; Control-F to host when done
  8248.     call    prtbout            ; output, no echo
  8249.     mov    dx,cursor
  8250.     ret
  8251. dgprtwn    endp
  8252.  
  8253. dgprtb    proc    near            ; worker to yield printable char
  8254.     call    getatch            ; read char (al) and attribute (ah)
  8255.     test    al,80h            ; high bit set?
  8256.     jnz    dgprtb1            ; nz = yes, use a space
  8257.     cmp    al,20h            ; in printables?
  8258.     ja    dgprtb2            ; a = yes
  8259. dgprtb1:mov    al,' '            ; replace with space
  8260. dgprtb2:ret
  8261. dgprtb    endp
  8262.  
  8263. dgrevidon:mov    ah,curattr        ; RS D  Control-V  reverse video on
  8264.     call    setrev            ; reverse video on
  8265.     mov    curattr,ah        ; store new attribute byte
  8266.     ret
  8267.  
  8268. dgrevidoff:mov    ah,curattr        ; RS E  Control-B  reverse video off
  8269.     call    clrrev            ; 2, reverse video off
  8270.     mov    curattr,ah        ; store new attribute byte
  8271.     ret
  8272.  
  8273. dgblkena:mov    blinkdis,0        ; Control-C  DG blink enable
  8274.     ret
  8275. dgblkdis:mov    blinkdis,1        ; Control-D  DG blink disable
  8276.     ret
  8277.  
  8278. dgblkon    proc    near            ; Control-N  DG Blink on
  8279.     cmp    blinkdis,0        ; disabled?
  8280.     jne    dgblkon1        ; ne = blink is disabled
  8281.     mov    ah,curattr        ; get current cursor attribute
  8282.     call    setblink        ; blink enable
  8283.     mov    curattr,ah        ; store new attribute byte
  8284. dgblkon1:ret
  8285. dgblkon    endp
  8286.  
  8287. dgblkoff proc    near            ; Control-O  DG Blink off
  8288.     mov    ah,curattr        ; get current cursor attribute
  8289.     call    clrblink        ;  blink disable
  8290.     mov    curattr,ah        ; store new attribute byte
  8291.     ret
  8292. dgblkoff endp
  8293.  
  8294. dgwinhome proc near            ; Control-H  DG window home
  8295.     mov    dl,mar_left        ; want to skip protected chars too
  8296.     mov    dh,mar_top
  8297.     jmp    dgsetcur        ; do protected mode positioning
  8298. dgwinhome endp
  8299.  
  8300. dguson    proc    near            ; Control-T  DG underscoring on
  8301.     mov    ah,curattr        ; get current cursor attribute
  8302.     call    setunder
  8303.     mov    curattr,ah        ; store new attribute byte
  8304.     ret
  8305. dguson    endp
  8306.  
  8307. dgusoff    proc    near            ; Control-U  DG underscoring off
  8308.     mov    ah,curattr        ; get current cursor attribute
  8309.     call    clrunder
  8310.     mov    curattr,ah        ; store new attribute byte
  8311.     ret
  8312. dgusoff    endp
  8313.  
  8314. dgdimon    proc    near            ; Control-\  DG dim on
  8315.     mov    ah,curattr        ; get current cursor attribute
  8316.     call    clrbold
  8317.     mov    curattr,ah        ; store new attribute byte
  8318.     ret
  8319. dgdimon    endp
  8320.  
  8321. dgdimoff proc    near            ; Control-]  DG dim off
  8322.     mov    ah,curattr        ; get current cursor attribute
  8323.     call    setbold
  8324.     mov    curattr,ah        ; store new attribute byte
  8325.     ret
  8326. dgdimoff endp
  8327.  
  8328. dgsfc    proc    near            ; RS A <color>, set foreground color
  8329.     mov    ttstate,offset dgsfc1    ; state to get next char
  8330.     ret
  8331. dgsfc1:    mov    ttstate,offset atnrm    ; reset state
  8332.     test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  8333.     jz    dgsfc2            ; z = no, D470
  8334.     mov    ah,curattr        ; current coloring
  8335.     test    al,0fh            ; setting to background?
  8336.     jnz    dgsfc1a            ; nz = no
  8337.     mov    cl,4
  8338.     rol    ah,cl            ; get background coloring
  8339. dgsfc1a:and    ah,0fh            ; keep foreground
  8340.     mov    dg463fore,ah        ; polygon foreground coloring
  8341.     ret
  8342. dgsfc2:    cmp    al,100            ; select ACM mode?
  8343.     je    dgsfc5            ; ne = no
  8344. dgsfc3:    and    al,0fh            ; keep lower 4 bits
  8345.     jz    dgsfc4            ; z = black
  8346.     xor    al,8            ; invert DG intensity bit
  8347.     jnz    dgsfc4
  8348.     or    al,8            ; pick up dark grey as second except'n
  8349. dgsfc4:    mov    ah,curattr
  8350.     and    ah,not 0Fh        ; remove foreground
  8351.     or    ah,al            ; set new foreground
  8352.     mov    ah,scbattr
  8353.     and    ah,not 0Fh
  8354.     or    ah,al
  8355.     mov    curattr,ah        ; save it
  8356.     mov    scbattr,ah
  8357.     ret
  8358. dgsfc5:    mov    ah,att_normal        ; get normal background colors
  8359.     mov    scbattr,ah
  8360.     mov    curattr,ah        ; set current to them
  8361. dgsfcx:    ret
  8362. dgsfc    endp
  8363.  
  8364. dgsbc    proc    near            ; RS B <color>, set background color
  8365.     mov    ttstate,offset dgsbc1    ; state to get next char
  8366.     ret
  8367. dgsbc1:    mov    ttstate,offset atnrm    ; reset state
  8368.     test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  8369.     jnz    dgsbcx            ; nz = yes, ignore command
  8370.     cmp    al,100            ; select ACM mode?
  8371.     je    dgsbc2            ; e = yes
  8372.     and    al,0fh            ; mask out all but IBM PC background
  8373.     jz    dgsbc3            ; z = black
  8374.     and    al,7            ; remove IBM PC blinking bit
  8375.     mov    cl,4
  8376.     shl    al,cl            ; move bits to high nibble
  8377. dgsbc3:    mov    ah,curattr
  8378.     and    ah,0fh            ; remove background
  8379.     or    ah,al            ; set new background
  8380.     mov    curattr,ah        ; save it
  8381.     mov    ah,scbattr
  8382.     and    ah,0fh            ; remove background
  8383.     or    ah,al            ; set new background
  8384.     mov    scbattr,ah        ; save it
  8385.     ret
  8386. dgsbc2:    mov    ah,att_normal        ; get normal background colors
  8387.     mov    scbattr,ah        ; set current to them
  8388.     mov    curattr,ah        ; set current to them
  8389. dgsbcx:    ret
  8390. dgsbc    endp
  8391.  
  8392. dgeol    proc    near            ; Control-K DG erase cursor to eol
  8393.     mov    ax,dx            ; cursor position
  8394.     mov    bx,ax
  8395.     mov    bl,mar_right        ; end of line
  8396.     call    atsclr            ; erase from ax to bx
  8397.     ret
  8398. dgeol    endp
  8399.  
  8400. dgtoansi proc    near            ; RS F @  D470 mode to ANSI mode
  8401.     test    flags.vtflg,ttd470    ; D470?
  8402.     jz    dgtoansi1        ; z = no
  8403.     mov    dgd470mode,1        ; say doing ANSI mode
  8404. dgtoansi1:ret
  8405. dgtoansi endp
  8406.  
  8407. dgeeos    proc    near            ; RS F F  DG erase cursor to end/scrn
  8408.     jmp    erprot
  8409. dgeeos    endp
  8410.  
  8411. dgescn    proc    near            ; RS F E  DG erase from 0,0 to eos
  8412.     xor    dh,dh
  8413.     mov    dl,mar_left        ; left margin, top row
  8414.     call    dggetmar        ; get margins for this window
  8415.     call    atsetcur        ; set cursor
  8416.     mov    ah,curattr
  8417.     call    clrunder        ; clear underline attribute
  8418.     call    clrblink        ; clear blink
  8419.     call    setbold            ; aka clear dim
  8420.     call    clrrev            ; clear reverse video attribute
  8421.     mov    atinvisible,0        ; clear invisible attribute
  8422.     mov    curattr,ah        ; and cursor attributes
  8423.     mov    extattr,0        ; clear extended attributes
  8424.     xor    ax,ax            ; erase from 0,0
  8425.     mov    bh,byte ptr low_rgt+1    ; to end of screen
  8426.     mov    bl,vswidth-1
  8427.     call    atsclr            ; clear screen
  8428.     ret
  8429. dgescn    endp
  8430.  
  8431. dgewin    proc    near            ; Control-L  DG erase window
  8432.     call    dgusoff            ; underscore off        
  8433.     call    clrblink        ; clear blink
  8434.     call    clrrev            ; remove special video attributes
  8435.     mov    ah,mar_top        ; from top line of window
  8436.     mov    bh,mar_bot        ; to bottom line of window
  8437.     mov    al,mar_left        ; left margin
  8438.     mov    bl,mar_right        ; right margin
  8439.     cmp    savdgmar,0        ; saved permanent margin?
  8440.     je    dgewin1            ; e = no, mar_left/right are permanent
  8441.     mov    al,byte ptr savdgmar    ; use permanent l/r margins
  8442.     mov    bl,byte ptr savdgmar+1
  8443. dgewin1:call    atsclr            ; clear the area
  8444.     jmp    dgwinhome        ; do DG window home
  8445. dgewin    endp
  8446.  
  8447. dgsleft    proc    near            ; RS F C <nn>  DG Scroll Left
  8448.     mov    bx,offset dgslef1    ; get <nn>
  8449.     jmp    get2n
  8450. dgslef1:mov    ax,dgnum        ; qty columns to scroll
  8451.     jmp    dglrworker        ; do common worker
  8452. dgsleft    endp
  8453.  
  8454. dgsright proc    near            ; RS F D <nn>  DG Scroll Right
  8455.     mov    bx,offset dgsrig1    ; get <nn>
  8456.     jmp    get2n
  8457. dgsrig1:mov    ax,dgnum
  8458.     neg    ax            ; go right
  8459.     jmp    dglrworker        ; do common worker
  8460. dgsright endp
  8461.  
  8462. ; Worker to assist dgsleft/dgsright horizontal scroll. Enter with AX holding
  8463. ; the additional scroll value, negative for scrolling left. Updates array
  8464. ; linescroll.
  8465. dglrworker proc    near
  8466.     cmp    dghscrdis,0        ; horiz scrolling disabled?
  8467.     je    dglrwor1        ; e = no
  8468.     ret                ; else ignore request
  8469. dglrwor1:mov    bl,mar_top        ; do entire DG window
  8470.     xor    bh,bh
  8471.     mov    cl,mar_bot
  8472.     xor    ch,ch
  8473.     sub    cx,bx
  8474.     inc    cx            ; number of lines in the window
  8475.     cmp    cl,byte ptr low_rgt+1    ; includes whole screen?
  8476.     jbe    dglrwor2        ; be = no
  8477.     inc    cx            ; include status line
  8478.  
  8479. dglrwor2:push    cx
  8480.     mov    cl,linescroll[bx]    ; get horz scroll value
  8481.     xor    ch,ch
  8482.     add    cx,ax            ; accumulate scroll
  8483.     jge    dglrwor3        ; ge = non-negative
  8484.     xor    cx,cx            ; set to zero
  8485. dglrwor3:cmp    cx,127            ; max scroll
  8486.     jbe    dglrwor4        ; be = in limits
  8487.     mov    cl,127            ; set to max left
  8488. dglrwor4:cmp    linescroll[bx],cl    ; any change?
  8489.     je    dglrwor5        ; e = no
  8490.     mov    linescroll[bx],cl    ; set scroll
  8491.     push    dx
  8492.     mov    dl,bl
  8493.     mov    dh,bl            ; start/stop line numbers
  8494.     call    touchup            ; repaint just this line
  8495.     pop    dx
  8496. dglrwor5:inc    bx            ; next line
  8497.     pop    cx
  8498.     loop    dglrwor2
  8499.     ret
  8500. dglrworker endp
  8501.  
  8502. dginsl    proc    near            ; RS F H  DG Insert Line in window
  8503.     push    dx            ; save cursor
  8504.     mov    param,0            ; set up ANSI call
  8505.     call    inslin            ; do insert line, can scroll
  8506.     pop    dx            ; recover cursor
  8507.     jmp    atsetcur        ; reset cursor
  8508. dginsl    endp
  8509.  
  8510. dgdell    proc    near            ; RS F I  DG Delete Line in window
  8511.     mov    scroll,1        ; line count
  8512.     push    word ptr mar_top    ; save current scrolling margins
  8513.     mov    mar_top,dh        ; temp top margin is here
  8514.     call    atscru            ; scroll up
  8515.     pop    word ptr mar_top    ; restore scrolling margins
  8516.     ret
  8517. dgdell    endp
  8518.  
  8519. dgnarrow proc    near            ; RS F J  DG select normal spacing
  8520.     mov    cx,dgwindcnt        ; number of windows
  8521.     xor    bx,bx
  8522.     jcxz    dgnarr3            ; z = none
  8523.     inc    cx            ; let implied last window be seen
  8524. dgnarr1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  8525.     jbe    dgnarr3            ; be = cursor is in this window
  8526.     add    bx,2            ; skip two margin bytes
  8527.     loop    dgnarr1            ; next window
  8528. dgnarr2:ret
  8529.  
  8530. dgnarr3:mov    cx,dgwindow[bx]        ; get mar_top and mar_bot (ch)
  8531.     push    cx            ; save margins for touchup below
  8532.     mov    bl,cl            ; mar_top
  8533.     xor    bh,bh
  8534.     sub    ch,cl            ; mar_bot - mar_top = lines in win -1
  8535.     xchg    ch,cl
  8536.     xor    ch,ch
  8537.     inc    cx
  8538.     xor    ax,ax            ; zero and make ah a changed flag
  8539. dgnarr4:mov    al,dgwindcomp[bx]
  8540.     and    dgwindcomp[bx],not 1    ; set window to normal width
  8541.     and    al,1            ; select width, ignore font
  8542.     or    ah,al            ; remember if window line were wide
  8543.     inc    bx
  8544.     loop    dgnarr4            ; do all lines in the window
  8545.     mov    cl,byte ptr low_rgt+1    ; see if any screen lines are wide
  8546.     inc    cl            ; text lines
  8547.     xor    ch,ch
  8548.     xor    bx,bx
  8549.     xor    al,al
  8550. dgnarr5:test    dgwindcomp[bx],1    ; count wide lines
  8551.     jz    dgnarr6            ; z = narrow
  8552.     inc    al
  8553.     jmp    short dgnarr7        ; one wide line is enough to count
  8554. dgnarr6:inc    bx
  8555.     loop    dgnarr5
  8556.  
  8557. dgnarr7:pop    cx            ; margins
  8558.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8559.     jz    dgnarr8            ; z = no
  8560.     or    ah,ah            ; any line widths changed?
  8561.     jz    dgnarr7a        ; z = no
  8562.     push    dx
  8563.     mov    dx,cx            ; cx = saved margins 
  8564.     call    touchup            ; dl, dh are start stop rows
  8565.     pop    dx
  8566. dgnarr7a:ret
  8567. dgnarr8:or    al,al            ; count of wide lines
  8568.     jz    dgnarr9            ; z = all are narrow, go to 80 cols
  8569.     ret                ; leave screen as-is with wide line(s)
  8570. dgnarr9:mov    al,3            ; prep call on atrsm6, 132/80 col
  8571.     mov    modeset,0        ; say want 80 columns
  8572.     jmp    atrsm6            ; common worker
  8573. dgnarrow endp
  8574.  
  8575. dgwide    proc    near            ; RS F K  DG select compressed spacing
  8576.     mov    cx,dgwindcnt        ; number of windows
  8577.     xor    bx,bx
  8578.     jcxz    dgwide3            ; z = none, means one as whole screen
  8579.     inc    cx            ; let implied last window be seen
  8580. dgwide1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  8581.     jbe    dgwide3            ; be = cursor is in this window
  8582.     add    bx,2            ; skip two margin bytes
  8583.     loop    dgwide1            ; next window
  8584. dgwide2:ret
  8585.  
  8586. dgwide3:mov    cx,dgwindow[bx]        ; get mar_top and mar_bot (ch)
  8587.     push    cx            ; save them for touchup below
  8588.     mov    bl,cl            ; mar_top
  8589.     xor    bh,bh
  8590.     sub    ch,cl            ; mar_bot - mar_top = lines in win -1
  8591.     xchg    ch,cl
  8592.     xor    ch,ch
  8593.     inc    cx
  8594.     mov    ax,1            ; al is set, ah is changed flag
  8595. dgwide5:mov    al,dgwindcomp[bx]
  8596.     or    dgwindcomp[bx],1    ; set this line to wide width
  8597.     xor    al,1            ; pick out width bit change
  8598.     or    ah,al            ; accumulate changes
  8599.     inc    bx
  8600.     loop    dgwide5            ; do all lines in the window
  8601.     pop    cx            ; margins
  8602. ifndef    no_graphics
  8603.     test    ah,2            ; soft fonts involved?
  8604.     jnz    dgwide5a        ; nz = yes, force graphics mode
  8605.     test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8606.     jnz    dgwide7            ; nz = yes
  8607.     test    vtemu.vtflgop,vscompress ; allowed to use graphics for it?
  8608.     jnz    dgwide8            ; nz = no, use 132 column text mode
  8609. dgwide5a:test    tekflg,tek_active+tek_sg ; special graphics mode active?
  8610.     jnz    dgwide7            ; nz = yes
  8611. dgwide6:push    cx
  8612.     push    dx
  8613.     call    dgsettek        ; setup special graphics mode
  8614.     pop    dx
  8615.     pop    cx
  8616.     ret
  8617. dgwide7:or    ah,ah            ; any changes to width?
  8618.     jz    dgwide7a        ; z = no
  8619.     push    dx
  8620.     mov    dx,cx            ; saved margins
  8621.     call    touchup            ; dl, dh are start stop rows
  8622.     pop    dx
  8623. dgwide7a:ret
  8624. endif    ; no_graphics
  8625.  
  8626. dgwide8:mov    al,3            ; prep call on atrsm6, 132/80 col
  8627.     mov    modeset,1        ; say want 132 columns
  8628.     call    atrsm6            ; common worker
  8629. ifndef    no_graphics
  8630.     cmp    byte ptr low_rgt,79
  8631.     jbe    dgwide6            ; did not work, use graphics anyway
  8632. endif    ; no_graphics
  8633.     ret
  8634. dgwide    endp
  8635.  
  8636. ; Toggle Normal/Compressed modes from the keyboard.
  8637. dgnctoggle proc    far
  8638.     mov    dx,cursor        ; get cursor
  8639.     mov    bl,dh            ; get row
  8640.     xor    bh,bh
  8641.     test    dgwindcomp[bx],1    ; normal mode?
  8642.     jz    dgnctog4        ; z = yes, do compressed
  8643.     call    dgnarrow        ; do normal
  8644.     ret
  8645. dgnctog4:call    dgwide            ; do compressed
  8646.     ret
  8647. dgnctoggle endp
  8648.  
  8649. dginsc    proc    near            ; RS J  DG Insert char
  8650.     mov    dx,cursor
  8651.     cmp    protectena,0        ; protected mode enabled?
  8652.     jne    dginsc1            ; ne = yes, find new right margin
  8653.     jmp    inschr            ; do regular inschr
  8654. dginsc1:cmp    dl,mar_right        ; at right margin?
  8655.     jae    dginsc2            ; ae = yes
  8656.     call    dgcurpchk        ; check for protected char
  8657.     jc    dginsc2            ; c = protected
  8658.     inc    dl            ; next column right
  8659.     jmp    short dginsc1        ; continue scanning
  8660.  
  8661. dginsc2:mov    al,mar_right        ; save right margin
  8662.     push    ax
  8663.     dec    dl            ; do not include margin char
  8664.     mov    mar_right,dl
  8665.     mov    dx,cursor
  8666.     call    inschr            ; insert char
  8667.     pop    ax
  8668.     mov    mar_right,al
  8669.     ret
  8670. dginsc    endp
  8671.  
  8672. dgdelc    proc    near            ; RS K  DG Delete char
  8673.     mov    dx,cursor
  8674.     mov    param,0            ; set up ANSI call for one char
  8675.     cmp    protectena,0        ; protected mode enabled?
  8676.     jne    dgdelc1            ; ne = yes, find new right margin
  8677.     jmp    atdelc            ; do delete
  8678. dgdelc1:cmp    dl,mar_right        ; at right margin?
  8679.     jae    dgdelc2            ; ae = yes
  8680.     call    dgcurpchk        ; check for protected char
  8681.     jc    dgdelc2            ; c = protected
  8682.     inc    dl            ; next column right
  8683.     jmp    short dgdelc1        ; continue scanning
  8684.  
  8685. dgdelc2:mov    al,mar_right        ; save right margin
  8686.     push    ax
  8687.     dec    dl            ; do not include margin char
  8688.     mov    mar_right,dl
  8689.     mov    dx,cursor
  8690.     call    atdelc            ; do delete
  8691.     pop    ax
  8692.     mov    mar_right,al
  8693.     ret
  8694. dgdelc    endp
  8695.  
  8696. dgilbm    proc    near            ; RS F [ Insert line between margins
  8697.     mov    al,dghscrdis        ; save horz scrolling disable flag
  8698.     push    ax            ; save til the end
  8699.     mov    dghscrdis,1        ; disable horz scrolling for this cmd
  8700.     mov    cursor,dx        ; save this
  8701.     mov    dl,mar_left        ; start at the left side
  8702.     mov    dh,mar_bot        ; bottom of window
  8703.     or    dh,dh            ; row zero?
  8704.     jz    dgilbm2            ; z = yes, just clear the line
  8705.  
  8706. dgilbm1:dec    dh            ; up one row
  8707.     call    getatch            ; read a char
  8708.     inc    dh            ; go down a row
  8709.     call    qsetatch        ; write the char
  8710.     inc    dl            ; next column
  8711.     cmp    dl,mar_right        ; off end of row yet?
  8712.     jbe    dgilbm1            ; be = no
  8713.     or    dh,dh            ; finished top row?
  8714.     jz    dgilbm2            ; z = yes
  8715.     dec    dh            ; redo this one row up
  8716.     mov    dl,mar_left        ; reset to left window margin
  8717.     cmp    dh,byte ptr cursor+1    ; finished cursor row yet?
  8718.     jae    dgilbm1            ; ae = no
  8719. dgilbm2:mov    dx,cursor        ; clear line cursor was on
  8720.     mov    al,mar_left        ; from left margin
  8721.     mov    bl,mar_right        ; to right window margin
  8722.     call    erinline        ; clear the window line
  8723.     mov    dl,dh
  8724.     mov    dh,mar_bot        ; lines changed
  8725.     call    touchup            ; redisplay the new material
  8726.     mov    dx,cursor
  8727.     pop    ax            ; recover horz scroll disable flag
  8728.     mov    dghscrdis,al
  8729.     ret
  8730. dgilbm    endp
  8731.  
  8732. dgdlbm    proc    near            ; RS F \ Delete line between margins
  8733.     mov    al,dghscrdis        ; get horizontal scroll disable flag
  8734.     push    ax            ; save til the end
  8735.     mov    dghscrdis,1        ; disable horz scrolling for this cmd
  8736.     mov    cursor,dx        ; save cursor position
  8737.     mov    dl,mar_left        ; start at the left side
  8738. dgdlbm1:inc    dh            ; down one row
  8739.     call    getatch            ; read a char
  8740.     dec    dh            ; go up a row
  8741.     call    qsetatch        ; write the char
  8742.     inc    dl            ; next column
  8743.     cmp    dl,mar_right        ; off end of row yet?
  8744.     jbe    dgdlbm1            ; be = no
  8745.     inc    dh            ; redo this one row down
  8746.     mov    dl,mar_left        ; reset to left window margin
  8747.     cmp    dh,mar_bot        ; finished bottom row yet
  8748.     jbe    dgdlbm1            ; be = no
  8749.     mov    dh,mar_bot        ; clear last line in window
  8750.     mov    al,mar_left
  8751.     mov    bl,mar_right
  8752.     call    erinline        ; clear the window line
  8753.     pop    ax            ; recover horz scroll disable flag
  8754.     mov    dghscrdis,al
  8755.     mov    dx,cursor
  8756.     mov    dl,dh            ; region changed
  8757.     mov    dh,mar_bot
  8758.     call    touchup
  8759.     ret
  8760. dgdlbm    endp
  8761.  
  8762. dgscs    proc    near            ; RS F S <nn>  DG Select Char Set
  8763.     mov    bx,dgscs1        ; setup for <nn> value
  8764.     jmp    get2n
  8765. dgscs1:    mov    bx,dgnum        ; get DG char set idents
  8766.     cmp    bl,1fh            ; last hard char set
  8767.     jbe    dgscs2            ; be = in the hard sets
  8768.     cmp    bl,45h            ; end of soft sets
  8769.     jbe    dgscs1a            ; be = in range
  8770.     ret                ; else ignore command
  8771. dgscs1a:add    bl,100-20h+1        ; add local offset for chrsetup
  8772.     jmp    short dgscs4        ; prep for chrsetup
  8773.  
  8774. dgscs2:    or    bl,bl            ; use "keyboard language"?
  8775.     jnz    dgscs3            ; nz = no
  8776.     mov    bl,vtemu.vtchset    ; get setup char set
  8777.     cmp    bl,13            ; top of the NRCs
  8778.     jbe    short dgscs4        ;  as keyboard language
  8779.     xor    bx,bx            ; default to ASCII
  8780. dgscs3:    mov    bl,dgchtab[bx]        ; translate to Kermit idents
  8781. dgscs4:    cmp    GLptr,offset G0set    ; are we shifted out?
  8782.     jne    dgscs5            ; ne = yes, presume G1set
  8783.     mov    Gsetid,bl        ; new set ident for G0
  8784.     jmp    short dgscs6
  8785. dgscs5:    mov    Gsetid+1,bl        ; new set ident for G1
  8786. dgscs6:    mov    bx,offset Gsetid    ; pass list of sets to setup
  8787.     jmp    chrsetup        ; go make the new set
  8788. dgscs    endp
  8789.  
  8790. dgalign    proc    near            ; RS F > char DG fill screen with char
  8791.     mov    ttstate,offset dgalig1    ; get char
  8792.     ret
  8793. dgalig1:mov    ttstate,offset atnrm    ; reset state
  8794.     jmp    atalig1            ; do DEC alignment work, char in AL
  8795. dgalign    endp
  8796.  
  8797. dggrid    proc    near            ; RS F 9 char DG fill screen with grid
  8798.     mov    al,'#'            ; set grid char in standard place
  8799.     jmp    atalig1            ; do DEC alignment work, char in AL
  8800. dggrid    endp
  8801.  
  8802.     
  8803. dgrolldis:mov    dgroll,0        ; Control-S  DG roll disable
  8804.     ret
  8805.  
  8806. dgrollena:mov    dgroll,1        ; Control-R  DG roll enable
  8807.     ret
  8808.  
  8809. dghsena:mov    dghscrdis,0        ; RS F ^  DG horiz scroll enable
  8810.     mov    dx,cursor
  8811.     jmp    atsetcur        ; set cursor to cause screen update
  8812.  
  8813. dghsdis:mov    dghscrdis,1        ; RS F ]  DG horiz scroll disable
  8814.     ret
  8815.  
  8816. dgpton:    call    setprot            ; RS F L  DG Protect on
  8817.     ret
  8818.  
  8819. dgptoff:call    clrprot            ; RS F M  DG Protect off
  8820.     ret
  8821.  
  8822. protena:mov    protectena,1        ; RS F V  DG Protect enable
  8823.     ret                ; 
  8824.     
  8825. protdis:mov    protectena,0        ; RS F W  DG Protect disable
  8826.     ret                ; 
  8827.  
  8828. dg78bit    proc    near            ; RS F U <n>  DG Select 7/8 bit ops
  8829.     mov    bx,dg78bit1        ; get <n>
  8830.     jmp    get1n
  8831. dg78bit1:cmp    dgnum,1            ; 0 is 7 bit, 1 is 8 bit
  8832.     ja    dg78bit3        ; a = illegal value, ignore
  8833.     je    dg78bit2        ; e = 1
  8834.     and    flags.remflg,not d8bit    ; 7-bit, chop DG high bit
  8835.     ret
  8836. dg78bit2:or    flags.remflg,d8bit    ; 8-bit
  8837. dg78bit3:ret
  8838. dg78bit    endp
  8839.  
  8840. dgdhdw    proc    near            ; RS R E <n>  DG Double high/wide
  8841.     mov    bx,offset dgdhdw1
  8842.     jmp    get1n            ; set up for <n> arg
  8843. dgdhdw1:mov    ax,dgnum        ; get <nn> result
  8844.     or    ax,ax            ; 2 and above are double highs
  8845.     jz    dgdhdw2
  8846.     mov    al,2            ; map double highs to 2
  8847.     jmp    linedbl            ; make line double width
  8848. dgdhdw2:jmp    linesgl            ; make single width
  8849. dgdhdw    endp
  8850.  
  8851. dgs25l    proc                ; RS F z <n>  DG go to/set status line
  8852.     mov    bx,offset dgs25l1    ; prep for <n> mode value
  8853.     jmp    get1n
  8854. dgs25l1:mov    ax,dgnum        ; get mode
  8855.     or    ax,ax            ; 0, 25th line is status?
  8856.     jnz    dgs25l2            ; nz = no
  8857.     mov    dspstate,0        ; no longer on mode line
  8858.     mov    param,1            ; turn on regular mode line
  8859.     call    atssdt1            ; do main worker
  8860.     ret
  8861.  
  8862. dgs25l2:cmp    al,3            ; blank the line?
  8863.     jne    dgs25l3            ; ne = no
  8864.     jmp    atssdt1            ; do main worker
  8865.     cmp    al,2            ; use as ordinary text?
  8866.     jne    dgs25l3            ; ne = no
  8867.     ret                ; ignore this request
  8868. dgs25l3:cmp    al,1            ; get msg for line?
  8869.     je    dgs25l4            ; e = yes
  8870.     ret
  8871. dgs25l4:mov    bx,offset dgs25l5    ; prep for <nn> text
  8872.     jmp    get2n
  8873. dgs25l5:mov    dspcmain,dx        ; save cursor in special area
  8874.     mov    dspstate,dsptype    ; say on status line
  8875.     mov    al,mar_left
  8876.     mov    ah,mar_right
  8877.     mov    dspmsave,ax        ; save margins
  8878.     mov    mar_left,0        ; set left to screen left
  8879.     call    fclrmod            ; clear the line
  8880.     and    yflags,not modoff    ; say modeline is not toggled off
  8881.     mov    flags.modflg,2        ; say mode line is owned by host
  8882.     mov    dh,byte ptr low_rgt+1    ; bottom text line
  8883.     inc    dh            ; status line
  8884.     xor    dl,dl            ; absolute left margin
  8885.     call    atsetcur        ; set cursor
  8886.     cmp    dgnum,0            ; number of chars of text
  8887.     je    dgs25l7            ; e = none
  8888.     mov    ttstate,offset dgs25l6    ; come here for text
  8889.     ret
  8890. dgs25l6:call    atnrm            ; write the character
  8891.     dec    dgnum            ; one less to do
  8892.     cmp    dgnum,0            ; done?
  8893.     jle    dgs25l7            ; le = yes
  8894.     ret                ; stay on status line
  8895. dgs25l7:mov    ttstate,offset atnrm    ; reset state
  8896.     mov    dx,dspcmain        ; restore cursor
  8897.     mov    ax,dspmsave        ; saved margins
  8898.     mov    mar_left,al
  8899.     mov    mar_right,ah
  8900.     mov    dspstate,0        ; no longer on mode line
  8901.     jmp    atsetcur        ; set cursor
  8902. dgs25l    endp
  8903.  
  8904. dgnscur    proc    near            ; RS F } <n> <n> DG cursor named save
  8905.     mov    bx,offset dgnscu1    ; get <n> memory cell (name, 0..15)
  8906.     jmp    get1n
  8907. dgnscu1:mov    ax,dgnum        ; get cell number
  8908.     mov    word ptr emubuf,ax    ; save here
  8909.     mov    bx,offset dgnscu2    ; get <n> save (0) / restore (1)
  8910.     jmp    get1n
  8911. dgnscu2:mov    bx,word ptr emubuf    ; get named subscript
  8912.     mov    ax,dgnum        ; get op code
  8913.     cmp    ax,1            ; save?
  8914.     jb    dgnscu3            ; b = save
  8915.     ja    dgnscu4            ; a = illegal, ignore
  8916.     mov    al,dgctypesave[bx]    ; get cursor size/type
  8917.     mov    atctype,al        ; active type
  8918.     call    csrtype            ; set it
  8919.     mov    dx,dgcursave[bx]    ; restore cursor position from storage
  8920.     jmp    dgsetcur        ; set the cursor DG style
  8921. dgnscu3:mov    dgcursave[bx],dx    ; save cursor
  8922.     mov    al,atctype        ; get cursor type
  8923.     mov    dgctypesave[bx],al    ; save
  8924. dgnscu4:ret
  8925. dgnscur    endp
  8926.  
  8927. dgsps    proc    near                 ; DG dual emulation set split screen
  8928.     mov    ttstate,offset dgsps1    ; RS R A 0 <nn><n> or RS R A 1 <nn>
  8929.     ret
  8930. dgsps1:    mov    bx,offset atnrm        ; setup to ignore command
  8931.     cmp    al,1            ; 0 or 1 expected
  8932.     ja    dgsps3            ; a = illegal, ignore
  8933.     je    dgsps2            ; e = case 1 <nn>
  8934.     jmp    get3n            ; case 0 <nn><n> as <nnn>
  8935. dgsps2:    jmp    get2n
  8936. dgsps3:    ret
  8937. dgsps    endp
  8938.  
  8939. dgdchs    proc    near            ; RS F q <nn><nn> Dealloc Char Sets
  8940.     mov    bx,offset dgdchs1    ; ignore for now
  8941.     jmp    get2n
  8942. dgdchs1:mov    bx,offset atnrm
  8943.     jmp    get2n
  8944. dgdchs    endp
  8945.  
  8946. dgdefch    proc    near            ; RS F R <char> 10/12<nn>'s Def Char
  8947.     mov    ttstate,offset dgdefc1    ; get char
  8948.     ret
  8949. dgdefc1:mov    emubufc,0        ; set counter
  8950.     mov    emubuf,al        ; char to be defined
  8951.     mov    cl,14            ; video cell bytes per char (8x14)
  8952.     mul    cl            ; ax = bytes to start of char
  8953.     mov    word ptr emubuf+1,ax    ; save string distance
  8954.     mov    ax,10            ; assume D470
  8955.     cmp    flags.vtflg,ttd470    ; D470?
  8956.     je    dgdefc1a        ; e = yes, uses 10 byte pairs
  8957.     mov    ax,12            ; D463 uses 12 byte pairs
  8958. dgdefc1a:mov    word ptr emubuf+3,ax    ; save string length
  8959.     jmp    dgdefc3            ; setup to get data
  8960.  
  8961. dgdefc2:mov    ax,word ptr emubuf+1    ; get char being defined
  8962.     add    ax,emubufc        ; plus byte into string
  8963.     inc    emubufc            ; count a <nn> pair
  8964. ifndef    no_graphics
  8965.     mov    bx,softptr        ; seg of soft font
  8966. else
  8967.     xor    bx,bx
  8968. endif    ; no_graphics
  8969.     or    bx,bx            ; segment of soft font, defined?
  8970.     jz    dgdefc3            ; z = no, do not store
  8971.     push    es
  8972.     mov    es,bx
  8973.     mov    bx,ax            ; offset to byte
  8974.     mov    ax,dgnum        ; get value
  8975.     cmp    emubuf+3,10        ; for D470 (8 bits wide)?
  8976.     je    dgdefc2a        ; e = yes
  8977.     shr    ax,1            ; D463, 10 bits, chop right most too
  8978. dgdefc2a:mov    es:[bx],al        ; store byte
  8979.     pop    es
  8980.  
  8981. dgdefc3:mov    ax,word ptr emubuf+3    ; wanted string count
  8982.     cmp    emubufc,ax        ; done all?
  8983.     jae    dgdefc6            ; ae = yes
  8984.     mov    bx,offset dgdefc2    ; get char byte pairs
  8985.     cmp    flags.vtflg,ttd470    ; D470?
  8986.     je    dgdefc5            ; e = yes, use get2nn
  8987.     jmp    getdd            ; for D463, 5 bit values
  8988. dgdefc5:jmp    get2n            ; for D470, 4 bit values
  8989.  
  8990. dgdefc6:
  8991. ifndef    no_graphics
  8992.     mov    bx,softptr        ; segment of soft font, defined?
  8993.     or    bx,bx
  8994.     jz    dgdefc7            ; z = no, do not store
  8995. ;JMP DGDEFC7
  8996.     push    es            ; repeat last row of dots
  8997.     push    di
  8998.     mov    es,bx
  8999.     mov    di,word ptr emubuf+1    ; start plus char offset
  9000.     mov    cx,emubufc        ; get current count
  9001.     add    di,cx            ; point to last stored char+1
  9002.     sub    cx,14-1            ; 14-1 dots high (omit last line)
  9003.     neg    cx            ; positive number
  9004.     mov    al,es:[di-1]        ; last stored char
  9005.     cmp    al,es:[di-2]        ; same as previous (line drawing)?
  9006.     jne    dgdefc6a        ; ne = no, do not extend cell
  9007.     cld
  9008.     rep    stosb
  9009. dgdefc6a:pop    di
  9010.     pop    es
  9011. endif    ; no_graphics
  9012. dgdefc7:mov    emubufc,0        ; clear counter
  9013.     jmp    atnorm            ; reset state
  9014. dgdefch    endp
  9015.  
  9016. dgrchr    proc    near            ; RS F d  DG Read Chars Remaining
  9017.     mov    al,dgescape        ; response string
  9018.     call    prtbout
  9019.     mov    al,'o'
  9020.     call    prtbout
  9021.     mov    al,'9'
  9022.     call    prtbout
  9023.     mov    al,'0'            ; high part of 10 bit count
  9024. ;graphics
  9025. mov al,'_'
  9026.     call    prtbout
  9027.     mov    al,'0'            ; low part of 10 bit count
  9028. ;graphics
  9029. mov al,'_'
  9030.     call    prtbout
  9031.     ret
  9032. dgrchr    endp
  9033.  
  9034. dgresch    proc    near            ; RS F e <n><n>  DG Reserve Character
  9035.     mov    bx,offset atnorm    ; discard
  9036.     jmp    get2n
  9037. dgresch    endp
  9038.  
  9039. dgskl    proc    near            ; RS F f <n>  DG Set Kbd Language
  9040.     mov    bx,offset dgskl1
  9041.     jmp    get1n            ; get parameter
  9042. dgskl1:    mov    ax,dgnum        ; 0=setup, 1=DG Int, 2=Latin1
  9043.     cmp    ax,2            ; in range?
  9044.     ja    dgskl4            ; a = no
  9045.     cmp    ax,1            ; DG International?
  9046.     je    dgskl2            ; e = yes
  9047.     ja    dgskl3            ; a = no, Latin1
  9048.     mov    al,vtemu.vtchset    ; get setup char set
  9049.     mov    dgkbl,al        ; store keyboard language ident
  9050.     ret
  9051. dgskl2:    mov    dgkbl,20        ; DG International
  9052.     ret
  9053. dgskl3:    mov    dgkbl,16        ; Latin1
  9054. dgskl4:    ret
  9055. dgskl    endp
  9056.  
  9057. dgsdo    proc    near            ; RS R B <n><n><n> Set Device Options
  9058.     mov    bx,offset dgsdo1    ; get first <n>
  9059.     jmp    get1n
  9060. dgsdo1:    mov    bx,offset atnrm        ; get second and third <n>'s
  9061.     jmp    get2n            ; discard all
  9062. dgsdo    endp
  9063.  
  9064. dgsfield:mov    bx,offset dgsfie1    ; RS F C <ss><rr>  Field attributes
  9065.     jmp    get2n            ; get first <nn>
  9066. dgsfie1:mov    bx,offset atnrm        ; discard proc
  9067.     jmp    get2n            ; get second <nn>
  9068.  
  9069. dgspage:mov    bx,offset dgspag1    ; RS F D <ss><rr>  Page attributes
  9070.     jmp    get2n            ; get first <nn>
  9071. dgspag1:mov    bx,offset atnrm        ; discard proc
  9072.     jmp    get2n            ; get second <nn>
  9073.  
  9074. dgsetw    proc    near            ; RS F B <nn><n>.. Set windows
  9075.     mov    dgwindcnt,0        ; count of windows entries
  9076.     mov    emubuf+4,0        ; normal(0)/compressed (!0) flag
  9077. dgsetw1:mov    bx,offset dgsetw2    ; next processor
  9078.     jmp    get2n            ; get a <nn> window length
  9079. dgsetw2:mov    ax,dgnum
  9080.     mov    word ptr emubuf,ax    ; save around get1n work
  9081.     mov    bx,offset dgsetw2a    ; get <n> 0/1, compressed mode
  9082.     jmp    get1n
  9083. dgsetw2a:mov    ax,dgnum
  9084.     mov    emubuf+4,al        ; save copy for just this window
  9085.     mov    ax,word ptr emubuf    ; <nn> length, 0 (end) to 24
  9086.     or    ax,ax            ; end of set indicator?
  9087.     jnz    dgsetw2b        ; nz = no
  9088.     mov    ax,24            ; pseudo end
  9089. dgsetw2b:xchg    al,ah            ; put row in ah
  9090.     mov    bx,dgwindcnt        ; get subscript
  9091.     cmp    bx,24            ; too many windows? (24 == DG limit)
  9092.     ja    dgsetw7            ; a = yes, else accept data
  9093.     inc    bx
  9094.     mov    dgwindcnt,bx        ; update counter (1 == one window)
  9095.     dec    bx
  9096.     shl    bx,1            ; index words
  9097.     or    bx,bx            ; initial window?
  9098.     jnz    dgsetw3            ; nz = no
  9099.     xor    al,al            ; start at 0,0
  9100.     jmp    short dgsetw4
  9101. dgsetw3:mov    al,byte ptr dgwindow[bx-1] ; previous ending line
  9102.     inc    al            ; start this window down one line
  9103. dgsetw4:add    ah,al            ; new mar_bot = new mar_top + skip
  9104.     dec    ah            ; count lines from zero
  9105.     cmp    ah,byte ptr low_rgt+1    ; bottom of displayable screen?
  9106.     jb    dgsetw5            ; b = no
  9107.     mov    ah,byte ptr low_rgt+1    ; clamp to that bottom
  9108. dgsetw5:mov    dgwindow[bx],ax        ; save [al=mar_top,ah=mar_bot] pair
  9109.     mov    al,ah            ; get current bottom
  9110.     mov    ah,byte ptr low_rgt+1    ; last text line
  9111.     mov    dgwindow[bx+2],ax    ; fill remaining space with next wind
  9112.  
  9113.     push    bx            ; setup new margins, keep window ptr
  9114.     mov    dghscrdis,0        ; horz scroll disable is disabled
  9115.     mov    cx,slen            ; max screen length
  9116.     mov    al,mar_left
  9117.     xor    bx,bx
  9118. dgsetw6:mov    linescroll[bx],al    ; horiz scroll left margin to edge
  9119.     inc    bx
  9120.     loop    dgsetw6
  9121.     pop    bx            ; recover current line count in bx
  9122.  
  9123.     mov    al,emubuf+4        ; get compressed/normal for this wind
  9124.     mov    dh,byte ptr dgwindow[bx+1]; set cursor to bottom row of window
  9125.     or    al,al            ; to regular width?
  9126.     jnz    dgsetw7            ; nz = no, to compressed
  9127.     call    dgnarrow        ; to normal width
  9128.     jmp    short dgsetw8
  9129. dgsetw7:call    dgwide            ; compress things
  9130.  
  9131. dgsetw8:mov    bx,dgwindcnt        ; get window count
  9132.     or    bx,bx            ; any windows (0 = no)
  9133.     jz    dgsetw9
  9134.     dec    bx            ; count from 0
  9135.     shl    bx,1            ; count words
  9136.     mov    al,byte ptr low_rgt+1    ; last text line on screen (typ 23)
  9137.     cmp    byte ptr dgwindow[bx+1],al ; DG limit of 24 lines?
  9138.     jb    dgsetw1            ; b = not reached yet, keep going
  9139.  
  9140. dgsetw9:call    dgshome            ; do necessary DG Screen Home
  9141.     ret
  9142. dgsetw    endp
  9143.  
  9144. dgwwa    proc    near            ; Control-P col row
  9145.     mov    ttstate,offset dgwwa1    ; DG Write window address (win rel)
  9146.     ret                ; get raw binary col
  9147. dgwwa1:    mov    emubuf,al        ; save col
  9148.     mov    ttstate,offset dgwwa2    ; get raw binary row
  9149.     ret
  9150. dgwwa2:    mov    ttstate,offset atnrm    ; reset state
  9151.     cmp    al,127            ; 127 means use current row
  9152.     je    dgwwa3            ; e = yes
  9153.     add    al,mar_top        ; relative to window top
  9154.     mov    dh,al            ; set cursor row
  9155. dgwwa3:    xor    al,al            ; get a zero
  9156.     xchg    al,emubuf        ; get raw column, clear temp word
  9157.     cmp    al,127            ; 127 means use current column
  9158.     je    dgwwa4            ; e = yes
  9159.     add    al,mar_left        ; add left margin
  9160.     mov    dl,al            ; new cursor position
  9161. dgwwa4:    cmp    dh,mar_bot        ; below bottom of window?
  9162.     jbe    dgwwa5            ; be = no, in bounds
  9163.     mov    dh,mar_bot        ; peg at bottom
  9164. dgwwa5:    cmp    dl,mar_right        ; beyond right margin?
  9165.     jbe    dgwwa6            ; be = no, in bounds
  9166.     mov    dl,mar_right        ; peg at right
  9167. dgwwa6:    jmp    dgsetcur        ; set cursor within window
  9168. dgwwa    endp
  9169.  
  9170. dgwsa    proc    near            ; RS F P <nn><nn> Write screen address
  9171.     mov    bx,offset dgwsa1    ; get <nn> col
  9172.     jmp    get2n
  9173. dgwsa1:    mov    ax,dgnum        ; absolute column
  9174.     mov    ah,mar_right        ; right most virtual column
  9175.     cmp    al,-1            ; means same screen column?
  9176.     je    dgwsa2a            ; e = yes
  9177.     cmp    al,ah            ; beyond right screen limit?
  9178.     jbe    dgwsa2            ; be = no
  9179.     mov    al,ah            ; peg at the right
  9180. dgwsa2:    mov    byte ptr cursor,al    ; column of cursor
  9181. dgwsa2a:mov    bx,offset dgwsa3    ; get <nn> row
  9182.     jmp    get2n
  9183. dgwsa3:    mov    ax,dgnum        ; get absolute row
  9184.     mov    ah,byte ptr low_rgt+1    ; last text row
  9185.     cmp    al,-1            ; means same screen row?
  9186.     je    dgwsa5            ; e = yes
  9187.     cmp    al,ah            ; below text screen?
  9188.     jbe    dgwsa4            ; be = no
  9189.     mov    al,ah            ; peg at the bottom
  9190. dgwsa4:    mov    byte ptr cursor+1,al    ; new row
  9191. dgwsa5:    mov    dx,cursor
  9192.     call    dggetmar        ; get margins for this dx
  9193.     add    dl,mar_left        ; add left margin
  9194.     jmp    dgsetcur        ; set cursor, protection included
  9195. dgwsa    endp
  9196.  
  9197. dgshome    proc    near            ; RS F G  DG Screen Home
  9198.     xor    dh,dh            ; absolute screen top
  9199.     call    dggetmar        ; get margins for this dx
  9200.     mov    dl,mar_left        ; go to left margin
  9201.     jmp    dgsetcur        ; set the cursor
  9202. dgshome    endp
  9203.  
  9204. dgsetmar proc    near            ; RS F X <nn> <nn> Set margins
  9205.     call    dggetmar        ; get margins for this window row
  9206.     mov    bx,offset dgsetm1    ; get <nn> left margin
  9207.     jmp    get2n
  9208. dgsetm1:mov    al,mar_left        ; current left margin
  9209.     mov    emubuf,al
  9210.     mov    ax,dgnum        ; get left margin info
  9211.     cmp    al,-1            ; use current margin?
  9212.     je    dgsetm2            ; e = yes
  9213.     mov    emubuf,al        ; set left margin
  9214. dgsetm2:mov    bx,offset dgsetm3    ; get right margin
  9215.     jmp    get2n
  9216. dgsetm3:mov    ax,dgnum        ; get right margin info
  9217.     cmp    al,-1            ; use current margin?
  9218.     jne    dgsetm4            ; ne = no
  9219.     mov    al,vswidth-1        ; use full screen
  9220. dgsetm4:cmp    al,vswidth-1        ; check sanity
  9221.     ja    dgsetmx            ; a = too large a right margin
  9222.     cmp    al,emubuf        ; getting things on the wrong side?
  9223.     jb    dgsetmx            ; b = yes (ok for left=right)
  9224. dgsetm5:cmp    emubuf,vswidth-1    ; this side too
  9225.     jae    dgsetmx            ; ae = too large
  9226.     mov    mar_right,al        ; set right margin
  9227.     mov    al,emubuf        ; new left
  9228.     mov    mar_left,al        ; new left
  9229.     mov    byte ptr cursor,al    ; set cursor to left margin
  9230.     mov    dx,cursor
  9231.     mov    emubuf,al        ; preset args for dgschw1
  9232.     mov    al,mar_right
  9233.     mov    emubuf+1,al
  9234.     jmp    dgschw1            ; try to show both margins, set cursor
  9235. dgsetmx:ret                ; ignore command
  9236. dgsetmar endp
  9237.  
  9238. dgsetamar proc    near            ; DG RS F Y <nn><nn><nn>
  9239.     cmp    savdgmar,0        ; have we saved l/r margins?
  9240.     jne    dgsetam0        ; ne = yes, don't save current
  9241.     mov    ah,mar_right        ; save originals
  9242.     mov    al,mar_left
  9243.     mov    savdgmar,ax        ; saved
  9244. dgsetam0:mov    bx,offset dgsetam1    ; Set Alternate Margins
  9245.     jmp    get2n            ; get cursor row
  9246. dgsetam1:mov    ax,dgnum        ; cursor row wrt top margin
  9247.     mov    bl,dh            ; row of cursor
  9248.     cmp    al,-1            ; use current row?
  9249.     je    dgsetam2        ; e = yes
  9250.     mov    bl,mar_top        ; get row at top of this window
  9251.     add    bl,al            ; new cursor row is mar_top + new
  9252. dgsetam2:cmp    bl,mar_bot        ; below window?
  9253.     jbe    dgsetam3        ; be = no
  9254.     mov    bl,mar_bot        ; clamp to window bottom
  9255. dgsetam3:mov    emubuf,bl        ; save cursor row
  9256.     mov    bx,offset dgsetam4    ; get <nn> col of new left margin
  9257.     jmp    get2n
  9258. dgsetam4:mov    ax,dgnum
  9259.     mov    bl,byte ptr savdgmar    ; get permanent left margin
  9260.     cmp    al,-1            ; use current left margin?
  9261.     je    dgsetam5        ; e = yes
  9262.     add    bl,al            ; new left, wrt old left
  9263. dgsetam5:mov    word ptr emubuf+2,bx    ; save left margin
  9264.     mov    bx,offset dgsetam6    ; get <nn> right margin
  9265.     jmp    get2n
  9266. dgsetam6:mov    ax,dgnum
  9267.     mov    bl,byte ptr savdgmar+1    ; current right margin
  9268.     cmp    al,-1            ; use current right margin?
  9269.     je    dgsetam7        ; e = yes
  9270.     mov    bl,al            ; new relative right margin
  9271.     add    bl,mar_left        ; relative to old left margin
  9272.     cmp    bl,byte ptr savdgmar+1    ; exceeds old right_margin?
  9273.     jbe    dgsetam7        ; be = no
  9274.     mov    bl,byte ptr savdgmar+1    ; yes, use old right_margin
  9275. dgsetam7:cmp    bl,vswidth-1        ; too far right?
  9276.     ja    dgsetam9        ; a = yes, abandon the command
  9277.     mov    mar_right,bl        ; alt right margin
  9278.     mov    al,emubuf+2        ; get alt left margin
  9279.     mov    mar_left,al
  9280.     mov    dl,al            ; cursor to left margin
  9281.     mov    dh,emubuf        ; get row for cursor
  9282.     mov    dghscrdis,1        ; horz scroll disabled (if 1)
  9283.     call    dgsetcur        ; set cursor
  9284. dgsetam9:ret
  9285. dgsetamar endp
  9286.  
  9287. dgrnmar    proc    near            ; RS F Z  DG Restore normal margins
  9288.     cmp    savdgmar,0        ; anything saved?
  9289.     jz    dgrnma1            ; z = no, do nothing
  9290.     xor    ax,ax            ; get a null
  9291.     xchg    ax,savdgmar        ; recover saved margins, clear saved
  9292.     mov    mar_left,al
  9293.     mov    mar_right,ah
  9294. dgrnma1:ret
  9295. dgrnmar    endp
  9296.  
  9297. ; Worker. Given cursor in dx, set mar_top, mar_bot based on finding the 
  9298. ; DG window for that cursor row.
  9299. dggetmar proc    near
  9300.     mov    cx,dgwindcnt        ; number of windows
  9301.     xor    bx,bx
  9302.     jcxz    dggetma2        ; z = none
  9303.     inc    cx            ; let implied last window be seen
  9304. dggetma1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  9305.     jbe    dggetma3        ; be = cursor is in this window
  9306.     add    bx,2            ; skip two margin bytes
  9307.     loop    dggetma1        ; next window
  9308. dggetma2:ret
  9309.  
  9310. dggetma3:mov    ax,dgwindow[bx]        ; DG Window structure
  9311.     mov    mar_top,al
  9312.     mov    mar_bot,ah
  9313.     ret
  9314. dggetmar endp
  9315.  
  9316. ; Worker. Given cursor in dx, and al=mar_top, ah=mar_bot
  9317. ; store these margins in the window structure for that row, based on
  9318. ; finding the DG window for that cursor row.
  9319. dgstoremar proc    near
  9320.     push    cx
  9321.     mov    cx,dgwindcnt        ; number of windows
  9322.     xor    bx,bx
  9323.     jcxz    dgstore2        ; z = none
  9324. dgstore1:cmp    dh,byte ptr dgwindow[bx+1] ; look at window bottom edge
  9325.     jbe    dgstore2        ; be = cursor is in this window
  9326.     add    bx,2            ; skip two margin bytes
  9327.     loop    dgstore1        ; next window
  9328.     xor    bx,bx            ; fail, use first window slot
  9329. dgstore2:pop    cx
  9330.     mov    dgwindow[bx],ax
  9331.     ret
  9332. dgstoremar endp
  9333.  
  9334. dgsmid    proc    near            ; RS F { <nn><n> DG Set Model ID
  9335.     mov    bx,offset dgsmid1    ; setup for <nn>
  9336.     jmp    get2n
  9337. dgsmid1:mov    ax,dgnum        ; get new model id
  9338.     mov    byte ptr dgaltid,al    ; save
  9339.     mov    bx,dgsmid2        ; get graphics possible (1) bit
  9340.     jmp    get1n
  9341. dgsmid2:mov    ax,dgnum
  9342.     mov    byte ptr dgaltid+1,al
  9343.     ret
  9344. dgsmid    endp
  9345.  
  9346. dgscrup    proc    near            ; DG  RS H
  9347.     mov    scroll,1
  9348.     call    atscru            ; scroll up one line
  9349.     jmp    dgsetcur        ; place according to protected mode
  9350. dgscrup endp
  9351.  
  9352. dgscrdn    proc    near            ; DG  RS I
  9353.     mov    scroll,1
  9354.     call    atscrd            ; scroll down one line
  9355.     jmp    dgsetcur        ; place according to protected mode
  9356. dgscrdn    endp
  9357.  
  9358. dgcuu    proc    near            ; Control-W  DG cursor up
  9359. dgcuu1:    cmp    dh,mar_top        ; above the top margin?
  9360.     ja    dgcuu2            ; a = not on top margin
  9361.     mov    dh,mar_bot        ; roll to bottom margin
  9362.     inc    dh
  9363. dgcuu2:    dec    dh            ; go up one row
  9364.     call    dgcurpchk        ; do proteced mode check
  9365.     jc    dgcub1            ; c = protected, do cursor back
  9366.     jmp    atsetcur        ; set the cursor
  9367. dgcuu    endp
  9368.  
  9369. dgcud    proc    near            ; Control-Z  DG cursor down
  9370. dgcud1:    cmp    dh,mar_bot        ; below the bottom text line?
  9371.     jb    dgcud2            ; b = no
  9372.     mov    dh,mar_top        ; roll to top margin
  9373.     dec    dh
  9374. dgcud2:    inc    dh            ; go down one row
  9375.     call    dgcurpchk        ; check for protected cell
  9376.     jc    dgcuf1            ; c = on protected cell, go forward
  9377.     jmp    dgsetcur        ; set cursor
  9378. dgcud    endp
  9379.  
  9380. dgcuf    proc    near            ; Control-X  DG cursor forward
  9381.     cmp    dl,mar_right        ; test for about to wrap
  9382.     jb    dgcuf1            ; b = not wrapping
  9383.     test    anspflg,vtautop        ; printing desired?
  9384.     jz    dgcuf1            ; e = no
  9385.     push    dx            ; save cursor value
  9386.     call    pntlin            ; print line current line
  9387.     mov    al,LF            ; terminate in LF
  9388.     call    fpntchr
  9389.     call    fpntflsh        ; flush printer buffer
  9390.     mov    atwrap,0
  9391.     pop    dx
  9392.  
  9393. dgcuf1:    cmp    dl,mar_right        ; to right of right margin?
  9394.     jb    dgcuf5            ; b = not on right margin
  9395.     mov    dl,mar_left        ; go to left margin
  9396.     inc    dh            ; and down one
  9397.     cmp    dh,mar_bot        ; below bottom line now?
  9398.     jbe    dgcuf6            ; be = no
  9399.     mov    dh,mar_bot        ; stay on bottom line
  9400.     cmp    dgroll,0        ; is roll mode disabled?
  9401.     jne    dgcuf3            ; ne = no, do the scroll
  9402.     mov    dh,mar_top        ; yes, wrap to top
  9403.     jmp    short dgcuf6
  9404. dgcuf3:    mov    scroll,1
  9405.     call    atsetcur        ; set cursor before the scroll
  9406.     call    atscru            ; scroll up one line
  9407.     ret
  9408. dgcuf5:    inc    dl            ; go right one column
  9409. dgcuf6:    cmp    dx,cursor        ; is this the same place?
  9410.     je    dgcuf7            ; e = yes, stop here
  9411.     call    dgcurpchk        ; check protection
  9412.     jc    dgcuf1            ; c = stepped on protected cell
  9413. dgcuf7:    jmp    atsetcur        ; set cursor
  9414. dgcuf    endp
  9415.  
  9416. dgcub    proc    near            ; Control-Y  DG cursor left
  9417. dgcub1:    cmp    dl,mar_left        ; to left of left margin?
  9418.     ja    dgcub2            ; a = no
  9419.     mov    dl,mar_right        ; go to right margin 
  9420.     jmp    dgcuu1            ; and do a cursor up
  9421. dgcub2:    dec    dl            ; go left one column
  9422.     call    dgcurpchk        ; check protection
  9423.     jc    dgcub1            ; c = stepped on protected cell
  9424.     jmp    atsetcur        ; set real cursor and exit
  9425. dgcub    endp
  9426.  
  9427. dgcurpchk proc    near
  9428.     cmp    protectena,0        ; protected mode enabled?
  9429.     je    dgcurpc1        ; e = no
  9430.     push    dx
  9431.     push    bx
  9432.     mov    bl,dh            ; row
  9433.     xor    bh,bh
  9434.     cmp    linetype[bx],0        ; single width?
  9435.     pop    bx
  9436.     je    dgcurpc2        ; e = yes
  9437.     shl    dl,1            ; double cursor position
  9438. dgcurpc2:call    getatch            ; read char under new cursor position
  9439.     pop    dx
  9440.     test    cl,att_protect        ; protected?
  9441.     jz    dgcurpc1        ; z = no, accept this position
  9442.     stc                ; say stepping on protected char cell
  9443.     ret
  9444. dgcurpc1:clc                ; say no other action needed
  9445.     ret
  9446. dgcurpchk endp
  9447.  
  9448. ; Worker for cursor cmds. Skips protected fields, but remembers if we have
  9449. ; come full circle and then does a cursor right from there. Enter with
  9450. ; pre-motion cursor in "cursor", new desired position in dx.
  9451. dgsetcur proc    near
  9452.     call    dgcurpchk        ; call protected cell checker
  9453.     jnc    dgsetcu1        ; nc = ok, accept this position
  9454.     jmp    dgcuf1            ; do cursor forward
  9455. dgsetcu1:mov    bl,dh            ; get row
  9456.     xor    bh,bh
  9457.     cmp    dl,linescroll[bx]    ; to left of visible screen?
  9458.     jae    dgsetcu2        ; ae = no
  9459.     mov    emubuf,dl        ; set desired left margin
  9460.     mov    cl,mar_right
  9461.     mov    emubuf+2,cl        ; set desired right margin
  9462.     mov    cursor,dx        ; preset for dgschw1
  9463.     jmp    dgschw1            ; do Show Window to track cursor
  9464.  
  9465. dgsetcu2:jmp    atsetcur        ; set real cursor and exit
  9466. dgsetcur endp
  9467.  
  9468. dglf    proc    near            ; Control-J  DG New Line
  9469.     test    anspflg,vtautop        ; printing desired?
  9470.     jz    dglf1            ; e = no
  9471.     push    dx            ; save cursor
  9472.     call    pntlin            ; print line
  9473.     mov    al,LF            ; terminate in LF
  9474.     call    fpntchr
  9475.     call    fpntflsh        ; flush printer buffer
  9476.     mov    atwrap,0
  9477.     pop    dx
  9478. dglf1:    mov    dl,mar_left        ; to left margin
  9479.     cmp    dh,mar_bot        ; on bottom margin?
  9480.     jb    dglf3            ; b = no
  9481.     cmp    dgroll,0        ; is roll disabled
  9482.     je    dglf2            ; e = yes, do home
  9483.     mov    bl,dh            ; row
  9484.     xor    bh,bh
  9485.     mov    al,linescroll[bx]    ; save current line scroll
  9486.     push    dx
  9487.     push    bx
  9488.     push    ax
  9489.     mov    scroll,1
  9490.     call    atscru            ; do a scroll up by one line
  9491.     pop    ax
  9492.     pop    bx
  9493.     pop    dx
  9494.     mov    linescroll[bx],al    ; set line scroll for new line
  9495.     jmp    dgsetcur        ; set cursor, does show columns too
  9496.  
  9497. dglf2:    mov    dh,mar_top        ; do window Home
  9498.     jmp    short dglf4
  9499. dglf3:    inc    dh            ; down one row
  9500. dglf4:    jmp    dgsetcur        ; set cursor wrt protected mode
  9501. dglf    endp
  9502.  
  9503. dgcr    proc    near            ; DG Control-M
  9504.     mov    dl,mar_left        ; go to left margin, same row
  9505.     jmp    dgsetcur        ; set cursor, with protected mode
  9506. dgcr    endp
  9507.  
  9508. dgrmid    proc    near            ; RS C  DG Read Model ID
  9509.     mov    al,dgescape        ; resp RS o # <mm> <x> <y>
  9510.     call    prtbout
  9511.     mov    al,'o'
  9512.     call    prtbout
  9513.     mov    al,'#'
  9514.     call    prtbout
  9515.     mov    al,'5'            ; 5 is DG D217
  9516.     test    flags.vtflg,ttd217    ; D217?
  9517.     jnz    dgrmid6            ; nz = yes
  9518.     mov    al,'6'            ; 6 is DG D413/D463
  9519.     test    flags.vtflg,ttd470    ; D470?
  9520.     jz    dgrmid6            ; z = no
  9521.     mov    al,44            ; 44 is DG D470
  9522. dgrmid6:cmp    byte ptr dgaltid,0    ; alternate ID given?
  9523.     je    dgrmid1            ; e = no
  9524.     mov    al,byte ptr dgaltid    ; use alternate
  9525. dgrmid1:call    prtbout
  9526.     xor    al,al            ; <x> byte, clear it
  9527.     test    flags.remflg,d8bit    ; using 8 bits?
  9528.     jz    dgrmid2            ; z = no
  9529.     or    al,10h            ; say 8-bit mode
  9530. dgrmid2:push    ax
  9531.     mov    ah,ioctl        ; get printer status, via DOS
  9532.     mov    al,7            ; status for output
  9533.     push    bx
  9534.     mov    bx,4            ; std handle for system printer
  9535.     int    dos
  9536.     pop    bx
  9537.     jnc    dgrmid3            ; nc = call succeeded
  9538.     mov    al,0ffh
  9539. dgrmid3:cmp    al,0ffh            ; code for Ready
  9540.     pop    ax
  9541.     jne    dgrmid4            ; ne = not ready
  9542.     or    al,8            ; say printer present
  9543. dgrmid4:or    al,40h
  9544.     call    prtbout            ; send composite byte
  9545.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  9546.     xor    bh,bh
  9547.     mov    al,nrcdgkbd[bx]        ; <y>, get DG keyboard code from table
  9548.     or    al,50h            ; 01+kbd installed (no graphics)
  9549.     or    al,20h            ; say have graphics
  9550.     cmp    byte ptr dgaltid,0    ; alternate id given?
  9551.     je    dgrmid5            ; e = no
  9552.     cmp    byte ptr dgaltid+1,0    ; host wants to say no graphics?
  9553.     jne    dgrmid5            ; ne = no, let things stand
  9554.     and    al,not 20h        ; remove graphics bit
  9555. dgrmid5:call    prtbout
  9556.     ret
  9557. dgrmid    endp
  9558.                     ; D470 command, absent from D463's
  9559. dgscmap    proc    near            ; RS F c <n><n><n><n> DG set color map
  9560.     mov    bx,offset dgscmap1    ; get language ident
  9561.     jmp    get3n            ; get three of the <n>'s
  9562. dgscmap1:mov    bx,offset dgscmap2    ; get the fourth
  9563.     jmp    get1n
  9564. dgscmap2:ret
  9565. dgscmap    endp
  9566.  
  9567. dgshcol    proc    near            ; RS F _ <nn><nn>  DG Show Columns
  9568.     mov    bx,offset dgshco1    ; get left col to show
  9569.     jmp    get2n
  9570. dgshco1:mov    ax,dgnum        ; left column to show, is dominant
  9571.     mov    cx,vswidth        ; max columns in vscreen
  9572.     dec    cx            ; max column ident
  9573.     sub    cl,byte ptr low_rgt    ; visible display width - 1
  9574.     sbb    ch,0            ; max left column showable
  9575.     cmp    ax,cx            ; want further right than this?
  9576.     jbe    dgshco2            ; be = no
  9577.     mov    ax,cx            ; limit to max
  9578. dgshco2:mov    emubuf,al        ; save max left col to show
  9579.     mov    bx,offset dgshco3    ; get right col to show
  9580.     jmp    get2n
  9581. dgshco3:mov    ax,dgnum        ; right col
  9582.     cmp    al,emubuf        ; right less than left?
  9583.     jae    dgshco4            ; ae = no
  9584.     ret                ; else ignore command
  9585. dgshco4:mov    emubuf+1,al
  9586.     cmp    dghscrdis,0        ; is horizontal scrolling disabled?
  9587.     je    dgschw1            ; e = no
  9588.     ret                ; disabled, ignore this command
  9589.  
  9590. ; worker. emubuf=wanted visible left, emubuf+1=wanted visible right margin
  9591. dgschw1:mov    bl,mar_top        ; get window top
  9592.     xor    bh,bh
  9593.     mov    cl,mar_bot
  9594.     sub    cl,bl
  9595.     inc    cl
  9596.     xor    ch,ch            ; lines in window
  9597.     mov    al,emubuf+1        ; desired right margin
  9598.     sub    al,emubuf        ; minus desired left
  9599.     cmp    al,byte ptr low_rgt    ; more than a screen's width?
  9600.     jbe    dgschw2            ; be = no
  9601.     mov    al,emubuf        ; desired left
  9602.     add    al,byte ptr low_rgt    ; plus screen width
  9603.     mov    emubuf+1,al        ; chop desired rm to give one screen
  9604.  
  9605. dgschw2:mov    al,linescroll[bx]    ; get scroll now in effect
  9606.     cmp    emubuf,al        ; is left margin to left of screen?
  9607.     jb    dgshw4            ; b = yes, put it on screen
  9608.     je    dgshw8            ; e = there now, do nothing
  9609.     mov    ah,emubuf+1        ; right margin to use
  9610.     add    al,byte ptr low_rgt    ; visible right edge
  9611.     cmp    al,ah            ; visible vs wanted right edge
  9612.     jae    dgshw8            ; ae = rm visible now, do nothing
  9613.     sub    ah,al            ; distance right margin is invisible
  9614.     xchg    ah,al
  9615.     add    al,linescroll[bx]    ; new shift plus current shift
  9616.     jmp    short dgshw5
  9617.  
  9618. dgshw4:    mov    al,emubuf        ; new scroll
  9619. dgshw5:    mov    linescroll[bx],al    ; horiz scroll for this line (window)
  9620.     inc    bx
  9621.     loop    dgshw5            ; do all lines in this window
  9622.     mov    dx,cursor
  9623.     cmp    dl,al            ; is cursor off to the left?
  9624.     jae    dgshw6            ; ae = no
  9625.     mov    dl,al            ; offset cursor too
  9626. dgshw6:    add    al,byte ptr low_rgt    ; visible right edge
  9627.     cmp    dl,al            ; cursor is on screen?
  9628.     jbe    dgshw7            ; be = yes
  9629.     mov    dl,al            ; move cursor to right edge
  9630. dgshw7:    push    dx
  9631.     mov    dl,mar_top        ; region affected
  9632.     mov    dh,mar_bot
  9633.     call    touchup            ; repaint based on new linescroll
  9634.     pop    dx
  9635. dgshw8:    jmp    dgsetcur        ; set cursor, updates screen
  9636. dgshcol    endp
  9637.  
  9638. dgrnmod    proc    near            ; RS F w  DG Read New Model ID
  9639.     mov    al,dgescape        ; resp RS o w <c><s><r><n><res>
  9640.     call    prtbout
  9641.     mov    al,'o'
  9642.     call    prtbout
  9643.     mov    al,'w'
  9644.     call    prtbout
  9645.     mov    al,'1'            ; <c> D217 terminal
  9646.     test    flags.vtflg,ttd217 ; DG D217?
  9647.     je    dgrnmod3        ; e = yes
  9648. ;    mov    al,'3'            ; <c> D413 level graphics terminal
  9649.     mov    al,'8'            ; <c> D470/D463 graphics terminal
  9650. dgrnmod3:call    prtbout
  9651.     mov    al,'0'            ; <s> pair, 01 is D470/D463
  9652.     call    prtbout
  9653.     mov    al,'1'
  9654.     call    prtbout
  9655.     mov    al,'0'            ; <r> rev level as <nn>
  9656.     call    prtbout            ; report 00
  9657.     mov    al,'0'
  9658.     call    prtbout
  9659.     mov    cx,4
  9660. ;;    mov    si,offset d413model    ; 8 char name, all printables
  9661.     mov    si,offset d463model    ; graphics term name, 8 printables
  9662.     test    flags.vtflg,ttd470    ; D470?
  9663.     jz    dgrnmo1            ; z = no
  9664.     mov    si,offset d470model
  9665. dgrnmo1:lodsb
  9666.     push    cx
  9667.     call    prtbout
  9668.     pop    cx
  9669.     loop    dgrnmo1
  9670.     mov    cx,4+4            ; <reserved> four spaces
  9671. dgrnmo2:mov    al,' '
  9672.     push    cx
  9673.     call    prtbout
  9674.     pop    cx
  9675.     loop    dgrnmo2
  9676.     ret
  9677. dgrnmod    endp
  9678.  
  9679. dgunix    proc    near            ; RS P @ <n>  DG Unix mode
  9680.     mov    ttstate,offset dgunix1    ; setup to ignore @
  9681.     ret
  9682. dgunix1:mov    bx,offset atnrm        ; consume the <n>
  9683.     jmp    get1n
  9684. dgunix    endp
  9685.  
  9686. dgsct    proc    near            ; RS F Q <n>  DG Set Cursor Type
  9687.     mov    bx,offset dgsct1
  9688.     jmp    get1n            ; get the <n> arg
  9689. dgsct1:    mov    ax,dgnum        ; get cursor type
  9690.     or    al,al            ; case 0, invisible/off?
  9691.     jnz    dgsct2            ; nz = no
  9692.     call    csrtype            ; set text cursor bits, keep kind
  9693.     or    atctype,4        ; remember, is off
  9694.     jmp    short dgsct5
  9695.  
  9696. dgsct2:    cmp    al,2            ; standard 1,2? (underline, block)
  9697.     jbe    dgsct4            ; be = yes
  9698.     sub    al,5
  9699.     neg    al            ; 5 - AL
  9700.     js    dgsct6            ; s = out of range, ignore
  9701.     jnz    dgsct4            ; nz = cases 3 and 4 (block, uline)
  9702.     mov    al,atctype        ; case 5, use saved cursor type
  9703.     and    al,not 4        ; remove invisible bit
  9704. dgsct4:    mov    atctype,al        ; save text cursor type here
  9705.     push    ax
  9706.     or    vtemu.vtflgop,vscursor ; set to underlined
  9707.     test    al,2            ; setting to block?
  9708.     jz    dgsct4a            ; z = no, underline
  9709.     and    vtemu.vtflgop,not vscursor ; say block in status word
  9710. dgsct4a:call    csrtype            ; set the cursor bits
  9711.     pop    ax
  9712. dgsct5:    test    tekflg,tek_active+tek_sg ; special graphics mode active?
  9713.     jz    dgsct6            ; z = no
  9714.     mov    dx,cursor
  9715. ifndef    no_graphics
  9716.     call    teksetcursor        ; set new cursor
  9717. endif    ; no_graphics
  9718. dgsct6:    ret
  9719. dgsct    endp
  9720.  
  9721. dgchatr    proc    near            ; RS F N <nnn><n><n> DG change attrib
  9722.     mov    bx,offset dgchat1    ; get <nnn> qty chars to change
  9723.     jmp    get3n
  9724. dgchat1:mov    ax,dgnum        ; qty chars to change
  9725.     mov    word ptr emubuf,ax    ; save
  9726.     mov    bx,offset dgchat2    ; get <n> set list
  9727.     jmp    get1n
  9728. dgchat2:mov    ax,dgnum        ; bitfield for characteristics
  9729.     mov    emubuf+2,al        ; save set list
  9730.     mov    bx,offset dgchat3    ; get final <n> reset list
  9731.     jmp    get1n
  9732. dgchat3:mov    bl,byte ptr dgnum    ; get reset list to BL
  9733.     mov    emubuf+3,bl        ; save reset list
  9734.     mov    bh,emubuf+2        ; set list
  9735.     and    bh,bl            ; get toggle bits
  9736.     mov    emubuf+4,bh        ; save toggle list here
  9737.     not    bh            ; clear out bits processed here
  9738.     and    emubuf+2,bh        ; update set list
  9739.     and    emubuf+3,bh        ; update reset list
  9740.     mov    cursor,dx        ; save cursor location
  9741.  
  9742.     mov    cx,word ptr emubuf    ; qty of bytes to change, max
  9743.     or    cx,cx            ; some count?
  9744.     jnz    dgchag4            ; nz = something to do
  9745.     ret
  9746. dgchag4:mov    al,extattr        ; preserve settable attributes
  9747.     mov    ah,scbattr
  9748.     push    ax
  9749. dgchag4a:push    cx            ; save loop counter
  9750.     call    getatch            ; get video in ah, extended att in cl
  9751.     mov    extattr,cl        ; place extended where procs can see
  9752.     mov    emubuf+5,al        ; save char
  9753.     call    dgchag10        ; process this char
  9754.     mov    al,emubuf+5        ; restore char
  9755.     call    qsetatch        ; quietly update the char
  9756.     pop    cx
  9757.     inc    dl            ; next column
  9758.     cmp    dl,mar_right        ; at the right margin?
  9759.     jbe    dgchag5            ; be = no, not yet
  9760.     mov    dl,mar_left        ; wrap to left and next line
  9761.     inc    dh            ; next line down
  9762.     cmp    dh,mar_bot        ; below the window bottom?
  9763.     ja    dgchag6            ; a = yes, all done
  9764. dgchag5:loop    dgchag4a        ; do more chars
  9765. dgchag6:pop    ax
  9766.     mov    extattr,al        ; restore setables
  9767.     mov    scbattr,ah
  9768.     mov    dl,byte ptr cursor+1    ; dl = starting row, dh = ending row
  9769.     mov    dh,mar_bot
  9770.     call    touchup            ; repaint part of screen
  9771.     mov    dx,cursor        ; reset cursor location
  9772.     ret
  9773.  
  9774. ; worker for dgchag            ; do toggle mode
  9775. dgchag10:mov    bh,emubuf+4        ; toggle list
  9776.     or    bh,bh            ; any work?
  9777.     jz    dgchag20        ; z = no
  9778.     test    bh,1            ; blink?
  9779.     jz    dgchag11        ; z = no
  9780.     xor    ah,att_blink        ; xor blink
  9781. dgchag11:test    bh,2            ; underscore?
  9782.     jz    dgchag13        ; z = no
  9783.     test    cl,att_uline        ; is it set now?
  9784.     jz    dgchag12        ; z = no
  9785.     call    clrunder        ; reset it
  9786.     jmp    short dgchag13
  9787. dgchag12:call    setunder        ; set it
  9788. dgchag13:test    bh,4            ; reverse video
  9789.     jz    dgchag15        ; z = no
  9790.     test    cl,att_rev        ; reversed now?
  9791.     jz    dgchag14        ; z = no
  9792.     call    clrrev            ; unreverse it
  9793.     jmp    short dgchag15
  9794. dgchag14:call    setrev            ; reverse it
  9795. dgchag15:test    bh,8            ; Dim
  9796.     jz    dgchag20
  9797.     xor    ah,att_bold
  9798.                     ; do set list from emubuf+2
  9799. dgchag20:mov    bh,emubuf+2        ; get set list
  9800.     or    bh,bh            ; any work?
  9801.     jz    dgchag30        ; z = no
  9802.     test    bh,1            ; blink?
  9803.     jz    dgchag21        ; z = no
  9804.     call    setblink        ; set blink
  9805. dgchag21:test    bh,2            ; underscore?
  9806.     jz    dgchag22        ; z = no
  9807.     call    setunder        ; set underline
  9808. dgchag22:test    bh,4            ; reverse video?
  9809.     jz    dgchag23        ; z = no
  9810.     call    setrev            ; set reverse video
  9811. dgchag23:test    bh,8            ; dim?
  9812.     jz    dgchag30        ; z = no
  9813.     call    clrbold            ; set Dim
  9814.                     ; do reset list from emubuf+3
  9815. dgchag30:mov    bh,emubuf+3        ; get reset list
  9816.     or    bh,bh            ; any work?
  9817.     jz    dgchag34        ; z = no
  9818.     test    bh,1            ; blink?
  9819.     jz    dgchag31        ; z = no
  9820.     call    clrblink        ; clear blink
  9821. dgchag31:test    bh,2            ; underscore?
  9822.     jz    dgchag32        ; z = no
  9823.     call    clrunder        ; clear underscore
  9824. dgchag32:test    bh,4            ; reverse video?
  9825.     jz    dgchag33        ; z = no
  9826.     call    clrrev
  9827. dgchag33:test    bh,8            ; Dim?
  9828.     jz    dgchag34        ; z = no
  9829.     call    setbold            ; reset dim
  9830. dgchag34:ret                ; end of callable worker
  9831. dgchatr    endp
  9832.  
  9833. dgsclk    proc    near            ; RS r <n> <pos> <time> DG Set Clock
  9834.     mov    bx,offset dgsclk1    ; set up to get <n><0000>
  9835.     jmp    get3n
  9836. dgsclk1:mov    bx,offset dgsclk2    ; setup to get HH
  9837.     jmp    get1n
  9838. dgsclk2:mov    ttstate,offset dgsclk3    ; setup to get ":"
  9839.     ret
  9840. dgsclk3:mov    bx,offset atnrm        ; absorb final MM
  9841.     jmp    get1n
  9842. dgsclk    endp
  9843.  
  9844. dgrss    proc    near            ; RS F t  DG Report Screen Size
  9845.     mov    al,dgescape        ; resp RS o < <5 more items>
  9846.     call    prtbout
  9847.     mov    al,'o'
  9848.     call    prtbout
  9849.     mov    al,'<'
  9850.     call    prtbout
  9851.     mov    al,byte ptr low_rgt+1    ; number of screen rows -1
  9852.     inc    al
  9853.     call    out2n            ; first item
  9854.     mov    al,207            ; number of screen cols (DG hard #)
  9855.     call    out2n            ; second item
  9856.     mov    al,mar_bot
  9857.     sub    al,mar_top
  9858.     inc    al            ; third item, num rows in window
  9859.     call    out2n
  9860.     mov    al,mar_right
  9861.     sub    al,mar_left
  9862.     inc    al            ; fourth item, num cols in window
  9863.     call    out2n
  9864.     mov    al,01110000b        ; fifth item, status
  9865.     call    prtbout
  9866.     ret
  9867. dgrss    endp
  9868.  
  9869. dgrhso    proc    near            ; RS F O  DG Read Horz Scroll Offset
  9870.     mov    al,dgescape        ; resp RS o : <nn>
  9871.     call    prtbout
  9872.     mov    al,'o'
  9873.     call    prtbout
  9874.     mov    al,':'
  9875.     call    prtbout
  9876.     mov    bl,dh            ; get current row
  9877.     xor    bh,bh
  9878.     mov    al,linescroll[bx]    ; get scroll value
  9879.     call    out2na
  9880.     ret
  9881. dgrhso    endp
  9882.  
  9883. dgrwa    proc    near            ; Control-E  DG Read Window Address
  9884.     mov    al,1fh            ; Response string Control-_ col row
  9885.     call    prtbout
  9886.     mov    al,dl            ; col, raw binary
  9887.     call    prtbout
  9888.     mov    al,dh            ; row, raw binary
  9889.     call    prtbout
  9890.     ret
  9891. dgrwa    endp
  9892.  
  9893. dgrsa    proc    near            ; RS F b  DG Read Screen Address
  9894.     mov    al,dgescape        ; resp RS o 8 <nn> <nn>
  9895.     call    prtbout
  9896.     mov    al,'o'
  9897.     call    prtbout
  9898.     mov    al,'8'
  9899.     call    prtbout
  9900.     mov    al,byte ptr cursor    ; column
  9901.     call    out2na
  9902.     mov    al,byte ptr cursor+1    ; row
  9903.     call    out2na
  9904.     ret
  9905. dgrsa    endp
  9906.  
  9907. dgrwc    proc    near            ; RS F v <r1> <c1> <r2> <c2>
  9908.     mov    emubufc,0        ; counter. DG Read Window Contents
  9909. dgrwc1:    mov    bx,offset dgrwc2
  9910.     jmp    get2n            ; read <nn>
  9911. dgrwc2:    mov    bx,emubufc        ; get counter
  9912.     inc    emubufc
  9913.     mov    ax,dgnum        ; r1, c1, r2, or c2
  9914.     mov    emubuf[bx],al        ; save here
  9915.     cmp    bx,3            ; done all four?
  9916.     jb    dgrwc1            ; b = no, get more
  9917.     mov    dh,emubuf        ; starting row
  9918.     cmp    dh,emubuf+2        ; versus ending row
  9919.     ja    dgrwc8            ; a = fail if wrong order
  9920. dgrwc3:    mov    dl,emubuf+3        ; ending column
  9921.     mov    cl,dl
  9922.     sub    cl,emubuf+1        ; minus starting column
  9923.     jl    dgrwc8            ; fail if wrong order
  9924.     inc    cl            ; number of cells to examine
  9925.     xor    ch,ch
  9926.  
  9927. dgrwc4:    push    cx
  9928.     push    dx
  9929.     call    direction
  9930.     call    getatch            ; read char into AL at cursor dx
  9931.     pop    dx
  9932.     pop    cx
  9933.     cmp    al,' '            ; space?
  9934.     jne    dgrwc5            ; found non-space
  9935.     dec    dl
  9936.     loop    dgrwc4
  9937. dgrwc5:    jcxz    dgrwc7            ; z = only spaces on the line
  9938.     mov    dl,emubuf+1        ; staring column
  9939. dgrwc6:    push    cx
  9940.     push    dx
  9941.     call    direction
  9942.     call    getatch            ; get char and attribute
  9943.     call    prtbout            ; send char in al
  9944.     pop    dx
  9945.     pop    cx
  9946.     inc    dl            ; across the row
  9947.     loop    dgrwc6            ; do all interesting cols
  9948. dgrwc7:    push    dx
  9949.     mov    al,CR            ; send line terminators
  9950.     call    prtbout
  9951.     mov    al,LF
  9952.     call    prtbout
  9953.     pop    dx
  9954.     inc    dh            ; next row down
  9955.     cmp    dh,emubuf+2        ; beyond last row?
  9956.     jbe    dgrwc3            ; be = no
  9957.     mov    dx,cursor
  9958.     mov    emubufc,0        ; clear counter
  9959. dgrwc8:    ret
  9960. dgrwc    endp
  9961.         ; Data General D463/D470 graphics commands
  9962.  
  9963. dggline    proc    near            ; RS L and RS G 8  DG line drawing
  9964.     call    dgsettek        ; setup special graphics mode
  9965. dggline1:mov    bx,offset dggline2    ; get <NNN> x coord
  9966.     jmp    get3loc
  9967. dggline2:jc    dggline9        ; c = read null terminator
  9968.     mov    ax,dgnum        ; start x coord
  9969.     mov    word ptr emubuf+0,ax    ; save here
  9970.     mov    word ptr emubuf+4,ax    ; and here
  9971.     mov    bx,offset dggline3    ; get <NNN> y coord
  9972.     jmp    get3loc
  9973. dggline3:jc    dggline9
  9974.     mov    ax,dgnum
  9975.     mov    word ptr emubuf+2,ax    ; start y
  9976.     mov    word ptr emubuf+6,ax    ; and here
  9977. dggline4:mov    bx,offset dggline5    ; get <NNN> end x coord
  9978.     jmp    get3loc
  9979. dggline5:jc    dggline8        ; c = ending on single coord, do a dot
  9980.     mov    ax,dgnum
  9981.     mov    word ptr emubuf+4,ax    ; end x
  9982.     mov    bx,offset dggline6    ; get <NNN> end y coord
  9983.     jmp    get3loc
  9984. dggline6:jc    dggline9        ; c = null char
  9985.     mov    ax,dgnum        ; end y
  9986.     mov    word ptr emubuf+6,ax
  9987.     call    dggline8        ; plot line
  9988.     jmp    short dggline4        ; continue gathering coord pairs
  9989.  
  9990. dggline8:                ; worker called above
  9991. ifndef    no_graphics
  9992.     push    word ptr mar_top    ; mar_top in low byte
  9993.     push    dglinepat        ; line pattern
  9994.     push    word ptr emubuf+6    ; end y
  9995.     push    word ptr emubuf+4    ; end x
  9996.     push    word ptr emubuf+2    ; start y
  9997.     push    word ptr emubuf+0    ; start x
  9998.     call    dgline            ; do the line
  9999.     add    sp,12            ; clear the argument stack
  10000.     mov    ax,word ptr emubuf+4    ; old end is new beginning
  10001.     mov    word ptr emubuf,ax
  10002.     mov    ax,word ptr emubuf+6
  10003.     mov    word ptr emubuf+2,ax
  10004. endif    ; no_graphics
  10005. dggline9:ret
  10006. dggline    endp
  10007.  
  10008. dggarc    proc    near            ; RS G 0  DG arc drawing
  10009.     mov    bx,offset dggarc1    ; get <NNN> x coord
  10010.     jmp    get3loc
  10011. dggarc1:jc    dggarc9            ; unexpected terminator
  10012.     mov    ax,dgnum        ; x coord
  10013.     mov    word ptr emubuf,ax    ; save here
  10014.     mov    bx,offset dggarc2    ; get <NNN> y coord
  10015.     jmp    get3loc
  10016. dggarc2:jc    dggarc9
  10017.     mov    ax,dgnum
  10018.     mov    word ptr emubuf+2,ax
  10019.     mov    bx,offset dggarc3    ; get <NNN> radius
  10020.     jmp    get3loc
  10021. dggarc3:jc    dggarc9
  10022.     mov    ax,dgnum
  10023.     mov    word ptr emubuf+4,ax
  10024.     mov    bx,offset dggarc4    ; get <NNN> start angle
  10025.     jmp    get3loc
  10026. dggarc4:jc    dggarc9
  10027.     mov    ax,dgnum
  10028.     mov    word ptr emubuf+6,ax
  10029.     mov    bx,offset dggarc5    ; get <NNN> end angle
  10030.     jmp    get3loc
  10031. dggarc5:
  10032. ifndef    no_graphics
  10033.     call    dgsettek        ; setup graphics mode
  10034.     mov    al,mar_bot        ; bottom margin in PC text lines
  10035.     xor    ah,ah
  10036.     push    ax
  10037.     mov    al,mar_top        ; top margin in PC text lines
  10038.     push    ax
  10039.     push    dgnum            ; end angle
  10040.     push    word ptr emubuf+6    ; start angle
  10041.     push    word ptr emubuf+4    ; radius
  10042.     push    word ptr emubuf+2    ; start y
  10043.     push    word ptr emubuf+0    ; start x
  10044.     call    dgarc            ; draw the arc in msgibm
  10045.     add    sp,14            ; clean stack
  10046. endif    ; no_graphics
  10047. dggarc9:ret
  10048. dggarc    endp
  10049.  
  10050. dggbar    proc    near            ; RS G 1  DG bar drawing
  10051.     call    dgsettek        ; setup special graphics mode
  10052.     mov    bx,offset dggbar1    ; get <NNN> x coord, lower left
  10053.     jmp    get3loc
  10054. dggbar1:jc    dggbar9            ; c = unexpected terminator
  10055.     mov    ax,dgnum        ; x coord
  10056.     mov    word ptr emubuf,ax    ; save here
  10057.     mov    bx,offset dggbar2    ; get <NNN> y coord
  10058.     jmp    get3loc
  10059. dggbar2:jc    dggbar9
  10060.     mov    ax,dgnum
  10061.     mov    word ptr emubuf+2,ax
  10062.     mov    bx,offset dggbar3    ; get <NNN> width
  10063.     jmp    get3loc
  10064. dggbar3:jc    dggbar9
  10065.     mov    ax,dgnum
  10066.     mov    word ptr emubuf+4,ax
  10067.     mov    bx,offset dggbar4    ; get <NNN> height
  10068.     jmp    get3loc
  10069. dggbar4:jc    dggbar9
  10070.     mov    ax,dgnum
  10071.     mov    word ptr emubuf+6,ax
  10072.     mov    bx,offset dggbar5    ; get <n> foreground/background
  10073.     jmp    get1n
  10074. dggbar5:jc    dggbar9
  10075. ifndef    no_graphics
  10076.     xor    ah,ah
  10077.     mov    al,mar_bot
  10078.     push    ax
  10079.     mov    al,mar_top
  10080.     push    ax
  10081.     push    dgnum            ; fore(1) or background (0) color
  10082.     push    word ptr emubuf+6    ; height
  10083.     push    word ptr emubuf+4    ; width
  10084.     push    word ptr emubuf+2    ; start y lower left corner
  10085.     push    word ptr emubuf+0    ; start x
  10086.     call    dgbar            ; msgibm bar drawer
  10087.     add    sp,14            ; clean stack
  10088. endif    ; no_graphics
  10089. dggbar9:ret
  10090. dggbar    endp
  10091.  
  10092. dggpoly    proc    near            ; RS G :  DG polygon fill drawing
  10093.     mov    word ptr rdbuf,0    ; count argument pairs
  10094. dggpol1:mov    bx,offset dggpol2    ; get <NNN> x coord
  10095.     jmp    get3loc
  10096. dggpol2:jc    dggpol4            ; c = got null terminator
  10097.     mov    ax,dgnum        ; x coord
  10098.     mov    word ptr emubuf,ax    ; save here
  10099.     mov    bx,offset dggpol3    ; get <NNN> y coord
  10100.     jmp    get3loc
  10101. dggpol3:jc    dggpol4
  10102.     mov    bx,word ptr rdbuf    ; vertex index
  10103.     shl    bx,1            ; count words
  10104.     shl    bx,1            ; count pairs
  10105.     mov    cx,word ptr emubuf    ; x coord
  10106.     mov    ax,dgnum        ; y coord
  10107.     mov    word ptr rdbuf+2[bx],cx    ; stuff x
  10108.     mov    word ptr rdbuf+2[bx+2],ax ; stuff y
  10109.     inc    word ptr rdbuf        ; another vertex in list
  10110.     jmp    short dggpol1        ; get another vertex
  10111. dggpol4:cmp    word ptr rdbuf,3    ; minimum viable point count
  10112.     jb    dggpol6            ; b = insufficient qty
  10113.     mov    bx,word ptr rdbuf    ; vertex index
  10114.     shl    bx,1            ; count words
  10115.     shl    bx,1            ; count pairs
  10116.     mov    al,mar_top
  10117.     xor    ah,ah
  10118.     mov    word ptr rdbuf+2[bx],ax    ; top margin, PC text lines
  10119.     mov    al,mar_bot
  10120.     mov    word ptr rdbuf+2[bx+2],ax ; bottom margin, PC text lines
  10121.     call    dgsettek        ; setup special graphics mode
  10122.     mov    al,curattr        ; save current coloring
  10123.     push    ax
  10124.     test    flags.vtflg,ttd463+ttd217 ; D463/D217?
  10125.     jz    dgpoly5            ; z = no
  10126.     and    al,0f0h            ; remove foreground
  10127.     or    al,dg463fore        ; OR in D463 foreground color
  10128.     mov    curattr,al        ; set drawing coloring
  10129. dgpoly5:
  10130. ifndef    no_graphics
  10131.     call    dgpoly            ; call worker in msgibm
  10132. endif    ; no_graphics
  10133.     pop    ax
  10134.     mov    curattr,al        ; restore coloring
  10135. dggpol6:ret
  10136. dggpoly    endp
  10137.  
  10138. dggsetp    proc    near            ; RS G p 1  DG Set Pattern
  10139.     mov    ttstate,offset dggset1    ; setup to read the 1
  10140.     ret
  10141. dggset1:cmp    al,'1'            ; correct?
  10142.     je    dggset2            ; e = yes
  10143. dggsetx:jmp    atnorm            ; fail and reset state
  10144. dggset2:mov    ttstate,offset dggset3    ; setup to read <offset>
  10145.     mov    dglinepat,0        ; init line pattern to all zeros
  10146.     call    dgsettek        ; setup special graphics mode
  10147.     ret
  10148. dggset3:sub    al,'@'            ; remove ASCII bias
  10149.     jc    dggset9            ; c = failure
  10150.     and    al,1fh            ; keep lower five bits
  10151.     xor    ah,ah
  10152.     mov    word ptr emubuf,ax    ; save initial bit position
  10153.     mov    cl,al
  10154.     rcl    dglinepat,cl        ; rotate initial pattern
  10155.     mov    ttstate,offset dggset4    ; setup to read <n> 0/1 bit
  10156.     ret
  10157. dggset4:or    al,al            ; null terminator?
  10158.     jz    dggset6            ; z = yes
  10159.     and    al,0fh            ; keep lower four bits of <n>
  10160.     cmp    al,1            ; legal values are 0, 1, and other
  10161.     jbe    dggset5            ; be = 0 or 1
  10162.     xor    al,al            ; above 1 is made to be zero
  10163. dggset5:rcr    al,1
  10164.     rcr    dglinepat,1        ; put into line pattern high bit
  10165.     inc    word ptr emubuf        ; count bit added to pattern
  10166.     ret                ; continue in state dggset4
  10167.  
  10168. dggset6:mov    cx,16            ; bits in pattern
  10169.     sub    cx,word ptr emubuf    ; get pattern bit count
  10170.     jle    dggset9            ; le = rotated enough
  10171.     mov    ax,dglinepat        ; pattern
  10172.     mov    bx,ax            ; a copy
  10173.     mov    cx,word ptr emubuf    ; pattern bit count
  10174.     mov    dx,16            ; overall bits
  10175. dggset6a:sub    dx,cx            ; minus original pattern
  10176.     jg    dggset7            ; g = still have room to copy
  10177.     je    dggset8            ; e = all done
  10178.     neg    dx
  10179.     mov    cx,dx            ; else tag end
  10180. dggset7:ror    ax,cl            ; rotate pattern to starting position
  10181.     or    ax,bx            ; move in a copy
  10182.     jmp    short dggset6a
  10183.  
  10184. dggset8:mov    dglinepat,ax        ; store line pattern
  10185. dggset9:jmp    atnorm
  10186. dggsetp    endp
  10187.  
  10188. dggrcl    proc    near            ; RS G ? |  DG Read Cursor Location
  10189.     mov    ttstate,offset dggrcl1
  10190.     ret
  10191. dggrcl1:mov    ttstate,atnrm        ; reset state
  10192.     cmp    al,'|'            ; correct terminator?
  10193.     jne    dggrcl3            ; ne = no
  10194. dggrcl2:
  10195. ifndef    no_graphics
  10196.     call    dgcrossrpt        ; generate report in msgibm
  10197. endif    ; no_graphics
  10198. dggrcl3:ret
  10199. dggrcl    endp
  10200.  
  10201. dggcon    proc    near            ; RS G B  DG Cursor on
  10202. ifndef    no_graphics
  10203.     call    dgsettek        ; setup special graphics mode
  10204.     call    dgcrosson        ; turn on crosshair
  10205. endif    ; no_grpahics
  10206.     ret
  10207. dggcon    endp
  10208.  
  10209. dggcoff    proc    near            ; RS G C  DG Cursor off
  10210. ifndef    no_graphics
  10211.     call    dgcrossoff        ; turn off crosshair
  10212. endif    ; no_graphics
  10213.     ret
  10214. dggcoff    endp
  10215.  
  10216. dggcloc    proc    near            ; RS G > | <NNN> <NNN> DG Cursor loc
  10217.     mov    ttstate,offset dggclo1    ; get vertical bar
  10218.     ret
  10219. dggclo1:mov    ttstate,offset atnrm    ; reset state
  10220.     cmp    al,'|'            ; correct character?
  10221.     je    dggclo2            ; e = yes
  10222.     ret
  10223. dggclo2:mov    bx,offset dggclo3    ; get <nnn> x ordinate
  10224.     jmp    get3loc            ; as 15 bit location argument
  10225. dggclo3:mov    ax,dgnum
  10226.     mov    word ptr emubuf,ax    ; got x ordinate
  10227.     mov    bx,offset dggclo4    ; get <nnn> y ordinate
  10228.     jmp    get3loc            ; as 15 bit location argument
  10229. dggclo4:mov    bx,dgnum        ; setup registers for call
  10230.     mov    ax,word ptr emubuf
  10231. ifndef    no_graphics
  10232.     call    dgsetcrloc        ; setup crosshair location
  10233. endif    ; no_graphics
  10234.     ret
  10235. dggcloc    endp
  10236.  
  10237. dggctrk    proc    near            ; RS G H <n>  DG Cursor track
  10238.     mov    bx,offset dggctr1
  10239.     jmp    get1n
  10240. dggctr1:and    al,2+4            ; pick out our trackables
  10241.     and    dgcross,not (2+4)    ; preserve on/of bit (1)
  10242.     or    dgcross,al        ; track keypad (2) and/or mouse (4)
  10243.     ret
  10244. dggctrk    endp
  10245.  
  10246. dggcatt    proc    near            ; RS G @  DG graphics cursor attribute
  10247.     mov    al,dgescape
  10248.     call    prtbout
  10249.     mov    al,'o'
  10250.     call    prtbout
  10251.     mov    al,','
  10252.     call    prtbout
  10253.     mov    al,'0'            ; say crosshair is off
  10254.     test    dgcross,1        ; is it on?
  10255.     jz    dggcatt1        ; z = no
  10256.     inc    al            ; say '1' for on
  10257. dggcatt1:call    prtbout            ; output <v1>
  10258.     mov    al,'0'            ; <v2> is always 0 for not blinking
  10259.     call    prtbout
  10260.     mov    al,'1'            ; <v3> is 1 for long crosshair, D463
  10261.     test    flags.vtflg,ttd470    ; D470?
  10262.     jz    dggcatt2        ; z = no
  10263.     dec    al            ; <v3> is 0 for short crosshair, D470
  10264. dggcatt2:call    prtbout
  10265.     mov    al,dgcross        ; get tracked devices
  10266.     and    al,2+4            ; pick out just devices
  10267.     add    al,'0'            ; bias
  10268.     call    prtbout            ; output <v4>
  10269.     mov    al,CR            ; terminal character
  10270.     call    prtbout
  10271.     ret
  10272. dggcatt    endp
  10273.  
  10274. dggcrst    proc    near            ; RS G A  DG Cursor reset
  10275. ifndef    no_graphics
  10276.     call    dgcrossoff        ; turn off crosshair
  10277. endif    ; no_graphics
  10278.     mov    dgcross,0        ; and no kind of tracking
  10279.     ret
  10280. dggcrst    endp
  10281.  
  10282. ; D470 ANSI mode support routines
  10283.  
  10284. dgesc_ch proc    near            ; ESC <Gn> <set> Select character set
  10285.     cmp    ninter,1        ; just one intermediate?
  10286.     je    dgesc_ch2        ; e = yes, designator
  10287.     cmp    inter+1,' '        ; DRCB 1..16?
  10288.     je    dgesc_ch1        ; e = yes
  10289.     cmp    inter+1,'!'        ; DRCB 17..22?
  10290.     je    dgesc_ch1        ; e = yes
  10291.     ret                ; else ignore
  10292. dgesc_ch1:mov    bx,20h            ; identify one soft set
  10293.     jmp    short dgesc_ch4
  10294.  
  10295. dgesc_ch2:cmp    al,'0'            ; final char, use keyboard language?
  10296.     jne    dgesc_ch3        ; ne = no, look it up
  10297.     xor    bh,bh
  10298.     mov    bl,vtemu.vtchset    ; get setup char set
  10299.     cmp    bl,13            ; top of the NRCs
  10300.     jbe    short dgesc_ch4        ;  as keyboard language
  10301.     xor    bx,bx            ; default to ASCII
  10302.     jmp    short dgesc_ch4
  10303. dgesc_ch3:xor    bx,bx            ; look up set in table
  10304.     push    es
  10305.     mov    di,seg d470chr        ; get translation table address
  10306.     mov    es,di
  10307.     mov    di,offset d470chr
  10308.     mov    cx,d470chrlen        ; get table length
  10309.     cld
  10310.     repne    scasb            ; look for match
  10311.     pop    es
  10312.     dec    di            ; backup on match
  10313.     jne    dgesc_ch5        ; ne = no match, ignore
  10314.     sub    di,offset d470chr    ; compute index
  10315.     mov    bl,mskchr[di]        ; get Kermit equivalent code
  10316.     xor    bh,bh
  10317. dgesc_ch4:                ; bx holds Kermit set ident
  10318.     mov    al,inter        ; get set designator
  10319.     sub    al,'('            ; minus bias
  10320.     xor    ah,ah
  10321.     cmp    al,3            ; range check 0..3
  10322.     ja    dgesc_ch5        ; a = out of range
  10323.     mov    si,ax            ; point at set id
  10324.     mov    Gsetid[si],bl        ; indentify new set
  10325.     mov    bx,offset Gsetid    ; tell chrset where to get info
  10326.     jmp    chrsetup        ; create new set
  10327. dgesc_ch5:ret
  10328. dgesc_ch endp
  10329.  
  10330. dgesc_c    proc    near            ; DG ESC c  reset terminal
  10331.     cmp    ninter,0        ; any intermediates?
  10332.     jne    dgesc_c1        ; ne = yes, not this command
  10333.     cmp    nparam,0        ; no params too?
  10334.     jne    dgesc_c1        ; ne = no, ignore
  10335.     jmp    atreset            ; reset
  10336. dgesc_c1:ret
  10337. dgesc_c endp
  10338.  
  10339. dgesc_D    proc    near            ; DG ESC D index
  10340.     cmp    ninter,0        ; any intermediates?
  10341.     jne    dgesc_D5        ; ne = yes, not this command
  10342.     test    anspflg,vtautop        ; printing desired?
  10343.     jz    dgesc_D1        ; e = no
  10344.     push    dx            ; save cursor
  10345.     call    pntlin            ; print line
  10346.     mov    al,LF            ; terminate in LF
  10347.     call    fpntchr
  10348.     call    fpntflsh        ; flush printer buffer
  10349.     mov    atwrap,0
  10350.     pop    dx
  10351. dgesc_D1:cmp    dh,mar_bot        ; on bottom margin?
  10352.     jb    dgesc_D3        ; b = no
  10353.     cmp    dgroll,0        ; is roll disabled
  10354.     je    dgesc_D2        ; e = yes, do home
  10355.     push    dx
  10356.     mov    scroll,1
  10357.     call    atscru            ; do a scroll up by one line
  10358.     pop    dx
  10359.     jmp    dgsetcur        ; set cursor, does show columns too
  10360.  
  10361. dgesc_D2:mov    dh,mar_top        ; do window Home
  10362.     jmp    short dgesc_D4
  10363. dgesc_D3:inc    dh            ; down one row
  10364. dgesc_D4:jmp    dgsetcur        ; set cursor wrt protected mode
  10365. dgesc_D5:ret
  10366. dgesc_D endp
  10367.  
  10368. dgesc_E    proc    near            ; DG ESC E next line
  10369.     cmp    ninter,0        ; any intermediates?
  10370.     jne    dgesc_E1        ; ne = yes, not this command
  10371.     jmp    dglf            ; do line feed
  10372. dgesc_E1:ret
  10373. dgesc_E    endp
  10374.  
  10375. dgesc_M    proc    near            ; DG ESC M reverse index
  10376.     cmp    ninter,0        ; any intermediates?
  10377.     jne    dgesc_M3        ; ne = yes, not this command
  10378.     test    anspflg,vtautop        ; printing desired?
  10379.     jz    dgesc_M1        ; e = no
  10380.     push    dx            ; save cursor
  10381.     call    pntlin            ; print line
  10382.     mov    al,LF            ; terminate in LF
  10383.     call    fpntchr
  10384.     call    fpntflsh        ; flush printer buffer
  10385.     mov    atwrap,0
  10386.     pop    dx
  10387. dgesc_M1:cmp    dh,mar_top        ; on top margin?
  10388.     ja    dgesc_M2        ; a = no
  10389.     cmp    dgroll,0        ; is roll disabled
  10390.     je    dgesc_M3        ; e = yes, do nothing
  10391.     push    dx
  10392.     mov    scroll,1
  10393.     call    atscrd            ; do a scroll down by one line
  10394.     pop    dx
  10395.     jmp    dgsetcur        ; set cursor, does show columns too
  10396.     
  10397. dgesc_M2:jmp    dgcuu            ; do cursor up
  10398. dgesc_M3:ret
  10399. dgesc_M    endp
  10400.  
  10401.  
  10402. dgesc_V    proc    near            ; DG ESC V start protected area
  10403.     cmp    ninter,0        ; any intermediates?
  10404.     jne    dgesc_V1        ; ne = yes, not this command
  10405.     call    setprot            ; protect on
  10406. dgesc_V1:ret
  10407. dgesc_V endp
  10408.  
  10409. dgesc_W    proc    near            ; DG ESC W end protected area
  10410.     cmp    ninter,0        ; any intermediates?
  10411.     jne    dgesc_W1        ; ne = yes, not this command
  10412.     call    clrprot            ; protect off
  10413. dgesc_W1:ret
  10414. dgesc_W endp
  10415.  
  10416. dgcsi_@    proc    near            ; DG CSI Pc @  ins chars, scroll left
  10417.     cmp    inter,' '        ; see if ends in space
  10418.     je    dgcsi_@1        ; e = yes
  10419.     mov    cx,param        ; do cx chars
  10420.     or    cx,cx            ; zero?
  10421.     jnz    dgcsi_@2        ; nz = no
  10422.     inc    cx            ; zero means one
  10423. dgcsi_@2:mov    bh,1            ; insert operation
  10424.     jmp    insdel            ; insert space
  10425. dgcsi_@1:mov    bx,offset dgsleft    ; scroll left
  10426.     jmp    dec2getn        ; convert param
  10427. dgcsi_@ endp
  10428.  
  10429. dgcsi_A    proc    near            ; DC CSI Pc A cursor up, scroll right
  10430.     cmp    inter,' '        ; see if ends in space
  10431.     je    dgcsi_A2        ; e = yes
  10432.     mov    cx,param        ; do cx chars
  10433.     or    cx,cx            ; zero?
  10434.     jnz    dgcsi_A1        ; nz = no
  10435.     inc    cx            ; do once
  10436. dgcsi_A1:push    cx
  10437.     call    dgcuu            ; cursor up
  10438.     pop    cx
  10439.     loop    dgcsi_A1
  10440.     ret
  10441. dgcsi_A2:mov    bx,offset dgsright    ; scroll left
  10442.     jmp    dec2getn        ; convert param
  10443. dgcsi_A endp
  10444.  
  10445. dgcsi_B    proc    near            ; DC CSI Pc B cursor down
  10446.     mov    cx,param        ; do cx chars
  10447.     or    cx,cx            ; zero?
  10448.     jnz    dgcsi_B1        ; nz = no
  10449.     inc    cx            ; do once
  10450. dgcsi_B1:push    cx
  10451.     call    dgcud            ; cursor down
  10452.     pop    cx
  10453.     loop    dgcsi_B1
  10454.     ret
  10455. dgcsi_B endp
  10456.  
  10457. dgcsi_C    proc    near            ; DC CSI Pc C cursor forward
  10458.     mov    cx,param        ; do cx chars
  10459.     or    cx,cx            ; zero?
  10460.     jnz    dgcsi_C1        ; nz = no
  10461.     inc    cx            ; do once
  10462. dgcsi_C1:push    cx
  10463.     call    dgcuf            ; cursor forward
  10464.     pop    cx
  10465.     loop    dgcsi_C1
  10466.     ret
  10467. dgcsi_C endp
  10468.  
  10469. dgcsi_D    proc    near            ; DC CSI Pc D cursor back
  10470.     mov    cx,param        ; do cx chars
  10471.     or    cx,cx            ; zero?
  10472.     jnz    dgcsi_D1        ; nz = no
  10473.     inc    cx            ; do once
  10474. dgcsi_D1:push    cx
  10475.     call    dgcub            ; cursor back
  10476.     pop    cx
  10477.     loop    dgcsi_D1
  10478.     ret
  10479. dgcsi_D endp
  10480.  
  10481. dgcsi_L    proc    near            ; DG CSI Pc L  insert Pc lines
  10482.     push    dx            ; save cursor
  10483.     call    inslin            ; do insert line, can scroll
  10484.     pop    dx            ; recover cursor
  10485.     jmp    atsetcur        ; reset cursor
  10486. dgcsi_L endp
  10487.  
  10488. dgcsi_M    proc    near            ; DG CSI Pc M  delete Pc lines
  10489.     push    dx            ; save cursor
  10490.     call    dellin            ; delete lines
  10491.     pop    dx
  10492.     jmp    atsetcur        ; reset cursor
  10493. dgcsi_M    endp
  10494.  
  10495. dgcsi_S    proc    near            ; DC CSI Pc S  scroll up
  10496.     mov    ax,param        ; scroll count
  10497.     or    al,al            ; zero?
  10498.     jnz    dgcsi_S1        ; nz = no
  10499.     inc    al
  10500. dgcsi_S1:mov    scroll,al        ; scroll amount
  10501.     call    atscru            ; scroll up
  10502.     ret
  10503. dgcsi_S    endp
  10504.  
  10505. dgcsi_T    proc    near            ; DC CSI Pc T  scroll down
  10506.     mov    ax,param        ; scroll count
  10507.     or    al,al            ; zero?
  10508.     jnz    dgcsi_T1        ; nz = no
  10509.     inc    al
  10510. dgcsi_T1:mov    scroll,al        ; scroll amount
  10511.     call    atscrd            ; scroll down
  10512.     ret
  10513. dgcsi_T    endp
  10514.  
  10515. dgcsi_f    proc    near            ; DG CSI row; col f
  10516.     mov    ax,param+2        ; get column
  10517.     or    al,al            ; zero now?
  10518.     jz    dgcsi_f1        ; z = yes
  10519.     dec    al            ; count from 0
  10520. dgcsi_f1:mov    emubuf,al        ; column
  10521.     mov    ax,param        ; get row
  10522.     or    al,al            ; zero now?
  10523.     jz    dgcsi_f2        ; z = yes
  10524.     dec    al            ; count from 0
  10525. dgcsi_f2:jmp    dgwwa2            ; do Control-P col row
  10526. dgcsi_f endp
  10527.  
  10528. dgcsi_h    proc    near            ; DG CSI Pc; Pc h  set mode
  10529.     mov    modeset,1        ; say setting modes
  10530.     cmp    lparam,'<'
  10531.     jne    dgcsi_h1
  10532.     mov    di,offset dgcsi_rsm    ; set/reset routine
  10533.     call    atreps            ; repeat for all parameters
  10534. dgcsi_h1:ret
  10535. dgcsi_h endp
  10536.  
  10537. dgcsi_i    proc    near            ; DG CSI Pc i  media copy
  10538.     cmp    lparam,'<'        ; CSI < 0 ?
  10539.     jne    dgcsi_i1        ; ne = no
  10540.     ret                ; ignore CSI <0
  10541. dgcsi_i1:mov    ax,param        ; get parameter
  10542.     cmp    ax,4            ; stop media copy?
  10543.     je    dgcsi_i2        ; e = yes
  10544.     cmp    ax,5            ; start media copy?
  10545.     je    dgcsi_i2        ; e = yes
  10546.     or    ax,ax            ; print window?
  10547.     je    dgcsi_i3        ; e = yes
  10548.     ret                ; ignore others
  10549. dgcsi_i2:jmp    ansmc            ; do 4, 5 as ANSI transparent print
  10550. dgcsi_i3:mov    al,':'            ; setup for window print
  10551.     jmp    dgprt6            ; print window
  10552. dgcsi_i    endp
  10553.  
  10554. dgcsi_sl proc    near            ; DG CSI Pc; Pc l  reset mode
  10555.     mov    modeset,0        ; say resetting modes
  10556.     cmp    lparam,'<'        ; this letter parameter?
  10557.     jne    dgcsi_sl1        ; ne = no
  10558.     mov    di,offset dgcsi_rsm    ; set/reset routine
  10559.     call    atreps            ; repeat for all parameters
  10560. dgcsi_sl1:
  10561.     ret
  10562. dgcsi_sl endp
  10563.  
  10564. ; Worker for set/reset routines. Invoke via atreps with modeset for set/reset
  10565. dgcsi_rsm proc    near
  10566.     mov    ax,param[si]        ; get parameter
  10567.     mov    ah,modeset        ; get set (1), reset (0) mode
  10568.     cmp    al,0            ; roll mode?
  10569.     jne    dgcsi_rsm1        ; ne = no
  10570.     mov    dgroll,ah        ; roll mode
  10571.     ret
  10572. dgcsi_rsm1:cmp    al,1            ; blink mode
  10573.     jne    dgcsi_rsm2        ; ne = no
  10574.     neg    ah            ; invert sense
  10575.     mov    blinkdis,ah        ; blink disable
  10576.     ret
  10577. dgcsi_rsm2:cmp    al,2            ; horizontal scroll?
  10578.     jne    dgcsi_rsm3        ; ne = no
  10579.     neg    ah            ; invert sense
  10580.     mov    dghscrdis,ah        ; horizontal scroll disable
  10581.     ret
  10582. dgcsi_rsm3:cmp    al,3            ; DG D470 ANSI mode?
  10583.     jne    dgcsi_rsm4        ; ne = no
  10584.     mov    dgd470mode,ah        ; set ANSI mode
  10585.     ret
  10586. dgcsi_rsm4:cmp    al,4            ; forms mode?
  10587.     jne    dgcsi_rsm5        ; ne = no
  10588.     ret
  10589. dgcsi_rsm5:cmp    al,5            ; margins mode?
  10590.     jne    dgcsi_rsm6
  10591.     ret
  10592. dgcsi_rsm6:ret
  10593. dgcsi_rsm endp
  10594.  
  10595. dgcsi_n    proc    near            ; DC CSI Pc n  device status report
  10596.     cmp    param,5            ; send ready report?
  10597.     jne    dgcsi_n1        ; ne = no
  10598.     mov    al,ESCAPE        ; response is Esc [ 0 n
  10599.     call    prtbout            ; meaning "ready"
  10600.     mov    al,'['
  10601.     call    prtbout
  10602.     mov    al,'0'
  10603.     call    prtbout
  10604.     mov    al,'n'
  10605.     call    prtbout
  10606.     ret
  10607. dgcsi_n1:cmp    param,6            ; cursor position report?
  10608.     jne    dgcsi_n2        ; ne = no
  10609.     mov    al,ESCAPE        ; response is ESC [ row; col R
  10610.     call    prtbout
  10611.     mov    al,'['
  10612.     call    prtbout
  10613.     mov    al,byte ptr cursor+1    ; get current row
  10614.     call    prtnout            ; output number as decimal ASCII
  10615.     mov    al,';'
  10616.     call    prtbout
  10617.     mov    al,byte ptr cursor    ; column
  10618.     call    prtnout
  10619.     mov    al,'R'
  10620.     call    prtbout
  10621. dgcsi_n2:ret
  10622. dgcsi_n    endp
  10623.  
  10624. dgcsi_sp proc    near            ; DG CSI..p  draw bar or arc
  10625.     cmp    inter,' '        ; ends on space?
  10626.     je    dgcsi_sp1        ; e = yes, do draw arc
  10627.     mov    bx,offset dggbar    ; draw bar
  10628.     jmp    dec2getn        ; convert params to <loc> form
  10629. dgcsi_sp1:mov    bx,offset dggarc    ; draw arc
  10630.     jmp    dec2getn        ; convert params to <loc> form
  10631. dgcsi_sp endp
  10632.  
  10633. dgcsi_q    proc    near            ; DG CSI Pc q  change attributes
  10634.     cmp    inter,' '        ; read graphics cursor signature?
  10635.     je    dgcsi_q1        ; e = yes
  10636.     mov    bx,offset dgchatr    ; change attributes routine
  10637.     jmp    dec2getn        ; convert args to DG <n> form
  10638. dgcsi_q1:                ; similar to RS G ? |
  10639. ifndef    no_graphics
  10640.     call    dgcrossrpt        ; do report via MSGIBM
  10641. endif    ; no_graphics
  10642.     ret
  10643. dgcsi_q    endp
  10644.  
  10645. dgcsi_r    proc    near            ; DG CSI <space> r  read cursor att
  10646.     mov    al,Escape        ; response similar to RS G @
  10647.     call    prtbout
  10648.     mov    al,'['
  10649.     call    prtbout
  10650.     mov    al,'0'            ; say crosshair is off
  10651.     test    dgcross,1        ; is it on?
  10652.     jz    dgcsi_r1        ; z = no
  10653.     inc    al            ; say '1' for on
  10654. dgcsi_r1:call    prtbout            ; output <v1>
  10655.     mov    al,';'
  10656.     call    prtbout
  10657.     mov    al,'0'            ; <v2> is always 0 for not blinking
  10658.     call    prtbout
  10659.     mov    al,';'
  10660.     call    prtbout
  10661.     mov    al,'0'            ; <v3> is 0 for short crosshair, D470
  10662.     call    prtbout
  10663.     mov    al,';'
  10664.     call    prtbout
  10665.     mov    al,dgcross        ; get tracked devices
  10666.     and    al,2+4            ; pick out just devices
  10667.     add    al,'0'            ; bias
  10668.     call    prtbout            ; output <v4>
  10669.     mov    al,'r'            ; terminal character
  10670.     call    prtbout
  10671.     ret
  10672. dgcsi_r    endp
  10673.  
  10674. dgcsi_ss proc    near            ; DG CSI Pc s read/reserve characters
  10675.     mov    ax,param        ; get parameter
  10676.     or    ax,ax            ; do report?
  10677.     jnz    dgcsi_ss2        ; nz = no, reserve (do nothing here)
  10678.     mov    al,ESCAPE        ; report is ESC [ <qty> s
  10679.     call    prtbout
  10680.     mov    al,'['
  10681.     call    prtbout
  10682.     mov    al,'2'            ; say <qty> is 2000
  10683.     call    prtbout
  10684.     mov    cx,3
  10685. dgcsi_ss1:push    cx
  10686.     mov    al,'0'
  10687.     call    prtbout
  10688.     pop    cx
  10689.     loop    dgcsi_ss1
  10690.     mov    al,'s'            ; terminator
  10691.     call    prtbout
  10692. dgcsi_ss2:ret
  10693. dgcsi_ss endp
  10694.  
  10695. dgcsi_st proc    near            ; DG CSI Pc t  read offset/show cols
  10696.     cmp    inter,' '        ; Write graphics cursor command?
  10697.     je    dgcsi_st3        ; e = yes
  10698.     cmp    param,0            ; read offset?
  10699.     jne    dgcsi_st1        ; ne = no
  10700.     mov    al,ESCAPE        ; response is Esc [ col t
  10701.     call    prtbout
  10702.     mov    al,'['
  10703.     call    prtbout
  10704.     mov    bl,dh            ; get current row
  10705.     xor    bh,bh
  10706.     mov    al,linescroll[bx]    ; get scroll value
  10707.     call    prtnout            ; output number as decimal ASCII
  10708.     mov    al,'t'
  10709.     call    prtbout
  10710.     ret
  10711. dgcsi_st1:cmp    param,1            ; show columns?
  10712.     jne    dgcsi_st2        ; ne = no
  10713.     mov    ax,param+2        ; remove initial param
  10714.     mov    param,ax
  10715.     mov    ax,param+4
  10716.     mov    param+2,ax
  10717.     mov    nparam,2        ; setup for call
  10718.     mov    bx,offset dgshcol    ; show columns, RS F _
  10719.     jmp    dec2getn        ; perform the routine
  10720. dgcsi_st2:ret
  10721.  
  10722. dgcsi_st3:mov    ax,param        ; x graphics coord
  10723.     mov    bx,param+2        ; y graphics coord
  10724. ifndef    no_graphics
  10725.     call    dgsetcrloc        ; set crosshairs to x,y
  10726. endif    ; no_graphics
  10727.     ret
  10728. dgcsi_st endp
  10729.  
  10730. dgcsi_u    proc    near            ; DG CSI Pc <space> u
  10731.     cmp    inter,' '        ; ends on space
  10732.     je    dgcsi_u1        ; e = yes, cursor off
  10733.     mov    inter,0
  10734.     mov    ninter,0        ; best to clear these
  10735.     jmp    dgcsi_f            ; it's cursor row, col
  10736. dgcsi_u1:jmp    dggcoff            ; do RS G C  graphics cursor off
  10737. dgcsi_u    endp
  10738.  
  10739. dgcsi_v    proc    near            ; DG CSI <space> v cursor on
  10740.     cmp    inter,' '        ; proper form?
  10741.     jne    dgcsi_v1        ; ne = no
  10742.     jmp    dggcon            ; do RS G B  graphics cursor on
  10743. dgcsi_v1:ret
  10744. dgcsi_v    endp
  10745.  
  10746. dgcsi_w    proc    near            ; DG CSI Pn; Pc w  set margins
  10747.     cmp    inter,' '        ; graphics cursor reset indicator?
  10748.     jne    dgcsi_w4        ; ne = no, must be margins
  10749. ifndef    no_graphics
  10750.     call    dgcrossoff        ; turn off crosshair
  10751. endif    ; no_graphics
  10752.     mov    dgcross,0        ; and no kind of tracking
  10753.     ret
  10754. dgcsi_w4:mov    bx,param        ; set margins
  10755.     mov    ax,param+2
  10756.     mov    param,ax
  10757.     mov    ax,param+4
  10758.     mov    param+2,ax        ; remove leading param
  10759.     mov    ax,param+6
  10760.     mov    param+4,ax
  10761.     dec    nparam            ; one less parameter
  10762.     cmp    bx,1            ; set margins?
  10763.     je    dgcsi_w1        ; e = 1 = yes, do draw arc
  10764.     ja    dgcsi_w2        ; a = 2 = set alt margins
  10765.     jmp    dgrnmar            ; 0 = restore normal margins
  10766. dgcsi_w1:mov    bx,offset dgsetmar    ; set margins
  10767.     jmp    dec2getn        ; convert params to <nn> form
  10768. dgcsi_w2:mov    bx,offset dgsetamar    ; set alt margins
  10769.     jmp    dec2getn        ; convert params to <nn> form
  10770. dgcsi_w endp
  10771.  
  10772. dgcsi_x    proc    near            ; DG CSI Pc x   cursor track
  10773.     cmp    inter,' '        ; proper form for cursor track?
  10774.     jne    dgcsi_x1        ; ne = no
  10775.     mov    ax,param        ; get arg
  10776.     and    al,2+4            ; pick out our trackables
  10777.     and    dgcross,not (2+4)    ; preserve on/of bit (1)
  10778.     or    dgcross,al        ; track keypad (2) and/or mouse (4)
  10779. dgcsi_x1:                ; like RS C  DG Read Model ID
  10780.     mov    al,escape        ; resp ESC [ <mm> <x> <y>
  10781.     call    prtbout
  10782.     mov    al,'['
  10783.     call    prtbout
  10784.     mov    al,'5'            ; 5 is DG D470 in ANSI mode
  10785.     call    prtbout
  10786.     mov    al,'4'            ; 4 is DG D470
  10787.     call    prtbout
  10788.     mov    al,';'
  10789.     call    prtbout
  10790.     mov    al,'0'            ; two bytes here
  10791.     call    prtbout
  10792.     mov    al,'0'
  10793.     test    flags.remflg,d8bit    ; using 8 bits?
  10794.     jz    dgcsi_x2        ; z = no
  10795.     or    al,2            ; say 8-bit mode
  10796. dgcsi_x2:push    ax
  10797.     mov    ah,ioctl        ; get printer status, via DOS
  10798.     mov    al,7            ; status for output
  10799.     push    bx
  10800.     mov    bx,4            ; std handle for system printer
  10801.     int    dos
  10802.     pop    bx
  10803.     jnc    dgcsi_x3        ; nc = call succeeded
  10804.     mov    al,0ffh
  10805. dgcsi_x3:cmp    al,0ffh            ; code for Ready
  10806.     pop    ax
  10807.     jne    dgcsi_x4        ; ne = not ready
  10808.     or    al,1            ; say printer present
  10809. dgcsi_x4:call    prtbout            ; send composite byte
  10810.     mov    al,';'
  10811.     call    prtbout
  10812.     mov    al,'0'            ; revision 0
  10813.     call    prtbout
  10814.     mov    al,';'
  10815.     call    prtbout
  10816.     mov    bl,vtemu.vtchset    ; get Kermit NRC code (0-13)
  10817.     xor    bh,bh
  10818.     mov    al,nrcdgkbd[bx]        ; get DG keyboard code from table
  10819.     call    prtnout
  10820.     mov    al,'x'
  10821.     call    prtbout
  10822.     ret
  10823. dgcsi_x    endp
  10824.  
  10825. dgdcs_F    proc    near            ; DC DCS F ST  failure report
  10826.     mov    al,Escape        ; report DCS F ST for no failure
  10827.     call    prtbout
  10828.     mov    al,'P'
  10829.     call    prtbout
  10830.     mov    al,'F'
  10831.     call    prtbout
  10832.     mov    al,Escape
  10833.     call    prtbout
  10834.     mov    al,'\'
  10835.     call    prtbout
  10836.     jmp    atnorm
  10837. dgdcs_F    endp
  10838.  
  10839.         ; End of Data General specific routines
  10840.  
  10841.         ; Start Wyse-50 specific routines
  10842.  
  10843. wyenq    proc    near            ; Control E, ESC sp  inquire
  10844.     mov    al,'5'
  10845.     call    prtbout            ; send 5 0 CR
  10846.     mov    al,'0'
  10847.     call    prtbout
  10848.     mov    al,CR
  10849.     call    prtbout
  10850.     ret
  10851. wyenq    endp
  10852.  
  10853. wycub    proc    near            ; Control H  cursor left (back)
  10854.     sub    dl,1            ; column, one to the left
  10855.     jns    wycub1            ; ns = no wrap
  10856.     mov    dl,mar_right        ; wrap left to right
  10857.     sub    dh,1            ; up one row
  10858.     jns    wycub1            ; ns = no wrap
  10859.     mov    dh,mar_bot        ; wrap top to bottom
  10860. wycub1:    jmp    atsetcur        ; set cursor
  10861. wycub    endp
  10862.  
  10863. wycup    proc    near            ; Control K (VT) cursor up
  10864.     mov    dx,cursor
  10865.     sub    dh,1            ; compute new cursor position
  10866.     jnc    wycu1            ; nc = ok
  10867.     mov    dh,mar_bot        ; overflow, wrap to last line
  10868. wycu1:    jmp    atscur            ; set the cursor at its new position
  10869. wycup    endp
  10870.  
  10871. wysub    proc    near            ; Control Z  erase all unprotected
  10872.                     ; also ESC ; and ESC :
  10873.     mov    dl,mar_left        ; upper left corner
  10874.     mov    dh,mar_top
  10875.     call    erprot            ; do protected erasure
  10876.     jmp    short wyhome        ; home the cursor
  10877. wysub    endp
  10878.  
  10879. wyhome    proc    near            ; Control ^  cursor home
  10880.     mov    dl,mar_left        ; upper left corner
  10881.     mov    dh,mar_top
  10882.     jmp    atscur            ; set cursor
  10883. wyhome    endp
  10884.  
  10885. wyprtoff proc    near            ; Autoprint off
  10886.     test    anspflg,vtautop        ; check state of print flag
  10887.     jz    wyprtof1        ; z = off already
  10888.     or    anspflg,vtautop        ; say auto-print enabled to toggle off
  10889.     call    ftrnprs            ; toggle mode line PRN indicator
  10890.     and    anspflg,not (vtautop + vtcntp) ; clear all printing kinds
  10891. wyprtof1:ret
  10892. wyprtoff endp
  10893.  
  10894. wyprton    proc    near            ; Autoprint on
  10895.     test    anspflg,vtautop        ; is print already enabled?
  10896.     jnz    wyprton1        ; nz = yes, leave trnprs intact
  10897.     and    anspflg,not vtautop    ; say auto-print disabled to toggle on
  10898.     call    ftrnprs            ; toggle on mode line PRN indicator
  10899. wyprton1:ret
  10900. wyprton    endp
  10901.  
  10902. wyesc    proc    near            ; ESC processor, enter when ESC seen
  10903.     mov    ttstate,offset wyesc1    ; come here for next char
  10904.     ret
  10905. wyesc1:    mov    param,0
  10906.     mov    param+2,0
  10907.     mov    lparam,0
  10908.     mov    bx,offset wyescf    ; dispatch table
  10909.     mov    ttstate,offset atnrm    ; reset state
  10910.     jmp    atdispat        ; dispatch on char in AL
  10911. wyesc    endp
  10912.  
  10913. wytab0    proc    near            ; ESC 0
  10914.     mov    param,3            ; clear all tab stops
  10915.     jmp    attbc            ; do it
  10916. wytab0    endp
  10917.  
  10918. wytab2    proc    near            ; ESC 2
  10919.     mov    param,0            ; clear this tab stop
  10920.     jmp    attbc            ; do it
  10921. wytab2    endp
  10922.  
  10923. wy_bang    proc    near            ; ESC ! attrib, set attribute on all
  10924.     mov    ttstate,offset wy_ban1    ;  unprotected chars, clear chars
  10925.     mov    emubuf,0        ; say ESC ! rather than ESC A 0
  10926.     ret
  10927. wy_ban1:xor    dx,dx            ; home position
  10928.     mov    ttstate,offset atnrm    ; reset state
  10929.     mov    bl,al            ; save argument
  10930.     mov    ah,scbattr        ; normal background
  10931.     mov    curattr,ah        ; current attributes, update
  10932.     mov    extattr,0        ; clear extended attributes
  10933.     test    bl,2            ; set blink?
  10934.     jz    wy_ban2            ; z = no
  10935.     test    bl,1            ; and blank?
  10936.     jnz    wy_ban2            ; nz = yes, ignore blink
  10937.     call    setblink
  10938. wy_ban2:test    bl,4            ; set reverse video bit?
  10939.     jz    wy_ban3            ; z = no
  10940.     call    setrev
  10941. wy_ban3:test    bl,8            ; set underscore?
  10942.     jz    wy_ban4            ; z = no
  10943.     call    setunder
  10944. wy_ban4:test    bl,40h            ; dim?
  10945.     jz    wy_ban5            ; z = no
  10946.     call    setbold
  10947. wy_ban5:mov    curattr,ah        ; new attributes
  10948.     mov    extattr,cl
  10949.     mov    al,mar_right
  10950.     sub    al,mar_left
  10951.     inc    al            ; width
  10952.     mov    cl,mar_bot
  10953.     sub    cl,mar_top
  10954.     inc    cl            ; rows
  10955.     mul    cl
  10956.     mov    cx,ax            ; number of character cells to do
  10957.     xor    dx,dx            ; home position
  10958. wy_ban6:push    cx            ; save loop counter
  10959.     call    getatch            ; get video in ah, extended att in cl
  10960.     test    cl,att_protect        ; protected?
  10961.     jnz    wy_ban7            ; nz = yes, skip it
  10962.     mov    cl,extattr
  10963.     mov    ah,curattr
  10964.     cmp    emubuf,0        ; erase char?
  10965.     jne    wy_ban6a        ; ne = no
  10966.     mov    al,' '            ; cleared character
  10967. wy_ban6a:call    qsetatch        ; quietly update the char
  10968. wy_ban7:pop    cx
  10969.     inc    dl            ; next column
  10970.     cmp    dl,mar_right        ; at the right margin?
  10971.     jbe    wy_ban8            ; be = no, not yet
  10972.     mov    dl,mar_left        ; wrap to left and next line
  10973.     inc    dh            ; next line down
  10974.     cmp    dh,mar_bot        ; below the window bottom?
  10975.     ja    wy_ban9            ; a = yes, all done
  10976. wy_ban8:loop    wy_ban6            ; do more chars
  10977. wy_ban9:call    frepaint        ; repaint screen
  10978.     xor    dx,dx            ; home cursor
  10979.     cmp    emubuf,0        ; erase char?
  10980.     je    wy_ban10        ; e = yes
  10981.     mov    dx,cursor        ; else replace cursor
  10982. wy_ban10:jmp    atsetcur        ; restore cursor
  10983. wy_bang    endp
  10984.  
  10985. wy_dot    proc    near            ; ESC . CODE   clr unprotected chars
  10986.     mov    ttstate,offset wy_dot1    ;  of value code
  10987.     ret
  10988. wy_dot1:mov    ttstate,offset atnrm    ; reset state
  10989.     mov    emubuf,al        ; save char code
  10990.     mov    al,mar_right
  10991.     sub    al,mar_left
  10992.     inc    al            ; width
  10993.     mov    cl,mar_bot
  10994.     sub    cl,mar_top
  10995.     inc    cl            ; rows
  10996.     mul    cl
  10997.     mov    cx,ax            ; number of character cells to do
  10998. wy_dot2:push    cx            ; save loop counter
  10999.     call    getatch            ; get video in ah, extended att in cl
  11000.     test    cl,att_protect        ; protected?
  11001.     jnz    wy_dot3            ; nz = yes, skip it
  11002.     cmp    al,emubuf        ; same as code?
  11003.     jne    wy_dot3            ; ne = no
  11004.     mov    al,' '            ; char
  11005.     mov    ah,scbattr        ; normal background
  11006.     xor    cl,cl            ; clear extended attributes
  11007.     call    qsetatch        ; quietly update the char
  11008. wy_dot3:pop    cx
  11009.     inc    dl            ; next column
  11010.     cmp    dl,mar_right        ; at the right margin?
  11011.     jbe    wy_dot4            ; be = no, not yet
  11012.     mov    dl,mar_left        ; wrap to left and next line
  11013.     inc    dh            ; next line down
  11014.     cmp    dh,mar_bot        ; below the window bottom?
  11015.     ja    wy_dot5            ; a = yes, all done
  11016. wy_dot4:loop    wy_dot2            ; do more chars
  11017. wy_dot5:call    frepaint        ; repaint screen
  11018.     mov    dx,cursor        ; reset cursor location
  11019.     ret
  11020. wy_dot    endp
  11021.  
  11022. wy_8    proc    near            ; ESC 8 enter STX (2) code
  11023.     mov    al,2
  11024.     jmp    atnrm
  11025. wy_8    endp
  11026.  
  11027. wy_9    proc    near            ; ESC 9 enter ETX (3) code
  11028.     mov    al,3
  11029.     jmp    atnrm
  11030. wy_9    endp
  11031.  
  11032. wy_slash proc    near            ; ESC /  send txt seg and cursor
  11033.     mov    al,'0'            ; text segment 0
  11034.     call    prtbout            ; send
  11035.     jmp    wy_query        ; send cursor position
  11036. wy_slash endp
  11037.  
  11038. wy_query proc    near            ; ESC ?  send rc CR cursor report
  11039.     mov    al,byte ptr cursor+1    ; row
  11040.     add    al,20h            ; plus bias
  11041.     call    prtbout
  11042.     mov    al,byte ptr cursor    ; column
  11043.     add    al,20h
  11044.     call    prtbout
  11045.     mov    al,CR            ; terminator
  11046.     call    prtbout
  11047.     ret
  11048. wy_query endp
  11049.  
  11050. wy_sa    proc    near            ; ESC a rr R ccc C  cursor to row,col
  11051.     mov    ttstate,offset wy_sa1    ; get first row char
  11052.     ret
  11053. wy_sa1:    cmp    al,'R'            ; field termination?
  11054.     je    wy_sa2            ; yes
  11055.     push    ax
  11056.     mov    ax,param        ; ASCII decimal to binary
  11057.     mov    cx,10
  11058.     imul    cx
  11059.     mov    param,ax
  11060.     pop    ax
  11061.     sub    al,'0'            ; ccc, decimal col
  11062.     cbw
  11063.     add    param,ax
  11064.     ret                ; stay in this state
  11065. wy_sa2:    mov    lparam,al        ; save it
  11066.     mov    ttstate,offset wy_sa3    ; get column
  11067.     ret
  11068. wy_sa3:    cmp    al,'C'            ; field termination?
  11069.     je    wy_sa4            ; e = yes
  11070.     push    ax
  11071.     mov    ax,param+2        ; ASCII decimal to binary
  11072.     mov    cx,10
  11073.     imul    cx
  11074.     mov    param+2,ax
  11075.     pop    ax
  11076.     sub    al,'0'            ; ccc, decimal col
  11077.     cbw
  11078.     add    param+2,ax
  11079.      ret                ; stay in this state
  11080. wy_sa4:    mov    ttstate,offset atnrm
  11081.     xor    ah,ah
  11082.     xchg    ah,lparam        ; get the 'R', clear lparam
  11083.     cmp    ax,'RC'            ; proper terminators?
  11084.     jne    wy_sax            ; ne = no
  11085.     xor    ax,ax
  11086.     xor    bx,bx
  11087.     xchg    ax,param        ; row
  11088.     xchg    bx,param+2        ; column
  11089.     or    ax,ax            ; zero now?
  11090.     jz    wy_sa5            ; z = yes
  11091.     dec    ax            ; count row from zero
  11092. wy_sa5:    or    bx,bx            ; zero now?
  11093.     jz    wy_sa6            ; z = yes
  11094.     dec    bx            ; count column from zero
  11095. wy_sa6:    cmp    ax,24            ; row, in bounds?
  11096.     ja    wy_sax            ; a = no
  11097.     cmp    bx,132            ; column, in bounds?
  11098.     ja    wy_sax            ; a = no
  11099.     mov    dh,al            ; row
  11100.     mov    dl,bl            ; column
  11101.     jmp    atscur            ; set cursor
  11102. wy_sax:    mov    param,0
  11103.     mov    param+2,0        ; clear temps
  11104.     ret                ; ignore command
  11105. wy_sa    endp
  11106.  
  11107. wy_equ    proc    near            ; ESC = r c  cursor to row, col
  11108.     mov    ttstate,offset wy_equ1    ; get row char
  11109.     ret
  11110. wy_equ1:sub    al,' '-1        ; remove ASCII bias
  11111.     cbw                ; grab sign
  11112.     mov    param,ax        ; save as row
  11113.     mov    ttstate,offset wy_equ2
  11114.     ret
  11115. wy_equ2:sub    al,' '-1        ; remove ASCII bias
  11116.     cbw
  11117.     mov    param+2,ax        ; save as column
  11118.     mov    lparam,'R'        ; setup R..C form
  11119.     mov    al,'C'
  11120.     jmp    wy_sa4            ; parse completion as ESC a rr R ccc C
  11121. wy_equ    endp
  11122.  
  11123. wy_minus proc    near            ; ESC - nrc  cursor to txt seg row col
  11124.     and    al,1            ; n can be anything (despite manual)
  11125.     mov    ttstate,offset wy_equ    ; parse rest as if ESC = r c
  11126.     ret
  11127. wy_minus endp
  11128.  
  11129. wy_star    proc    near            ; ESC *   ESC + 
  11130.                     ; protect mode off, clear screen
  11131.     mov    protectena,0        ; disable protect mode
  11132.     xor    dx,dx            ; set cursor to home
  11133.     mov    cursor,dx
  11134.     jmp    ereos            ; clear entire screen
  11135. wy_star    endp
  11136.  
  11137. wy_comma proc    near            ; ESC ,  screen clear to prot'd spaces
  11138.     mov    protectena,0        ; disable protect mode
  11139.     xor    dx,dx            ; set cursor to home
  11140.     mov    cursor,dx
  11141.     mov    ah,scbattr        ; normal background
  11142.     mov    al,' '            ; space
  11143.     mov    cl,att_protect        ; set protection bit
  11144. wy_comm1:call    setatch            ; write cell
  11145.     inc    dl            ; next column
  11146.     cmp    dl,mar_right        ; beyond right edge?
  11147.     jbe    wy_comm1        ; be = no
  11148.     xor    dl,dl            ; left edge
  11149.     inc    dh            ; next row
  11150.     cmp    dh,mar_bot        ; below bottom?
  11151.     jbe    wy_comm1        ; be = no
  11152.     xor    dx,dx            ; top left corner
  11153.     jmp    atsetcur        ; set cursor
  11154. wy_comma endp
  11155.  
  11156. wy_A    proc    near            ; ESC A n attrib  set video attribs
  11157.     mov    ttstate,offset wy_A1    ; get field code n
  11158.     ret
  11159. wy_A1:    cmp    al,'0'            ; entire text display?
  11160.     jne    wy_A2            ; ne = no, ignore after getting attrib
  11161.     mov    emubuf,1        ; flag to wy_bang to not erase chars
  11162.     mov    ttstate,offset wy_ban1    ; process attrib in ESC ! procedure
  11163.     ret
  11164. wy_A2:    mov    ttstate,offset atnorm    ; ignore next byte, exit command
  11165.     ret
  11166. wy_A    endp
  11167.  
  11168. wy_F    proc    near            ; ESC F text CR, to message area
  11169.     mov    ttstate,offset wy_F1
  11170.     ret
  11171. wy_F1:    cmp    al,CR            ; end of string?
  11172.     jne    wy_F2            ; ne = no, continue discarding bytes
  11173.     mov    ttstate,offset atnrm    ; reset state
  11174. wy_F2:    ret
  11175. wy_F    endp
  11176.  
  11177. wy_G    proc    near            ; ESC G n  set char attributes
  11178.     mov    ttstate,offset wy_G1    ; get attribute code
  11179.     ret
  11180. wy_G1:    mov    ttstate,offset atnrm    ; reset state
  11181.     mov    ah,curattr        ; current attributes
  11182.     mov    bl,al            ; get code
  11183.     cmp    bl,' '            ; space code?
  11184.     je    wy_Gx            ; e = yes, just ignore it
  11185.     cmp    bl,'0'            ; range check for '0' et seq
  11186.     jb    wy_Gx            ; b = out of range
  11187.     ja    wy_G2            ; a = in range
  11188.     call    clrbold            ; clear bold attribute
  11189.     call    clrblink        ; clear blink attribute
  11190.     call    clrrev            ; clear reverse video attribute
  11191.     call    clrunder        ; clear underline attribute
  11192.     mov    atinvisible,0        ; clear invisible attribute
  11193.     mov    extattr,0        ; clear extended attributes
  11194.     jmp    short wy_Gx
  11195.  
  11196. wy_G2:    test    bl,2            ; set blink?
  11197.     jz    wy_G3            ; z = no
  11198.     test    bl,1            ; and blank?
  11199.     jnz    wy_G3            ; nz = yes, ignore blink
  11200.     push    bx
  11201.     call    setblink        ; set blink
  11202.     pop    bx
  11203. wy_G3:    test    bl,4            ; set reverse video bit?
  11204.     jz    wy_G4            ; z = no
  11205.     push    bx
  11206.     call    setrev            ; set reverse video
  11207.     pop    bx
  11208. wy_G4:    test    bl,8            ; set underscore?
  11209.     jz    wy_G5            ; z = no
  11210.     push    bx
  11211.     call    setunder        ; set underline
  11212.     pop    bx
  11213. wy_G5:    cmp    bl,'p'            ; dim?
  11214.     jb    wy_Gx            ; b = no
  11215.     call    clrbold            ; set dim
  11216. wy_Gx:    mov    curattr,ah        ; store new attribute byte
  11217. ;;;;;    mov    byte ptr wyse_protattr,ah ; Wyse-50 protected char attributes
  11218. ;;;;;    mov    byte ptr wyse_protattr+1,att_protect
  11219.     mov    dx,cursor        ; moves cursor left one column
  11220.     inc    dl
  11221.     jmp    atscur
  11222. wy_G    endp
  11223.  
  11224. wy_H    proc    near            ; ESC H x  show graphics char
  11225.     mov    ttstate,offset wy_H1    ; setup to read x
  11226.     ret
  11227. wy_H1:    mov    ttstate,offset atnrm    ; reset state
  11228.     cmp    al,2            ; STX (^B) enter graphics mode?
  11229.     jne    wy_H2            ; ne = no
  11230.     jmp    atls1            ; do LS1 to get graphics set
  11231.  
  11232. wy_H2:    cmp    al,3            ; ETX (^C) exit graphics mode?
  11233.     jne    wy_H3            ; ne = no
  11234.     jmp    atls0            ; do LS0 to exit graphics mode
  11235.  
  11236. wy_H3:    mov    SSptr,offset G1set    ; set Single Shift to G1 for graphics
  11237.     jmp    atnrm            ; show code
  11238. wy_Hx:    ret
  11239. wy_H    endp
  11240.  
  11241. wy_I    proc    near            ; ESC I  cursor back to previous tab
  11242.     xor    ch,ch
  11243.     cmp    cl,dl            ; cursor column
  11244.     jcxz    wy_I3            ; z = at left margin
  11245. wy_I1:    dec    dl            ; tab always moves at least one column
  11246.     push    si
  11247.     mov    si,vtemu.vttbst        ; active buffer
  11248.     call    istabs            ; returns carry set if at a tabstop
  11249.     pop    si
  11250.     jc    wy_I2            ; c = at a tabstop
  11251.     loop    wy_i1
  11252. wy_I2:    call    dgsetcur        ; set cursor and return
  11253. wy_I3:    ret
  11254. wy_I    endp
  11255.  
  11256. wy_N    proc    near            ; ESC N  turn on no-scroll mode
  11257.     mov    wyse_scroll,1
  11258.     ret
  11259. wy_N    endp
  11260.  
  11261. wy_O    proc    near            ; ESC O  turn off no-scroll mode
  11262.     mov    wyse_scroll,0
  11263.     ret
  11264. wy_O    endp
  11265.  
  11266. wy_R    proc    near            ; ESC R  delete line
  11267.     call    dellin
  11268.     xor    dl,dl            ; cursor to left margin
  11269.     jmp    atsetcur        ; set cursor
  11270. wy_R    endp
  11271.  
  11272. wy_V    proc    near            ; ESC V  mark column as protected
  11273.     push    cursor            ; remember starting cursor
  11274.     mov    dh,mar_top        ; start with this row
  11275.     mov    cl,mar_bot
  11276.     sub    cl,mar_top
  11277.     inc    cl
  11278.     xor    ch,ch            ; count of rows to touch
  11279.     call    direction        ; set column in dl
  11280. wy_V1:    push    cx
  11281.     call    getatch            ; get char to al, attrib to ah,cl
  11282.     or    cl,att_protect        ; set protected attribute
  11283.     call    qsetatch        ; quite writeback
  11284.     pop    cx
  11285.     inc    dh            ; next row
  11286.     loop    wy_V1
  11287.     pop    cursor
  11288.     mov    dx,cursor
  11289.     jmp    atsetcur        ; set cursor, just in case
  11290. wy_V    endp
  11291.  
  11292. wy_acc    proc    near            ; ESC ` n  set screen features
  11293.     mov    ttstate,offset wy_acc1    ; setup to read "n"
  11294.     ret
  11295. wy_acc1:mov    ttstate,offset atnrm    ; reset state
  11296.     cmp    al,'0'            ; 0, cursor off?
  11297.     jne    wy_acc2            ; ne = no
  11298.     mov    al,4            ; set cursor off code
  11299.     jmp    wy_acc7
  11300. wy_acc2:cmp    al,'1'            ; 1, cursor on?
  11301.     jne    wy_acc3            ; ne = no
  11302.     mov    al,atctype        ; get cursor type
  11303.     jmp    wy_acc7
  11304.     ret
  11305. wy_acc3:cmp    al,'2'            ; 2, block cursor?
  11306.     je    wy_acc4            ; e = yes
  11307.     cmp    al,'5'            ; blinking block?
  11308.     jne    wy_acc5            ; ne = no
  11309. wy_acc4:mov    al,2            ; block cursor code
  11310.     jmp    wy_acc7
  11311. wy_acc5:cmp    al,'3'            ; 3, blinking line?
  11312.     je    wy_acc6            ; e = yes
  11313.     cmp    al,'4'            ; 4, steady line?
  11314.     jne    wy_acc8            ; ne = no
  11315. wy_acc6:mov    al,1            ; line code
  11316. wy_acc7:call    atsctyp            ; set cursor type, remember it
  11317.     ret
  11318.  
  11319. wy_acc8:cmp    al,'A'            ; normal protected char?
  11320.     jne    wy_acc9            ; ne = no
  11321.     mov    cl,extattr        ; running extended attribute
  11322.     push    cx
  11323.     mov    ah,curattr        ; current attribute
  11324.     call    getblink        ; save blinking attribute
  11325.     mov    al,ah            ;  to al
  11326.     mov    ah,scbattr        ; normal attribute
  11327.     or    ah,al            ;  include blinking
  11328.     or    cl,att_protect        ; set protected extended attrib
  11329.     and    cl,not att_uline+att_rev
  11330.     mov    extattr,cl
  11331.     call    setbold            ; set bold
  11332.     mov    byte ptr wyse_protattr,ah ; store attribute to write
  11333.     mov    byte ptr wyse_protattr+1,cl
  11334.     call    wy_setp            ; set attributes on protected chars
  11335.     pop    cx
  11336.     mov    extattr,cl        ; restore extended attribute
  11337.     ret
  11338.  
  11339. wy_acc9:cmp    al,'6'            ; reverse protected char?
  11340.     jne    wy_acc10        ; ne = no
  11341.     mov    cl,extattr        ; running extended attribute
  11342.     push    cx
  11343.     mov    ah,curattr        ; current attribute
  11344.     call    getblink        ; save blinking attribute
  11345.     mov    al,ah            ;  to al
  11346.     mov    ah,scbattr        ; normal attribute
  11347.     or    ah,al            ;  include blinking
  11348.     or    cl,att_protect        ; set protected extended attrib
  11349.     and    cl,not att_uline+att_rev
  11350.     mov    extattr,cl
  11351.     call    clrbold            ; clear bold (set dim)
  11352.     call    setrev            ; set reverse
  11353.     mov    byte ptr wyse_protattr,ah ; store attribute to write
  11354.     mov    byte ptr wyse_protattr+1,cl
  11355.     call    wy_setp            ; set attributes on protected chars
  11356.     pop    cx
  11357.     mov    extattr,cl        ; restore extended attribute
  11358.     ret
  11359.  
  11360. wy_acc10:cmp    al,'7'            ; dim protected char?
  11361.     jne    wy_acc11        ; ne = no
  11362.     mov    cl,extattr        ; running extended attribute
  11363.     push    cx
  11364.     mov    ah,curattr        ; current attribute
  11365.     call    getblink        ; save blinking attribute
  11366.     mov    al,ah            ;  to al
  11367.     mov    ah,scbattr        ; normal attribute
  11368.     or    ah,al            ;  include blinking
  11369.     or    cl,att_protect        ; set protected extended attrib
  11370.     and    cl,not att_uline+att_rev
  11371.     mov    extattr,cl
  11372.     call    clrbold            ; set dim
  11373.     mov    byte ptr wyse_protattr,ah ; store attribute to write
  11374.     mov    byte ptr wyse_protattr+1,cl
  11375.     call    wy_setp            ; set attributes on protected chars
  11376.     pop    cx
  11377.     mov    extattr,cl        ; restore extended attribute
  11378.     ret
  11379.  
  11380. wy_acc11:cmp    al,':'            ; set 80 columns?
  11381.     jne    wy_acc12
  11382.     mov    al,3            ; arg for columns set/reset
  11383.     mov    modeset,0        ; reset condition
  11384.     jmp    atrsm6
  11385.  
  11386. wy_acc12:cmp    al,';'            ; set 132 columns?
  11387.     jne    wy_acc14        ; ne = no
  11388.     mov    al,3            ; arg for columns
  11389.     mov    modeset,1        ; set condition
  11390.     jmp    atrsm6            ; do set/reset operation
  11391. wy_acc14:ret
  11392. wy_acc    endp
  11393.  
  11394. ; worker for wy_acc. Set attributes of all protected characters. New
  11395. ; attributes are in word wyse_protattr.
  11396. wy_setp    proc    near            ; set protected char attributes
  11397.     push    cursor            ; remember starting cursor
  11398.     mov    dh,mar_top        ; start with this row
  11399.     mov    cl,mar_bot
  11400.     sub    cl,mar_top
  11401.     inc    cl
  11402.     xor    ch,ch            ; count of rows to touch
  11403.     xor    dl,dl            ; left physical column
  11404. wy_setp1:push    cx
  11405.     call    getatch            ; get char to al, attrib to ah,cl
  11406.     test    cl,ATT_PROTECT        ; protected?
  11407.     jz    wy_setp2        ; z = no, do nothing
  11408.     mov    ah,byte ptr wyse_protattr ; "normal" attributes
  11409.     mov    cl,byte ptr wyse_protattr+1 ; extended, set protected
  11410.     call    setatch            ; visible writeback
  11411. wy_setp2:pop    cx
  11412.     inc    dl
  11413.     cmp    dl,mar_right        ; at right margin?
  11414.     jb    wy_setp1        ; b = no, more on this row
  11415.     xor    dl,dl            ; left column
  11416.     inc    dh            ; next row
  11417.     loop    wy_setp1
  11418.     pop    cursor
  11419.     mov    dx,cursor
  11420.     jmp    atsetcur        ; set cursor, just in case
  11421. wy_setp    endp
  11422.  
  11423.  
  11424. wy_M    proc    near            ; ESC M  send to host char at cursor
  11425.     call    getatch            ; get char to al
  11426.     call    prtbout            ; send, no echo
  11427.     ret
  11428. wy_M    endp
  11429.  
  11430. wy_b    proc    near            ; ESC b send cursor address to host
  11431.     mov    al,'0'            ; three digits
  11432.     call    prtbout
  11433.     mov    al,byte ptr cursor+1    ; get row
  11434.     inc    al            ; count from 1
  11435.     cmp    al,10
  11436.     jae    wy_b1            ; ae = have two digits
  11437.     push    ax
  11438.     mov    al,'0'            ; second leadin
  11439.     call    prtbout
  11440.     pop    ax
  11441. wy_b1:    call    prtnout            ; decimal ASCII
  11442.     mov    al,'R'            ; report rr R ccc C
  11443.     call    prtbout
  11444.     mov    al,byte ptr cursor    ; column
  11445.     inc    al            ; count from 1
  11446.     cmp    al,100            ; three digits again
  11447.     jae    wy_b2
  11448.     push    ax
  11449.     mov    al,'0'
  11450.     call    prtbout
  11451.     pop    ax
  11452.     cmp    al,10
  11453.     jae    wy_b2
  11454.     push    ax
  11455.     mov    al,'0'
  11456.     call    prtbout
  11457.     pop    ax
  11458. wy_b2:    call    prtnout
  11459.     mov    al,'C'            ; terminator
  11460.     call    prtbout
  11461.     ret
  11462. wy_b    endp
  11463.  
  11464. wy_d    proc    near            ; ESC d #, transparent print on
  11465.     mov    ttstate,offset wy_d1    ; get sharp sign
  11466.     ret
  11467. wy_d1:    cmp    al,'#'            ; proper terminator?
  11468.     je    wy_d2            ; e = yes
  11469.     jmp    atnorm            ; reset state
  11470.  
  11471. wy_d2:    mov    ttstate,offset wy_d3    ; do transparent printing (Control-X)
  11472.     and    anspflg,not vtautop    ; clear single-char flag for toggling
  11473.     call    ftrnprs            ; toggle mode line PRN indicator
  11474.     jc    wy_d2a            ; c = printer failure
  11475.     or    anspflg,vtcntp        ; controller printing is on
  11476. wy_d2a:    ret
  11477.  
  11478. wy_d3:    cmp    al,'T'-40h        ; Control-T to end printing?
  11479.     je    wy_d4            ; e = yes
  11480.     call    fpntchr            ; print char in al, ignore errors
  11481.     ret
  11482.  
  11483. wy_d4:    mov    ttstate,offset atnrm    ; return to normal state
  11484.     call    fpntflsh        ; flush printer buffer
  11485.     test    anspflg,vtcntp        ; was printing active?
  11486.     jz    wy_d5            ; z = no
  11487.     and    anspflg,not vtcntp    ; yes, disable print controller
  11488.     call    ftrnprs            ; toggle mode line PRN indicator
  11489.     and    anspflg,not (vtautop + vtcntp) ; clear all printing kinds
  11490. wy_d5:    ret
  11491. wy_d    endp
  11492.  
  11493. wy_q    proc    near            ; ESC q   turn on insert mode
  11494.     mov    insmod,1
  11495.     ret
  11496. wy_q    endp
  11497.  
  11498. wy_sr    proc    near            ; ESC r  turn off insert mode
  11499.     mov    insmod,0
  11500.     ret
  11501. wy_sr    endp
  11502.  
  11503. wy_x    proc    near            ; ESC x n HSR  change display format
  11504.     mov    ttstate,offset wy_x1    ; get argument n (0, 1)
  11505.     ret
  11506. wy_x1:    cmp    al,'1'            ; 1, split screen?
  11507.     jne    wy_x2            ; ne = no
  11508.     mov    ttstate,offset wy_x2    ; get HSR screen split code
  11509.     ret
  11510. wy_x2:    
  11511.     mov    ttstate,offset atnrm    ; reset state
  11512.     ret
  11513. wy_x    endp
  11514.  
  11515. wy_z    proc    near            ; ESC z n aaaa CR  set msg to place
  11516.     mov    ttstate,offset wy_z1    ; get argument n
  11517.     ret
  11518. wy_z1:    cmp    al,CR            ; terminator?
  11519.     je    wy_z2            ; e = yes
  11520.     cmp    al,DEL            ; or shift terminator?
  11521.     je    wy_z2            ; e = yes
  11522.     ret                ; continue to consume bytes
  11523. wy_z2:    jmp    atnorm            ; reset state, return
  11524. wy_z    endp
  11525.  
  11526.     ; Wyse-50 end
  11527.  
  11528. ; Display "LEDs" routine. yflags from MSYIBM is needed to know if the mode
  11529. ; line is enabled. Display current state of "LEDs" on line 25.
  11530. ansdsl    proc    near            ; display "LEDs"
  11531.     test    yflags,modoff        ; mode line off?
  11532.     jnz    ansdsl2            ; nz = yes, just return
  11533.     cmp    flags.modflg,1        ; mode line on and owned by us?
  11534.     jne    ansdsl2            ; ne = no, leave it intact
  11535.     mov    cx,10            ; length of the array
  11536.     call    getled            ; set si to string, c set if no leds
  11537.     push    es
  11538.     mov    di,ds
  11539.     mov    es,di
  11540.     mov    di,led_col+offset modbuf ; mode line buffer, our position
  11541.     cld
  11542.     rep    movsb
  11543.     pop    es
  11544. ansdsl2:ret
  11545. ansdsl    endp
  11546.  
  11547. ; Return pointer to "led" display in si, set carry if terminal type does
  11548. ; not have leds 1..4.
  11549. getled    proc    near
  11550.     mov    ax,flags.vtflg        ; terminal type
  11551.     mov    si,offset v320leds    ; VT320 ident
  11552.     cmp    ax,ttvt320        ; VT320?
  11553.     je    getled2            ; e = yes
  11554.     mov    si,offset v220leds    ; VT220 ident
  11555.     cmp    ax,ttvt220        ; VT220?
  11556.     je    getled2            ; e = yes
  11557.     mov    si,offset v102leds    ; VT102 ident
  11558.     cmp    ax,ttvt102        ; VT102 mode?
  11559.     je    getled2            ; e = yes
  11560.     mov    si,offset v100leds
  11561.     cmp    ax,ttvt100        ; VT100?
  11562.     je    getled2            ; e = yes
  11563.     mov    si,offset honeyleds
  11564.     cmp    ax,tthoney        ; Honeywell?
  11565.     je    getled2            ; e = yes
  11566.     mov    si,offset ansileds
  11567.     cmp    ax,ttansi        ; ANSI-BBS?
  11568.     je    getled2            ; e = yes
  11569.     mov    si,offset v52leds    ; VT52 ident
  11570.     cmp    ax,ttvt52        ; VT52?
  11571.     je    getled1            ; e = yes, no leds
  11572.     mov    si,offset pt20leds
  11573.     cmp    ax,ttpt200        ; Prime PT200?
  11574.     je    getled2            ; e = yes
  11575.     mov    si,offset d217leds
  11576.     cmp    ax,ttd217        ; DG D217?
  11577.     je    getled1            ; e = yes, but no led dots
  11578.     mov    si,offset d463leds
  11579.     cmp    ax,ttd463        ; DG D463?
  11580.     je    getled1            ; e = yes, but no led dots
  11581.     mov    si,offset d470leds
  11582.     cmp    ax,ttd470        ; DG D470?
  11583.     je    getled1            ; e = yes, but no led dots
  11584.     mov    si,offset wyseleds
  11585.     cmp    ax,ttwyse        ; Wyse-50?
  11586.     je    getled1            ; e = yes
  11587.     mov    si,offset h19leds    ; Heath-19 ident
  11588. getled1:stc                ; c = set, does not have leds 1..4
  11589.     ret
  11590. getled2:clc                ; c = clear, has leds 1..4
  11591.     ret
  11592. getled    endp
  11593.  
  11594. ; This routine is called to adjust the cursor for the "indexing" like commands
  11595. ; (e.g., index, reverse index, newline, etc.).    It contrains the cursor, and
  11596. ; indicates if scrolling is necessary, and if so, in which direction.
  11597. ;
  11598. ; Call: cursor = "old" cursor position
  11599. ;    dx =     "new" cursor position
  11600. ;
  11601. ; Return: ax = pointer to scrolling routine to call (or to a ret)
  11602. ;      bx = "old" cursor position
  11603. ;      dx = "new" cursor position adjusted for screen limits or
  11604. ;               scrolling region, depending on whether the original
  11605. ;               cursor position was inside or outside the scrolling region.
  11606. ;
  11607. ; On the VT100, a scroll does not occur unless the original cursor position
  11608. ; was on the top or bottom margin. This routine assumes that when decom is
  11609. ; set the cursor position is set to the new origin, and that no other routine
  11610. ; allows the cursor to be positioned outside the scrolling region as long
  11611. ; as decom is set (which is the way a real VT100 works).  Note that for the
  11612. ; normal case (no limited scrolling region defined) the margins are the same
  11613. ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
  11614. ; an attempt is made to index off the screen. Preserves cx.
  11615.  
  11616. atccic    proc    near
  11617.     push    cx
  11618.     mov    cl,byte ptr low_rgt    ; get right margin
  11619.     mov    bl,dh            ; get row
  11620.     xor    bh,bh
  11621.     cmp    bl,crt_lins        ; below screen?
  11622.     jae    atcci0            ; ae = yes, use single width line
  11623.     cmp    linetype[bx],0        ; single width chars?
  11624.     je    atcci0            ; e = yes, single width
  11625.     shr    cl,1            ; halve margin for double wides
  11626. atcci0:    mov    ax,offset atign        ; assume no scrolling necessary
  11627.     mov    bx,cursor        ; get old cursor
  11628.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG terminal?
  11629.     jz    atcci0a            ; z = no
  11630.     mov    cl,mar_right
  11631.     cmp    dl,mar_left        ; left of left margin?
  11632.     jae    atcci1            ; ae = no
  11633.     mov    dl,mar_right        ; fold to right
  11634.     dec    dh            ; and go up
  11635.     jmp    short atcci1
  11636. atcci0a:cmp    dl,250            ; left of left margin? (wide screen)
  11637.     jb    atcci1            ; b = no, go check right
  11638.     xor    dl,dl            ; set to left margin
  11639. atcci1:    cmp    dl,cl            ; left of right margin
  11640.     jbe    atcci2            ; be = yes, go check top
  11641.     mov    dl,cl            ; set to right margin
  11642.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG terminal?
  11643.     jz    atcci2            ; z = no
  11644.     mov    dl,mar_left        ; to left margin
  11645.     inc    dh            ; and down one
  11646. atcci2:    pop    cx
  11647.     cmp    bh,mar_top        ; was old pos above scroll top margin?
  11648.     jb    atcci7            ; b = yes
  11649.     cmp    dh,mar_top        ; want to go above top margin?
  11650.     jge    atcci5            ; ge = no
  11651.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11652.     jz    atcci3            ; z = no
  11653.     mov    dh,mar_bot        ; roll over to bottom margin
  11654.     ret
  11655. atcci3:    mov    scroll,1
  11656.     mov    ax,offset atscrd    ; indicate scroll down required
  11657.     mov    dh,mar_top        ; set to top margin
  11658.     ret
  11659.  
  11660. atcci5:    cmp    bh,mar_bot        ; old position below bottom margin?
  11661.     ja    atcci7            ; a = yes
  11662.     cmp    dh,mar_bot        ; want to go below?
  11663.     jbe    atcci6            ; be = no, nothing to worry about
  11664.     mov    scroll,1        ; 1 line
  11665.     mov    ax,offset atscru    ; indicate scroll up required
  11666.     mov    dh,mar_bot        ; set to bottom margin
  11667. atcci6:    ret
  11668. atcci7:    jmp    short atccpc        ; old pos was outside scrolling region
  11669. atccic    endp
  11670.  
  11671. ; This routine is called to check the cursor position after any kind of cursor
  11672. ; positioning command.    Note that cursor positioning does NOT cause scrolling
  11673. ; on a VT100 (hence the need for a routine separate from this for "indexing".
  11674. ; Call:    dx = "new" cursor position (modified cursor)
  11675. ; Return: dx = "new" cursor position adjusted for screen limits (if
  11676. ;        decom is reset), or scrolling region (if decom is set).
  11677. ; Preserves ax, bx, and cx.
  11678.  
  11679. atccpc    proc    near
  11680.     push    bx            ; save bx and cx
  11681.     push    cx
  11682.     mov    cx,low_rgt        ; margins, cl = right margin
  11683.     mov    bl,dh            ; get row
  11684.     xor    bh,bh
  11685.     cmp    linetype [bx],0        ; single width line?
  11686.     je    atccp0            ; e = yes, single width
  11687.     shr    cl,1            ; halve right margin for double wides
  11688. atccp0:    test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11689.     jz    atccp0a            ; z = no
  11690.     mov    cl,mar_right
  11691.     cmp    dl,mar_left        ; left of margin?
  11692.     jae    atccp1            ; ae = no
  11693.     mov    dl,mar_right        ; go to right margin
  11694.     dec    dh            ; do a cursor up
  11695.     jmp    short atccp1        ; do a cursor up
  11696.  
  11697. atccp0a:cmp    dl,250            ; to left of left margin?(wide screen)
  11698.     jb    atccp1            ; b = no, go check right
  11699.     xor    dl,dl            ; set to left margin
  11700. atccp1: cmp    dl,cl            ; to right of right margin?
  11701.     jbe    atccp2            ; be = yes, go check top
  11702.     mov    dl,cl            ; set to right margin
  11703.  
  11704.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11705.     jz    atccp2            ; z = no
  11706.     mov    dl,mar_left        ; to left margin
  11707.     jmp    atlf            ; do a LF operation now
  11708.  
  11709. atccp2:    pop    cx
  11710.     pop    bx
  11711.     test    vtemu.vtflgop,decom    ; Origin mode set?
  11712.     jnz    atccp5            ; nz = yes, stay in scrolling region
  11713.     or    dh,dh            ; above top of screen?
  11714.     jns    atccp3            ; ns = no, check bottom
  11715.     xor    dh,dh            ; stop here
  11716. atccp3: cmp    dh,byte ptr low_rgt+1    ; below bottom of screen?
  11717.     jbe    atccp4            ; be = no, stay in margins
  11718.     mov    dh,byte ptr low_rgt+1    ; stop at end of text screen
  11719.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  11720.     jne    atccp4            ; ne = no
  11721.     test    h19stat,h19l25        ; 25th line enabled?
  11722.     jnz    atccp4            ; nz = yes
  11723.     inc    dh            ; allow 25th line
  11724. atccp4:    ret
  11725.  
  11726. atccp5: cmp    dh,mar_top        ; above top of scrolling region?
  11727.     jae    atccp6            ; ae = no, check bottom
  11728.     mov    dh,mar_top        ; yes, stop there
  11729.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11730.     jz    atccp6            ; z = no
  11731.     mov    dh,mar_bot        ; roll to bottom
  11732.     ret
  11733. atccp6: cmp    dh,mar_bot        ; below bottom perhaps?
  11734.     jbe    atccp4            ; be = no, return
  11735.     mov    dh,mar_bot        ; yes, stop at the bottom margin
  11736.     test    flags.vtflg,ttd463+ttd470+ttd217 ; DG D463/D470/D217?
  11737.     jz    atccp7            ; z = no
  11738.     mov    dh,mar_top        ; roll to top
  11739. atccp7:    ret
  11740. atccpc    endp
  11741.  
  11742.  
  11743. ; Routine to set cursor type (off, block, underline).
  11744. ; 4 = do not show, but keep block/underline attributes.
  11745. ; 2 = block, 1 = underline
  11746. atsctyp:cmp    flags.vtflg,ttheath    ; Heath-19?
  11747.     jne    atsct1            ; ne = no
  11748.     mov    al,h19ctyp        ; get cursor kind and on/off bit
  11749.     test    al,4            ; is cursor to be off?
  11750.     jz    atsct4            ; z = no, al has kind
  11751.     xor    al,al            ; turn off cursor
  11752.     jmp    short atsct4        ; do it
  11753. atsct1:    test    atctype,4        ; VTxxx cursor type, off?
  11754.     jnz    atsct3            ; z = no
  11755. atsct2:    mov    al,1            ; assume underline
  11756.     test    vtemu.vtflgop,vscursor    ; block?
  11757.     jnz    atsct3            ; nz = no, underline
  11758.     inc    al
  11759. atsct3:    mov    atctype,al        ; save VTxxx cursor type here
  11760. atsct4:    call    csrtype            ; set the cursor type
  11761.     ret
  11762.  
  11763. atdeb    proc    near            ; Debug, display all chars in tty style
  11764.     test    yflags,capt        ; capturing output?
  11765.     jz    atdeb3            ; z = no, forget this part
  11766.     call    fcptchr            ; give it captured character
  11767. atdeb3:    mov    bl,curattr        ; save attribute
  11768.     push    bx
  11769.     push    word ptr mar_top    ; save limited scrolling region
  11770.     push    ax            ; save character for a second
  11771.     mov    ah,curattr        ; get attribute
  11772.     call    clrblink        ; clear blink attribute
  11773.     call    clrunder        ; clear underline attribute
  11774.     mov    atinvisible,0        ; clear invisible attribute
  11775.     mov    extattr,0        ; extended attribute
  11776.     mov    curattr,ah        ; store
  11777.     or    vtemu.vtflgop,decawm    ; set autowrap temporarily
  11778.     mov    mar_top,0        ; set scrolling region to entire page
  11779.     mov    al,byte ptr low_rgt+1
  11780.     mov    mar_bot,al
  11781.     pop    ax            ; restore character
  11782.     mov    ah,al
  11783.     test    al,80h            ; high bit set?
  11784.     jz    atdeb0            ; z = not set
  11785.     push    ax            ; save the character for a second
  11786.     mov    al,7eh            ; output a tilde
  11787.     call    atnrm2
  11788.     pop    ax            ; restore character
  11789.     and    al,7fh            ; and remove high bit
  11790. atdeb0:    cmp    al,del            ; DEL?
  11791.     je    atdeb1            ; e = yes, output "^?"
  11792.     cmp    al,20h            ; control character?
  11793.     jnb    atdeb2            ; nb = no, just output char in al
  11794. atdeb1: push    ax            ; save the character for a second
  11795.     mov    al,5eh            ; output a caret
  11796.     call    atnrm2
  11797.     pop    ax            ; restore character
  11798.     add    al,40h            ; make ^letter (or ^? for DEL)
  11799.     and    al,7fh            ; clear bit 7 (for DEL)
  11800. atdeb2:    push    ax
  11801.     call    atnrm2            ; output translated character
  11802.     pop    ax
  11803.     cmp    ah,LF            ; natural line break?
  11804.     jne    atdeb4            ; ne = no
  11805.     call    atcr
  11806.     call    atlf
  11807. atdeb4:    pop    word ptr mar_top    ; restore scrolling region,
  11808.     pop    bx            ;  flags, and cursor attribute
  11809.     mov    curattr,bl
  11810.     ret
  11811. atdeb    endp
  11812. code1    ends
  11813.     end
  11814.