home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msz55x.asm < prev    next >
Assembly Source File  |  2020-01-01  |  159KB  |  3,751 lines

  1.       NAME      msz55x
  2. ; File MSZ55X.ASM
  3. ; System dependent file for Sanyo 55x series.
  4. ; Done by Robert W. Babcock and Joe H. White.
  5. ; For version which replaces the BIOS keycode translation table,
  6. ;  use -dMODIFIED flag to MASM.
  7.     page 60,132
  8. ; Terminal emulator module for IBM PC's and compatibles. Emulates Heath-19,
  9. ; VT52, and VT102. Original version done by James Harvey, Indiana Purdue
  10. ; Univ, for MS Kermit 2.27. Taken from there by Joe Doupnik, Utah State Univ
  11. ; for MS Kermit 2.29 et seq.
  12. ; Edit history
  13. ; Last edit 20 April 1988, add color trans. table for monochrome systems [rwb]
  14. ; 15 Sept 1987 version which runs with or without optional video board [rwb]
  15. ; Use bios calls for video output.  Also change test for monochrome [jhw]
  16. ; monitor from crt_mode = 7 to 2. Set swidth and slen back to 80 and 25 [jhw]
  17. ; Make vtsound public so it can be called from msx55x. [rwb]
  18. ;
  19. ; 1 Jan 1988 version 2.30
  20. ; 29 Dec 1987 Absorb escape sequences of the form ESC [ ... <40h to 7fh>
  21. ;  to sense but not act on unknown legally formatted ANSI escapes. [jrd]
  22. ; 28 Dec 1987 Add corrections from Frank da Cruz: home cursor on select/desel
  23. ;  origin mode, make select/deselect ansi mode return to US ascii graphics
  24. ;  rendition sets (where is this item documented?). [jrd]
  25. ; 12 Dec 1987 Sense denyflg to supress automatic Tek mode when ESC Control-L
  26. ;  is received; part of ENABLE/DISABLE command. [jrd]
  27. ; 4 Dec 1987 Strip high bit of chars within escape sequences, test for end of
  28. ;  transparent print without high bit but playback 8 bit intermediates. [jrd]
  29. ; 16 Nov 1987 Add multiple timed retries on printer status. [jrd]
  30. ; 5 Nov 1987 Add Tektronix terminal type, including ESC FF branch to Tek
  31. ; mode and toggling among terminal types. [jrd]
  32. ; 28 Oct 1987 Remove NUL and DEL chars from normal logging and display,
  33. ;  ignore Control-X and -Z unless in an esc sequence. [jrd]
  34. ; 3 Oct 1987 Remove cursor action for DEL when local echo is on. [jrd]
  35. ; 11 Sept 1987 Remove Translation Input from emulator proper.
  36. ; 23 Aug 1987 Add byte vtemu.vtflgop to hold emulator runtime values as
  37. ;  distinct from the vtemu.vtflgst setup values so a reset restores setups.
  38. ; 19 Aug 1987 Make sure cursor type is correct on warm start, from Bob Babcock
  39. ; 18 Aug 1987 Change ESC to escape for MASM 4.5+. Add Heath graphics,
  40. ;  add screen alignment, redo line wrap material, size screen from crt_cols
  41. ;  and crt_rows given by MSYxxx. [jrd]
  42. ; 31 June 1987 Clear counter mccnt when completing transparent print. [jrd]
  43. ; 17 June 1987 Correct jump from atreset to atres2 when changing 80/132 cols
  44. ;  and always copy all 132 columns of tabs. [jrd]
  45. ; 16 June 1987 Fix bug in cursor positioning when outside scrolling region,
  46. ;  thanks to Richard Saxton. Remove global byte jwait (for msy), add code to
  47. ;  clear the status line when the Heath-19 is commanded to disable that line
  48. ;  (wierd, but Dave says that's the way H-19's work), thanks to Dave Tweten.
  49. ; 8 June 1987 Tell file msy... about change of keypad applications mode. [jrd]
  50. ; 31 May 1987 Correct several Heath-19 problems: use ansi escape table when
  51. ;  in ansi mode, reject ESC [ (hold screen mode), use correct cursor left,
  52. ;  remember cursor type (underline/block/on/off) separately from VT100 setup.
  53. ;  Thanks to Dave Tweten. [jrd]
  54. ; 10 May 1987 Move input translate table rxtable within this emulator,
  55. ;  don't translate if debug is active, don't translate escape sequences,
  56. ;  no translation if controller print is active, make byte anspflg global
  57. ;  so msyibm can sense print screen status. Add print controls for VT52. [jrd]
  58. ; 4 May 1987 Correct several jumps to be signed for scrolling region. [jrd]
  59. ; 7 April 1987 Fix cursor wrap for H-19's, from Mike Iglesias [uci]
  60. ;  Fix cursor wrap top to bottom when reverse indexing, from Matt Tomlinson.
  61. ;  Fix tests for cursor left of left margin for wide screens by comparing
  62. ;  column number exceeding 250D.  [jrd]
  63. ; 28 March 1987 Use global variable low_rgt vs proc call for it. [jrd]
  64. ; 24 March 1987 In vtsound, always use most recent port 61h state. [jrd]
  65. ; 22 March 1987 Add call to proc chgdsp (change display adapter) to shift
  66. ;  between 80 and 132 columns, from David L. Knoell. [jrd]
  67. ; 14 March 1987 Correct small bugs. Change signed jumps to unsigned plus
  68. ;  allow screen widths to 132 columns, thanks to David Knoell.
  69. ;  Add constants Swidth (132) and Slen (43) as max screen dimensions and
  70. ;  base screen ops on low_rgt (high = row, low = column of lower right corner,
  71. ;  counted from 0,0) dimensions stated by msyibm. [jrd]
  72. ; 6 March 87 Add transparent printing when ANSI Media Copy (ESC [ 5 i) is
  73. ;  active. [jrd]
  74. ; 19 Feb 1987 correct problem in atccic of cursor being forced into scrolling
  75. ;  region if starting point was outside the region. [jrd]
  76. ; 27 Oct 1986 correct typo for anspflg under atnrm3: [jrd]
  77. ; 16 Oct 1986 keep several ansflg bits under warm start, correct screen,
  78. ;  linewrap, and newline status under warm start.
  79. ; 1 Oct 1986 Version 2.29a
  80. ; 20 Sept 1986 revise procedure atccic to use proper scrolling limits. [jrd]
  81. ; 1 Sept 1986 Add 8 bit wide comms when parity = none. In debug mode high bit
  82. ;  set shows as tilde then rest of 7 bit code. [jrd]
  83. ; 27 August 1986 Add full VT102 printer support. DOS printer operations used
  84. ;  so printer can be redirected; requires Kermit's Critical Error routine in
  85. ;  mssker.asm to avoid "Abort, Retry, Ignore" msgs on screen. Shows printer
  86. ;  not ready msg on mode line and quits printing operation if PRN not ready.
  87. ; Correct indexing of cursor when it is outside limited scrolling region.[jrd]
  88. ; Fix parameter decanm not being updated in stblmds under soft reset.
  89. ;  21 May 1986 [jrd]
  90. ; [2.29] code frozen on 6 May 1986 [jrd]
  91. ;    [Joe R. Doupnik, Utah State Univ]
  92. ;
  93.  
  94.     public    anstty, ansini, ansrei, ansdsl, anstat, anskbi ; Entry points
  95.     public    ans52t, vclick, vsinit
  96.     public    vtsound                ; [rwb]
  97.     public    mar_top, mar_bot, anspflg    ; data for msyibm
  98.     include mssdef.h
  99.  
  100. ; * Disclaimer *
  101. ;
  102. ; DEC and VT are trademarks of Digital Equipment Corporation.
  103. ;
  104. ; There is a naming convention
  105. ; for the ANSI and VT100 functions and flags; generally, the stuff in the
  106. ; symbol after "ans" or "at" is the function or mode mnemonic used in the
  107. ; VT100 manual.
  108. ;
  109. ; Every effort has been made to make the VT100 emulation as much like the
  110. ; real thing as possible.   The reference used was the VT100 User's Guide, 2nd
  111. ; ed. Jan. 1979, DEC part no. EK-VT100-UG.    Some aspects of the behavior
  112. ; of the terminal (e.g., the interaction of the "origin mode", limited
  113. ; scrolling region, and indexing), were gleaned from programming experiments
  114. ; on an actual VT100 terminal.    Implemented features include: (1) Limited
  115. ; scolling region, (2) Settable tab stops, (3) Special "graphics" character
  116. ; set and UK ASII set, (4) All graphic renditions (underline, blink, and
  117. ; high intensity), (5) Simulated "LEDs" on the mode line, (6) Screen mode
  118. ; (normal or reverse video), (7) All terminal reports (status, active position,
  119. ; terminal parameters, and device attributes), (8) The ANSI new-line mode and
  120. ; several of the DEC private modes, including keypad application, cursor key,
  121. ; screen, auto-wrap, and origin, (9) cursor position/graphic rendition/
  122. ; character set save/restore, and last (and probably least): (10) VT52 com-
  123. ; patibility mode.    Also, various details of behavior required by the ANSI
  124. ; standard (e.g. most control characters do not affect the interpretation of
  125. ; the current escape sequence, relative cursor positioning (up, down, left
  126. ; right, and of course tab) stop at the screen margins, etc.) have been
  127. ; scrupulously observed.
  128. ;
  129. ; This was the first thing I ever wrote in 8088 assembler (some of it was
  130. ; stolen from MSYIBM), and one of the constraints was that the emulator
  131. ; should work with a vanilla PC with a monochrome monitor. Given these and
  132. ; other constraints, no attempt was made to implement the following VT100
  133. ; features: (1) Smooth scolling, (2) 132 column lines, (3) Auto repeat,
  134. ; (5) Interlace/no interlace, (6) Double-width/double-height lines. The
  135. ; escape sequences to set and reset these are recognized, but ignored.
  136. ;
  137. ;    - James A. Harvey, IUPUI Computing Services, DEC Systems Group
  138. ;
  139. ; * End of Disclamer *
  140. ; ---------------------------------------------------------------------------
  141. ;
  142. ; Description of the global entry points and calls on external routines
  143. ; needed by this emulator.                    [jrd]
  144. ;
  145. ; vsinit - start up routine called as Kermit initializes. Takes no arguments.
  146. ;       Sets up address pointers to tabs, reads default terminal parameters
  147. ;       reads current screen coloring. Examines and updates structure
  148. ;       "vtemu." which is how mssset communicates changed information
  149. ;       about many Set Term parameters; "flags." is a Kermit structure
  150. ;       carrying the other Set Term parameters.
  151. ; anstty - starting point for displaying a character, delivered in AL.
  152. ;       Returns when the display operation is completed and that may
  153. ;       take many many instructions. All normal "characters received by
  154. ;       the terminal" are provided by calling anstty with the char in AL.
  155. ; ansini - entry point to initialize the emulator. It requires information
  156. ;       from msy in four registers: the Kermit terminal routine flags
  157. ;       "yflags" (used mainly to sense debug mode and the mode line toggle)
  158. ;       "low_rgt" (bh = row, bl = column of the lower right display corner)
  159. ;       "lbaudtab" (index into baud rate table, for status reporting)
  160. ;       "lpartab" (index into parity table, for status reporting)
  161. ;       Ansini causes a full reset of the emulator, including screen
  162. ;       clearing and a beep. Ansini is also called by msy in response to
  163. ;       sensing the Alt = key combination to fully reset the emulator.
  164. ; ansrei - entry point to reinitialize the emulator. Nearly the same as
  165. ;       ansini except operating flags, tabs, etc are retained from the
  166. ;       previous emulator session. Items which can be changed by Set Term
  167. ;       are examined and updated. The msy flags "yflags" are needed.
  168. ;       This is the warm-restart entry point used when connect mode
  169. ;       is reentered gracefully. The screen is cleared only if the coloring
  170. ;       has changed. The starting cursor location is whereever msy puts it.
  171. ; ansdsl - display "led" (status line) information. Invoked by msy when
  172. ;       the mode line is constructed so the emulator can write the
  173. ;       terminal type and the VT100 led status lights when Connect mode
  174. ;       is started. Requires "yflags" from msy to sense whether the mode
  175. ;       line is to be shown.
  176. ; anstat - reports our working flags and screen coloring to msy. Nearly
  177. ;       obselete but not quite. Reads msy "yflags" and reports "mlbattr"
  178. ;       the video attributes used on the mode line, "scbattr" the video
  179. ;       attributes of an empty character cell (background), "curattr"
  180. ;       the video attributes of displayable characters, and "ansflgs"
  181. ;       the emulator's working flags (needed for keyboard translations
  182. ;       done in msy).
  183. ; anskbi - a routine called by msy to notify the emulator that a character
  184. ;       is available from the keyboard. No character is read, just flag
  185. ;       ttkbi is set. This is actually used only to beep when the cursor
  186. ;       goes beyond column 72 and the margin bell flag is on.
  187. ; ans52t - called by msy to change terminal types "on the fly" without
  188. ;       fully updating all operating parameters and without losing setup
  189. ;       information. Msy senses the Alt minus key and calls ans52t with
  190. ;       no arguments. Ans52t cycles among VT102, VT52 and Heath-19 modes.
  191. ; vclick - called by msy to cause a click sound. Simulates keyboard clicks,
  192. ;       sort of anyway. No arguments.
  193. ; other modules in msy are called by this file to handle screen scrolling
  194. ;       mode line on/off, output to the serial port (reports), screen
  195. ;       particulars (location, cursor shape, blanking). The list is
  196. ;       the set of code extrn procedures below; all are in file msy.
  197. ;
  198. ; data exchange is directly with msy to assist in scrolling (varaibles
  199. ;       "mar_top", "mar_bot") and in sensing the non-connect
  200. ;       mode screen coloring ("scbattr"). Screen coloring controlled by
  201. ;       the emulator is not permitted to influence the non-connect mode
  202. ;       screens whereas the emulator attempts to use the regular Kermit
  203. ;       screen colors as defaults. The kind of terminal to emulate is
  204. ;       held in byte "flags.vtflg" which is set by Set Term and by this
  205. ;       module for global information within Kermit.
  206. ;
  207. ; The emulator assumes the screen is laid out in the manner of a conventional
  208. ;       IBM monochrome or color graphics adapter running in 80 column TEXT
  209. ;       modes. That layout is one word per displayable location starting at
  210. ;       the upper left corner (0,0) and running contiguously to the lower
  211. ;       right corner (24,79). Each word holds the displayable character in
  212. ;       the low order byte and the display attributes in the high order
  213. ;       byte. Attributes are, from high to low bits: blinking on, back-
  214. ;       ground red, green, and blue on, high intensity, foreground red,
  215. ;       green, and blue on. Normal white chars on a black field is 07H.
  216. ;       The starting segment of screen memory is given by msy module
  217. ;       "scrseg" to be TopView/MS Windows compatible. Msy module "scrsync"
  218. ;       is used to inform these windowing environments of memory updates.
  219. ;       Variable "crt_mode" is set by msy to indicate which IBM display
  220. ;       mode is active; only the monochrome and CGA modes are recognized.
  221. ;       Direct reading and writing of display memory is done, compatibly
  222. ;       with TopView/Windows, to attain speed over Bios and DOS calls
  223. ;       when editing of previously entered text is needed. However, IBM
  224. ;       Bios interrupt 10H is used where possible for normal cursor
  225. ;       movement/sensing and writing of new characters. See the IBM PC
  226. ;       hardware Technical Reference Manuals for further details.
  227. ;
  228. ; Many things have been added, or modified since James Harvey donated this
  229. ;       code to Columbia University for use in Kermit.           [jrd]
  230. ; ---------------------------------------------------------------------------
  231.  
  232. screen    equ    10h            ; Bios screen call
  233. swidth    equ    132            ; assumed max screen width [dlk]
  234. slen    equ    43            ; assumed max screen length [jrd]
  235.  
  236. att_low_mask    equ    06H        ; Various attribute-related equates
  237. ;;;att_reverse    equ    70H        ; these two are now storable items
  238. ;;;att_normal    equ    07H        ; to allow external settings. [jrd]
  239. att_underline    equ    01H
  240. att_intensity    equ    08H
  241. att_blink    equ    80H
  242.  
  243. ; VT100 status flags ansflg
  244.  
  245. ;anslnm     equ     01H             ; ANSI line feed/new line mode
  246. ;decckm     equ     02H             ; VT100 cursor keys mode
  247. ;deckpam equ     04H             ; VT100 keypad application mode
  248. ;decscnm equ     08H             ; VT100 screen mode (n.y.i.)
  249. ;decom     equ     10H             ; VT100 origin mode
  250. ;decawm     equ     20H             ; VT100 autowrap mode
  251. ;decanm     equ     40H             ; ANSI(VT100)/VT52 mode
  252. ;decmode equ     80H             ; "?" seen in lead-in
  253.  
  254. ;;;;;;;;;;;;;;;; items for reference from mssdef.h ;;;;;;;;;;;;;
  255.  
  256. ; VT100 SETUP mode flags
  257.  
  258. ;vsscreen     equ     40H         ; Screen mode (0 = normal video)
  259. ;vscursor     equ     20H         ; Cursor (0 = block)
  260. ;vsmarginbell     equ     10H         ; Margin bell (0 = off)
  261. ;vskeyclick     equ     08H         ; Keyclick (0 = off)
  262. ;vsshift3     equ     04H         ; Shift-3 (0 = American pound sign)
  263. ;vswrap         equ     02H         ; Line wrap around (0 = no wrap)
  264. ;vsnewline     equ     01H         ; ANSI new line (0 = off)
  265.  
  266. ;vsdefaults     equ     0+vscursor
  267.  
  268. ;[IU1] Definitions for terminal emulation
  269. ;TTGENRC EQU    0        ; Type 0 - TTY (no special emulation)
  270. ;TTHEATH EQU    1        ; Type 1 - HEATH 19
  271. ;TTVT52 EQU    2        ; Type 2 - VT52
  272. ;TTVT100 EQU    3        ; Type 3 - ANSI (VT100 subset)
  273. ;TTTEK    EQU    4        ; Type 4: Tektronix 4010
  274. ;TTTYPES equ    5        ; Number of terminal types defined
  275.  
  276. ;emulst struc        ; structure of vtemu.xxx for VT100 emulator
  277. ;vtflgst db    0    ; VT100 setup flags (from SET)
  278. ;vtflgop db    0    ; VT100 runtime flags, like setup flags (here & STAT)
  279. ;vttbs    dw    0    ; pointer to default tab stops, for SET
  280. ;vttbst dw    0    ; pointer to active tab stops, for STATUS
  281. ;att_ptr dw    0    ; pointer to normal & reverse video attributes
  282. ;emulst ends
  283. ;;;;;;;;;;;;;;;;  end references ;;;;;;;;;;;;;;;;;;;;
  284.  
  285. datas    segment public 'datas'
  286.     extrn vtemu:byte, crt_mode:byte, scbattr:byte, flags:byte
  287.     extrn crt_lins:byte, crt_cols:byte, rxtable:byte, denyflg:word
  288.         extrn usevb:byte
  289.     extrn tekflg:byte
  290.  
  291. ; Early versions of MASM have a bug that causes it to consider the
  292. ; expression (offset foo) as non-relocatable if used in an arithmetic
  293. ; operation (for example, "sub di,offset foo"), and if foo is defined
  294. ; within the first 256 bytes of the data segment.
  295.  
  296.  
  297. ; ANSI special character table - 32 entries indexed by control char value
  298.  
  299. ansspc    dw    5 dup (atign)        ; ignore NUL,SOH,STX,ETX,EOT
  300.     dw    atign            ; ENQ - answerback message
  301.     dw    atign            ; ACK - ignore
  302.     dw    atbel            ; BEL - ring terminal bell
  303.     dw    atbs            ; BS - ANSI backspace
  304.     dw    atht            ; HT - ANSI tab
  305.     dw    atlf            ; LF - ANSI line feed
  306.     dw    atlf            ; VT - Interpreted as ANSI LF
  307.     dw    atff            ; FF - do as LF (but ESC FF does Tek)
  308.     dw    atcr            ; CR - ANSI carriage-return
  309.     dw    atso            ; SO - Select char set G1
  310.     dw    atsi            ; SI - Select char set G0
  311.     dw    8 DUP (atign)    ; ignore DLE,DC1,DC2,DC3,DE4,NAK,SYN,ETB
  312.     dw    atcan            ; CAN - cancel ANSI sequence
  313.     dw    atign            ; EM - ignore
  314.     dw    atcan            ; SUB - treat as CAN
  315.     dw    atesc            ; ESC - ANSI CSI.
  316.     dw    4 DUP (atign)        ; ignore FS,GS,RS,US
  317.  
  318. ; Heath-19 mode escape follower table
  319.  
  320. h19esc    db    'YABCD', 'KIHJF', 'G=><Z', 'ELM'
  321.     db    'NO@p', 'qvwjk', 'xynz', 'blor'
  322. lh19esc equ    $-h19esc
  323.  
  324. ; Dispatch table for Heath-19 escape sequence table h19esc.
  325. ; Two byte sequences of the form ESC char, where char is not in the
  326. ; table above, are completely ignored.
  327.  
  328. h19ejt    dw    v52pos,atcuu,h19cud,h19cuf,atbs        ; 'YABCD'
  329.     dw    atel,atri,atcup,ated,v52egm        ; 'KIHJF'
  330.     dw    v52xgm,atkpam,atkpnm,h19ans,decid    ; 'G=><Z'
  331.     dw    h19clrs,inslin,dellin            ; 'ELM'
  332.     dw    atdelc,noins,entins,h19herv        ; 'NO@p'
  333.     dw    h19hxrv,h19wrap,h19nowrp,atsc,atrc    ; 'qvwjk'
  334.     dw    h19smod,h19cmod,hrcup,atreset        ; 'xynz'
  335.     dw    h19erb,h19erl,h19ero,h19mbr        ; 'blor'
  336.  
  337. ; Heath-19 special graphics characters. Use as offsets from caret (94D) [jrd]
  338.  
  339. hgrtab    db    249,17,179,196,197    ; caret,underscore,accent grave,a,b
  340.     db    191,217,192,218,241    ; c,d,e,f,g
  341.     db    26,219,246,25,220    ; h,i,j,k,l
  342.     db    220,223,223,223,222    ; m,n,o,p,q
  343.     db    16,203,185,202,204    ; r,s,t,u,v
  344.     db    'X','/','\','-','-'    ; w,x,y,z,{
  345.     db    221,222,20        ; |,},~
  346.  
  347. ; VT52 compatibility mode escape follower table
  348.  
  349. v52esc    db    'Y','A','B','C','D'
  350.     db    'K','I','H','J','F'
  351.     db    'G','=','>','<','Z'
  352.     db    '7','8','c','^','_'
  353.     db    'W','X',']','V'
  354. lv52esc equ    $-v52esc        ; length of table
  355.  
  356. ; Dispatch for v52esc table
  357.  
  358. v52ejt    dw    v52pos,atcuu,atcud,atcuf,atcub
  359.     dw    atel,atri,atcup,ated,v52egm
  360.     dw    v52xgm,atkpam,atkpnm,v52ans,decid
  361.     dw    atsc,atrc,v52ris,v52apb,v52ape
  362.     dw    v52pcb,v52pce,v52ps,v52pl
  363.  
  364. ; ANSI escape special character table
  365.  
  366. ansesc    db    '[','D','E','M','H'
  367.     db    '7','8','=','>','c'
  368.     db    '(',')','#','Z','<'
  369.     db    'P','*'
  370. lansesc equ    $-ansesc        ; length of table
  371.  
  372. ; Dispatch for ansesc table
  373.  
  374. ansejt    dw    atcsi,atind,atnel,atri,athts
  375.     dw    atsc,atrc,atkpam,atkpnm,atris
  376.     dw    atsg0,atsg1,atsdhl,at52id,atnorm
  377.     dw    atpriv,atpriv
  378.  
  379.  
  380. ; Final char table for ANSI escape sequences (ESC [ Pn ; ... Pm ch)
  381.  
  382. anstab    db    'H','A','B','C','D'
  383.     db    'K','J','m','g','r'
  384.     db    'c','q','x','n','f'
  385.     db    'l','h','y','P','L'
  386.     db    'M','i','s','u','z'
  387.     db    '@'
  388. lanstab equ    $-anstab        ; Define table length
  389.  
  390. ; Dispatch for anstab table
  391.  
  392. ansjmp    dw    atcup,atcuu,atcud,atcuf,atcub
  393.     dw    atel,ated,atsgr,attbc,atstbm
  394.     dw    atda,atll,atreqt,atdsr,atcup
  395.     dw    atrm,atsm,atctst,atdelc,inslin
  396.     dw    dellin,ansprt,htsc,htrc,htrest
  397.     dw    ansich
  398.  
  399. ; "Special graphics" set translation table for characters 137 (octal)
  400. ; through 176 when the special graphics set is selected.  Some characters
  401. ; (142, 143, 144, 145, 150, 151, 157, 160, 162, 163, and 174) do not
  402. ; have exact equivalents in the available set on the IBM, so a (some-
  403. ; times reasonably close) substitution is made.     Table is indexed by
  404. ; ASCII char value minus 137 octal for chars 137-176 octal.
  405.  
  406. sgrtab    db    032,004,177,026,023
  407.     db    027,025,248,241,021
  408.     db    018,217,191,218,192
  409.     db    197,196,196,196,196
  410.     db    196,195,180,193,194
  411.     db    179,243,242,227,157
  412.     db    156,250
  413.  
  414. ; Device attributes response string. (Note: If "with AVO" causes problems,
  415. ; change the last parameter from "2" to "0". The default is to indicate
  416. ; the AVO option is present because the emulator can set all of the graphic
  417. ; rendition attributes (bold, blink, etc.) independently). A VT100 reports
  418. ; as ESC [ ? 1 ; 2 c  but a VT102 uses ESC [ ? 6 ; 2 c.
  419.  
  420. dastr    db    escape,'[?6;2c'        ; VT102
  421. ldastr    equ    $-dastr
  422.  
  423. ; Identify response used while in VT52 compatibility mode...
  424.  
  425. v52str    db    escape,'/Z'
  426. lv52str equ    $-v52str
  427.  
  428. ; Identify response when a Heath-19 terminal. [jrd]
  429.  
  430. h19str    db    escape,'/K'
  431. lh19str equ    $-h19str
  432.  
  433. ; ANSI Escape sequence to turn off Media Copy (Print Controller Off)
  434.  
  435. mcoff    db    escape,'[4i'
  436. mcofflen equ    $-mcoff            ; length of sequence
  437. mcoffs    db    4 dup (0)        ; received chars in sequence
  438. mccnt    dw    ?            ; counter of matched char in mcoff
  439.  
  440. ; Parity code translation table
  441.  
  442. partab    db    5            ; Even
  443.     db    3            ; Mark
  444.     db    1            ; None
  445.     db    4            ; Odd
  446.     db    2            ; Space
  447. lpartab equ    $-partab
  448.  
  449. ; Baud rate code translation table
  450.  
  451. baudtab db    0            ; 45.5 - no VT100 code (call it 50)
  452.     db    0            ; 50
  453.     db    8            ; 75
  454.     db    16            ; 110
  455.     db    24            ; 134.5
  456.     db    32            ; 150
  457.     db    48            ; 300
  458.     db    56            ; 600
  459.     db    64            ; 1200
  460.     db    72            ; 1800
  461.     db    80            ; 2000
  462.     db    88            ; 2400
  463.     db    104            ; 4800
  464.     db    112            ; 9600
  465.     db    120            ; 19200
  466.     db    128            ; 38400     extended beyond DEC [jrd]
  467. lbaudtab    equ    $-baudtab
  468.  
  469. belcol    db    ?            ; column at which to ring margin bell
  470. yflags    db    ?            ; Flags from MSYxxx term routine.
  471. video_state db    0            ; video state (0=normal,1=reversed)
  472. oldbatr db    ?            ; old scbattr [jrd]
  473. oldterm db    ?            ; terminal type from previous entry
  474. baudidx db    ?            ; Index into baud rate table
  475. parcode db    ?            ; Parity code (0-4)
  476. datbits db    ?            ; Number of databits (7 or 8)
  477. savflgs db    ?            ; Saved flags for atsc/atrc.
  478. modeset db    ?            ; Temp for atsm/atrm.
  479. h19mod    db    ?            ; flag for atsm/atrm.
  480. h19l25    db    ?            ; Heath-19 25th line enabled flag
  481. insmod    db    ?            ; Insert mode on (1) or off (0).[jrd]
  482. kbicsr    dw    ?            ; Cursor when keyboard input typed
  483. kbiflg    db    ?            ; Set/reset for keyboard input
  484. ttstate dw    offset atnrm        ; terminal automata state.
  485.  
  486.                     ; Start of stuff to save for ESC 7 fxn
  487. ukset    equ    0            ; Set 1 = UK ASCII set
  488. ascset    equ    1            ; Set 2 = US ASCII set
  489. sgrset    equ    2            ; Set 3 = "Special graphics set"
  490. svattr_index    equ 0            ; To set saved cursor attribute only.
  491.  
  492. curattr db    07h            ; Cursor attribute
  493. cursor    dw    0            ; Cursor position
  494. chr_set dw    offset chr_sg0        ; Ptr. to currently selected char set
  495. chr_sg0 db    ascset            ; Current SG0 set
  496. chr_sg1 db    ascset            ; Current SG1 set
  497. lsavecu equ    $-curattr        ; Length of stuff to save.
  498.  
  499. savecu    db    lsavecu dup (?)        ; Saved cursor, attr., charset, etc.
  500. h19ctyp db    1            ; H-19 cursor type (1=ul, 2=bk, 4=off)
  501.  
  502. att_normal    db    07H        ; retain order: normal then reverse
  503. att_reverse    db    70H
  504.  
  505. mlbattr db    ?            ; Mode line background attribute
  506.  
  507. ansflgs db    0            ; ANSI/VT100 mode flags
  508. ; (flags are defined in mssdefs.h)
  509.  
  510. vtflags db    0            ; VT100 SETUP flags
  511. ; (SETUP flags are defined in mssdefs.h)
  512. tmpflags    db    0        ; (Temporary for asnrei/stblmds).
  513.  
  514. ; (tab stops are stored here)        ; [jrd]
  515. tabs    db    swidth dup (?)        ; active tab stops.
  516. deftabs db    swidth dup (?)        ; default tab stops
  517. vttabs    dw    0            ; Pointer to default VT100 tab stops
  518.  
  519. ; byte per line, type of line: 0=normal, 1=double wide, 2=double high [jrd]
  520. linetype db    slen dup (?)
  521.  
  522. linelen db    79            ; active screen line length (79, 131)
  523. low_rgt dw    0            ; text screen dimensions.
  524.                     ; byte low_rgt = max columns (79)
  525.                     ; byte low_rgt+1 = max rows (23)
  526. ttkbi    db    0            ; Flag for keyboard input seen.
  527.  
  528. ; Scrolling region - do not separate or change order of mar_top & mar_bot.
  529. mar_top db    ?            ; Scrolling region top margin
  530. mar_bot db    ?            ; Scrolling region bottom margin
  531.  
  532. led_col equ    65            ; column position for "LEDs" display
  533. led_off equ    '.'            ; "Off" LED. [jrd]
  534. ansleds db    'VT102 ....'        ; "LEDs".Terminal ident (10 bytes)
  535. v52leds db    '   VT52   '        ; This is used in VT52 mode.
  536. h19leds db    ' Heath-19 '        ; For Heath-19 mode [jrd]
  537.                     ; message for mode line [jrd]
  538. pntmsg    db    'Printer not ready, printing request skipped.'
  539. pntmsgl equ    $-pntmsg        ; length of pntmsg
  540.  
  541. nansarg db    0            ; Index for ANSI argument list
  542. ansargs db    16 dup (0)        ; Room for 16 ANSI arguments
  543. lansarg equ    $-ansargs        ; Max number of ANSI arguments
  544.                     ; printer support data
  545. anspflg db    0            ; printer flag bits and definitions
  546. vtautop equ    1            ; autoprint enabled (1)
  547. vtcntp    equ    2            ; controller print enabled (1)
  548. vtextp    equ    4            ; printer extent set (1)
  549. vtffp    equ    8            ; form feed wanted at end of print (1)
  550. trtbl    db    0h,1h,2h,3h,1h,2h,3h,7h      ; color translation table
  551.     db    7h,9h,0ah,0bh,9h,0ah,0bh,0fh
  552.     db    10h,14h,15h,16h,14h,15h,16h,18h
  553.     db    18h,19h,1ah,1bh,1ch,1dh,1eh,1fh
  554.     db    20h,24h,25h,26h,24h,25h,26h,28h
  555.     db    28h,29h,2ah,2bh,2ch,2dh,2eh,2fh
  556.     db    30h,34h,35h,36h,34h,35h,36h,38h
  557.     db    38h,39h,3ah,3bh,3ch,3dh,3eh,3fh
  558.     db    41h,41h,42h,43h,41h,42h,43h,47h
  559.     db    47h,49h,4ah,4bh,49h,4ah,4bh,4fh
  560.     db    51h,51h,52h,53h,51h,52h,53h,57h
  561.     db    57h,59h,5ah,5bh,59h,5ah,5bh,5fh
  562.     db    61h,61h,62h,63h,61h,62h,63h,67h
  563.     db    67h,69h,6ah,6bh,69h,6ah,6bh,6fh
  564.     db    70h,74h,75h,76h,74h,75h,76h,78h
  565.     db    78h,79h,7ah,7bh,7ch,7dh,7eh,7fh
  566.  
  567.  
  568. datas    ends
  569.  
  570.  
  571. code    segment public 'code'
  572.     extrn    prtbout:near, prtnout:near, csrtype:near, trnmod:near
  573.     extrn    scrmod:near, scrseg:near, scrsync:near, scroff:near
  574.     extrn    scron:near, atsclr:near, vtscru:near, vtscrd:near
  575.     extrn    modwrt:near, telmsy:near, scrloc:near, pcwait:near
  576.     extrn    chgdsp:near, trnprs:near, cptchr:near, tekesc:near
  577.                 ; extrn procedures are all in module msyibm
  578.     extrn    tekini:near, tekemu:near, tekend:near
  579.     assume    cs:code, ds:datas, es:datas
  580.  
  581. ; This routine initializes the VT100 setups at startup.     It is called from
  582. ; procedure lclyini in module msyibm.
  583.  
  584. vsinit    proc    near
  585.     mov    vtemu.vtflgst,vsdefaults ; Init to defaults in mssdef.h
  586.     mov    vtemu.vtflgop,vsdefaults ; Init runtime state to setup items
  587.     mov    insmod,0        ; turn off insert mode. [jrd]
  588.     mov    deftabs,0        ; Column 1 has no tab stop.
  589.     mov    cl,crt_cols        ; physical screen width (80)
  590.     dec    cl            ; we count from column 0
  591.     mov    ch,crt_lins        ; physical screen length-1
  592.     dec    ch            ; we count from row 0
  593.     mov    low_rgt,cx        ; store active text area
  594.     mov    cx,131
  595.     mov    di,1            ; Starting index for column 2.
  596. vsini1: mov    al,0            ; Assume we will clear this one.
  597.     test    di,0007H        ; Index mod 8 equals 0?
  598.     jnz    vsini2            ; No, clear it.
  599.     mov    al,0FFH            ; Yes, set it.
  600. vsini2: mov    deftabs[di],al        ; Set or clear a tab stop.
  601.     inc    di            ; Advance to next.
  602.     loop    vsini1            ; Loop for all.
  603.     mov    cx,slen            ; clear linetype array [jrd]
  604.     mov    di,0
  605. vsini3: mov    linetype[di],0
  606.     inc    di
  607.     loop    vsini3
  608.     mov    vtemu.vttbst,offset deftabs ; addrs of active tabs for STATUS
  609.     mov    vtemu.vttbs,offset deftabs  ; addrs of tabs for setup (SET)
  610.     mov    vttabs,offset deftabs    ; initial source of tabs. [jrd]
  611.     call    cpytabs            ; copy default to active [jrd]
  612.     mov    vtemu.att_ptr,offset att_normal     ; ptr to video attributes[jrd]
  613.     mov    ah,8            ; read current attributes
  614.     xor    bh,bh            ; page 0
  615.     int    screen
  616.     mov    scbattr,ah        ; save video attributes
  617.     mov    att_normal,ah        ; set att_normal to present colors
  618.     call    brkatt            ; separate colors from blink/bold
  619.     rol    ah,1            ; reverse foreground & background
  620.     rol    ah,1            ; RGB bits.
  621.     rol    ah,1
  622.     rol    ah,1
  623.     call    addatt            ; reinsert bold/blink bits
  624.     mov    att_reverse,ah        ; set att_reverse too.
  625.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  626.     sub    ah,8            ; place marker 9 columns from margin
  627.     mov    belcol,ah        ; store column number to ring bell
  628.     ret                ; And return.
  629. vsinit    endp
  630.  
  631.  
  632. ; Initialization routine.
  633. ;
  634. ; Call:        al/    yflags byte that was passed to Term routine.
  635. ;        dl/    index for baud rate table
  636. ;        dh/    parity in bits 4-7, number of data bits in bits 0-3
  637. ;
  638.  
  639. ansini    proc    near
  640.     mov    yflags,al        ; Always save flags
  641.     mov    ah,vtemu.vtflgst    ; setup flags [jrd]
  642.     mov    vtflags,ah
  643.     mov    vttabs,offset deftabs    ; tab stop pointer.
  644.     mov    vtemu.vttbst,offset tabs; store here for STATUS [jrd]
  645.     mov    al,flags.vtflg        ; get current terminal type
  646.     mov    oldterm,al        ; remember it here for soft restarts
  647.     mov    insmod,0        ; turn off insert mode. [jrd]
  648.     mov    h19l25,0        ; clear Heath 25th line enable. [jrd]
  649.     mov    h19ctyp,1        ; set Heath cursor to underline, on
  650.     mov    anspflg,0        ; clear printer flag [jrd]
  651.     push    ax
  652.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  653.     sub    ah,8            ; place marker 9 columns from margin
  654.     mov    belcol,ah        ; store column number to ring bell
  655.     pop    ax
  656.     cmp    dl,lbaudtab        ; Wierd index?
  657.     jb    ansin1            ; No - OK - store it.
  658.     mov    dl,lbaudtab-1        ; Yes - make it the maximum.
  659. ansin1: mov    baudidx,dl        ; Save baud rate index
  660.     mov    al,dh            ; Get parity/number of databits
  661.     and    al,0FH            ; Isolate number of databits
  662.     mov    datbits,al        ; Save.
  663.     mov    cl,4            ; Isolate parity code
  664.     shr    dh,cl            ; Isolate parity code
  665.     cmp    dh,lpartab        ; Weird code?
  666.     jb    ansin2            ; No - OK - store it.
  667.     mov    dh,lpartab-1        ; Yes - make it the maximum.
  668. ansin2: mov    parcode,dh        ; Save.
  669.     call    scrmod            ; Get the screen mode, in MSYxxx
  670.     mov    cl,crt_cols        ; physical screen number columns (80)
  671.     dec    cl            ; we count from column 0 here
  672.     mov    ch,crt_lins        ; physical screen number rows-1 (24)
  673.     dec    ch            ; we count from row 0 here
  674.     mov    low_rgt,cx        ; save as active text screen size
  675. ansin3: call    atreset            ; Reset everything
  676.     mov    ttstate,offset atnrm    ; Reset state to "normal".
  677.     ret                ; And return.
  678. ansini    endp
  679.  
  680.  
  681. ; Re-initialization routine.      Called when Term was called but screen was
  682. ; restored from a previously saved screen, etc.
  683. ;
  684. ; Call: al/    yflags byte that was passed from msyibm module.
  685. ;
  686.  
  687. ansrei    proc    near
  688.     mov    yflags,al        ; Always save flags
  689.     mov    ah,vtemu.vtflgop    ; get runtime flags [jrd]
  690.     mov    tmpflags,ah
  691.     call    scrmod            ; Get the screen mode.
  692.     call    atsctyp            ; set cursor type [rbv]
  693.     mov    ah,3            ; get cursor position from msy
  694.     mov    bh,0            ; Page zero.
  695.     int    screen
  696.     mov    cursor,dx        ; dh = row, dl = column
  697.     mov    cl,crt_cols        ; physical screen number columns (80)
  698.     dec    cl            ; we count from column 0 here
  699.     mov    ch,crt_lins        ; physical screen number rows-1 (24)
  700.     dec    ch            ; we count from row 0 here
  701.     mov    low_rgt,cx        ; save as active text screen size
  702.     cmp    linelen,79        ; want 80 cols?
  703.     ja    ansre2            ; a = no
  704.     cmp    byte ptr low_rgt,79    ; want 80 cols. Is active screen wider?
  705.     jbe    ansre2            ; be = no
  706.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  707. ansre2: call    stblmds            ; Check settable modes, set flags.
  708.     ret
  709. ansrei    endp
  710.  
  711.  
  712. ; This routine copies the new tab stops when they have changed.
  713. ; Copies all 132 columns.
  714. cpytabs proc    near
  715.     mov    cx,swidth        ; number of screen columns
  716.     jcxz    cpytab1            ; z = none to do
  717.     mov    si,vttabs        ; Source.
  718.     mov    di,offset tabs        ; Destination.
  719.     push    es            ; save es
  720.     push    ds
  721.     pop    es            ; set es to datas segment
  722.     cld
  723.     rep    movsb            ; Do the copy.
  724.     pop    es            ; recover es
  725. cpytab1:ret
  726. cpytabs endp
  727.  
  728.  
  729. ; This routine checks to see whether any of the settable modes have changed
  730. ; (things that can be changed in both SETUP and by host commands), and
  731. ; changes those that need to be changed.  TMPFLAGS has the new VT100 setup
  732. ; flags, VTFLAGS has the old. This routine also updates VTFLAGS.
  733. ; Revised by [jrd] to allow MSY to reset scbattr when not in connect mode,
  734. ; to do "soft reset" if terminal type has changed, and to do a screen clear
  735. ; reset if the actual screen colors have changed.
  736.  
  737. stblmds proc    near
  738.     mov    al,flags.vtflg        ; get current terminal type [jrd]
  739.     cmp    al,oldterm        ; same as before?
  740.     je    stblm10            ; e = yes, skip over soft reset.
  741.     mov    oldterm,al        ; remember current terminal type
  742.     mov    insmod,0        ; reset insert mode flag
  743.     mov    h19l25,0        ; reset heath-19 25th line enable
  744.     mov    mar_top,0        ; reset top scrolling margin
  745.     mov    al,byte ptr low_rgt+1    ; and scrolling margin
  746.     mov    mar_bot,al        ; to last normal line on screen
  747.     mov    ah,byte ptr low_rgt    ; right most column (counted from 0)
  748.     sub    ah,8            ; place marker 9 columns from margin
  749.     mov    belcol,ah        ; store column number to ring bell
  750.     and    ansflgs,decckm+deckpam+decom ; save some flags
  751.     push    bx            ; save this register around loop
  752.     mov    bx,offset linetype    ; setup to clear double width chars
  753.     mov    cx,slen            ; number of linetype slots to clear
  754.     cmp    flags.vtflg,ttvt100    ; VT100 now?
  755.     jne    stblm0            ; ne = no
  756.     or    ansflgs,decanm        ; set ansi flag bit
  757. stblm0: mov    byte ptr [bx],0        ; clear the linetype array to single
  758.     inc    bx            ;  width characters.
  759.     loop    stblm0            ; do each line (1 byte per line)
  760.     pop    bx            ; restore bx
  761. stblm10:mov    al,tmpflags        ; Get the new flags.
  762.     and    ansflgs,not anslnm    ; assume we do not want newline
  763.     test    al,vsnewline        ; is newline mode desired?
  764.     jz    stblm1            ; No - continue.
  765.     or    ansflgs,anslnm        ; Yes - set corresponding mode flag.
  766. stblm1: and    ansflgs,not decawm    ; assume not want wrap
  767.     test    al,vswrap        ; Did wrap mode change?
  768.     jz    stblm2            ; No - continue.
  769.     or    ansflgs,decawm        ; Yes - set corresponding mode flag.
  770. stblm2: mov    ah,vtflags        ; old flags
  771.     xor    ah,tmpflags        ; new flags
  772.     test    ah,vsshift3        ; pick out char set bit
  773.     jz    stblm4            ; z = no change
  774.     mov    ah,ascset        ; assume US ASCII.
  775.     test    tmpflags,vsshift3    ; Want UK?
  776.     jz    stblm3            ; No - guessed right.
  777.     mov    ah,ukset        ; Yes - use UK set.
  778. stblm3: mov    chr_sg0,ah        ; Set the sets.
  779.     mov    chr_sg1,ah
  780. stblm4: mov    ah,oldbatr        ; get old screen background scbattr
  781.     mov    scbattr,ah        ; and update working copy
  782.     mov    ah,att_normal        ; get new attributes (Set Term Color)
  783.     push    bx
  784.     mov    bh,ah            ; get new intensity bit of att_normal
  785.     and    bh,att_intensity
  786.     and    curattr,not att_intensity ; char attrs. clear intensity bit
  787.     or    curattr,bh        ; set new intensity
  788.     and    mlbattr,not att_intensity ; mode line attrs. clear intensity
  789.     and    scbattr,not att_intensity ; screen background attribute
  790.     or    scbattr,bh        ; set its intensity also
  791.     mov    bl,scbattr
  792.     mov    oldbatr,bl        ; and save it here as well
  793.     pop    bx
  794.     call    brkatt            ; separate color and blink/bold
  795.     rol    ah,1            ; reverse fore/back color fields
  796.     rol    ah,1
  797.     rol    ah,1
  798.     rol    ah,1
  799.     call    addatt            ; put back blink/bold
  800.     push    bx            ; check on color change
  801.     mov    bh,ah            ; new att_reverse pattern
  802.     and    bh,not(att_intensity+att_blink) ; look at just color bits
  803.     mov    bl,att_reverse        ; previous att_reverse pattern
  804.     and    bl,not(att_intensity+att_blink) ; look at just color bits
  805.     mov    att_reverse,ah        ; save new reverse pattern
  806.     cmp    bh,bl            ; have any color bits changed?
  807.     pop    bx            ; does not affect flags
  808.     je    stblm9            ; e = no
  809.     mov    cursor,0        ; reset cursor position
  810.     jmp    atres2            ; go to semi-reset
  811. stblm9:                    ; check on screen normal/reversed.
  812.     mov    al,tmpflags
  813.     xor    al,vtflags        ; Find which ones have changed.
  814.     test    al,vsscreen        ; How about screen background?
  815.     jz    stblm8            ; No - don't touch it.
  816.     test    tmpflags,vsscreen    ; Flag to be set?
  817.     jnz    stblm5            ; Yes - go to it.
  818.     and    ansflgs,not decscnm    ; No - cleared (normal video).
  819.     and    savflgs,not decscnm
  820.     mov    al,att_normal        ; No - get new background.
  821.     jmp    short stblm6        ; And reverse everything.
  822.  
  823. stblm5: or    ansflgs,decscnm        ; Set (reverse video).
  824.     or    savflgs,decscnm
  825.     mov    al,att_reverse        ; No - set reverse video.
  826. stblm6: call    atrss2            ; Reverse screen and cursor attribute.
  827. stblm7: mov    al,scbattr        ; Reset saved attribute also.
  828.     mov    savecu+svattr_index,al
  829.     mov    oldbatr,al        ; and save our attribute
  830. stblm8: mov    al,tmpflags        ; Get new flags.
  831.     mov    vtflags,al        ; Store them.
  832.     ret
  833. stblmds endp
  834.  
  835. ; Return screen offset - given rol, col in dx, returns offset of the word
  836. ; for that character from the screen origin in ax.    Preserves all other acs.
  837. ; Use same routine in msy to more closely track screen width.  [jrd]
  838. ;;scrloc    proc    near
  839. ;;    push    bx            ; We will use bx.
  840. ;;    mov    al,dh            ; Get row.
  841. ;;    mov    bl,swidth        ; And length of a line
  842. ;;    mul    bl            ; Offset for this row
  843. ;;    mov    dh,0            ; Clear row.
  844. ;;    add    ax,dx            ; Word offset for this position
  845. ;;    sal    ax,1            ; Make it a byte offset
  846. ;;    pop    bx            ; Restore bx.
  847. ;;    ret                ; And return.
  848. ;;scrloc    endp
  849.  
  850.  
  851.  
  852. ; Fetch status/attributes routine.
  853. ;
  854. ; Call:        al/    "yflags" byte from MSYxxx.
  855. ;
  856. ; Return:    ah/    mode line background attribute
  857. ;        al/    screen background attribute
  858. ;        bl/    current cursor attribute
  859. ;        bh/    ANSI (VT100) mode flags
  860.  
  861. anstat    proc    near
  862.     mov    yflags,al        ; Mostly for disleds
  863.     mov    ah,mlbattr        ; Return them our attrs, flags, etc.
  864.     mov    al,scbattr
  865.     mov    bl,curattr
  866.     mov    bh,ansflgs
  867.     ret
  868. anstat    endp
  869.  
  870.  
  871. ; Routine called when something is typed on the keyboard
  872. ;
  873. ; Call:        No arguments
  874. ;
  875.  
  876. anskbi    proc    near
  877.     mov    ttkbi,0FFH        ; Just set a flag
  878.     ret
  879. anskbi    endp
  880.  
  881. ; Routine to do keyclick if flag is set.
  882. ;
  883. ; Call:        No arguments
  884. ;
  885.  
  886. vclick    proc    near
  887.     test    vtflags,vskeyclick    ; Is the flag on?
  888.     jz    vclick1            ; No - just return
  889.     push    bx            ; Save some ACs
  890.     push    di
  891.     mov    di,8            ; 5000 Hertz [rwb]
  892.     mov    bx,1            ; For 3 milliseconds. [rwb]
  893.     call    vtsound            ; Do it.
  894.     pop    di            ; Restore the ACs
  895.     pop    bx
  896. vclick1:ret
  897. vclick    endp
  898.  
  899.  
  900. ; Routine to do VT100-style bell.
  901. ;
  902. ; Call:        No arguments
  903. ;
  904.  
  905. vtbell    proc    near
  906.     push    di
  907.     push    bx
  908.     mov    di,45            ; 880 Hertz [rwb]
  909.     mov    bx,22            ; For 70 ms. [rwb]
  910.     call    vtsound            ; Do it.
  911.     pop    bx
  912.     pop    di
  913.     ret
  914. vtbell    endp
  915.  
  916. ; Routine to make noise of arbitrary frequency for arbitrary duration.
  917. ; Derived from a routine in December 1984 Soft Sector, page 28. [rwb]
  918. ; Frequency and duration parameters are different than in the IBM ver. [rwb]
  919. ; Sound is generated by toggling the break bit in the keyboard UART [rwb]
  920. ;
  921. ; Call:        di/    frequency is 40KHz / di value [rwb]
  922. ;        bx/    duration is 3.2 msec * bx value [rwb]
  923. ;         These approximate values break down badly for di < 10 [rwb]
  924. ;         or if an accelerator board is installed. [rwb]
  925.  
  926. vtsound proc    near
  927.     push    ax            ; Save regs.
  928.     push    bx
  929.     push    cx
  930.     mov    ax,35h            ; UART cmd with break bit off
  931. vtsou1: mov    cx,di
  932.     xor    al,8            ; toggle break bit
  933.     out    3ah,al            ; send it to UART
  934. vtsou2: dec    ah
  935.     jnz    vtsou3
  936.     dec    bx            ; count down duration
  937.     jz    vtsou4
  938. vtsou3: loop    vtsou2            ; frequency count down
  939.     jmp    vtsou1
  940. vtsou4: mov    al,35h
  941.     out    3ah,al            ; turn off break bit on exit
  942.     pop    cx            ; Restore regs.
  943.     pop    bx
  944.     pop    ax
  945.     ret
  946. vtsound endp
  947.  
  948. ; Routine to toggle VT100/VT52/Heath-19 modes. No arguments.
  949. ; Use & update global byte flags.vtflg for terminal type and update local
  950. ; bit decanm. Note: shifting to Heath-19 here does Not reset the scrolling
  951. ; margins mar_top & mar_bot nor reset the double char linetype array.
  952. ; [jrd]
  953. ans52t    proc    near
  954.     cmp    tekflg,0        ; in Tek sub mode?
  955.     jne    ans52c            ; ne = yes, get out now
  956.     cmp    flags.vtflg,ttvt100    ; in VT100 mode?
  957.     jne    ans52a            ; ne = no
  958.     and    ansflgs,not decanm    ; reset VT100 ansi mode
  959.     mov    flags.vtflg,ttvt52    ; say VT52 now (clears vt100 bit)
  960.     mov    oldterm,ttvt52        ; and remember it
  961.     jmp    ans52e
  962. ans52a: cmp    flags.vtflg,ttvt52    ; in VT52 mode?
  963.     jne    ans52b            ; ne = no
  964.     mov    flags.vtflg,ttheath    ; say Heath-19 now
  965.     mov    oldterm,ttheath
  966.     jmp    ans52e
  967. ans52b: cmp    flags.vtflg,ttheath    ; in Heath-19 mode?
  968.     jne    ans52c            ; ne = no
  969.     call    atsc            ; save cursor and associated data
  970.     mov    flags.vtflg,tttek    ; set Tek mode
  971.     call    tekini            ; init Tek to switch screens
  972.     jmp    atnorm            ; normal state and return
  973. ans52c: cmp    flags.vtflg,tttek    ; in Tek mode now?
  974.     je    ans52d            ; e = yes
  975.     cmp    tekflg,0        ; doing Tek sub mode?
  976.     jne    ans52d            ; ne = yes
  977.     jmp    atnorm            ; else ignore this call
  978.  
  979. ans52d: call    tekend            ; exit Tek graphics mode
  980.     mov    tekflg,0        ; end Tek sub mode (do after tekend)
  981.     mov    flags.vtflg,ttvt100    ; say VT100 now
  982.     mov    oldterm,ttvt100
  983.     or    ansflgs,decanm        ; set, go to VT100 mode
  984.     call    atrc            ; restore cursor etc
  985.     cmp    flags.modflg,0        ; is mode line disabled? [jrd]
  986.     je    ans52e            ; e = yes, disabled [jrd]
  987.     test    yflags,modoff        ; Mode line off?
  988.     jnz    ans52e            ; nz = yes - just return.
  989.     mov    al,yflags        ; get current flags
  990.     or    al,modoff        ; say mode line is off
  991.     call    telmsy            ; let msy hear the news
  992.     call    trnmod            ; turn it on
  993. ans52e: call    chrdef            ; Set default character sets
  994.     call    atsc            ; Save cursor etc.
  995.     call    disleds            ; Remove or redisplay "LEDs".
  996.     jmp    atnorm            ; Say state is "normal" and return.
  997. ans52t    endp
  998.  
  999.  
  1000. ; Display "LEDs" routine. Note that this routine
  1001. ; is not used internally in this module (because it updates the flags from
  1002. ; MSYIBM). Internally, disleds is used instead. The yflags from MSYIBM are
  1003. ; needed because we have to know if the mode line is enabled.
  1004. ;
  1005. ; Call:        al/    yflags from MSYIBM
  1006. ;
  1007. ; Return:    Current state of "LEDs" displayed on line 25.
  1008. ;
  1009.  
  1010. ansdsl    proc    near            ; Update flags and display "LEDs"
  1011.     mov    yflags,al        ; Update the flags.
  1012.     call    disleds            ; Display LEDs
  1013.     ret
  1014. ansdsl    endp
  1015.  
  1016. ; Internal routine to display LEDs.
  1017.  
  1018. disleds:test    yflags,modoff        ; Mode line off?
  1019.     jnz    disled2            ; Yes - just return.
  1020. ;;    mov    al,0            ; Turn cursor off.
  1021. ;;    call    csrtype
  1022.     mov    ah,2            ; Position cursor at (slen-1),70
  1023.     mov    bh,0            ; Page zero.
  1024.     mov    dh,byte ptr low_rgt+1    ; last screen line - 1
  1025.     inc    dh            ; status line
  1026.     mov    dl,led_col        ; column for led display
  1027.     int    screen
  1028.     mov    cx,10            ; Length of byte array is ten
  1029.     mov    si,offset ansleds    ; The "LEDs"
  1030.     cmp    flags.vtflg,ttvt100    ; VT100 mode?
  1031.     je    disled1            ; e = yes
  1032.     mov    si,offset v52leds    ; try VT52
  1033.     cmp    flags.vtflg,ttvt52    ; VT52?
  1034.     je    disled1            ; e = yes
  1035.     mov    si,offset h19leds    ; use Heath-19
  1036. disled1:lodsb                ; Get a character
  1037.     mov    ah,14            ; Write character function
  1038.     mov    bh,0            ; Page zero.
  1039.     int    screen            ; ...
  1040.     loop    disled1            ; Loop for all chars
  1041.     mov    ah,2            ; Reposition cursor when finished
  1042.     mov    bh,0            ; Page zero
  1043.     mov    dx,cursor
  1044.     int    screen
  1045.     call    atsctyp            ; Reset right type of cursor.
  1046. disled2:ret
  1047.  
  1048.  
  1049. ; ANSI terminal output routine.     Call with character in al.
  1050.  
  1051. anstty    proc    near            ; ANSI terminal output.
  1052.     mov    dx,cursor        ; Some routines need cursor in dx.
  1053.     mov    kbiflg,0        ; Clear old flag value
  1054.     test    yflags,trnctl        ; Debug mode?
  1055.     jz    anstt1            ; z = no
  1056.     jmp    atdeb            ; Yes - just translate control chars.
  1057. anstt1: cmp    ttkbi,0            ; New keyboard input?
  1058.     je    anstt2            ; No - just continue
  1059.     mov    kbiflg,1        ; Yes - set flag
  1060.     mov    kbicsr,dx        ; Save old cursor
  1061.     mov    ttkbi,0            ; Clear this flag.
  1062.  
  1063. anstt2: test    anspflg,vtcntp        ; print controller on?
  1064.     jz    anstt4            ; z = no
  1065.     test    yflags,capt        ; capturing output?
  1066.     jz    anstt3            ; z = no, forget this part
  1067.     push    ax            ; save char
  1068.     call    cptchr            ; give it captured character
  1069.     pop    ax            ; restore character
  1070. anstt3: jmp    ansmc            ; print transparently
  1071.                     ; Set Display 7/8 bit filter
  1072. anstt4: test    flags.remflg,d8bit    ; keep 8 bits for displays?
  1073.     jnz    anstt5            ; nz = yes, 8 bits if possible
  1074.     and    al,7fh            ; remove high bit
  1075. anstt5: cmp    al,spc            ; control char?
  1076.     jb    anstt6            ; b = yes
  1077.     cmp    ttstate,offset atnrm    ; doing displayable text?
  1078.     jne    anstt7            ; ne = no, no translation
  1079.                     ; Set Translation filter
  1080. anstt6: cmp    rxtable+256,0        ; translation turned off?
  1081.     je    anstt7            ; e = yes, no translation
  1082.     mov    bx,offset rxtable    ; address of translate table [jrd]
  1083.     xlatb                ; new char is in al
  1084. anstt7: cmp    al,DEL            ; ANSI Delete char?
  1085.     je    atdel            ; e = yes, ignore it before logging
  1086.     cmp    al,0            ; NUL char?
  1087.     je    atign            ; e = yes, ignore it before logging
  1088.     test    yflags,capt        ; capturing output?
  1089.     jz    anstt8            ; z = no, forget this part
  1090.     push    ax            ; save char
  1091.     call    cptchr            ; give it captured character
  1092.     pop    ax            ; restore character and keep going
  1093.                     ; Direct char to processor module
  1094. anstt8: cmp    al,20h            ; Control character?
  1095.     jb    atctrl            ; b = yes, handle it.
  1096. anstt9: jmp    ttstate            ; Nope, dispatch according to state.
  1097.  
  1098. atign:    ret                ; Something to be ignored.
  1099.  
  1100. atctrl: mov    ah,0            ; Make sure this is zero..
  1101.     cmp    al,escape        ; an escape sequence starting?
  1102.     je    atctrl1            ; e = yes, don't print it
  1103.     test    anspflg,vtautop+vtcntp    ; printing desired?
  1104.     jz    atctrl1            ; z = no
  1105.     call    pntchr            ; print char in al
  1106. atctrl1:mov    di,ax            ; Put it in an index register
  1107.     shl    di,1            ; Make it a word offset
  1108.     jmp    ansspc[di]        ; Dispatch.
  1109.  
  1110. atdel:    jmp    short atign        ; ignore DEL char
  1111. ;;    test    yflags,lclecho        ; doing local echoing?
  1112. ;;    jz    atign            ; z = no, ignore character
  1113. ;;    mov    ansargs,0        ; Delete one char to left [jrd]
  1114. ;;    cmp    dl,0            ; at column 0 already?
  1115. ;;    je    atdel1            ; e = yes
  1116. ;;    dec    dl            ; move back one column
  1117. ;;atdel1:    call    atscu5            ; move the cursor there and
  1118. ;;    jmp    atdelc            ; delete the char now under cursor
  1119.  
  1120. atdeb:    test    yflags,capt        ; capturing output?
  1121.     jz    atdeb3            ; z = no, forget this part
  1122.     push    ax            ; save char
  1123.     call    cptchr            ; give it captured character
  1124.     pop    ax            ; restore character and keep going
  1125. atdeb3: mov    bh,ansflgs        ; Save flags and attribute
  1126.     mov    bl,curattr
  1127.     push    bx
  1128.     push    word ptr mar_top    ; Save limited scrolling region
  1129.     push    ax            ; Save character for a second
  1130.     mov    ah,curattr        ; Get attribute
  1131.     call    brkatt            ; Break it up
  1132.     and    al,att_intensity    ; clear attributes, except bold bit
  1133.     call    addatt            ; Put it back together
  1134.     mov    curattr,ah        ; Store
  1135.     or    ansflgs,decawm        ; Set autowrap temporarily
  1136.     mov    mar_top,0        ; Set scrolling region to entire page
  1137.     mov    al,byte ptr low_rgt+1
  1138.     mov    mar_bot,al
  1139.     pop    ax            ; Restore character
  1140.     test    al,80h            ; high bit set? [jrd]
  1141.     jz    atdeb0            ; z = not set
  1142.     push    ax            ; Save the character for a second
  1143.     mov    al,7eh            ; Output a tilde [jrd]
  1144.     call    atnrm2
  1145.     pop    ax            ; Restore character
  1146.     and    al,7fh            ; and remove high bit
  1147. atdeb0: cmp    al,del            ; A DELETE?
  1148.     je    atdeb1            ; Yes - output "^?" [jrd]
  1149.     cmp    al,20h            ; A control character?
  1150.     jnb    atdeb2            ; No - just output char in al.
  1151. atdeb1: push    ax            ; Save the character for a second
  1152.     mov    al,5eh            ; Output a caret [jrd]
  1153.     call    atnrm2
  1154.     pop    ax            ; Restore character
  1155.     add    al,40h            ; Make ^letter (or ^? for DELETE)
  1156.     and    al,7fh            ; Clear bit 7 (for DELETE)
  1157. atdeb2: call    atnrm2            ; Output translated character
  1158.     pop    word ptr mar_top    ; Restore scrolling region
  1159.     pop    bx            ; And flags and cursor attribute
  1160.     mov    curattr,bl
  1161.     mov    ansflgs,bh
  1162.     ret
  1163.  
  1164. atnorm: mov    ttstate,offset atnrm    ; Reset state to "normal".
  1165.     ret
  1166.  
  1167.                     ; Normal character processor
  1168. atnrm:    mov    bx,chr_set        ; Get character set
  1169.     cmp    byte ptr [bx],sgrset    ; "Special" set?
  1170.     jne    atnrm1            ; No - check UK.
  1171.     cmp    flags.vtflg,ttheath    ; Heath-19?
  1172.     je    atnrm0a            ; e = yes
  1173.     cmp    al,137Q            ; Yes - is it in the "special" range?
  1174.     jb    atnrm2            ; No - just output the char in al.
  1175.     mov    bl,al            ; Yes - compute index in bx.
  1176.     mov    bh,0
  1177.     sub    bx,137Q
  1178.     mov    al,sgrtab[bx]        ; Fetch translation.
  1179.     jmp    short atnrm2        ; Output it.
  1180.  
  1181. atnrm0a:cmp    al,94            ; H-19, in range for special graphics?
  1182.     jb    atnrm2            ; b = no
  1183.     cmp    al,126            ; too large?
  1184.     ja    atnrm2            ; a = too large
  1185.     sub    bx,94            ; H-19, offset from caret
  1186.     mov    bl,al
  1187.     mov    bh,0
  1188.     sub    bx,94
  1189.     mov    al,hgrtab[bx]        ; fetch translation
  1190.     jmp    short atnrm2
  1191.  
  1192. atnrm1: cmp    al,'#'            ; This thing?
  1193.     jne    atnrm2            ; No - just output it
  1194.     cmp    byte ptr [bx],ukset    ; Yes - UK set?
  1195.     jne    atnrm2            ; No - just output it.
  1196.     mov    al,156            ; Yeah, show them our pound sign.
  1197. atnrm2:
  1198.     mov    dx,cursor        ; get cursor virtual position
  1199.     push    ax            ; save character
  1200.     call    atscur            ; set cursor physical position
  1201.     pop    ax
  1202.  
  1203.     cmp    insmod,0        ; insert mode off? [jrd]
  1204.     je    atnrm3            ; e = yes [jrd]
  1205.     push    ax            ; save char
  1206.     call    inschr            ; open a char space in this line [jrd]
  1207.     push    bx
  1208.     mov    bx,cursor        ; get current row
  1209.     mov    bl,bh
  1210.     mov    bh,0
  1211.     cmp    linetype [bx],0        ; single width line?
  1212.     je    atnrm2a            ; e = yes
  1213.     call    inschr            ; open second space for double width
  1214. atnrm2a:pop    bx
  1215.     pop    ax            ; restore char
  1216. atnrm3:                    ; set cursor before writing char
  1217.     mov    bl,dh            ; check for double characteristic
  1218.     xor    bh,bh            ; bx = row, in bl
  1219.  
  1220.     test    anspflg,vtautop        ; printing desired? [jrd]
  1221.     jz    atnrm4d            ; e = no
  1222.     call    pntchr            ; print char in al
  1223.     cmp    linetype [bx],0        ; normal characteristic?
  1224.     je    atnrm4d            ; e = yes
  1225.     push    ax            ; save current char
  1226.     mov    al,' '            ; add a space for double width
  1227.     call    pntchr
  1228.     pop    ax            ; recover char to be processed
  1229. atnrm4d:
  1230.     cmp    linetype [bx],0        ; normal characteristic?
  1231.     je    atnrm4a            ; e = yes
  1232.     push    ax            ; save char
  1233.     shl    dl,1            ; double the column number
  1234.     mov    ah,2            ; set cursor (bh = 0 from above)
  1235.     int    screen
  1236.     pop    ax            ; recover the char
  1237.     mov    ah,9            ; Output char in al to screen [jrd]
  1238.     mov    bh,0            ; Page zero
  1239.     mov    bl,curattr        ; Current attribute
  1240.     mov    cx,1            ; Only one character
  1241.     int    screen
  1242.     inc    dl            ; next column
  1243.     mov    ah,2            ; set cursor
  1244.     int    screen
  1245.     mov    al,' '            ; use a space for doubling
  1246.     mov    ah,9            ; Output to screen [jrd]
  1247.     mov    bh,0            ; Page zero
  1248.     mov    bl,curattr        ; Current attribute
  1249.     mov    cx,1            ; Only one character
  1250.     int    screen
  1251.     shr    dl,1            ; keep "cursor" in single units
  1252.     jmp    atnrm4b            ; check autowrap in double width mode
  1253.  
  1254. atnrm4a:mov    ah,9            ; Output to screen [jrd]
  1255.     mov    bh,0            ; Page zero
  1256.     mov    bl,curattr        ; Current attribute
  1257.     mov    cx,1            ; Only one character
  1258.     int    screen
  1259.                     ; set physical cursor after this char
  1260. atnrm4b:test    ansflgs,decawm        ; Autowrap?
  1261.     jz    atnrm5            ; No, continue
  1262.     mov    cx,low_rgt        ; copy logical cursor margins to cx
  1263.     push    bx
  1264.     mov    bl,dh            ; get row
  1265.     xor    bh,bh
  1266.     cmp    linetype[bx],0        ; single width line?
  1267.     pop    bx            ; pop preserves flags
  1268.     je    atnrm4c            ; e = yes, single
  1269.     shr    cl,1            ; halve right column # for wide chars
  1270. atnrm4c:cmp    dl,cl            ; wrote in right-most column?
  1271.     jb    atnrm5            ; b = no
  1272.     inc    dl            ; say want to use next column
  1273.     cmp    flags.vtflg,ttheath    ; emulating a H-19? [uci]
  1274.     je    atscur            ; e = yes, show wrap now. [uci]
  1275.     mov    cursor,dx        ; virtual cursor position
  1276.     ret                ; exit without moving cursor from eol
  1277. atnrm5: mov    dx,cursor        ; Restore cursor position
  1278.     inc    dl            ; Bump cursor
  1279.  
  1280. atscur: cmp    dl,250            ; To left of column zero?(wide screen)
  1281.     jb    atscu1            ; b = no, continue
  1282.     mov    dl,0            ; Yes - set at column zero.
  1283. atscu1: mov    cx,low_rgt        ; copy logical margins; cl=right col
  1284.     push    bx
  1285.     mov    bl,dh            ; get row
  1286.     xor    bh,bh
  1287.     cmp    linetype [bx],0        ; single width lines?
  1288.     pop    bx
  1289.     je    atscu1a            ; e = yes, single width
  1290.     shr    cl,1            ; halve column # for double wides
  1291. atscu1a:cmp    dl,cl            ; To right of right margin?
  1292.     jbe    atscu3            ; be = no, continue
  1293.     mov    dl,cl            ; Yes - assume no autowrap.
  1294.     test    ansflgs,decawm        ; Autowrap?
  1295.     jz    atscu3            ; No, continue
  1296.     mov    dl,0            ; Yes - set to column zero
  1297.     cmp    dh,byte ptr low_rgt+1    ; at bottom of screen?
  1298.     je    atscu1b            ; e = yes
  1299.     cmp    dh,mar_bot        ; At bottom of scrolling region?
  1300.     jl    atscu2            ; l = No - bump cursor and continue
  1301. atscu1b:call    atscru            ; Scroll up.
  1302.     dec    dh            ; offset inc dh below
  1303. atscu2: inc    dh            ; Just bump it.
  1304. atscu3: cmp    dh,0            ; Constrain row to valid range.
  1305.     jge    atscu4            ; ge = non-negative row, ok
  1306.     mov    dh,0
  1307. atscu4: cmp    dh,byte ptr low_rgt+1    ; 25th line?
  1308.     jle    atscu5            ; le = no
  1309.     mov    dh,byte ptr low_rgt+1    ; set to 24th line
  1310.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  1311.     jne    atscu4a            ; ne = no [hlk]
  1312.     cmp    h19l25,0        ; Heath 25th line enabled?
  1313.     je    atscu5            ; e = no
  1314.     jmp    short atscu4b        ; do 25th line
  1315. atscu4a:test    ansflgs,decom        ; Origin mode active?
  1316. ;;;##    jz    atscu5            ; z = no, no 25th line allowed
  1317. atscu4b:inc    dh            ; yes, go to line 25 [hlk]
  1318.     test    yflags,modoff        ; is mode line off?
  1319.     jnz    atscu8            ; nz = yes
  1320.     push    dx            ; save cursor position
  1321.     call    trnmod            ; no, turn it off now.
  1322.     pop    dx
  1323. atscu8: mov    flags.modflg,0        ; and disable mode line. [jrd]
  1324.     mov    al,yflags        ; place to communicate [jrd]
  1325.     call    telmsy            ; tell msy the news. [jrd]
  1326.  
  1327. atscu5: push    cx            ; save cx around screen call
  1328.     mov    cursor,dx        ; Set cursor and return.
  1329.     mov    ah,2            ; setup for position cursor call.
  1330.     mov    bl,dh            ; get row
  1331.     mov    bh,0
  1332.     cmp    linetype [bx],0        ; single width line?
  1333.     je    atscu5a            ; e = yes
  1334.     shl    dl,1            ; double the column number
  1335.     int    screen            ; set the physical cursor
  1336.     shr    dl,1            ; restore dl (logical column)
  1337.     jmp    short atscu5b
  1338. atscu5a:int    screen
  1339. atscu5b:pop    cx
  1340.     cmp    kbiflg,0        ; Is keyboard input flag set?
  1341.     je    atscu6            ; No - just return
  1342.     test    vtflags,vsmarginbell    ; Yes - do we care?
  1343.     jz    atscu6            ; Return if no margin bell.
  1344.     mov    dx,cursor        ; Get new and old cursors
  1345.     mov    bx,kbicsr
  1346.     cmp    bh,dh            ; Same row?
  1347.     jne    atscu6            ; No - just return
  1348.     cmp    bl,belcol        ; Old cursor at or left of bell column?
  1349.     ja    atscu6            ; a = no, just return
  1350.     cmp    dl,belcol        ; Yes - new cursor past bell column?
  1351.     jbe    atscu6            ; be = no, just return
  1352.     call    vtbell            ; Yes - ring the bell
  1353. atscu6: ret
  1354.  
  1355. ; This routine is called to check the cursor position after any kind of cursor
  1356. ; positioning command.    Note that cursor positioning does NOT cause scrolling
  1357. ; on a VT100 (hence the need for a routine separate from this for "indexing".
  1358. ;
  1359. ; Call:        dx/    "new" cursor position (modified cursor)
  1360. ;
  1361. ; Return:    dx/    "new" cursor position adjusted for screen limits (if
  1362. ;            decom is reset), or scrolling region (if decom is set).
  1363. ;
  1364. ; Preserves ax, bx, and cx.
  1365. ;
  1366.  
  1367. atccpc: push    bx            ; save bx and cx
  1368.     push    cx
  1369. atccp7: mov    cx,low_rgt        ; margins, cl = right margin
  1370.     mov    bl,dh            ; get row
  1371.     xor    bh,bh
  1372.     cmp    linetype [bx],0        ; single width line?
  1373.     je    atccp0            ; e = yes, single width
  1374.     shr    cl,1            ; halve right margin for double wides
  1375. atccp0: cmp    dl,250            ; To left of left margin?(wide screen)
  1376.     jb    atccp1            ; b = no, go check right
  1377.     mov    dl,0            ; No, set to left margin
  1378. atccp1: cmp    dl,cl            ; To right of right margin
  1379.     jbe    atccp2            ; be = yes, go check top
  1380.     mov    dl,cl            ; No, set to right margin
  1381. atccp2: test    ansflgs,decom        ; Origin mode set?
  1382.     jnz    atccp5            ; Yes, can't go out of scrolling region
  1383.     cmp    dh,0            ; Above top of screen?
  1384.     jge    atccp3            ; ge = no, check bottom
  1385.     mov    dh,0            ; Yes, stop here
  1386. atccp3: cmp    dh,byte ptr low_rgt+1    ; Below bottom of screen?
  1387.     jle    atccp4            ; le = no, return
  1388.     mov    dh,byte ptr low_rgt+1    ; Yes, stop at bottom margin
  1389.     cmp    flags.vtflg,ttheath    ; Heath-19 mode?
  1390.     jne    atccp4            ; ne = no
  1391.     cmp    h19l25,0        ; 25th line enabled?
  1392.     je    atccp4            ; e = no
  1393.     inc    dh            ; allow 25th line
  1394. atccp4: pop    cx
  1395.     pop    bx
  1396.     ret
  1397.  
  1398. atccp5: cmp    dh,mar_top        ; Above top of scrolling region?
  1399.     jge    atccp6            ; ge = no, check bottom
  1400.     mov    dh,mar_top        ; Yes, stop there.
  1401. atccp6: cmp    dh,mar_bot        ; Below bottom perhaps?
  1402.     jle    atccp4            ; le = no, return
  1403.     mov    dh,mar_bot        ; Yes, stop at the bottom margin
  1404.     pop    cx
  1405.     pop    bx
  1406.     ret
  1407.  
  1408.  
  1409. ; This routine is called to adjust the cursor for the "indexing" like commands
  1410. ; (e.g., index, reverse index, newline, etc.).    It contrains the cursor, and
  1411. ; indicates if scrolling is necessary, and if so, in which direction.
  1412. ;
  1413. ; Call:        cursor/ "old" cursor position
  1414. ;        dx/    "new" cursor position
  1415. ;
  1416. ; Return:    ax/    pointer to scrolling routine to call (or to a ret)
  1417. ;        bx/    "old" cursor position
  1418. ;        dx/    "new" cursor position adjusted for screen limits or
  1419. ;            scrolling region, depending on whether the original
  1420. ;            cursor position was inside or outside the scrolling
  1421. ;            region.
  1422. ;
  1423. ; On the VT100, a scroll does not occur unless the original cursor position
  1424. ; was on the top or bottom margin.    This routine assumes that when decom is
  1425. ; set the cursor position is set to the new origin, and that no other routine
  1426. ; allows the cursor to be positioned outside the scrolling region as long
  1427. ; as decom is set (which is the way a real VT100 works).  Note that for the
  1428. ; normal case (no limited scrolling region defined) the margins are the same
  1429. ; as the screen limits and scrolling occurs (as on a "normal" terminal) when
  1430. ; an attempt is made to index off the screen.        Preserves cx.
  1431. ; Revised 16 June 1987 [jrd]
  1432.  
  1433. atccic: push    cx
  1434.     mov    cx,low_rgt        ; get margins, cl = right margin
  1435.     mov    bl,dh            ; get row
  1436.     xor    bh,bh
  1437.     cmp    bl,ch            ; Below screen? [jrd]
  1438.     jg    atcci0            ; g = yes, use single width line
  1439.     cmp    linetype[bx],0        ; single width chars?
  1440.     je    atcci0            ; e = yes, single width
  1441.     shr    cl,1            ; halve margin for double wides
  1442. atcci0: mov    ax,offset atign        ; Assume no scrolling necessary
  1443.     mov    bx,cursor        ; Get old cursor.
  1444.     cmp    dl,250            ; To left of left margin?(wide screen)
  1445.     jb    atcci1            ; b = no, go check right
  1446.     mov    dl,0            ; No, set to left margin
  1447. atcci1: cmp    dl,cl            ; To right of right margin
  1448.     jbe    atcci2            ; be = yes, go check top
  1449.     mov    dl,cl            ; No, set to right margin
  1450. atcci2: cmp    bh,mar_top        ; was old pos at scrolling top margin?
  1451.     jne    atcci5            ; ne = no, check other end
  1452.     cmp    dh,mar_top        ; want to go above top margin?
  1453.     jge    atcci7            ; ge = no
  1454.     mov    ax,offset atscrd    ; Yes, indicate scroll down required.
  1455.     mov    dh,mar_top        ; Set to top margin
  1456.     jmp    atcci7
  1457.  
  1458. atcci5: cmp    bh,mar_bot        ; Was old position at bottom margin?
  1459.     jne    atcci7            ; ne = no, so don't trap cursor
  1460.     cmp    dh,mar_bot        ; want to go below?
  1461.     jb    atcci7            ; b = no, nothing to worry about
  1462.     mov    ax,offset atscru    ; Yes, indicate scroll up required.
  1463. atcci6: mov    dh,mar_bot        ; Set to bottom margin
  1464.     pop    cx
  1465.     ret
  1466. atcci7: pop    cx            ; old pos was outside scrolling region
  1467.     jmp    atccpc            ; do full screen check and return
  1468.  
  1469. ; This routine picks an attribute apart into its component "parts" - the
  1470. ; base attribute for the screen and the "extras" - i.e., blink, intensity
  1471. ; and underline.
  1472. ;
  1473. ; Call:        ah/    a cursor attribute
  1474. ;
  1475. ; Return:    ah/    base attribute for screen (07H normal, 70H reverse).
  1476. ;        al/    "extra" attributes
  1477. ;
  1478. ; Note that there is a complementary routine, addatt, for putting attributes
  1479. ; back together...
  1480. ;
  1481.  
  1482. brkatt: mov    al,0            ; Clear returned "extra" attributes
  1483.     cmp    crt_mode,2        ; monochrome display adapter mode?
  1484.     jnz    brkat1            ; Yes, can't be underline
  1485.     test    ah,att_underline    ; Underline?
  1486.     jz    brkat2            ; No, some kind of reverse video
  1487.     or    al,att_underline    ; Yes, say underline
  1488.     test    ah,70h ;;att_reverse    ; Reverse video + underline?
  1489.     jz    brkat1            ; No, fix up low nibble
  1490.     and    ah,not att_underline    ; Yes, clear the underline bit in ah
  1491.     jmp short brkat2        ; And forge on.
  1492.  
  1493. brkat1: or    ah,att_normal        ; Normal - turn on all normal bits
  1494. brkat2: test    ah,att_intensity    ; Intensity attribute on?
  1495.     jz    brkat3            ; No - check blink
  1496.     or    al,att_intensity    ; Yes - turn on the bit
  1497. brkat3: test    ah,att_blink        ; Blink on?
  1498.     jz    brkat4            ; No - forge on
  1499.     or    al,att_blink        ; Yes - turn on the bit
  1500. brkat4: and    ah,not(att_intensity+att_blink) ;strip blink/bold, leave color
  1501.     ret
  1502.  
  1503. ; This routine builds a cursor attribute given the base attribute for the
  1504. ; screen background and the "extra" attributes we want (blink, etc.).
  1505. ;
  1506. ; Call:        ah/    base attribute for background (07H or 70H)
  1507. ;        al/    "extra" attributes (89H for all three)
  1508. ;
  1509. ; Return:    ah/    base combined with "extras".
  1510. ;
  1511.  
  1512. addatt: test    al,att_underline    ; Want underline?
  1513.     jz    addat1            ; No - no need for hack
  1514.     and    ah,not att_low_mask    ; Yes - clear these bits
  1515. addat1: or    ah,al            ; Or in the attributes.
  1516. ; When a monochrome monitor is used on a Sanyo with a video board, some [rwb]
  1517. ; "colors" are completely invisible.  Following code guarantees all text
  1518. ; is visible.
  1519.     test    usevb,1            ; video board in use?
  1520.     jz    addat2            ; z = no
  1521.     cmp    crt_mode,2        ; monochrome?
  1522.     jne    addat2            ; ne = no
  1523.     push    bx
  1524.     mov    bx,offset trtbl        ; point at translate table
  1525.     xchg    al,ah            ; get original attribute in al
  1526.     and    al,7fH            ; translate table only half length
  1527.     xlat                ; translate attribute
  1528.     xchg    al,ah            ; return in ah
  1529.     pop    bx
  1530. addat2:
  1531.  
  1532.     ret
  1533.  
  1534.  
  1535. ; This routine is called when we want to reverse everything on the screen
  1536. ; from normal to reverse video, or vice versa.    It is called only when
  1537. ; the decscnm attribute is changed.
  1538. ;
  1539. ; Call:        no arguments.
  1540. ;
  1541. ; This routine may destroy ax-dx
  1542. ;                            [begin jhw]
  1543. ; Modified to use bios calls for Sanyo without video board
  1544. ;
  1545.  
  1546. revscn: test    usevb,1            ; video board in use?
  1547.     jz    revscnv            ; z = no
  1548.     mov    dh,byte ptr low_rgt+1    ; Compute last screen offset in ax
  1549.     inc    dh            ; One more row to catch mode line
  1550.     mov    dl,crt_cols        ; physical width
  1551.     dec    dl            ; and we count from 0
  1552.     call    scrloc
  1553.     mov    cx,ax            ; Save it in cx for a minute
  1554.     mov    dx,0            ; Compute first screen offset in ax
  1555.     call    scrloc
  1556.     sub    cx,ax            ; Compute number of locs to change..
  1557.     add    cx,2
  1558.     sar    cx,1            ; In 16-bit words please...
  1559.     push    di            ; Save some more acs
  1560.     push    es
  1561.     push    cx            ; save word count for Topview [jrd]
  1562.     push    ax            ; save screen displacement
  1563.     call    scrseg            ; Get address of screen in ax, es:di
  1564.     pop    ax            ; recover displacement
  1565.     add    di,ax            ; displacement addr of start of change
  1566.     call    scroff            ; Turn screen off if color card.
  1567. revsc1: mov    ax,es:[di]        ; Fetch a word
  1568.     mov    bl,al            ; Save the character
  1569.     call    brkatt            ; Break up the attributes
  1570.     rol    ah,1            ; Reverse the video
  1571.     rol    ah,1            ; Reverse the video
  1572.     rol    ah,1            ; Reverse the video
  1573.     rol    ah,1            ; Reverse the video
  1574.     call    addatt            ; Put attributes back together
  1575.     mov    al,bl            ; Restore character
  1576.     mov    es:[di],ax        ; Stuff into screen memory.
  1577.     add    di,2            ; Point di to next word of screen mem.
  1578.     loop    revsc1            ; Loop for entire screen.
  1579.     pop    cx            ; recover word count for Topview [jrd]
  1580.     call    scrsync            ; synch with Topview
  1581.     call    scron            ; Turn screen back on if color card.
  1582.     pop    es            ; Restore segment register
  1583.     pop    di            ; And destination index
  1584.     ret
  1585. revscnv:mov    ax,0300h        ; save cursor position on stack
  1586.     int    screen
  1587.     push    dx
  1588.     mov    dx,0
  1589. revs1:    mov    ax,0200h
  1590.     int    screen
  1591.     mov    ax,0800h        ; read character at cursor
  1592.     int    screen
  1593.     mov    bh,al            ; char/attrib in al/ah
  1594.     call    brkatt            ; redo the attribute
  1595.     rol    ah,1
  1596.     rol    ah,1
  1597.     rol    ah,1
  1598.     rol    ah,1
  1599.     call    addatt            ; reassemble attributes
  1600.     mov    bl,ah            ; set up char/attrib in al/bl
  1601.     mov    al,bh            ;
  1602.     mov    cx,1
  1603.     mov    ah,09h            ; write char/attrib to screen
  1604.     int    screen
  1605.     cmp    dl,79            ; end of line?
  1606.     jae    revs7            ; yes, go to next line
  1607.     inc    dl            ; else, go to next char
  1608.     jmp    revs1
  1609. revs7:    mov    dl,0
  1610.     cmp    dh,24            ; bottom of screen? (done?)
  1611.     jae    revs8            ; yes, finish up
  1612.     inc    dh            ; no, go to next line
  1613.     jmp    revs1
  1614. revs8:    pop    dx            ; restore cursor to where it was
  1615.     mov    ax,0200h
  1616.     int    screen            ; end jhw        [end jhw]
  1617.     ret
  1618.  
  1619.  
  1620. ; Reset-everything routine.
  1621.  
  1622. atreset:mov    al,0            ; Make cursor disappear for a while.
  1623. ;;    call    csrtype
  1624.     mov    cursor,0        ; Cursor is at 0,0
  1625.     mov    ansflgs,0        ; reset these flags[jrd]
  1626.     cmp    flags.vtflg,ttvt100    ; VT100? [jrd]
  1627.     jne    atres7            ; ne = no. [jrd]
  1628.     mov    ansflgs,decanm        ; turn on ANSI mode flag. [jrd]
  1629. atres7: mov    mar_top,0        ; Reset scrolling region
  1630.     mov    al,byte ptr low_rgt+1
  1631.     mov    mar_bot,al
  1632.     mov    ah,vtemu.vtflgst
  1633.     mov    vtemu.vtflgop,ah
  1634.     mov    vtflags,ah
  1635.     mov    insmod,0        ; reset insert mode. [jrd]
  1636.     mov    h19l25,0        ; clear heath 25th line enable
  1637.     mov    h19ctyp,1        ; Heath-19 cursor to underline [jrd]
  1638.     mov    anspflg,0        ; clear printer flag [jrd]
  1639.     mov    cx,4            ; Initialize the "LEDs". [jrd]
  1640.     mov    al,led_off        ; Turn them all off.
  1641.     mov    di,offset ansleds+6    ; Point to the "LEDs".
  1642.     push    es            ; save es
  1643.     push    ds
  1644.     pop    es            ; use datas segment for es:di below
  1645.     cld                ; set forward direction
  1646.     rep    stosb            ; Do it. [jrd]
  1647.     pop    es
  1648.     call    disleds            ; update mode line. [jrd]
  1649.     mov    vttabs,offset deftabs    ; [jrd]
  1650.     call    cpytabs            ; Initialize tab stops.
  1651.     call    chrdef            ; Set default character set.
  1652.     call    vtbell            ; Ding bell like VT100
  1653.     test    vtflags,vsnewline    ; Want ANSI newline mode?
  1654.     jz    atres1            ; No.
  1655.     or    ansflgs,anslnm        ; Yes - set it in the mode flags.
  1656. atres1: test    vtflags,vswrap        ; How about autowrap?
  1657.     jz    atres2            ; No.
  1658.     or    ansflgs,decawm        ; Yes - set it in the mode flags.
  1659. atres2: mov    ah,att_normal        ; get present normal coloring
  1660.     call    brkatt            ; separate color and blink/bold
  1661.     rol    ah,1            ; reverse fore/back color fields
  1662.     rol    ah,1
  1663.     rol    ah,1
  1664.     rol    ah,1
  1665.     call    addatt            ; put back blink/bold
  1666.     mov    att_reverse,ah        ; this is the reverse video code
  1667.     mov    al,att_normal        ; Assume normal video.
  1668.     test    vtflags,vsscreen    ; Want reverse video?
  1669.     jz    atres3            ; No.
  1670.     or    ansflgs,decscnm        ; Yes - turn on the mode flag...
  1671.     xchg    al,ah            ; And reverse the video.
  1672. atres3: mov    cx,slen            ; typically 24 but do max lines [jrd]
  1673.     mov    di,0
  1674. atres8: mov    linetype[di],0        ; clear the linetype array to single
  1675.     inc    di            ; width/height characters.
  1676.     loop    atres8
  1677.     mov    curattr,al        ; Give cursor and screen nice
  1678.     mov    scbattr,al        ; attributes..
  1679.     mov    oldbatr,al        ; place to remember long term
  1680.     mov    mlbattr,ah        ; Give the other to the mode line.
  1681.     and    mlbattr,not att_intensity    ; turn off intensity bit
  1682.     mov    video_state,0        ; say normal video. [jrd]
  1683.     mov    ax,0            ; Clear entire screen.
  1684.     mov    bx,low_rgt
  1685.     mov    bl,crt_cols
  1686.     dec    bl            ; do physical screen
  1687.     call    atsclr
  1688.     mov    dx,cursor        ; Set cursor to 0,0.
  1689.     call    atscu5
  1690.     call    atsc            ; Give saved cursor reasonable values.
  1691.     call    atsctyp            ; Set right cursor type.
  1692.     mov    al,yflags
  1693.     call    telmsy            ; update msy about ansflgs state
  1694.  
  1695.     test    yflags,modoff        ; is mode line off?
  1696.     jnz    atres9            ; nz = yes
  1697.     push    dx            ; save cursor position
  1698.     call    trnmod            ; toggle off then on again so we
  1699.     call    trnmod            ;   use it with current coloring
  1700.     pop    dx
  1701. atres9: ret
  1702.  
  1703. ; Routine to set cursor type (block, underline).
  1704.  
  1705. atsctyp:cmp    flags.vtflg,ttheath    ; Heath-19?
  1706.     jne    atsct0            ; ne = no
  1707.     mov    al,h19ctyp        ; get cursor kind and on/off bit
  1708.     test    al,4            ; is cursor to be off?
  1709.     jz    atsct1            ; z = no, al has kind
  1710.     mov    al,0            ; turn off cursor
  1711.     jmp    short atsct1        ; do it
  1712. atsct0: mov    al,1            ; Assume underline.
  1713.     test    vtflags,vscursor    ; Want block?
  1714.     jnz    atsct1            ; nz = no, underline
  1715.     mov    al,2            ; Yes.
  1716. atsct1: call    csrtype            ; Do it.
  1717.     ret
  1718.  
  1719. ; Routine to set default character set.
  1720.  
  1721. chrdef: mov    al,ascset        ; Assume US ASCII.
  1722.     test    vtflags,vsshift3    ; Want UK for default?
  1723.     jz    chrde1            ; No.
  1724.     mov    al,ukset        ; Yes - use the UK set.
  1725. chrde1: mov    chr_sg0,al        ; Reset character sets.
  1726.     mov    chr_sg1,al
  1727.     mov    ax,offset chr_sg0    ; Select character set zero.
  1728.     mov    chr_set,ax
  1729.     ret
  1730. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; end of part one ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1731. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start of part two ;;;;;;;;;;;;;;;;;;;;;;;;;;
  1732. ; Routine to set special graphics character set (used in VT52 mode).
  1733.  
  1734. chrsgs: mov    al,sgrset        ; Select "graphics" set.
  1735.     jmp    chrde1            ; Do it and return.
  1736.  
  1737. ; Control-character handling routines
  1738.  
  1739. atbel:    call    vtbell            ; Just ring bell and return.
  1740.     ret
  1741.  
  1742. atbs:    cmp    dl,0            ; Backspace. too far?
  1743.     je    atbs1            ; e = at column 0 already.
  1744.     dec    dl            ; Backup cursor
  1745. atbs1:    call    atccpc            ; Check range
  1746.     jmp    atscu5            ; Set cursor and return
  1747.  
  1748. atht:    cmp    flags.vtflg,ttheath    ; Heath-19 mode? [jrd]
  1749.     je    atht2            ; e = yes. handle specially. [jrd]
  1750.     cmp    dl,byte ptr low_rgt    ; At or beyond last column?
  1751.     jae    atbs1            ; Yes, check range, set cursor and ret
  1752.     mov    al,0            ; For ORing.
  1753.     mov    bh,0            ; Make an index
  1754.     mov    bl,dl            ; For column.
  1755. atht1:    inc    bx            ; Tab always moves at least one space.
  1756.     or    al,tabs[bx]        ; Look for non-zero.
  1757.     jz    atht1            ; ...
  1758.     mov    dl,bl            ; Get the new row index
  1759.     jmp    atbs1            ; Check range, set cursor, and return
  1760. atht2:    mov    dx,cursor        ; Heath-19. get cursor position
  1761.     add    dl,8            ; tabs are every 8 columns
  1762.     and    dl,not 7        ; do modulo 8
  1763.     cmp    dl,byte ptr low_rgt    ; check against right edge
  1764.     jae    atht3            ; ae = out of range
  1765.     jmp    atscu5            ; set cursor and return
  1766. atht3:    test    ansflgs,decawm        ; doing line wrapping?
  1767.     jnz    atht4            ; nz = yes. wrap to next line
  1768.     mov    dl,byte ptr low_rgt    ; else go to right margin
  1769.     jmp    atscu5            ; set cursor and return
  1770. atht4:    inc    dh            ; say want next line down
  1771.     xor    dl,dl            ; and left margin
  1772.     call    atccic            ; index check
  1773.     call    ax            ; do any needed scrolling
  1774. atht4a: jmp    atscu5            ; reset cursor
  1775.  
  1776. atlf:    cmp    flags.vtflg,ttheath    ; Heath-19 mode? [jrd]
  1777.     je    atlf2            ; e = yes [jrd]
  1778.     test    ansflgs,anslnm        ; New-line mode?
  1779.     jz    atlf2            ; No - just move to next line down
  1780.     mov    dl,0            ; Yes - move to left margin also.
  1781. atlf2:    inc    dh            ; Index line down
  1782.     call    atccic            ; Check indexing
  1783.     call    ax            ; Call scrolling routine
  1784.     jmp    atscu5            ; Set cursor
  1785.  
  1786. atcr:    mov    dl,0            ; Go to left margin
  1787.     jmp    atscu5            ; Set cursor and return.
  1788.  
  1789. atff:    cmp    ttstate,offset atescf    ; parsing escape sequence?
  1790.     jne    atlf            ; ne = no, do as line feed
  1791.     test    denyflg,200h        ; is auto Tek mode disabled?
  1792.     jnz    atlf            ; nz = yes, treat as line feed.
  1793.     call    atsc            ; save cursor and associated data
  1794.     JMP    TEKESC            ; Jump to Tektronix Emulator, al=FF
  1795.  
  1796. atso:    mov    ax,offset chr_sg1    ; Select set G1 and return
  1797.     mov    chr_set,ax
  1798.     ret
  1799.  
  1800. atsi:    mov    ax,offset chr_sg0    ; Select set G0 and return
  1801.     mov    chr_set,ax
  1802.     ret
  1803.  
  1804. atcan:    cmp    ttstate,offset atnrm    ; doing normal chars (vs esc seq)?
  1805.     jne    atcan1            ; ne = no, assume esc seq
  1806.     jmp    atign            ; ignore ^X, ^Z in normal mode
  1807. atcan1: mov    ttstate,offset atnrm    ; Reset state to "normal".
  1808.     mov    al,sgrtab+2        ; replace CAN (^X) by checkerboard
  1809.     jmp    atnrm            ; Process char as a normal one
  1810.  
  1811. atesc:    mov    nansarg,0        ; Clear ANSI arguments
  1812.     mov    al,0
  1813.     mov    cx,lansarg
  1814.     mov    di,offset ansargs
  1815.     push    es
  1816.     push    ds
  1817.     pop    es            ; use datas segment for es:di below
  1818.     cld                ; set direction forward
  1819.     rep    stosb
  1820.     pop    es
  1821.     and    ansflgs,not decmode    ; Clear "DEC modes" flag.
  1822.     mov    h19mod,0        ; clear Heath-19 mode flag
  1823.     mov    ttstate,offset atescf    ; Next state is escape follower
  1824.     ret
  1825.  
  1826. atescf: cmp    flags.vtflg,ttvt100    ; VT100? [jrd]
  1827.     jne    atv52f            ; ne = not VT100, try others. [jrd]
  1828. atescf0:mov    cx,lansesc        ; Escape follower - get table length
  1829.     mov    di,offset ansesc    ; Point di at table
  1830.     push    es
  1831.     push    ds
  1832.     pop    es            ; use datas segment for es:di below
  1833.     cld                ; set direction forward
  1834.     repne    scasb            ; Find it.
  1835.     pop    es
  1836.     je    atescf1            ; Found - now go do something with it
  1837.     jmp    atnorm            ; Not there - just ignore it.
  1838.  
  1839. atescf1:mov    di,lansesc - 1        ; Compute word index into jump table.
  1840.     sub    di,cx
  1841.     shl    di,1
  1842.     jmp    ansejt[di]        ; Dispatch to the routine.
  1843.  
  1844. atv52f: cmp    flags.vtflg,ttheath    ; Heath-19? [jrd]
  1845.     je    ath19f            ; e = yes. Use Heath esc seqs. [jrd]
  1846.     mov    ttstate,offset atnrm    ; Assume state "normal" on return.
  1847.     mov    cx,lv52esc        ; Get table length
  1848.     mov    di,offset v52esc    ; Point di at table.
  1849.     push    es
  1850.     push    ds
  1851.     pop    es            ; use datas segment for es:di below
  1852.     cld                ; set direction forward
  1853.     repne    scasb            ; Find it.
  1854.     pop    es
  1855.     je    atv52f1            ; Found - do something with it.
  1856.     ret                ; Not there - just ignore it.
  1857.  
  1858. atv52f1:mov    di,lv52esc - 1        ; Compute word index into jump table.
  1859.     sub    di,cx
  1860.     shl    di,1
  1861.     jmp    v52ejt[di]        ; Dispatch to the routine.
  1862.  
  1863. ath19f: mov    ttstate,offset atnrm    ; Assume state "normal" on return.
  1864.     test    ansflgs,decanm        ; ansi mode?
  1865.     jnz    atescf0            ; nz = yes, use ansi table
  1866.     mov    cx,lh19esc        ; Get table length
  1867.     mov    di,offset h19esc    ; Point di at table.
  1868.     push    es
  1869.     push    ds
  1870.     pop    es            ; use datas segment for es:di below
  1871.     cld                ; set direction forward
  1872.     repne    scasb            ; Find it.
  1873.     pop    es
  1874.     je    ath19f1            ; Found - do something with it.
  1875.     ret                ; Not there - just ignore it.
  1876.  
  1877. ath19f1:mov    di,lh19esc - 1        ; Compute word index into jump table.
  1878.     sub    di,cx
  1879.     shl    di,1
  1880.     jmp    h19ejt[di]        ; Dispatch to the routine.
  1881.  
  1882.  
  1883. ; Escape follower routines.
  1884.  
  1885. atcsi:    mov    ttstate,offset atpaa    ; Next state is parse ansi args.
  1886.     ret
  1887.  
  1888. atpaa:    test    al,80h            ; high bit set?
  1889.     jz    atpaa6            ; z = no
  1890.     and    al,7fh            ; strip high bit
  1891.     cmp    al,' '            ; control code remainder?
  1892.     jae    atpaa6            ; ae = no, use 7 bit result
  1893.     mov    ttstate,offset atnrm    ; reset state to normal text
  1894.     jmp    atctrl            ; execute 7 bit control code
  1895. atpaa6: cmp    al,'0'            ; A digit?
  1896.     jb    atpaa1            ; No - just ignore it.
  1897.     cmp    al,'9'            ; Maybe - A separator or final char?
  1898.     ja    atpaa2            ; Perhaps - go check it out
  1899.     mov    cl,al            ; A digit - convert ASCII to binary
  1900.     sub    cl,'0'
  1901.     mov    bl,nansarg        ; put index in bx [dlk]
  1902.     xor    bh,bh
  1903.     mov    al,ansargs[bx]        ; Pick up what we've done so far [dlk]
  1904.     shl    al,1            ; multiply by 10.  2 * al
  1905.     mov    ah,al            ; save
  1906.     shl    al,1            ; 4 * al
  1907.     shl    al,1            ; 8 * al
  1908.     add    al,ah            ; 10 * al
  1909.     mov    ah,0            ; clear high field
  1910.     add    ax,cx            ; add in this digit [dlk]
  1911.     cmp    ax,0feh            ; max value is 0ffh [dlk]
  1912.     jbe    atpaa0            ; be = ok [dlk]
  1913.     mov    al,0ffh            ; set to max value [dlk]
  1914. atpaa0: mov    ansargs[bx],al        ; Put result back for next time [dlk]
  1915. atpaa1: ret                ; And return
  1916.  
  1917. atpaa2: cmp    al,'?'            ; The deadly question mark?
  1918.     jne    atpaa2a            ; No - check further.
  1919.     or    ansflgs,decmode        ; Yes - say DEC modes are coming.
  1920.     ret                ; And return.
  1921. atpaa2a:cmp    al,'>'            ; Heath private mode? [jrd]
  1922.     jne    atpaa3            ; ne = no
  1923.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19?
  1924.     jne    atpaa3            ; ne = no, ignore this sequence
  1925.     mov    h19mod,1        ; say Heath mode sequence follows.
  1926.     ret
  1927.  
  1928. atpaa3: cmp    al,';'            ; Argument separator?
  1929.     jne    atpaa4            ; No - check for final char.
  1930.     mov    al,nansarg        ; Get argument index
  1931.     inc    al            ; Bump it.
  1932.     cmp    al,lansarg        ; Too many?
  1933.     jl    atpa3a            ; l = no, continue
  1934.     mov    ttstate,offset atnrm    ; Reset state to "normal".
  1935.     ret                ; and pretend all is well [jrd]
  1936. ; [jrd] jmp    atcan            ; Yes - abandon sequence on error.
  1937. atpa3a: mov    nansarg,al        ; Save it.
  1938.     ret
  1939.  
  1940. atpaa4: mov    cx,lanstab
  1941.     mov    di,offset anstab    ; Look for it in the table
  1942.     push    es
  1943.     push    ds
  1944.     pop    es            ; use datas segment for es:di below
  1945.     cld                ; set direction forward
  1946.     repne    scasb
  1947.     pop    es
  1948.     je    atpaa5            ; Found it - go dispatch
  1949.     cmp    al,40h            ; in range for a legal terminator?
  1950.     jb    atpaa4a            ; b = not in range, ignore
  1951.     cmp    al,7eh            ; other end of the range
  1952.     ja    atpaa4a            ; a = out of range, ignore
  1953.                     ; in range, absorb and become normal
  1954.     mov    ttstate,offset atnrm    ; Put state back to normal
  1955. atpaa4a:ret                ; Just return if it is unknown.
  1956.  
  1957. atpaa5: mov    ttstate,offset atnrm    ; Put state back to normal
  1958.     mov    di,lanstab - 1        ; Compute word index into jump table.
  1959.     sub    di,cx
  1960.     shl    di,1
  1961.     jmp    ansjmp[di]        ; Off into the wild blue...
  1962.  
  1963. atind:    inc    dh            ; Index - move cursor down one.
  1964. atind1: call    atccic            ; Check cursor position.
  1965.     call    ax            ; Scroll if necessary.
  1966.     mov    ttstate,offset atnrm    ; Reset state.
  1967.     jmp    atscu5            ; Set cursor, etc. and return.
  1968.  
  1969. atnel:    mov    dl,0            ; Next line - sort of like CRLF...
  1970.     inc    dh            ; ... all in one command
  1971.     jmp    atind1            ; Check cursor, etc., and return.
  1972.  
  1973. atri:    dec    dh            ; Reverse index...
  1974.     jmp    atind1            ; Check cursor, etc., and return.
  1975.  
  1976. athts:    call    atccpc            ; Make sure we have valid column number.
  1977.     mov    dh,0            ; Zap row
  1978.     mov    al,0FFH            ; Indicates a tab stop
  1979.     mov    di,dx            ; Dumb specialized registers.
  1980.     mov    tabs[di],al        ; Store it.
  1981.     jmp    atnorm            ; Reset state and return.
  1982.  
  1983. atsc:    mov    si,offset curattr    ; Save cursor, attribute, char set etc.
  1984.     mov    di,offset savecu    ; Place to save the stuff.
  1985.     mov    cx,lsavecu        ; Length of save area
  1986.     push    es            ; save es
  1987.     push    ds
  1988.     pop    es            ; set es to datas segment
  1989.     cld
  1990.     rep    movsb            ; Save it.
  1991.     pop    es
  1992.     mov    cl,ansflgs        ; Save a copy of the flags.
  1993.     mov    savflgs,cl        ; ...
  1994.     jmp    atnorm            ; Reset state and return.
  1995.  
  1996. atrc:    mov    si,offset savecu    ; Restore cursor, attributes, etc..
  1997.     mov    di,offset curattr    ; Where stuff goes
  1998.     mov    cx,lsavecu        ; Length of save area
  1999.     push    es            ; save es
  2000.     push    ds
  2001.     pop    es            ; set es to datas segment
  2002.     cld
  2003.     rep    movsb            ; Put the stuff back.
  2004.     pop    es
  2005.     mov    al,savflgs        ; Get saved flags
  2006.     xor    al,ansflgs        ; Exclusive-or with current flags
  2007.     test    al,decscnm        ; Did screen mode change?
  2008.     jz    atrc1            ; No, just reset saved flags and leave
  2009.     mov    ah,curattr        ; Get cursor attribute that was saved
  2010.     call    brkatt            ; Break into background & extra stuff
  2011.     rol    ah,1            ; Reverse the background
  2012.     rol    ah,1            ; Reverse the background
  2013.     rol    ah,1            ; Reverse the background
  2014.     rol    ah,1            ; Reverse the background
  2015.     call    addatt            ; Put it all back together
  2016.     mov    curattr,ah        ; Store
  2017. atrc1:    mov    al,ansflgs        ; Reset flags in case called again
  2018.     and    al, not(decckm+deckpam+decom)  ; remove old bits [dlk]
  2019.     and    savflgs,(decckm+deckpam+decom) ; remove all but new bits [dlk]
  2020.     or    al,savflgs        ; restore saved bits [dlk]
  2021.     mov    ansflgs,al        ; update these flags [dlk]
  2022.     mov    savflgs,al
  2023.     mov    dx,cursor        ; Get cursor
  2024.     mov    kbiflg,0        ; Don't bother them with beeps here
  2025.     call    atscu5            ; Set cursor.
  2026.     jmp    atnorm            ; Reset state and return.
  2027.  
  2028. atkpam: or    ansflgs,deckpam        ; Turn on the bit
  2029.     mov    al,yflags
  2030.     call    telmsy            ; inform msy of new state
  2031.     jmp    atnorm            ; Reset state and return.
  2032.  
  2033. atkpnm: and    ansflgs,not deckpam    ; Turn off the bit
  2034.     mov    al,yflags
  2035.     call    telmsy            ; inform msy of new state
  2036.     jmp    atnorm            ; Reset state and return.
  2037.  
  2038. atris:    call    atreset            ; Reset everything
  2039.     jmp    atnorm            ; And state too, return, etc.
  2040.  
  2041. atsg0:    mov    ttstate,offset atsg01    ; Setup to get last character
  2042.     ret
  2043.  
  2044. atsg01: call    atscs            ; Get code for character set
  2045.     mov    chr_sg0,al        ; Store it.
  2046.     jmp    atnorm            ; Reset state etc. and return
  2047.  
  2048. atsg1:    mov    ttstate,offset atsg11    ; Setup to get last character
  2049.     ret
  2050.  
  2051. atsg11: call    atscs            ; Get code for character set
  2052.     mov    chr_sg1,al        ; Store it.
  2053.     jmp    atnorm            ; Reset state etc. and return
  2054.  
  2055. atscs:    cmp    al,'A'            ; UK ASCII set?
  2056.     jne    atscs1            ; No.
  2057.     mov    al,ukset        ; Yes - give them that and return
  2058.     ret
  2059.  
  2060. atscs1: cmp    al,'B'            ; US ASCII set?
  2061.     jne    atscs3            ; No.
  2062. atscs2: mov    al,ascset        ; Yes - give them that and return
  2063.     ret
  2064.  
  2065. atscs3: cmp    al,'0'            ; Special graphics set?
  2066.     jne    atscs4            ; ne = no
  2067.     mov    al,sgrset        ; Yes - say that's what it is
  2068.     ret
  2069.  
  2070. atscs4: cmp    al,'1'            ; alt char ROM, std char set? [jrd]
  2071.     jne    atscs5            ; ne = no
  2072.     mov    al,ascset        ; use US ASCII set
  2073.     ret
  2074.  
  2075. atscs5: cmp    al,'2'            ; alt char ROM, special graphics?[jrd]
  2076.     jne    atscs2            ; ne = no, use US ASCII
  2077.     mov    al,sgrset        ; set graphics
  2078.     ret
  2079.  
  2080.                     ; ESC # Pn  series. [jrd]
  2081. atsdhl: mov    ttstate,offset atsdbl    ; set up to parse argument
  2082.     ret
  2083. atsdbl: cmp    al,'3'            ; Double high lines. Top half? [jrd]
  2084.     je    atsdh2            ; e = yes
  2085.     cmp    al,'4'            ; bottom half?
  2086.     je    atsdh2            ; e = yes
  2087.     cmp    al,'5'            ; restore line to single width?
  2088.     je    atsdh1            ; e = yes
  2089.     cmp    al,'6'            ; double width single height?
  2090.     je    atsdh2            ; e = yes
  2091.     cmp    al,'8'            ; screen alignment?
  2092.     je    atsdh8            ; e = yes
  2093.     jmp    atnorm            ; else ignore
  2094. atsdh1: call    linesgl            ; set line to single width
  2095.     jmp    atnorm
  2096. atsdh2: call    linedbl            ; expand the line to double width
  2097.     jmp    atnorm            ; set state to normal and ret
  2098. atsdh8: call    atalign            ; do screen alignment
  2099.     jmp    atnorm
  2100. atpriv: mov    ttstate,offset atnorm    ; ignore next char.
  2101.     ret                ; and return to normal afterward.
  2102.  
  2103. atalign proc    near            ; Fill screen with 'E'
  2104.     call    atreset            ; clear system
  2105.     or    ansflgs,decawm        ; set wrap
  2106.     mov    cl,byte ptr low_rgt    ; number of columns-1
  2107.     inc    cl
  2108.     mov    al,byte ptr low_rgt+1    ; number of rows-1
  2109.     inc    al
  2110.     mul    cl            ; ax = number of chars on screen
  2111.     mov    cx,ax
  2112. atalig1:push    cx
  2113.     mov    al,'E'            ; write screen full of E's
  2114.     call    atnrm            ; write the 'E'
  2115.     pop    cx
  2116.     loop    atalig1            ; cx times
  2117.     ret
  2118. atalign endp
  2119.  
  2120. ; This routine may be used to repeat a call to a selected action routine
  2121. ; for all of the ANSI parameters given in a call.   When the action routine
  2122. ; is called, si will contain the index for the current ANSI parameter (i.e.,
  2123. ; the current ANSI parameter may be gotten using ansargs[si] for an effective
  2124. ; address).    The action routine may modify any ACs it wants, but cx, si,
  2125. ; and di are preserved over the call to the action routine, so these may
  2126. ; not be used for building return values for the original caller.   Note that
  2127. ; if there are no ANSI parameters, the effect is the same as if one ANSI
  2128. ; parameter with a value of zero was given.
  2129. ;
  2130. ; Call:        di/    offset of action routine in code seqment
  2131. ;
  2132.  
  2133. atreps: mov    cl,nansarg        ; Pick up number of parameters
  2134.     inc    cl            ; Zero parms is same as 1 zero parm.
  2135.     mov    ch,0
  2136.     mov    si,0            ; Init parm index
  2137. atrep1: push    cx            ; Save important acs
  2138.     push    si
  2139.     push    di
  2140.     call    di            ; Call indicated routine
  2141.     pop    di            ; Restore acs
  2142.     pop    si
  2143.     pop    cx
  2144.     inc    si            ; Advance to next parameter
  2145.     loop    atrep1            ; Loop for all
  2146.     ret                ; And return.
  2147.  
  2148.  
  2149. ; Final char (ANSI) routines.
  2150.  
  2151. atcup:    mov    dh,ansargs        ; Get the two arguments
  2152.     mov    dl,ansargs+1
  2153.     cmp    dh,0            ; Zero line number?
  2154.     jne    atcup1            ; No - continue
  2155.     mov    dh,1            ; Yes - default to one.
  2156. atcup1: cmp    dl,0            ; Ditto for row
  2157.     jne    atcup2
  2158.     mov    dl,1
  2159. atcup2: dec    dh            ; Now normalize
  2160.     dec    dl
  2161.     test    ansflgs,decom        ; Origin mode?
  2162.     jz    atcup4            ; No - skip this stuff
  2163.     add    dh,mar_top        ; Yes - it was relative to top margin
  2164.     jno    atcup4            ; If no overflow, continue
  2165.     mov    dh,byte ptr low_rgt+1    ; Otherwise just set to screen bottom
  2166. atcup4: cmp    dh,byte ptr low_rgt+1    ; going to 25th line? [hlk]
  2167.     jbe    atcup5            ; be = no [dlk]
  2168.     cmp    flags.vtflg,ttheath    ; emulating a Heath-19? [jrd]
  2169.     jne    atcup6            ; ne = no [hlk]
  2170.     cmp    h19l25,0        ; Heath 25th line enabled?
  2171.     je    atcup5            ; e = no
  2172.     mov    dh,byte ptr low_rgt+1    ; [hlk]
  2173.     inc    dh            ; go there
  2174.     jmp    atscu4            ; set cursor position & mode line
  2175.  
  2176. atcup6: test    ansflgs,decom        ; origin mode? [jrd]
  2177. ;;;##    jz    atcup5            ; z = no, no 25th line stuff allowed
  2178.     mov    dh,byte ptr low_rgt+1    ; bottom normal line
  2179.     inc    dh            ; the 25th line
  2180.     jmp    atscu4            ; set cursor position and return
  2181. atcup5: call    atccpc            ; Check position
  2182.     jmp    atscu5            ; Set cursor position and return.
  2183.  
  2184. atcuarg:mov    al,ansargs        ; Get a cursor move argument
  2185.     cmp    al,0            ; Zero?
  2186.     jne    atcua1            ; No - return
  2187.     mov    al,1            ; Yes - default to one.
  2188. atcua1: ret                ; Return.
  2189.                     ; Disallow movement to 25th line.
  2190. atcuu:    call    atcuarg            ; Get cursor move argument in al
  2191.     sub    dh,al            ; Compute new cursor position
  2192.     jnc    atcuu1            ; nc = ok [dlk]
  2193.     xor    dh,dh            ; overflow, restrict range. [dlk]
  2194. atcuu1: call    atccic            ; check indexing, ignore action in ax
  2195.     jmp    atscu5            ; set the cursor at its new position
  2196.  
  2197. atcud:    call    atcuarg            ; Get the argument
  2198.     add    dh,al            ; Compute new cursor position
  2199.     jnc    atcud1            ; nc = ok [dlk]
  2200.     mov    dh,byte ptr low_rgt+1    ; default bottom [dlk]
  2201. atcud1: call    atccic            ; check indexing, ignore action in ax
  2202.     jmp    atscu5            ; set the cursor at its new position
  2203.  
  2204.                     ; Allow horiz movement on 25th line.
  2205. atcuf:    call    atcuarg            ; Get the argument
  2206.     add    dl,al            ; Compute new cursor position
  2207.     jnc    atcup4            ; If no carry, continue [dlk]
  2208.     mov    dl,byte ptr low_rgt    ; Else set to right margin
  2209.     jmp    atcup4            ; Check/set cursor, return.
  2210.  
  2211. atcub:    call    atcuarg            ; Get the argument
  2212.     sub    dl,al            ; Compute new cursor position
  2213.     jnc    atcup4            ; If no carry, continue [dlk]
  2214.     mov    dl,0            ; Else set to left margin
  2215.     jmp    atcup4            ; Check/set cursor, return.
  2216.  
  2217. ated:    mov    di,offset ated0        ; Routine to process parm.
  2218.     call    atreps            ; Do all selected parms.
  2219.     ret
  2220.  
  2221. ated0:    cmp    ansargs[si],0        ; Was arg zero?
  2222.     jne    ated2            ; No - continue
  2223.     mov    ax,dx            ; Yes - erase from cursor to end of screen
  2224.     push    dx            ; save dx
  2225.     mov    bl,dh            ; get row number
  2226.     xor    bh,bh
  2227.     cmp    linetype [bx],0        ; single width line?
  2228.     je    ated0a            ; e = yes
  2229.     shl    dl,1            ; physical column is twice logical
  2230. ated0a: or    dl,dl            ; starting at left margin?
  2231.     je    ated0b            ; e = yes, this goes to single width
  2232.     inc    bl            ; else start on next line
  2233. ated0b: cmp    bl,byte ptr low_rgt+1    ; at the end of the screen?
  2234.     ja    ated0c            ; a = yes, stop singling-up
  2235.     mov    byte ptr linetype [bx],0 ; set to single width
  2236.     inc    bx
  2237.     jmp    short ated0b        ; loop, reset lines to end of screen
  2238. ated0c: mov    bx,low_rgt        ; erase from cursor to end of screen
  2239.     mov    bl,crt_cols
  2240. ;;;##
  2241.     test    yflags,modoff        ; is mode line disabled?
  2242.     jz    ated0d            ; z = yes, don't extend erase
  2243.     inc    bh            ; yes, extend erase to 25th line
  2244. ated0d:
  2245. ;;;##
  2246.     dec    bl            ; do physical screen width
  2247.     call    atsclr            ; Clear it.
  2248.     pop    dx            ; restore dx
  2249. ated1:    ret
  2250.  
  2251. ated2:    cmp    ansargs[si],1        ; Was arg one?
  2252.     jne    ated3            ; No - continue
  2253.     mov    ax,0            ; Yes -     erase from start of screen...
  2254.                     ; ...to cursor, inclusive
  2255.     xor    bx,bx            ; start at top row (0)
  2256. ated2b: cmp    bl,dh            ; check rows from the top down
  2257.     jae    ated2c            ; ae = at or below current line
  2258.     mov    byte ptr linetype [bx],0; set line to single width
  2259.     inc    bx            ; inc row
  2260.     jmp    short ated2b        ; look at next line
  2261. ated2c: or    dl,dl            ; at left margin of current line?
  2262.     jne    ated2d            ; ne = no, leave line width intact
  2263.     mov    byte ptr linetype [bx],0 ; convert to single width
  2264. ated2d: mov    bl,dh            ; get row number
  2265.     xor    bh,bh
  2266.     cmp    linetype [bx],0        ; single width line?
  2267.     je    ated2a            ; e = yes
  2268.     shl    dl,1            ; physical column is twice logical
  2269. ated2a: mov    bx,dx            ; cursor position to bx
  2270.     call    atsclr            ; Clear it.
  2271.     ret
  2272.  
  2273. ated3:    cmp    ansargs[si],2        ; Was arg two?
  2274.     jne    ated1            ; No - ignore it.
  2275.     mov    ax,0            ; Yes - erase entire screen.
  2276.     mov    bx,low_rgt
  2277.     mov    bl,crt_cols
  2278. ;;;##
  2279.     test    yflags,modoff        ; is mode line disabled?
  2280.     jz    ated3b            ; z = yes, don't extend erase
  2281.     inc    bh            ; yes, extend erase to 25th line
  2282. ated3b:
  2283. ;;;##
  2284.  
  2285.  
  2286.     dec    bl            ; physical width
  2287.     call    atsclr            ; Clear it.
  2288.     push    bx
  2289.     push    cx            ; set all 24 lines to single width
  2290.     mov    cl,byte ptr low_rgt+1    ; number of last line
  2291.     xor    ch,ch
  2292.     inc    cx            ; count from one
  2293.     xor    bx,bx
  2294. ated3a: mov    linetype [bx],0
  2295.     inc    bx
  2296.     loop    ated3a
  2297.     pop    cx
  2298.     pop    bx
  2299.     ret
  2300.  
  2301. atel:    mov    di,offset atel0        ; Get routine to call
  2302.     call    atreps            ; Repeat for all parameters.
  2303.     ret
  2304.  
  2305. atel0:    cmp    ansargs[si],0        ; Was arg zero?
  2306.     jne    atel2            ; No - continue
  2307.     mov    ax,dx            ; Yes - erase from cursor...
  2308.     mov    bh,dh            ; ...to end of line, inclusive
  2309.     push    bx
  2310.     mov    bl,bh            ; get row
  2311.     mov    bh,0
  2312.     cmp    linetype [bx],0        ; single width line?
  2313.     je    atel0a            ; e = yes
  2314.     shl    al,1            ; physical column is twice logical
  2315. atel0a: pop    bx
  2316.     mov    bl,byte ptr low_rgt
  2317.     call    atsclr            ; Clear it.
  2318. atel1:    ret
  2319.  
  2320. atel2:    cmp    ansargs[si],1        ; Was arg one?
  2321.     jne    atel3            ; No - continue
  2322.     mov    ah,dh            ; Yes -     erase from start of line...
  2323.     mov    al,0
  2324.     mov    bx,dx            ; ...to cursor, inclusive
  2325.     push    bx
  2326.     mov    bl,dh            ; get row
  2327.     mov    bh,0
  2328.     cmp    linetype [bx],0        ; single width line?
  2329.     pop    bx            ; pop does not affect flags
  2330.     je    atel2a            ; e = yes
  2331.     shl    bl,1            ; physical column is twice logical
  2332. atel2a: call    atsclr            ; Clear it.
  2333.     ret
  2334.  
  2335. atel3:    cmp    ansargs[si],2        ; Was arg two?
  2336.     jne    atel1            ; No - ignore it.
  2337.     mov    ah,dh            ; Yes - erase entire line.
  2338.     mov    al,0
  2339.     mov    bh,dh
  2340.     mov    bl,byte ptr low_rgt
  2341.     mov    bl,crt_cols
  2342.     dec    bl            ; physical line
  2343.     call    atsclr            ; Clear it.
  2344.     ret
  2345.  
  2346. atsgr:    mov    ah,curattr        ; Get current cursor attribute
  2347.     call    brkatt            ; Break it apart.
  2348.     mov    di,offset atsgr1    ; Routine to call.
  2349.     call    atreps            ; Repeat for all parms.
  2350.     call    addatt            ; Put the attributes back together
  2351.     mov    curattr,ah        ; Store.
  2352.     ret
  2353.  
  2354. atsgr1: mov    bl,ansargs[si]        ; Fetch an argument
  2355.     cmp    bl,0            ; Zero?
  2356.     jne    atsgr2            ; No.
  2357.     mov    al,0            ; Yes - clear the "extras"
  2358.     mov    ah,scbattr        ; And reset background.
  2359.     and    ah,77h            ; clear blink/bold here
  2360.     mov    video_state,0        ; say normal video now. [jrd]
  2361.     ret
  2362.  
  2363. atsgr2: cmp    bl,1            ; One?
  2364.     jne    atsgr3            ; No.
  2365.     or    al,att_intensity    ; Yes - set bold
  2366.     ret
  2367.  
  2368. atsgr3: cmp    bl,4            ; Four? Underline. Mods by [jrd]
  2369.     jne    atsgr4            ; No.
  2370.     or    al,att_underline    ; Yes, set underscore.
  2371.     cmp    crt_mode,2        ; monochrome display adapter mode?
  2372.     je    atsgr3a            ; e = yes. Otherwise reverse video
  2373.             ; use reversed video rather than blue on black
  2374.     and    al,not att_underline    ; clear underline and [jrd]
  2375.     rol    ah,1            ; reverse the colors [jrd]
  2376.     rol    ah,1            ; [jrd]
  2377.     rol    ah,1            ; [jrd]
  2378.     rol    ah,1
  2379. atsgr3a:ret
  2380.  
  2381. atsgr4: cmp    bl,5            ; Five?
  2382.     jne    atsgr5            ; No.
  2383.     or    al,att_blink        ; Yes - set blink
  2384.     ret
  2385.  
  2386. atsgr5: cmp    bl,7            ; Seven?
  2387.     jne    atsgr6            ; No - just ignore it.
  2388.     cmp    video_state,0        ; is video normal? [jrd]
  2389.     jne    atsgr6            ; ne = no, reversed already, ignore
  2390.     rol    ah,1            ; reverse the colors
  2391.     rol    ah,1
  2392.     rol    ah,1
  2393.     rol    ah,1
  2394.     mov    video_state,1        ; say reversed now.
  2395.     ret
  2396.  
  2397. atsgr6: cmp    bl,30            ; ANSI color series? [jrd]
  2398.     jb    atsgrx            ; b = no.
  2399.     cmp    bl,37            ; foreground set (30-37)?
  2400.     ja    atsgr7            ; a = no, try background set.
  2401.     sub    bl,30            ; take away the bias
  2402.     and    ah,not 07H        ; clear foreground bits
  2403.     test    bl,1            ; ANSI red?
  2404.     jz    atsgr6a            ; z = no
  2405.     or    ah,4            ; IBM red foreground bit
  2406. atsgr6a:test    bl,2            ; ANSI & IBM green?
  2407.     jz    atsgr6b            ; z = no
  2408.     or    ah,2            ; IBM green foreground bit
  2409. atsgr6b:test    bl,4            ; ANSI blue?
  2410.     jz    atsgr6c            ; z = no
  2411.     or    ah,1            ; IBM blue foreground bit
  2412. atsgr6c:ret
  2413.  
  2414. atsgr7: cmp    bl,40            ; background color set?
  2415.     jb    atsgrx            ; b = no
  2416.     cmp    bl,47            ; background set is 40-47
  2417.     ja    atsgrx            ; nb = no, not a color command.
  2418.     sub    bl,40            ; take away the bias
  2419.     and    ah,not 70H        ; clear background bits
  2420.     test    bl,1            ; ANSI red?
  2421.     jz    atsgr7a            ; z = no
  2422.     or    ah,40h            ; IBM red background bit
  2423. atsgr7a:test    bl,2            ; ANSI & IBM green?
  2424.     jz    atsgr7b            ; z = no
  2425.     or    ah,20h            ; IBM green background bit
  2426. atsgr7b:test    bl,4            ; ANSI blue?
  2427.     jz    atsgrx            ; z = no
  2428.     or    ah,10h            ; IBM blue background bit
  2429.  
  2430. atsgrx: ret
  2431.  
  2432. attbc:    call    atccpc            ; Make sure cursor is kosher
  2433.     mov    di,offset attbc0    ; Routine to call
  2434.     call    atreps            ; Do for all parms
  2435.     ret
  2436.  
  2437. attbc0: cmp    ansargs[si],0        ; Was argument zero?
  2438.     jne    attbc2            ; No - check further
  2439.     mov    dh,0            ; Zap row for indexing
  2440.     mov    di,dx
  2441.     mov    tabs[di],0        ; clear tab stop
  2442. attbc1: ret
  2443.  
  2444. attbc2: cmp    ansargs[si],3        ; Was arg 3 (clear all tab stops)?
  2445.     jne    attbc1            ; No - just ignore it.
  2446.     mov    cx,swidth        ; Get ready to zap swidth columns
  2447.     mov    di,offset tabs        ; Point to the tab stop table.
  2448.     mov    al,0            ; zero indicates no tab stop.
  2449.     push    es            ; save es
  2450.     push    ds
  2451.     pop    es            ; use datas segment for es:di below
  2452.     cld                ; set direction forward
  2453.     rep    stosb            ; Blit full of zeros.
  2454.     pop    es
  2455.     ret
  2456.  
  2457. atstbm: mov    al,ansargs        ; Get the two line number args
  2458.     mov    ah,ansargs+1
  2459.     cmp    al,0            ; Was first zero?
  2460.     jne    atstb1            ; No - continue
  2461.     mov    al,1            ; Yes - default is one
  2462. atstb1: cmp    ah,0            ; Was second zero?
  2463.     jne    atstb2            ; No - continue
  2464.     mov    ah,byte ptr low_rgt+1    ; Yes - default is last line on screen
  2465.     inc    ah
  2466. atstb2: dec    al            ; Normalize to our coord. system
  2467.     dec    ah
  2468.     cmp    ah,al            ; Is size of region at least two lines?
  2469.     jbe    atstb3            ; be = if not, indicate an error.
  2470.     cmp    al,0            ; Check against screen limits.
  2471.     jl    atstb3
  2472.     cmp    ah,byte ptr low_rgt+1
  2473.     ja    atstb3
  2474.     mov    mar_top,al        ; Set the limits
  2475.     mov    mar_bot,ah
  2476.     mov    dx,0            ; Home cursor
  2477.     call    atccpc            ; Check cursor (get it inside window)
  2478.     jmp    atscu5            ; Set cursor position and return.
  2479.  
  2480. atstb3: ret                ; ignore bad requests
  2481. ;;;    jmp    atcan            ; Indicate error and return.
  2482.  
  2483. atda:    cmp    ansargs,0        ; Was argument zero?
  2484.     je    decid            ; Yes - send the i.d. string.
  2485.     ret                ; No - only an echo...
  2486. at52id: mov    ttstate,offset atnrm    ; ensure state is correct
  2487. decid:    mov    cx,ldastr        ; Length of the string
  2488.     mov    si,offset dastr        ; Point to the string
  2489.     cmp    flags.vtflg,ttvt100    ; VT100? [jrd]
  2490.     je    decid1            ; e = yes [jrd]
  2491.     mov    cx,lv52str        ; No - try VT52 i.d. [jrd]
  2492.     mov    si,offset v52str
  2493.     cmp    flags.vtflg,ttvt52    ; Heath-19 mode? [jrd]
  2494.     je    decid1            ; e = yes. [jrd]
  2495.     mov    cx,lh19str        ; length of Heath-19 ident string
  2496.     mov    si,offset h19str    ; say Heath-19. [jrd]
  2497. decid1: cld
  2498.     lodsb                ; Get a byte
  2499.     push    cx            ; Save the important registers
  2500.     push    si
  2501.     call    prtbout            ; Send it to port with no local echo
  2502.     pop    si
  2503.     pop    cx
  2504.     loop    decid1            ; Loop for all characters
  2505.     ret
  2506.  
  2507. atll:    mov    di,offset atleds    ; Get pointer to routine to call
  2508.     call    atreps            ; Repeat for selective parameters.
  2509.     ret
  2510.  
  2511. atleds: cmp    ansargs[si],0        ; Zero argument?
  2512.     jne    atled3            ; No - check further.
  2513.     mov    cx,4            ; Reset the "LEDs". [jrd]
  2514.     mov    al,led_off        ; to all off.
  2515.     mov    di,offset ansleds+6    ; Point to the "LEDs".
  2516.     push    es            ; save es
  2517.     push    ds
  2518.     pop    es            ; make es:di point to datas seg
  2519.     cld                ; move forward
  2520.     rep    stosb            ; [jrd]
  2521.     pop    es
  2522. atled1: call    disleds            ; Update "LEDs" display and return.
  2523. atled2: ret
  2524.  
  2525. atled3: mov    al,ansargs[si]        ; Get the argument
  2526.     cmp    al,1            ; Must be .GE. 1
  2527.     jb    atled2            ; If not just ignore it. [dlk]
  2528.     cmp    al,4            ; Must be .LE. 4
  2529.     ja    atled2            ; Ignore if not so. [dlk]
  2530.     dec    al            ; Zero base it.
  2531.     cbw                ; Convert to index in ax.
  2532.     mov    di,ax            ; Dumb specialized registers.
  2533.     add    al,'1'            ; add ascii offset for digit
  2534.     mov    ansleds[di+6],al    ; Turn the "LED" on by storing digit
  2535.     jmp    atled1            ; Update display and return.
  2536.  
  2537. atreqt: cmp    ansargs,0        ; Want report?
  2538.     je    atreq1            ; Yes - give report
  2539.     cmp    ansargs,1        ; Want report?
  2540.     je    atreq1            ; Yes - give the report.
  2541.     ret                ; Gee, must have been an echo...
  2542.  
  2543. atreq1: mov    al,escape        ; Send an escape to start off...
  2544.     call    prtbout
  2545.     mov    al,'['            ; Then one of these...
  2546.     call    prtbout
  2547.     mov    al,'3'            ; We only report on request...
  2548.     cmp    ansargs,0        ; was argument a zero?
  2549.     jne    atreq1a            ; ne = no
  2550.     mov    al,'2'            ; yes
  2551. atreq1a:call    prtbout
  2552.     mov    al,';'            ; Separate
  2553.     call    prtbout
  2554.     mov    bl,parcode        ; Get the parity code
  2555.     mov    bh,0
  2556.     mov    al,partab[bx]        ; Get VT100 parity code
  2557.     push    ax            ; save parity code
  2558.     call    prtnout            ; Send number to the port..
  2559.     mov    al,';'            ; Separate
  2560.     call    prtbout
  2561.     mov    al,'2'            ; Assume 7 data bits
  2562.     pop    bx            ; get parity code into bl
  2563.     cmp    bl,1            ; is parity none?
  2564.     jne    atreq2            ; ne = no, so 7 data bits
  2565.     test    flags.remflg,d8bit    ; 8 bit display?
  2566.     jz    atreq2            ; z = no
  2567.     mov    al,'1'            ; must be eight.
  2568. atreq2: call    prtbout            ; Send it to the port
  2569.     mov    al,';'            ; Separate
  2570.     call    prtbout
  2571.     mov    bl,baudidx        ; Baud rate index
  2572.     mov    bh,0
  2573.     mov    al,baudtab[bx]        ; Get DEC baud rate code
  2574.     push    ax
  2575.     call    prtnout            ; Send it to the port
  2576.     mov    al,';'            ; Separate
  2577.     call    prtbout            ; Send it to the port
  2578.     pop    ax
  2579.     call    prtnout            ; Send it to the port
  2580.     mov    al,';'            ; Separate
  2581.     call    prtbout
  2582.     mov    al,'1'            ; Clock rate multiplier is always 1
  2583.     call    prtbout
  2584.     mov    al,';'            ; Separate (gasp - for the last time)
  2585.     call    prtbout
  2586.     mov    al,'0'            ; Flags are always zero (no STP)
  2587.     call    prtbout
  2588.     mov    al,'x'            ; Finally, say what this all was.
  2589.     call    prtbout
  2590.     ret
  2591.  
  2592. atdsr:    mov    di,offset atdsr1    ; Routine to call
  2593.     call    atreps            ; Do for all parms.
  2594.     ret
  2595.  
  2596. atdsr1: cmp    ansargs[si],5        ; Want status?
  2597.     je    rpstat            ; Yes - report status
  2598.     cmp    ansargs[si],6        ; Want cursor position?
  2599.     je    rpcup            ; Yes - do it.
  2600.     cmp    ansargs[si],15        ; Printer status? [jrd]
  2601.     je    rpstap            ; e = yes, do so.
  2602.     ret                ; No - must have been an echo
  2603.  
  2604. rpstat: mov    al,escape        ; Tell them we think we are OK
  2605.     call    prtbout
  2606.     mov    al,'['
  2607.     call    prtbout
  2608.     mov    al,'0'
  2609.     call    prtbout
  2610.     mov    al,'n'
  2611.     call    prtbout
  2612.     ret
  2613.  
  2614. rpstap: test    ansflgs,decmode        ; Printer status report from    [jrd]
  2615.     jz    rpstap3            ; ESC [ ? 15 n    request
  2616.     mov    al,escape
  2617.     call    prtbout
  2618.     mov    al,'['
  2619.     call    prtbout
  2620.     mov    al,'?'
  2621.     call    prtbout
  2622.     mov    al,'1'
  2623.     call    prtbout
  2624.     mov    ah,ioctl        ; get printer status, via DOS
  2625.     mov    al,7            ; status for output
  2626.     push    bx
  2627.     mov    bx,4            ; std handle for system printer
  2628.     int    dos
  2629.     pop    bx
  2630.     jc    rpstap1            ; c = call failed
  2631.     cmp    al,0ffh            ; code for Ready
  2632.     jne    rpstap1            ; ne = not ready
  2633.     mov    al,'0'            ; ready, send final digit
  2634.     jmp    rpstap2
  2635. rpstap1:mov    al,'3'            ; not ready, say printer disconnected
  2636. rpstap2:call    prtbout
  2637.     mov    al,'n'            ; final char of response
  2638.     call    prtbout
  2639. rpstap3:ret
  2640.  
  2641. rpcup:    mov    al,escape        ; Cursor position - send an escape
  2642.     call    prtbout
  2643.     mov    al,'['            ; And one of these
  2644.     call    prtbout
  2645.     mov    al,byte ptr cursor+1    ; Get row
  2646.     inc    al            ; They use coords that start at 1.
  2647.     test    ansflgs,decom        ; Origin mode set?
  2648.     jz    rpcup1            ; No - continue
  2649.     sub    al,mar_top        ; Yes - subtract off top margin
  2650. rpcup1: call    prtnout            ; Output the number.
  2651.     mov    al,';'            ; Separate
  2652.     call    prtbout
  2653.     mov    al,byte ptr cursor    ; Now get the column number.
  2654.     inc    al            ; Their coords start at 1.
  2655.     call    prtnout            ; Send it off to the port.
  2656.     mov    al,'R'            ; Finally end it with this
  2657.     call    prtbout
  2658.     ret
  2659.  
  2660.                     ; ESC [ ? xxx h/l  series
  2661. atrm:    mov    modeset,0        ; Say we are resetting modes
  2662.     mov    di,offset atrsm        ; Reset/set modes.
  2663.     call    atreps            ; Repeat for all parms.
  2664.     test    ansflgs,decanm        ; Did this get reset?
  2665.     jnz    atrm1            ; No - return.
  2666.     cmp    flags.vtflg,ttheath    ; were we a Heath-19?
  2667.     je    atrm0            ; e = yes, don't change terminal types
  2668.     mov    flags.vtflg,ttvt52    ; Yes. Say VT52 now. [jrd]
  2669. atrm0:    call    chrdef            ; Yes - set default char sets.
  2670.     call    atsc            ; Save cursor status.
  2671.     call    disleds            ; update terminal type
  2672. atrm1:    ret
  2673.  
  2674. atsm:    mov    modeset,1        ; Say we are setting modes
  2675.     mov    di,offset atrsm        ; Reset/set modes.
  2676.     call    atreps            ; Repeat for all parms.
  2677.     ret
  2678.  
  2679. atrsm:    mov    al,ansargs[si]        ; Pick up the argument.
  2680.     test    ansflgs,decmode        ; Is this DEC private mode ([ ?)stuff?
  2681.     jnz    atrsm1            ; nz = yes - go check it out.
  2682.     cmp    h19mod,0        ; Heath-19 private mode ([ >)?
  2683.     je    atrsma            ; e = no
  2684.     jmp    htrsm1            ; yes, do Heath specific things.
  2685. atrsma: cmp    al,20            ; No - ANSI new-line mode?
  2686.     jne    atrsm0            ;  but try insert mode. [jrd]
  2687.     and    vtemu.vtflgop,not vsnewline ; assume resetting
  2688.     cmp    modeset,0        ; resetting?
  2689.     je    atrsmb            ; e = yes
  2690.     or    vtemu.vtflgop,vsnewline ; setting
  2691. atrsmb: mov    al,anslnm        ; Yes - get the bit
  2692.     call    atrsflg            ; Set or reset it
  2693.     ret
  2694. atrsm0: cmp    al,4            ; toggle insert mode? [jrd]
  2695.     jne    atrsmx            ; ne = no [jrd]
  2696.     mov    al,modeset        ; set/reset insert mode [jrd]
  2697.     mov    insmod,al        ; store it. [jrd]
  2698. atrsmx: ret
  2699.  
  2700. atrsm1: cmp    al,1            ; Cursor keys mode?
  2701.     jne    atrsm2            ; No - check some more
  2702.     mov    al,decckm        ; Yes - get the bit.
  2703.     jmp    atrsflg            ; Set or reset it and return.
  2704.  
  2705. atrsm2: cmp    al,7            ; Auto-wrap?
  2706.     jne    atrsm3            ; No - check some more
  2707.     and    vtemu.vtflgop,not vswrap ; assume resetting line wrap
  2708.     cmp    modeset,0        ; resetting?
  2709.     je    atrsm2a            ; e = yes
  2710.     or    vtemu.vtflgop,vswrap    ; set the bit
  2711. atrsm2a:mov    al,decawm        ; Yes - get the bit
  2712.     jmp    atrsflg            ; Set or reset it and return.
  2713.  
  2714. atrsm3: cmp    al,6            ; Origin mode?
  2715.     jne    atrsm4            ; No - check for video change
  2716.     jmp    atrsom            ; Yes - change decom and return.
  2717.  
  2718. atrsm4: cmp    al,5            ; Change the video?
  2719.     jne    atrsm5            ; No - check for VT52 mode set/reset.
  2720.     jmp    atrsscnm        ; Yes - change it if we have to and ret.
  2721.  
  2722. atrsm5: cmp    al,2            ; Change VT52 compatibility mode?
  2723.     jne    atrsm6            ; No - ignore unknown DEC private modes
  2724.     cmp    flags.vtflg,ttheath    ; Heath-19 mode? [jrd]
  2725.     je    atrsm5a            ; e = yes, handle specially. [jrd]
  2726.     mov    al,ascset        ; return to US ascii graphics sets
  2727.     mov    chr_sg0,al        ; Store it.
  2728.     mov    chr_sg1,al        ; Store it.
  2729.     mov    al,decanm        ; Yes - get the flag.
  2730.     jmp    atrsflg            ; Set or reset it and return.
  2731.  
  2732. atrsm5a:mov    modeset,0        ; Heath-19 ESC [ ? 2 h, reset ansi
  2733.     mov    al,decanm        ; the flag needing adjustment
  2734.     jmp    atrsflg            ; reset the flag and return
  2735.  
  2736. atrsm6: cmp    al,3            ; 132/80 column mode change? [jrd]
  2737.     jne    atrsm7            ; ne = no
  2738.     mov    al,modeset        ; pass set/reset request to chgdsp[dlk]
  2739.     call    chgdsp            ; call Change Display proc in msy [dlk]
  2740.  
  2741.     call    scrmod            ; get current screen mode
  2742.     cmp    modeset,1        ; want 132 cols?
  2743.     jne    atrsm6n            ; ne = no, so use 80 columns
  2744.     push    ax
  2745.     mov    al,crt_cols        ; get current physical screen width
  2746.     dec    al            ; we count from column 0 here
  2747.     mov    byte ptr low_rgt,al    ; screen capability
  2748.     pop    ax
  2749.     mov    linelen,131        ; say using wide screen, if possible
  2750.     jmp    short atrsm6e
  2751. atrsm6n:mov    linelen,79        ; say using 80 columns
  2752.     cmp    byte ptr low_rgt,79    ; want 80 cols, is it wider?
  2753.     jbe    atrsm6e            ; be = no
  2754.     mov    byte ptr low_rgt,79    ; narrow down to 80 columns
  2755. atrsm6e:
  2756.     CALL    ATRES2            ; do partial reset of emulator
  2757.     xor    ax,ax            ; clear screen from 0,0
  2758.     mov    bh,byte ptr low_rgt+1    ; to end of text lines (typ. line 24)
  2759.     mov    bl,crt_cols        ; physical width
  2760.     dec    bl            ; we count from 0
  2761.     call    atsclr            ; do the clear
  2762.     push    bx            ; save regs. [jrd]
  2763.     push    cx
  2764.     mov    cl,byte ptr low_rgt+1    ; text lines (leave status line intact)
  2765.     mov    mar_top,0
  2766.     mov    mar_bot,cl        ; reset scrolling region
  2767.     xor    ch,ch
  2768.     xor    bx,bx
  2769. atrsm6a:mov    linetype [bx],0        ; reset linetype to single chars
  2770.     inc    bx
  2771.     loop    atrsm6a
  2772.     pop    cx
  2773.     pop    bx
  2774.     xor    dx,dx            ; new cursor position is 0,0
  2775.     mov    cursor,dx
  2776.     jmp    atscu5            ; place it there and return
  2777.  
  2778. atrsm7: cmp    al,18            ; 18?  18 & 19 = printer support [jrd]
  2779.     jne    atrsm8            ; ne = no
  2780.     cmp    modeset,0        ; resetting?
  2781.     jne    atrsm7a            ; ne = no, setting
  2782.     and    anspflg,not vtffp    ; no form feed after printing
  2783.     ret
  2784. atrsm7a:or    anspflg,vtffp        ; use form feed after printing
  2785.     ret
  2786.  
  2787. atrsm8: cmp    al,19            ; 19? [jrd]
  2788.     jne    atrsm9            ; ne = no
  2789.     cmp    modeset,0        ; resetting?
  2790.     jne    atrsm8a            ; ne = no, setting
  2791.     and    anspflg,not vtextp    ; reset print region to scrolling reg.
  2792.     ret
  2793. atrsm8a:or    anspflg,vtextp        ; set print region to whole screen
  2794.     ret
  2795.  
  2796. atrsm9: cmp    al,38            ; 38? Enter Tek sub-mode. VT340 seq
  2797.     jne    atrsm10            ; ne = no
  2798.     cmp    modeset,1        ; setting mode (ESC [ ? 38 h)?
  2799.     jne    atrsm10            ; ne = no, ignore sequence
  2800.     test    denyflg,200h        ; is auto Tek mode disabled?
  2801.     jnz    atrsm10            ; nz = yes, just ignore command
  2802.     call    atsc            ; save cursor and associated data
  2803.     mov    al,0            ; enter with this received character
  2804.     JMP    TEKEMU            ; Jump to Tektronix Emulator, al=null
  2805.  
  2806. atrsm10:ret
  2807.         ; Heath-19  ESC [ > Ps h or l where Ps = 1, 4, 7, or 9. [jrd]
  2808. htrsm1: cmp    al,1            ; 25th line?
  2809.     jne    htrsm4            ; ne = no
  2810.     mov    al,modeset        ; set/reset flag
  2811.     mov    h19l25,al
  2812.     cmp    al,0            ; resetting? Mods from Dave Tweten
  2813.     jne    htrsmx            ; ne = no, enabling. we are done
  2814.     mov    ah,byte ptr low_rgt+1    ; point to status (25th) line
  2815.     inc    ah            ;  which is here
  2816.     xor    al,al            ; from column 0
  2817.     mov    bh,ah            ; to same line
  2818.     mov    bl,crt_cols        ; physical width
  2819.     dec    bl            ; we count from 0
  2820.     jmp    atsclr            ; disabling status line clears it
  2821.  
  2822. htrsm4: cmp    al,4            ; block/line cursor?
  2823.     jne    htrsm5            ; ne = no
  2824.     and    h19ctyp,4        ; save on/off bit (4)
  2825.     cmp    modeset,0        ; reset?
  2826.     je    htrsm4a            ; e = yes
  2827.     or    h19ctyp,2        ; remember block kind here
  2828.     jmp    atsctyp
  2829. htrsm4a:or    h19ctyp,1        ; remember underline kind here
  2830.     jmp    atsctyp
  2831.  
  2832. htrsm5: cmp    al,5            ; on/off cursor?
  2833.     jne    htrsm7            ; ne = no
  2834.     cmp    modeset,0        ; on?
  2835.     je    htrsm5a            ; e = yes
  2836.     or    h19ctyp,4        ; remember off state in this bit
  2837.     jmp    atsctyp
  2838. htrsm5a:and    h19ctyp,not 4        ; set cursor on
  2839.     jmp    atsctyp
  2840.  
  2841. htrsm7: cmp    al,7            ; alternate application keypad?
  2842.     jne    htrsm9            ; ne = no
  2843.     mov    al,deckpam        ; get keypad application mode bit
  2844.     jmp    atrsflg            ; set or reset appl keypad mode
  2845.  
  2846. htrsm9: cmp    al,9            ; auto newline mode? (add cr to lf)
  2847.     jne    htrsmx            ; ne = no
  2848.     mov    al,anslnm        ; get the bit
  2849.     jmp    atrsflg            ; set or reset newline mode
  2850.  
  2851. htrsmx: ret                ; ignore the code
  2852.  
  2853. atrsflg:cmp    modeset,0        ; Want to reset
  2854.     je    atrsf1            ; Yes - reset it.
  2855.     or    ansflgs,al        ; No, set. OR in the flag
  2856.     test    al,decanm        ; Changing terminal type? [jrd]
  2857.     jz    atrsfx            ; z = no [jrd]
  2858.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode? [jrd]
  2859.     je    atrsfx            ; e = yes, don't flip terminal kinds.
  2860.     mov    flags.vtflg,ttvt100    ; say VT100 now. [jrd]
  2861.     jmp    short atrsfx
  2862. atrsf1: not    al            ; Complement
  2863.     and    ansflgs,al        ; Clear the bit
  2864.     not    al            ; recover the bit. [jrd]
  2865.     test    al,decanm        ; Changing terminal type? [jrd]
  2866.     jz    atrsfx            ; z = no
  2867.     cmp    flags.vtflg,ttheath    ; in Heath-19 mode? [jrd]
  2868.     je    atrsfx            ; e = yes, don't flip terminal kinds.
  2869.     mov    flags.vtflg,ttvt52    ; say VT52 now. [jrd]
  2870. atrsfx: push    ax
  2871.     mov    al,yflags
  2872.     call    telmsy            ; tell msy file about new state
  2873.     pop    ax
  2874.     ret
  2875.  
  2876. atrsom: cmp    modeset,0        ; Clearing DEC origin mode?
  2877.     jne    atrsom1            ; ne = no, setting
  2878.     and    ansflgs,not (decom)    ; clear the bit
  2879.     mov    dx,0            ; go to the home position
  2880.     jmp    atscu5            ; set cursor and return
  2881. atrsom1:or    ansflgs,decom        ; Set Origin mode
  2882.     mov    dx,cursor        ; Get the cursor
  2883.     mov    dl,0            ; go to right margin
  2884.     mov    dh,mar_top        ; go to home of scrolling region
  2885.     jmp    atscu5            ; Set the cursor and return
  2886.  
  2887. atrsscnm:
  2888.     cmp    modeset,0        ; Setting or resetting?
  2889.     je    atrss1            ; Do reset.
  2890.     test    ansflgs,decscnm        ; Setting. Is it set already?
  2891.     jnz    atrss3            ; Yes. Don't do it again.
  2892.     or    ansflgs,decscnm        ; No. Set it.
  2893.     or    vtemu.vtflgop,vsscreen    ; tell Status display
  2894.     or    vtflags,vsscreen    ; and our local flags
  2895.     mov    al,att_reverse        ; Want reverse video.
  2896.     jmp    short atrss2        ; Do it.
  2897.  
  2898. atrss1: test    ansflgs,decscnm        ; Resetting. Is it reset already?
  2899.     jz    atrss3            ; Yes.    Don't do it again.
  2900.     and    ansflgs,not decscnm    ; No. Clear it.
  2901.     and    vtemu.vtflgop,not vsscreen    ; tell Status display
  2902.     and    vtflags,not vsscreen    ; and our local flags
  2903.     mov    al,att_normal        ; Want normal video.
  2904.                     ; Fall through to atrss2...
  2905.  
  2906. ; Note: This is also called from the stblmds initialization routine.
  2907.  
  2908. atrss2: push    ax
  2909.     mov    scbattr,al        ; Set screen background attribute
  2910.     mov    oldbatr,al        ; update long term memory too.
  2911.     mov    ah,al            ; place where brkatt works
  2912.     call    brkatt            ; separate color and specials
  2913.     rol    ah,1            ; Reverse the reversal (sic.)
  2914.     rol    ah,1            ; Reverse the reversal (sic.)
  2915.     rol    ah,1            ; Reverse the reversal (sic.)
  2916.     rol    ah,1            ; Reverse the reversal (sic.)
  2917.     call    addatt            ; put blink/bold bits back in
  2918.     mov    mlbattr,ah        ; For mode line background
  2919.     mov    ah,curattr        ; Get current cursor attribute
  2920.     call    brkatt            ; Break it up
  2921.     rol    ah,1            ; Reverse its background
  2922.     rol    ah,1            ; Reverse its background
  2923.     rol    ah,1            ; Reverse its background
  2924.     rol    ah,1            ; Reverse its background
  2925.     call    addatt            ; Put it back together.
  2926.     mov    curattr,ah        ; And store it.
  2927.     pop    ax
  2928.     call    revscn            ; Reverse everything on the screen.
  2929. atrss3: ret
  2930.  
  2931.  
  2932. atctst: mov    al,0            ; Init test weight
  2933.     mov    di,offset atcts2    ; Routine to call
  2934.     call    atreps            ; Repeat for all parms
  2935.     test    al,80H            ; Want to reset?
  2936.     jz    atcts1            ; No - return.
  2937.     call    atreset            ; Yes - reset everything.
  2938. atcts1: ret
  2939.  
  2940. atcts2: mov    ah,ansargs[si]        ; Pick up an argument.
  2941.     cmp    ah,0            ; Zero?
  2942.     jne    atcts3            ; No - ignore others.
  2943.     or    al,80H            ; Yes - say we want reset
  2944. atcts3: ret
  2945.  
  2946.  
  2947. ; VT52 compatibility mode routines.
  2948.  
  2949. ; Return to ANSI mode.
  2950.  
  2951. v52ans: or    ansflgs,decanm        ; Turn ANSI flag back on.
  2952.     mov    flags.vtflg,ttvt100    ; Say VT100 now. [jrd]
  2953.     call    chrdef            ; Set default char sets.
  2954.     call    atsc            ; Save cursor status.
  2955.     call    disleds            ; Put "LEDs" back.
  2956.     jmp    atnorm            ; Reset state to normal and return.
  2957.  
  2958. ; Reset VT52 (does NOT cause return to VT100 mode). [jrd]
  2959.  
  2960. v52ris: call    atreset            ; Reset everything.
  2961.     call    disleds            ; Put "LEDs" back.
  2962.     ret
  2963.  
  2964. ; Enter VT52 "graphics" mode.
  2965.  
  2966. v52egm: call    chrsgs            ; Set "graphics" char set.
  2967.     jmp    atnorm            ; Reset state to normal and return.
  2968.  
  2969. ; Exit VT52 "graphics" mode.
  2970.  
  2971. v52xgm: call    chrdef            ; Set default character set.
  2972.     jmp    atnorm            ; Reset state to normal and return.
  2973.  
  2974. ; VT52 cursor positioning.
  2975.  
  2976. v52pos: mov    ttstate,offset v52pc1    ; Next state.
  2977.     ret
  2978.  
  2979. v52pc1: sub    al,' '-1        ; Minus offset.
  2980.     mov    ansargs,al        ; Stash it here.
  2981.     mov    ttstate,offset v52pc2    ; Next state.
  2982.     ret
  2983.  
  2984. v52pc2: sub    al,' '-1        ; Minus offset.
  2985.     mov    ansargs+1,al        ; Stash here.
  2986.     call    atnorm            ; Reset state to "normal".
  2987.     jmp    atcup            ; Position and return.
  2988.  
  2989. ; VT52 print controls
  2990.  
  2991. v52apb: mov    ansargs,5        ; Enter auto print mode
  2992.     or    ansflgs,decmode        ; simulate ESC [ ? 5 i
  2993.     jmp    ansprt            ; process command
  2994.  
  2995. v52ape: mov    ansargs,4        ; Exit auto print mode
  2996.     or    ansflgs,decmode        ; simulate ESC [ ? 4 i
  2997.     jmp    ansprt            ; process command
  2998.  
  2999. v52pcb: mov    ansargs,5        ; Enter printer controller on
  3000.     and    ansflgs,not decmode    ; simulate ESC [ 5 i
  3001.     jmp    ansprt            ; process command
  3002.  
  3003. v52pce: mov    ansargs,4        ; Exit printer controller on
  3004.     and    ansflgs,not decmode    ; simulate ESC [ 4 i
  3005.     jmp    ansprt            ; process command
  3006.  
  3007. v52ps:    mov    ansargs,0        ; print screen
  3008.     and    ansflgs,not decmode    ; simulate ESC [ 0 i
  3009.     jmp    ansprt            ; process command
  3010.  
  3011. v52pl:    mov    ansargs,1        ; print line
  3012.     or    ansflgs,decmode        ; simulate ESC [ ? 1 i
  3013.     jmp    ansprt            ; process command
  3014.  
  3015.                     ; Heath-19 special functions  [jrd]
  3016.  
  3017. h19ans: or    ansflgs,decanm        ; Turn on ANSI flag. ESC <
  3018.     call    chrdef            ; Set default char sets.
  3019.     jmp    atnorm            ; Reset state to normal and return.
  3020.  
  3021.                     ; do several "ESC ["  ANSI commands
  3022.                     ; but don't change terminal types
  3023. h19ansa:jmp    atcsi            ; parse ansi arguments.
  3024.  
  3025.                     ; clear screen and go home
  3026. h19clrs:mov    dx,0            ; go to upper left corner
  3027.     call    atscu5            ; do it
  3028.     mov    ax,0            ; clear screen from (0,0)
  3029.     mov    bh,byte ptr low_rgt+1    ; to lower right corner
  3030.     mov    bl,crt_cols        ; physical width
  3031.     dec    bl            ; we count from 0
  3032.     jmp    atsclr
  3033.                     ; cursor down (scrolls)
  3034. h19cud: mov    dx,cursor        ; get cursor position
  3035.     inc    dh            ; say next row down
  3036.     call    atccic            ; check position cursor (scrolls)
  3037.     mov    cursor,dx
  3038.     call    ax            ; do scrolling
  3039.     jmp    atscu5
  3040.                     ; cursor forward (right). ESC C
  3041. h19cuf: mov    dx,cursor        ; get cursor position
  3042.     inc    dl            ; move cursor right
  3043.     cmp    dl,byte ptr low_rgt    ; beyond right margin
  3044.     jb    h19cuf1            ; b = no. do it
  3045.     test    ansflgs,decawm        ; wrap mode on?
  3046.     jz    h19cuf2            ; z = no. just ignore movement
  3047.     xor    dl,dl            ; set to left margin
  3048.     inc    dh            ; and down a row
  3049.     call    atccic            ; adjust position
  3050.     call    ax            ; call scrolling routine
  3051. h19cuf1:jmp    atscu5            ; do positioning and return
  3052. h19cuf2:ret                ; just return
  3053.  
  3054.                     ; set line wrap on
  3055. h19wrap:or    ansflgs,decawm        ; turn on the flag
  3056.     jmp    atnorm
  3057.  
  3058.                     ; turn off line wrap
  3059. h19nowrp:and    ansflgs,not decawm    ; turn off the flag
  3060.     jmp    atnorm
  3061.  
  3062. h19erb: mov    bx,cursor        ; erase home to cursor, incl.
  3063.     xor    ax,ax            ; home
  3064.     jmp    atsclr            ; clear the area, cursor stays put???
  3065.  
  3066. h19erl: mov    bx,cursor        ; erase whole line
  3067.     mov    ax,bx            ; get row
  3068.     xor    al,al            ; column 0
  3069.     mov    bl,crt_cols        ; physical width
  3070.     dec    bl            ; we count from 0
  3071.     jmp    atsclr            ; erase whole line, cursor stays put
  3072.  
  3073. h19ero: mov    bx,cursor        ; erase start of line to cursor
  3074.     mov    ax,bx
  3075.     xor    al,al            ; start in column 0
  3076.     jmp    atsclr            ; clear that part of line
  3077.  
  3078. h19herv:cmp    video_state,0        ; is video normal? ESC p
  3079.     jne    h19hrv1            ; ne = no, reversed already, ignore
  3080.     mov    ah,curattr        ; current cursor attributes
  3081.     call    brkatt            ; breakup attributes byte
  3082.     rol    ah,1            ; reverse foreground to background
  3083.     rol    ah,1
  3084.     rol    ah,1
  3085.     rol    ah,1
  3086.     call    addatt            ; put things together again
  3087.     mov    curattr,ah        ; and store it
  3088.     mov    video_state,1        ; say we are reversed
  3089. h19hrv1:ret
  3090.  
  3091. h19hxrv:cmp    video_state,0        ; is video normal? ESC q
  3092.     je    h19hxr1            ; e = yes, so just ignore
  3093.     mov    ah,curattr        ; current cursor attributes
  3094.     call    brkatt            ; breakup attributes byte
  3095.     rol    ah,1            ; reverse foreground to background
  3096.     rol    ah,1
  3097.     rol    ah,1
  3098.     rol    ah,1
  3099.     call    addatt            ; put things together again
  3100.     mov    curattr,ah        ; and store it
  3101.     mov    video_state,0        ; say we are normal
  3102. h19hxr1:ret
  3103.  
  3104. h19mbr: mov    ttstate,offset hmbr    ; Modify baud rate ESC r char
  3105.     ret                ; setup to parse next char
  3106. hmbr:    jmp    atnorm            ; discard char (in al)
  3107.  
  3108. htsc:    cmp    flags.vtflg,ttheath    ; Heath-19? ESC [ s
  3109.     jne    htscx            ; ne = no, ignore
  3110.     call    atsc            ; store cursor position and attr.
  3111. htscx:    jmp    atnorm            ; reset state & return
  3112.  
  3113. htrc:    cmp    flags.vtflg,ttheath    ; Heath-19? ESC [ u
  3114.     jne    htrcx            ; ne = no, ignore
  3115.     call    atrc            ; restore cursor pos and attr.
  3116. htrcx:    jmp    atnorm            ; reset state & return
  3117.  
  3118.                     ; Heath-19 set mode "ESC x "
  3119. h19smod:mov    ttstate,offset hsmod    ; setup to parse rest of seq
  3120.     ret
  3121.  
  3122. hsmod:    mov    modeset,1        ; say set mode
  3123.     mov    ttstate,offset atnrm
  3124.     sub    al,'0'            ; remove ascii bias
  3125.     jmp    htrsm1            ; perform mode set
  3126.  
  3127. h19cmod:mov    ttstate,offset hcmod    ; setup to parse rest of seq
  3128.     ret
  3129.  
  3130. hcmod:    mov    modeset,0        ; say reset mode
  3131.     mov    ttstate,offset atnrm
  3132.     sub    al,'0'            ; remove ascii bias
  3133.     jmp    htrsm1            ; perform mode reset
  3134.  
  3135. htrest: cmp    flags.vtflg,ttheath    ; Heath-19? ESC [ z
  3136.     jne    htrestx            ; ne = no, ignore
  3137.     call    atreset            ; do a hard reset
  3138. htrestx:jmp    atnorm            ; reset state and return
  3139.  
  3140. hrcup:    mov    al,escape        ; send "ESC Y row col" cursor report
  3141.     call    prtbout            ; send with no local echo
  3142.     mov    al,'Y'
  3143.     call    prtbout
  3144.     mov    al,byte ptr cursor+1    ; get row
  3145.     add    al,' '            ; add ascii bias
  3146.     call    prtbout            ; send it
  3147.     mov    al,byte ptr cursor    ; get column
  3148.     add    al,' '            ; add ascii bias
  3149.     call    prtbout            ; and send it too
  3150.     jmp    atnorm            ; return to terminal mode
  3151.  
  3152.                     ; Heath-19 and VT102 additions [jrd]
  3153.  
  3154. inslin: cmp    ansargs,0        ; insert line(s). Any args? [jrd]
  3155.     jne    insli1            ; ne = yes. If no arg use 1
  3156.     mov    ansargs,1        ; insert one line.
  3157. insli1: mov    dx,cursor        ; current position
  3158.     cmp    dh,mar_bot        ; below bottom margin?
  3159.     jae    insli3            ; ae = at or below bottom margin
  3160.     push    word ptr mar_top
  3161.     mov    mar_top,dh        ; call present position the top
  3162.     push    cx            ; save a reg
  3163.     mov    cl,ansargs        ; get repeat count
  3164.     xor    ch,ch            ; clear high byte
  3165. insli2: call    atscrd            ; scroll down
  3166.     loop    insli2            ; repeat until done (cx times)
  3167.     pop    cx            ; restore reg
  3168.     pop    word ptr mar_top    ; restore margins
  3169.     xor    dl,dl            ; go to left margin
  3170.     jmp    atscu5            ; reposition cursor and return
  3171. insli3: ret
  3172.  
  3173. dellin: cmp    ansargs,0        ; delete line(s). Any args? [jrd]
  3174.     jne    delli1            ; no arg; use 1
  3175.     mov    ansargs,1        ; insert one line.
  3176. delli1: mov    dx,cursor        ; where we are presently
  3177.     cmp    dh,mar_bot        ; at or below bottom margin?
  3178.     jae    delli3            ; ae = yes.
  3179.     push    word ptr mar_top    ; save current scrolling margins
  3180.     mov    mar_top,dh        ; temp top margin is here
  3181.     push    cx            ; save a reg
  3182.     mov    cl,ansargs        ; get repeat count
  3183.     xor    ch,ch            ; clear high byte
  3184. delli2: call    atscru            ; scroll up
  3185.     loop    delli2            ; repeat until done (cx times)
  3186.     pop    cx            ; restore reg
  3187.     pop    word ptr mar_top    ; restore scrolling margins.
  3188.     jmp    atscu5            ; restore cursor and return
  3189. delli3: ret
  3190.  
  3191.                     ; Delete character(s)
  3192. atdelc: cmp    ansargs,0        ; zero becomes one operation
  3193.     jne    atdelc1
  3194.     mov    ansargs,1        ; delete one char. Heath ESC N
  3195. atdelc1:mov    cl,byte ptr low_rgt    ; number of columns on screen.
  3196.     mov    dx,cursor        ; get present cursor position
  3197.     push    bx
  3198.     mov    bl,dh            ; get row
  3199.     mov    bh,0
  3200.     cmp    linetype [bx],0        ; single width line?
  3201.     je    atdelc5            ; e = yes
  3202.     shl    dl,1            ; double the column number
  3203.     mov    bl,ansargs
  3204.     shl    bl,1            ; double # chars to delete
  3205.     mov    ansargs,bl
  3206. atdelc5:pop    bx
  3207.     test    usevb,1            ; video board in use?
  3208.     jz    atdelv1            ; z = no
  3209.     sub    cl,dl            ; end of screen - current column #
  3210.     xor    ch,ch            ; cx = number of chars to move
  3211.     cmp    cx,0            ; zero means just this char
  3212.     ja    atdelc4
  3213.     inc    cx            ; say one, this one
  3214. atdelc4:push    es
  3215.     push    cx            ; save word count for Topview
  3216.     cld
  3217.     call    scrloc            ; compute current cursor location
  3218.     mov    di,ax            ; temporary storage places
  3219.     mov    si,ax
  3220.     mov    al,ansargs        ; get delete count
  3221.     xor    ah,ah            ; clear high byte of delete count
  3222.     cmp    al,cl            ; clear more than rest of line?
  3223.     jb    atdelc2            ; b = no. some chars left at end
  3224.     mov    al,cl            ; say delete all to right, inclusive
  3225. atdelc2:cmp    al,0            ; zero?
  3226.     jne    atdelc3
  3227.     inc    al            ; none or 0 impiles one.
  3228. atdelc3:shl    ax,1            ; double: char and its attribute byte
  3229.     push    di            ; destination offset
  3230.     add    ax,si            ; src offset = dest + # deleted words
  3231.     push    ax            ; save it
  3232.     call    scroff
  3233.     call    scrseg            ; pick up screen segment
  3234.     mov    si,di            ; align memory addresses
  3235.     pop    ax            ; recover source offset
  3236.     add    si,ax            ; add to starting memory address
  3237.     pop    ax            ; recover destination offset
  3238.     add    di,ax            ; add to destination memory address
  3239.     push    ds            ; save ds around the move
  3240.     push    es            ; move es into ds to
  3241.     pop    ds            ; make ds point to screen memory too
  3242.     rep    movsw
  3243.     pop    ds            ; recover normal ds
  3244.     pop    cx            ; count for Topview
  3245.     call    scrsync            ; synch Topview
  3246.     pop    es
  3247.     call    scron
  3248.     jmp short atdelv2
  3249. ;            modify to use Sanyo bios sideways shift [begin jhw]
  3250. ;                (can't write to video RAM)
  3251. atdelv1:mov    al,ansargs        ; no. of positions to shift
  3252.     mov    ah,73h            ; Sanyo bios sideways scroll
  3253.     mov    cx,dx            ; cursor position -- now
  3254.     mov    dl,79            ; end of line coord. in dx
  3255.     mov    bh,scbattr        ; attribute for cleared position
  3256.     int    screen            ;            [end jhw]
  3257. atdelv2:
  3258.     mov    ax,cursor        ; get current row
  3259.     mov    bx,cursor
  3260.     mov    bl,byte ptr low_rgt    ; last col on screen
  3261.     mov    al,bl
  3262.     sub    al,ansargs        ; minus number of locations cleared
  3263.     inc    al
  3264.     call    atsclr            ; clear end of line
  3265. atdelcx:mov    dx,cursor
  3266.     jmp    atscu5            ; reposition cursor
  3267.  
  3268. inschr: mov    dx,cursor        ; open one char space in current line
  3269.     test    usevb,1            ; video board in use?
  3270.     jnz    insv1            ; nz = yes
  3271.     push    ax            ;
  3272.     mov    al,1            ; shift one space (for use later)
  3273. insv1:
  3274.     push    bx
  3275.     mov    bl,dh            ; get row
  3276.     mov    bh,0
  3277.     cmp    linetype [bx],0        ; single width line?
  3278.     je    insch2            ; e = yes
  3279.     shl    dl,1            ; double the column number
  3280.     test    usevb,1            ; video board in use?
  3281.     jnz    insv2            ; nz= yes
  3282.     mov    al,2            ; and the number of cols to shift
  3283. insv2:
  3284. insch2: pop    bx
  3285.     mov    ch,0
  3286.     mov    cl,byte ptr low_rgt    ; number of columns on screen
  3287.     push    dx
  3288.     mov    dh,0
  3289.     sub    cx,dx            ; compute distance to end
  3290.     pop    dx
  3291.     or    cx,cx
  3292.     jle    insch1            ; le = nothing to move... [dlk]
  3293.     test    usevb,1            ; video board in use?
  3294.     jz    insv3            ; z = no
  3295.     mov    dl,byte ptr low_rgt
  3296.     dec    dl            ; last col to move
  3297.     push    ax            ; save regs
  3298.     push    es            ; ditto
  3299.     push    cx            ; save count for Topview
  3300.     call    scrloc            ; compute position of end of line-1
  3301.     push    ax            ; save offset
  3302.     std                ; remember to move backward
  3303.     call    scroff            ; turn off color screen
  3304.     call    scrseg            ; get memory address in es:di
  3305.     pop    ax            ; recover offset
  3306.     add    di,ax            ; source memory address
  3307.     mov    si,di            ; align addresses. destination
  3308.     add    di,2            ;   is one char over
  3309.     push    di
  3310.     push    ds            ; save ds around move
  3311.     push    es            ; put es into ds
  3312.     pop    ds            ;   ds points to screen memory too
  3313.     rep    movsw
  3314.     pop    ds            ; recover normal ds
  3315.     cld                ; reset direction to be forward
  3316.     pop    di
  3317.     pop    cx            ; count for Topview
  3318.     call    scrsync            ; synch Topview
  3319.     pop    es            ; restore regs
  3320.     pop    ax            ; ditto
  3321.     call    scron            ; turn on screen again
  3322.     cld                ; reset direction
  3323.     jmp short insv4
  3324. ;                use bios calls since Sanyo can't write
  3325. ;                    to video RAM    [begin jhw]
  3326. insv3:    mov    ah,72h            ; Sanyo sideways bios scroll
  3327.     mov    cx,dx            ; set left end of scroll region
  3328.     mov    dl,79            ; set right end
  3329.     mov    bh,scbattr        ; attributes of cleared region
  3330.     int    screen            ; [end jhw]
  3331. insv4:
  3332. insch1: mov    dx,cursor
  3333.     test    usevb,1            ; video board in use?
  3334.     jnz    insv5            ; nz = yes
  3335.     pop    ax            ; [jhw]
  3336. insv5:
  3337.     jmp    atscu5            ; position cursor
  3338.  
  3339. noins:    mov    insmod,0        ; turn off insert mode
  3340.     jmp    atnorm            ; and return
  3341.  
  3342. entins: mov    insmod,0ffh        ; enter insert mode...
  3343.     jmp    atnorm            ; and return
  3344.  
  3345. ansich    proc    near            ; ANSI insert characters ESC [     @
  3346.     cmp    ansargs,0        ; any arguments?
  3347.     jne    ansic1            ; ne = no, ignore
  3348.     mov    ansargs,1        ; use one
  3349. ansic1: push    dx            ; save cursor
  3350.     mov    insmod,1        ; enter insert mode
  3351.     push    cx
  3352.     mov    cl,ansargs        ; get count of inserts
  3353.     mov    ch,0
  3354.     push    ax            ; save char
  3355. ansic2: push    cx            ; save counter
  3356.     mov    al,' '            ; character to write
  3357.     call    atnrm            ; do display
  3358.     pop    cx            ; recover counter
  3359.     loop    ansic2            ; do cx times
  3360.     pop    ax            ; restore char
  3361.     pop    cx
  3362.     mov    insmod,0        ; turn off insert mode
  3363.     pop    dx            ; get original cursor
  3364.     jmp    atscu5            ; set cursor
  3365. ansich    endp
  3366.  
  3367. ; routines supporting scrolling and double width/height chars [jrd]
  3368.  
  3369. atscru    proc    near            ; scroll screen up one line
  3370.     push    ax            ; assumes dx holds cursor position
  3371.     push    bx            ; returns with dx = old row, new col
  3372.     push    cx
  3373.     xor    ch,ch
  3374.     mov    cl,mar_bot        ; bottom line to move
  3375.     xor    bh,bh
  3376.     mov    bl,mar_top        ; top line to move
  3377.     sub    cx,bx            ; cx = number of lines to move
  3378.     jcxz    atscru2            ; cx = 0. nothing to do
  3379. atscru1:mov    al,linetype[bx+1]
  3380.     mov    linetype[bx],al        ; move line types up one line
  3381.     inc    bx
  3382.     loop    atscru1
  3383.     mov    linetype[bx],0        ; clear new line's type
  3384.                     ; reindex column of cursor
  3385.     cmp    linetype[bx-1],0    ; was old bottom line double wide?
  3386.     je    atscru2            ; e = no
  3387.     shr    dl,1            ; reindex to single wide columns
  3388. atscru2:pop    cx
  3389.     pop    bx
  3390.     pop    ax
  3391.     test    anspflg,vtcntp        ; controller print active?
  3392.     jz    atscru3            ; z = no, ok to change screen
  3393.     ret                ;  else keep screen intact
  3394. atscru3:jmp    vtscru            ; call & ret the msy scroll routine
  3395. atscru    endp
  3396.  
  3397. atscrd    proc    near            ; scroll screen down one line
  3398.     push    ax            ; assumes dx holds cursor position
  3399.     push    bx            ; returns with dx = old row, new col
  3400.     push    cx
  3401.     xor    ch,ch
  3402.     mov    cl,mar_top        ; top line to move
  3403.     xor    bh,bh
  3404.     mov    bl,mar_bot        ; bottom line to move
  3405.     sub    cx,bx
  3406.     neg    cx            ; cx = number of lines to move
  3407.     jcxz    atscrd2            ; cx = 0. nothing to do
  3408. atscrd1:mov    al,linetype[bx-1]
  3409.     mov    linetype[bx],al        ; move line types down one line
  3410.     dec    bx
  3411.     loop    atscrd1
  3412.     mov    linetype[bx],0        ; clear new line's type
  3413.                     ; reindex column of cursor
  3414.     cmp    linetype[bx+1],0    ; was old top line double wide?
  3415.     je    atscrd2            ; e = no
  3416.     shr    dl,1            ; reindex to single wide columns
  3417. atscrd2:pop    cx
  3418.     pop    bx
  3419.     pop    ax
  3420.     test    anspflg,vtcntp        ; controller print active?
  3421.     jz    atscrd3            ; z = no, ok to change screen
  3422.     ret                ;  else keep screen intact
  3423. atscrd3:jmp    vtscrd            ; call & ret the msy scroll routine
  3424. atscrd    endp
  3425.  
  3426. linesgl proc    near            ; convert line to single width char
  3427.     push    ax
  3428.     push    bx
  3429.     push    cx
  3430.     push    dx
  3431.     mov    bx,cursor
  3432.     mov    bl,bh
  3433.     xor    bh,bh            ; bx now holds row
  3434.     cmp    linetype [bx],0        ; is line already single width?
  3435.     je    linsglx            ; e = yes
  3436.     mov    linetype [bx],0        ; say will be single now.
  3437.     call    scroff            ; turn off video
  3438.     mov    dx,cursor
  3439.     mov    dl,0            ; start in column 0
  3440.     mov    cx,40            ; number of columns to do
  3441. linsgl1:push    cx            ; save loop counter
  3442.     shl    dl,1            ; double column number
  3443.     mov    ah,2            ; set cursor
  3444.     xor    bh,bh            ; page 0
  3445.     int    screen
  3446.     mov    ah,8            ; read char and attribute
  3447.     int    screen
  3448.     push    ax            ; save char and attribute
  3449.     shr    dl,1            ; restore column
  3450.     mov    ah,2            ; set cursor
  3451.     int    screen
  3452.     pop    ax            ; recover char and attribute
  3453.     mov    bl,ah            ; set attribute
  3454.     mov    cx,1            ; one char
  3455.     mov    ah,9            ; write char and attribute
  3456.     int    screen
  3457.     inc    dl            ; next column
  3458.     pop    cx
  3459.     loop    linsgl1
  3460.     mov    cx,40
  3461.     mov    dl,40
  3462.     mov    ah,2            ; set cursor
  3463.     int    screen
  3464.     mov    bl,scbattr        ; screen background
  3465.     mov    al,' '
  3466.     mov    ah,9            ; write char
  3467.     int    screen            ; write 40 spaces
  3468.     call    scron            ; turn on the video
  3469. linsglx:pop    dx
  3470.     pop    cx
  3471.     pop    bx
  3472.     pop    ax
  3473.     jmp    atscur            ; update cursor and return
  3474. linesgl endp
  3475.  
  3476. linedbl proc    near            ; convert line to double width char
  3477.     push    ax            ; must reset physical cursor
  3478.     push    bx            ; to same char as before expansion
  3479.     push    cx            ; but does not modify variable cursor
  3480.     push    dx
  3481.     mov    bx,cursor
  3482.     mov    bl,bh
  3483.     xor    bh,bh            ; bx now holds row
  3484.     cmp    linetype [bx],0        ; is line single width?
  3485.     jne    lindblx            ; ne = no. nothing to do
  3486.     mov    linetype [bx],1        ; say will be double width now.
  3487.     mov    dx,cursor
  3488.     mov    dl,39            ; start with col 39
  3489.     mov    cx,40
  3490.     call    scroff            ; turn off the video
  3491. lindbl1:push    cx            ; save loop counter
  3492.     mov    ah,2            ; set cursor
  3493.     mov    bh,0            ; page 0
  3494.     int    screen
  3495.     mov    ah,8            ; read char and attribute
  3496.     int    screen
  3497.     push    ax            ; save char and attribute
  3498.     shl    dl,1            ; double the column number
  3499.     mov    ah,2            ; set cursor
  3500.     int    screen
  3501.     pop    ax            ; recover char and attribute
  3502.     mov    bl,ah            ; set attribute
  3503.     mov    cx,1            ; one char
  3504.     mov    ah,9            ; write char and attribute
  3505.     int    screen
  3506.     inc    dl            ; move to second column of double.
  3507.     mov    ah,2            ; set cursor
  3508.     int    screen
  3509.     mov    al,' '            ; space as filler
  3510.     mov    ah,9            ; write that char
  3511.     int    screen
  3512.     dec    dl
  3513.     shr    dl,1
  3514.     dec    dl
  3515.     pop    cx
  3516.     loop    lindbl1
  3517.     call    scron            ; turn on the video
  3518. lindblx:pop    dx
  3519.     pop    cx
  3520.     pop    bx
  3521.     pop    ax
  3522.     jmp    atscur            ; update the cursor and return
  3523. linedbl endp
  3524.  
  3525. anstty    endp
  3526.  
  3527. ansprt    proc near            ; printer support routines. [jrd]
  3528.     cmp    ansargs,0        ; 0 (print all/part of screen)?
  3529.     jne    ansprt1            ; ne = no
  3530.     call    pntchk            ; check printer
  3531.     jc    ansprtx            ; c = printer not ready
  3532.     call    pntext            ; do whole screen or scrolling extent
  3533.     jmp    atscu5            ; reposition cursor and return
  3534.  
  3535. ansprt1:cmp    ansargs,1        ; 1 (print current line)?
  3536.     jne    ansprt4            ; ne = no
  3537.     call    pntchk            ; check for printer ready
  3538.     jc    ansprtx            ; c = printer not ready
  3539.     call    pntlin            ; print current line
  3540. anspr1a:jmp    atscu5            ; reposition cursor and return
  3541.  
  3542. ansprt4:cmp    ansargs,4        ; auto print disable?
  3543.     jne    ansprt5            ; ne = no
  3544.     test    ansflgs,decmode        ; was it ESC [ ? 4 i
  3545.     jz    anspr4a            ; z = no, so it was ESC [ 4 i
  3546.     test    anspflg,vtautop        ; check state of print flag
  3547.     jz    anspr4a            ; z = off already
  3548.     call    trnprs            ; toggle mode line PRN indicator
  3549.     and    anspflg,not vtautop    ; auto-print disable
  3550. anspr4a:jmp    ansprtx
  3551.  
  3552. ansprt5:cmp    ansargs,5        ; auto print enable?
  3553.     jne    ansprtx            ; ne = no
  3554.     call    pntchk            ; check printer, ignore carry ret
  3555.     jc    ansprtx            ; c = printer not ready
  3556.     test    ansflgs,decmode        ; was it ESC [ ? 5 i
  3557.     jz    anspr5a            ; z = no
  3558.     test    anspflg,vtautop        ; is print already enabled?
  3559.     jnz    ansprtx            ; nz = yes, leave trnprs intact
  3560.     call    trnprs            ; toggle on mode line PRN indicator
  3561.     or    anspflg,vtautop        ; auto-print enabled
  3562.     jmp    short ansprtx
  3563. anspr5a:or    anspflg,vtcntp        ; controller print enabled
  3564. ansprtx:jmp    atnorm
  3565. ansprt    endp
  3566.  
  3567. ; State machine active while Media Copy On (Print Controller ON). Copies all
  3568. ; chars to the printer until (and excluding) Media Copy Off (ESC [ 4 i) has
  3569. ; been received or the emulator reset. New char is in al. 6 March 1987 [jrd]
  3570.  
  3571. ansmc    proc    near
  3572.     mov    ah,al            ; copy active character
  3573.     and    ah,7fh            ; strip high bit
  3574.     cmp    ah,byte ptr mcoff    ; start of MC Off sequence?
  3575.     jne    ansmc1            ; ne = no
  3576.     call    ansmc4            ; playback previously matched chars
  3577.     mov    mccnt,1            ; count matched chars (one now)
  3578.     mov    mcoffs,al        ; save full character, with high bit
  3579.     jmp    short ansmcx        ;  and exit
  3580.  
  3581. ansmc1: push    bx            ; check for char in MC Off sequence
  3582.     mov    bx,mccnt        ; number of chars matched in MC Off
  3583.     mov    mcoffs[bx],al        ; save this char, with high bit
  3584.     cmp    ah,byte ptr mcoff[bx]    ; match expected char in sequence?
  3585.     pop    bx
  3586.     jne    ansmc3            ; ne = no, play back partial match
  3587.     inc    mccnt            ; count new match
  3588.     cmp    mccnt,mcofflen        ; matched all char in sequence?
  3589.     jne    ansmcx            ; ne = not yet, wait for more
  3590.     and    anspflg,not vtcntp    ; yes, disable print controller
  3591.     mov    mccnt,0            ; clear counter
  3592.     jmp    short ansmcx        ;  all done
  3593.  
  3594. ansmc3: call    ansmc4            ; playback previously matched chars
  3595.     call    pntchr            ; print current char, ignore errors
  3596.     mov    mccnt,0            ; reset to no match and exit
  3597. ansmcx: ret                ; common exit
  3598.  
  3599.                     ; local worker procedure
  3600. ansmc4: push    ax            ; save break char (in al)
  3601.     push    cx            ; playback partial sequence to printer
  3602.     mov    cx,mccnt        ; number of chars matched before break
  3603.     jcxz    ansmc4b            ; z = none
  3604.     push    si
  3605.     mov    si,offset mcoffs    ; string to be played back
  3606.     cld
  3607. ansmc4a:lodsb                ; get a char into al
  3608.     call    pntchr            ; print it, ignore errors
  3609.     loop    ansmc4a            ; do all that came in previously
  3610.     pop    si
  3611. ansmc4b:pop    cx
  3612.     pop    ax            ; recover break char
  3613.     ret
  3614. ansmc    endp
  3615.  
  3616. ; Check for PRN (DOS's printer) being ready. If ready, return with C clear.
  3617. ; Otherwise, write Not Ready msg on mode line and return with C bit set.
  3618. ; N.B. DOS Critical Error will occur here if PRN is not ready.    [jrd]
  3619. pntchk    proc    near
  3620.     push    dx
  3621.     push    cx
  3622.     push    ax
  3623.     mov    cx,10            ; ten retries before declaring error
  3624. pntchk0:mov    ah,ioctl        ; get printer status, via DOS
  3625.     mov    al,7            ; status for output
  3626.     push    bx
  3627.     mov    bx,4            ; std handle for system printer
  3628.     int    dos
  3629.     pop    bx
  3630.     jc    pntchk1            ; c = call failed
  3631.     cmp    al,0ffh            ; code for Ready
  3632.     je    pntchk3            ; e = yes, assume printer is ready.
  3633. pntchk1:push    cx            ; save counter, just in case
  3634.     mov    ax,100            ; wait 100 millisec
  3635.     call    pcwait
  3636.     pop    cx
  3637.     loop    pntchk0            ; and try a few more times
  3638.     test    yflags,modoff        ; is mode line off?
  3639.     jnz    pntchk2            ; nz = off, skip msg
  3640.     push    bx
  3641.     push    si
  3642.     mov    si,offset pntmsg    ; say printer not ready
  3643.     mov    cx,pntmsgl        ; length
  3644.     call    modwrt            ; write alternate mode line, in msy
  3645.     pop    si
  3646.     pop    bx
  3647. pntchk2:pop    ax
  3648.     pop    cx
  3649.     pop    dx
  3650.     stc                ; say printer not ready
  3651.     ret
  3652. pntchk3:pop    ax
  3653.     pop    cx
  3654.     pop    dx
  3655.     clc                ; say printer is ready
  3656.     ret
  3657. pntchk    endp
  3658.  
  3659. ; Print on PRN the char in register al. On success return with C bit clear.
  3660. ; On failure call procedure pntchk and return its C bit (typically C set).
  3661. pntchr    proc    near
  3662.     push    dx
  3663.     push    ax
  3664.     mov    ah,lstout        ; uses file handle 4
  3665.     mov    dl,al
  3666.     int    dos
  3667.     pop    ax
  3668.     pop    dx
  3669.     jnc    pntchr2            ; nc = success
  3670.     call    pntchk            ; c = error (printer not ready)
  3671. pntchr2:ret
  3672. pntchr    endp
  3673.  
  3674. pntlin    proc    near            ; print whole line given by dx
  3675.     push    ax
  3676.     push    bx
  3677.     push    cx
  3678.     push    dx
  3679.     xor    dl,dl            ; start in column 0
  3680.     xor    ch,ch
  3681.     mov    cl,byte ptr low_rgt    ; number of columns
  3682.     mov    dl,cl            ; Bios column counter
  3683.     inc    cl            ; actual line length, count it down
  3684. pntlin1:mov    ah,2            ; set cursor
  3685.     xor    bh,bh            ; page 0
  3686.     int    screen
  3687.     mov    ah,8            ; read char (al) and attribute (ah)
  3688.     int    screen
  3689.     cmp    al,' '            ; is this a space?
  3690.     jne    pntlin2            ; no, we have the end of the line
  3691.     dec    dl            ; else move left one column
  3692.     loop    pntlin1            ; and keep looking for non-space
  3693.  
  3694. pntlin2:jcxz    pntlin4            ; z = empty line
  3695.     xor    dl,dl            ; start in column 0, do cl chars
  3696. pntlin3:mov    ah,2            ; set cursor
  3697.     xor    bh,bh            ; page 0
  3698.     int    screen
  3699.     mov    ah,8            ; read char and attribute
  3700.     int    screen
  3701.     inc    dl            ; inc to next column
  3702.     call    pntchr            ; print the char (in al)
  3703.     jc    pntlin5            ; c = printer error
  3704.     loop    pntlin3            ; do cx columns
  3705. pntlin4:mov    al,cr            ; add trailing cr/lf for printer
  3706.     call    pntchr
  3707.     jc    pntlin5
  3708.     mov    al,lf
  3709.     call    pntchr
  3710. pntlin5:pop    dx
  3711.     pop    cx
  3712.     pop    bx
  3713.     pop    ax
  3714.     ret                ; C bit controlled by pntchr
  3715. pntlin    endp
  3716.  
  3717. pntext    proc    near            ; print an extent of lines, depending
  3718.     push    ax            ; on flag bit vtextp.
  3719.     push    bx
  3720.     push    dx
  3721.     xor    dx,dx            ; assume starting at top left
  3722.     mov    bx,low_rgt        ;  and extending to lower right
  3723.     test    anspflg,vtextp        ; full screen wanted?
  3724.     jnz    pntext1            ; nz = yes, else scrolling region
  3725.     mov    dh,mar_top        ; top of scrolling region
  3726.     mov    bh,mar_bot        ; bottom of scrolling region
  3727. pntext1:call    pntlin            ; print a line
  3728.     jc    pntext2            ; c = printer error
  3729.     inc    dh
  3730.     cmp    dh,bh            ; done all requested lines?
  3731.     jbe    pntext1            ; be = not yet, do another
  3732.     test    anspflg,vtffp        ; form feed needed at end?
  3733.     jz    pntext2            ; z = no.
  3734.     mov    al,ff
  3735.     call    pntchr            ; print the form feed char
  3736. pntext2:pop    dx
  3737.     pop    bx
  3738.     pop    ax
  3739.     ret
  3740. pntext    endp
  3741.  
  3742. code    ends
  3743.  
  3744. if1
  3745.     %out [End of pass 1]
  3746. else
  3747.     %out [End of assembly]
  3748. endif
  3749.  
  3750.     end
  3751.