home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msk230s2.zip / MSZIBM.ASM < prev   
Assembly Source File  |  1988-02-12  |  183KB  |  3,627 lines

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