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