home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msggri.asm < prev    next >
Assembly Source File  |  2020-01-01  |  50KB  |  1,509 lines

  1.     Name msggri
  2. ; File MSGIBM.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1991, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; Tektronix emulator for use with MS Kermit/IBM.
  9. ; Edit history:
  10. ; 2 March 1991 version 3.10
  11. ; John Nyenhuis      Purdue University  School of Electrical Engineering
  12. ; West Lafayette IN 47907   (317)494-3524     nyenhuis@ee.ecn.purdue.edu
  13. ; November 1988
  14. ; Modify msgibm.asm to work with the GRiD Compass II
  15. ; Functionality is same as for IBM except for the more message in OUTSCRN
  16. ;
  17. ; Last edit 22 May 1988
  18. ; 1 July 1988 Version 2.31
  19. ; 22 May 1988 Add support for ESC [ Pn ; Pn m (ANSI) screen coloring.
  20. ; 22 March 1988 Add global byte Tekgraf which forces graphics board type
  21. ;   0=auto-sensing, 1=cga, 2=ega, 3=VGA, 4=Hercules, 5=ATT. Tekgraf stored
  22. ;   here and set in file MSX by Set Term Graphics <board type>. Permit chars
  23. ;   to overlap existing pixels. [jrd]
  24. ; 27 Feb 1988 Add tests for Toshiba T3100 (tnx for assist from Rob Preuss),
  25. ;   for Olivetti M28/AT&T 6300+, and for DEC VAXmate II (tnx to Frank da Cruz)
  26. ;   Add pointer based dispatch to character-font drawing routine. Add tests
  27. ;   for stdin being a file rather than a device (keyboard). [jrd]
  28. ; 27 Jan 1988 Supress GIN and Status echos with Bypass byte. Bypass is reset
  29. ;  by receipt of BEL, LF, CR, US, escape sequences, terminal reset.
  30. ;  Bypass is set by receipt of ESC Control-E, ESC Control-X, ESC Control-Z.
  31. ;  Make GIN mode crosshairs remember last GIN mode postion until the terminal
  32. ;  is reset; make major steps smaller. Add ESC query-mark stands for DEL.
  33. ;  Make Horizontal Tab (Control-I) a non-printing cursor control character
  34. ;  to move right one column (with line wrap). Let real Hercules boards use
  35. ;  both pages of memory (clones behave differently), tnx to Daniel Gruner.
  36. ; 1 Jan 1988 version 2.30
  37. ; 31 Dec 1987 change name from msvibm to msgibm for final release. [jrd]
  38. ; 29 Dec 1987 Add ESC [ ? 3 8 l     as exit Tek mode command, from VT340's.[jrd]
  39. ; 26 Dec 1987 Add test to absorb echo of crosshairs report. [jrd]
  40. ; 22 Dec 1987 Revise parsing rules to make an escape sequence be a temporary
  41. ;  interruption to the current command (except Clear Screen seq). [jrd]
  42. ; Add Control-C and Control-Break as non-reporting exits from GIN mode. [jrd]
  43. ; 21 Dec 1987 Add AT&T 6300, Olivetti M24 presence tests and run code. [jrd]
  44. ; 16 Dec 1987 Correct screen coloring for 64KB mono/med res color egas. [jrd]
  45. ; 4 Dec 1987 Add quirks for Environments, such as TopView, Windows. [jrd]
  46. ; 3 Dec 1987 Let 128KB EGA boards save screens. [jrd]
  47. ; 30 Nov 1987 Add relative plotting, thanks to help from Bob Parks. [jrd]
  48. ; 24 Nov 1987 Add dashed line patterns. [jrd]
  49. ; 21 Nov 1987 Add full color background. [jrd]
  50. ; 15 Nov 1987 Do screen clears manually because a Bios mode-set keeps
  51. ;  interrupts off long enough to miss serial port characters. Make crosshairs
  52. ;  smaller. [jrd]
  53. ; 8 Nov 1987 Modularize line drawing using Bresneham's algorithm, use pointers
  54. ;  to action routines for different board types. Add screen save/restore.
  55. ;  Do display board presence tests. Add FS as point plot introducer. Allow
  56. ;  for virtual screens when operating under Environments (Windows, etc). [jrd]
  57. ; 1 Nov 1987 Heavy rewrite to integrate code into regular MS Kermit/IBM
  58. ;  material. [jrd]
  59. ;==============================================================================
  60. ; Original version for TI Pro computers by
  61. ; 12-Dec-84  Joe Smith, CSM Computing Center, Golden CO 80401
  62. ; adapted to IBM PC June 1987 by    Brian Holley,
  63. ;                    Faculty of Economics and Politics
  64. ;                    University of Cambridge, England
  65. ;                    Email: BJH6@UK.AC.CAM.PHX
  66. ; Upgraded and integrated into MS Kermit 2.30 by Joe Doupnik, Utah State Univ.
  67. ;
  68. ;           Description of Tektronix commands
  69. ;
  70. ; ESCAPE-CONTROL-E (ENQ) requests a status report
  71. ; ESCAPE-FORMFEED erases the screen.
  72. ; ESCAPE-CONTROL-X turns on bypass mode (no screen characters).
  73. ; ESCAPE-CONTROL-Z turns on the crosshairs (not on 4006 or 4025)
  74. ; ESCAPE-? is replaced by DEL code, to assist line plots with 7 bit systems.
  75. ; ESCAPE [ Pn ; Pn m  set screen colors. Pn = 30 + sum of colors for foregnd,
  76. ;  40 + sum of colors for background, Pn = 0 sets b/w, Pn = 1 for high
  77. ;  intensity. Colors are red = 1, green = 2, blue = 4.
  78. ; ESCAPE [ ? 3 8 l  exits Tek mode and returns to host text terminal type
  79. ;  (VT102 if none defined yet). This is an extension from DEC VT340's.
  80. ; CONTROL-] (GS) turns on plot mode, the first move will be with beam off.
  81. ; CONTROL-^ (RS) turns on incremental plot mode. RS space means move pen up
  82. ;  RS P means move pen down, following letters:A, E, D, F, B, J, H, I mean
  83. ;  move right, right and up, up, left and up, left, left and down, down, and
  84. ;  right and down, respectively. Ex: RS <space> J J J  means move three Tek
  85. ;  positions left and down with the pen up (invisibly).
  86. ; CONTROL-UNDERLINE (US) turns off plot mode, as does CR (for all but 4025).
  87. ; CONTROL-X switches from TEKTRONIX sub mode to NORMAL alpha mode but is
  88. ;  ignored if we are emulating a full Tek terminal rather than a sub mode
  89. ;  of DEC or Heath.
  90. ; FF erases screen.
  91. ; ESCAPE letter, where letter is accent grave (`), a-e sets the line drawing
  92. ;   pattern until reset to solid lines (same as escape accent) by command or
  93. ;   a terminal reset.
  94. ; where
  95. ;    ENQ = Control E
  96. ;    ESC = Control [ (left square bracket)
  97. ;    FF = Control L
  98. ;    FS = Control \ (backslash)
  99. ;    GS = Control ] (right square bracket)
  100. ;    RS = Control ^ (caret)
  101. ;    US = Control _ (underscore)
  102. ;
  103. ; The plot commands are characters which specify the absolute position to move
  104. ; the beam.  All moves except the one immediately after the GS character
  105. ; (Control-]) are with a visible trace.
  106. ;
  107. ; For 4010-like devices - The positions are from 0 to 1023 for both X and Y,
  108. ; although only 0 to 780 are visible for Y due to screen geometry.  The screen
  109. ; is 10.23 by 7.80 inches, and coordinates are sent as 1 to 4 characters.
  110. ;
  111. ; For 4014-like devices - The positions are from 0 to 4096, but each movement
  112. ; is a multiple of 4 positions unless the high-resolution LSBXY are sent.  This
  113. ; makes it compatible with the 4010 in that a full sized plot fills the screen.
  114. ;
  115. ; HIX,HIY = High-order 5 bits of position
  116. ; LOX,LOY = Middle-order 5 bits of position
  117. ; LSBXY      = Low-order 2 bits of X + low-order 2 bits of Y (4014 mode)
  118. ;
  119. ; Hi Y      Lo Y      Hi X      LSBXY      Characters sent (Lo-X always sent)
  120. ; ----      ----      ----      -----      ----------------------------------
  121. ; Same      Same      Same      Same                 Lo-X
  122. ; Same      Same      Same      Diff        LSB, Lo-Y,     Lo-X    4014
  123. ; Same      Same      Diff      Same             Lo-Y, Hi-X, Lo-X
  124. ; Same      Same      Diff      Diff        LSB, Lo-Y, Hi-X, Lo-X    4014
  125. ; Same      Diff      Same      Same             Lo-Y,     Lo-X
  126. ; Same      Diff      Same      Diff        LSB, Lo-Y,     Lo-X    4014
  127. ; Same      Diff      Diff      Same             Lo-Y, Hi-X, Lo-X
  128. ; Same      Diff      Diff      Diff        LSB, Lo-Y, Hi-X, Lo-X    4014
  129. ; Diff      Same      Same      Same      Hi-Y,             Lo-X
  130. ; Diff      Same      Same      Diff      Hi-Y, LSB, Lo-Y,     Lo-X    4014
  131. ; Diff      Same      Diff      Same      Hi-Y,         Lo-Y, Hi-X, Lo-X
  132. ; Diff      Same      Diff      Diff      Hi-Y, LSB, Lo-Y, Hi-X, Lo-X    4014
  133. ; Diff      Diff      Same      Same      Hi-Y,         Lo-Y,     Lo-X
  134. ; Diff      Diff      Same      Diff      Hi-Y, LSB, Lo-Y,     Lo-X    4014
  135. ; Diff      Diff      Diff      Same      Hi-y,         Lo-Y, Hi-X, Lo-X
  136. ; Diff      Diff      Diff      Diff      Hi-y, LSB, Lo-Y, Hi-X, Lo-X    4014
  137. ; Offset for byte:          20h    60h  60h   20h     40h
  138. ;
  139. ; Note that LO-Y must be sent if HI-X has changed so that the TEKTRONIX knows
  140. ; the HI-X byte (in the range of 20h-3fh) is HI-X and not HI-Y.     LO-Y must
  141. ; also be sent if LSBXY has changed, so that the 4010 will ignore LSBXY and
  142. ; accept LO-Y.    The LSBXY byte is 60h + MARGIN*10h + LSBY*4 + LSBX. (MARGIN=0)
  143. ;
  144. ;
  145. ;
  146. ; External variable tekflg and calls to tekini, tekemu, tekesc, tekcls:
  147. ; Byte TEKFLG is non-zero when the Tek emulator is active; it is set by the
  148. ; startup code in tekini and is maintained in this file. Internal variable
  149. ; inited remembers if we have a graphics screen saved, etc.
  150. ; TEKINI must be called when entering the emulator to establish the graphics
  151. ; screen mode and to calculate the screen dimensions.
  152. ; TEKRINT reinitialize complete emulator.
  153. ; TEKESC is called from say mszibm.asm to invoke Tek emulation when the
  154. ; external procedures have detected an Escape Control-L sequence. An implicit
  155. ; initialization is done if necessary.
  156. ; TEKEMU is the normal entry point to pass a received character to the emulator.
  157. ; It too will do an implicit initialization, if required.
  158. ; TEKCLS clears the graphics screen, but only if the emulator is active.
  159. ; The emulator remains active during Connect mode Help, Status, and other
  160. ; interrupts which do not change the terminal type.
  161.  
  162.     public    tekemu,tekini,tekrint,tekend,tekgraf    ; Terminal emulation
  163.     public    tekcls, tekesc, tekflg            ;  used by msz file
  164.  
  165. ENQ    equ    05h            ; ^E ENQ for TEK enquiries
  166. CAN    equ    18h            ; ^X to return to ANSI mode
  167. ESCZ    equ    1Ah            ; SUB, ESC-^Z triggers crosshairs
  168. VT    equ    0bh            ; ^K go up one line
  169. FS    equ    1ch            ; ^\ for point plot mode
  170. GS    equ    1Dh            ; ^] draw line (1st move is invisible)
  171. RS    equ    1Eh            ; ^^ for incremental line plot mode
  172. US    equ    1Fh            ; ^_ (underscore) returns to text mode
  173. accent    equ    60h            ; accent grave
  174.  
  175. txtmode equ    4            ; text mode for TEKTRONIX status
  176. maxtekx equ    1024            ; horizontal and
  177. maxteky equ    780            ; vertical resolution of TEK 4010
  178.  
  179.  
  180. uparr    equ    72            ; DOS scan codes for arrow keys
  181. dnarr    equ    80
  182. lftarr    equ    75
  183. rgtarr    equ    77
  184. homscn    equ    71            ; DOS home screen scan code
  185. shuparr equ    73         ;code-arrow keys [jan]
  186. shdnarr equ    81
  187. shlftarr equ    212
  188. shrgtarr equ    213
  189.  
  190. segcga    equ    0040h               ; grid display start [jan]
  191.  
  192.  
  193. hiy    equ    1            ; codes for Tek graphics components
  194. loy    equ    2
  195. hix    equ    4
  196. lox    equ    3
  197.  
  198. data    segment public 'data'
  199.     extrn    flags:byte, portval:word, rxtable:byte
  200.     extrn    bigscreen:byte, denyflg:word     ; control tek auto entry/exit
  201.  
  202.  
  203. xmult    dw    5            ; 320 = (5/16)*1024 small scrn [jan]
  204. xdiv    dw    16            ;     xmult/xdiv
  205. ymult    dw    12            ; 240=(12/39)*780  small scrn  [jan]
  206. ydiv    dw    39            ;     ymult/ydiv
  207. xmax    dw    312            ; 320-8 x coord of right most chr [jan]
  208. ybot    dw    239            ; 240 lines on small scrn [jan]
  209. linelen dw    40             ; offset increment between scan lines
  210. linebytes dw    40            ;40 bytes/line on small scn [jan]
  211.  
  212.  
  213.  
  214. ttstate dw    tektxt            ; state machine control pointer
  215. prestate dw    0            ; previous state, across interruptions
  216. visible db    0            ; 0 to move, 1 to draw a line
  217. tek_hiy dw    0            ; Y coordinate in Tektronix mode
  218. tek_loy db    0
  219. tek_hix dw    0            ; X coordinate in Tektronix mode
  220. tek_lox db    0
  221. tek_lsb db    0            ; Low-order 2 bits of X + low Y
  222.                     ;    (4014 mode)
  223. status    db    0
  224. lastc    db    0            ; last x/y coord fragment seen
  225. masktab db    80h,40h,20h,10h,8,4,2,1 ; quicker than calculations!
  226.                     ; dashed line patterns
  227. linetab dw    0ffffh            ; ESC accent    11111111 11111111
  228.     dw    0aaaah            ; ESC a        10101010 10101010
  229.     dw    0f0f0h            ; ESC b        11110000 11110000
  230.     dw    0fafah            ; ESC c        11111010 11111010
  231.     dw    0ffcch            ; ESC d        11111111 11001100
  232.     dw    0fc92h            ; ESC e        11111100 10010010
  233.  
  234. linepat dw    0ffffh            ; active line pattern, from above
  235.  
  236.  
  237. ;End of init data
  238.  
  239.  
  240. IDSEQ    dw    tekem            ; address of response to terminal
  241. CTLTAB    dw    0            ; .. inquiry
  242. tekem    db    'GRiD_TEK'         ; .. and the response
  243.     db    escape,'/Z',0
  244. x_coord dw    0            ; Tek text char X coordinate
  245. y_coord dw    8            ; Tek text char Y coordinate
  246. xcross    dw    0            ; cross hairs to start at centre
  247. ycross    dw    0
  248. oldx    dw    0            ; Tek coordinates of last point
  249. oldy    dw    767            ;  initially top left
  250. scalex    dw    0            ; PC coord for scaled x value
  251. scaley    dw    0            ;  for scaled y value
  252. curmode db    0            ; screen mode before graphics
  253. tekgraf db    1        ; Tek graphics board selection (def=cga)[jan]
  254.                 ; local variables for LINE plotting routine
  255. cursor    dw    0            ; saved text cursor
  256. inited    db    0            ; non-zero if inited (retains page)
  257. tekflg    db    0            ; Tek mode active flag
  258. yflags    db    0            ; flags byte from msy
  259. flow    dw    0            ; flow control word
  260. gpage    db    0            ; display adapter graphics page
  261. gfcol    db    15            ; graphics foreground colour
  262. gbcol    db    0            ; graphics background color
  263. tfcol    db    0            ; temp foreground color
  264. tbcol    db    0            ; temp background color
  265. lastd    db    0,0            ; worker for ESC [ Pn ; Pn m scanner
  266. ccode    db    0               ;coloring
  267. moremsg db    ' More >'
  268. mormsglen equ    $-moremsg        ; length of message
  269. putc    dw    gputc            ; ptr to plot a character routine
  270. psetup    dw    psetupc            ; ptr to plot setup routine
  271. pincy    dw    pincyc            ; ptr to inc y routine
  272. plotptr dw    pltcga            ; ptr to dot plot routine
  273. gcplot    dw    gcgen            ; ptr to char plot routine
  274. segscn    dw    0040h               ; actual screen segment to use[jan]
  275.                     ; ANSI Escape sequence to exit Tek mode
  276. tkoff    db    escape,'[?38l'        ; Exit Tek mode escape sequence
  277. tkofflen equ    $-tkoff            ; length of sequence
  278. tkoffs    db    6 dup (0)        ; received chars in rcv'd sequence
  279. tkcnt    dw    0            ; counter of matched char in tkoffs
  280. bypass    db    0            ; GIN mode bypass condition (0=off)
  281. temp    dw    0
  282.  
  283. ; 8*8 font for Hercules and such, CGA, and EGA
  284. ; - allows 43 lines, and 80 (90 for Hercules) chars per line.
  285. ; all printing (?) characters from <space> to <del> - two characters per line
  286. ; 8 bits per scan line, given top line first, 8 scan lines.
  287. font    db    0,0,0,0,0,0,0,0,           18h,18h,18h,18h,18h,0,18h,0
  288.     db    6ch,6ch,6ch,0,0,0,0,0,           36h,36h,7fh,36h,7fh,36h,36h,0
  289.     db    0ch,3fh,68h,3eh,0bh,7eh,18h,0, 60h,66h,0ch,18h,30h,66h,06h,0
  290.     db    38h,6ch,6ch,38h,6dh,66h,3bh,0, 0ch,18h,30h,0,0,0,0,0
  291.     db    0ch,18h,30h,30h,30h,18h,0ch,0, 30h,18h,0ch,0ch,0ch,18h,30h,0
  292.     db    0,18h,7eh,3ch,7eh,18h,0,0,     0,18h,18h,7eh,18h,18h,0,0
  293.     db    0,0,0,0,0,18h,18h,30h,           0,0,0,7eh,0,0,0,0
  294.     db    0,0,0,0,0,18h,18h,0,           0,06h,0ch,18h,30h,60h,0,0
  295.     db    3ch,66h,6eh,7eh,76h,66h,3ch,0, 18h,38h,18h,18h,18h,18h,7eh,0
  296.     db    3ch,66h,06h,0ch,18h,30h,7eh,0, 3ch,66h,06h,1ch,06h,66h,3ch,0
  297.     db    0ch,1ch,3ch,6ch,7eh,0ch,0ch,0, 7eh,60h,7ch,06h,06h,66h,3ch,0
  298.     db    1ch,30h,60h,7ch,66h,66h,3ch,0, 7eh,06h,0ch,18h,30h,30h,30h,0
  299.     db    3ch,66h,66h,3ch,66h,66h,3ch,0, 3ch,66h,66h,3eh,06h,0ch,38h,0
  300.     db    0,0,18h,18h,0,18h,18h,0,       0,0,18h,18h,0,18h,18h,30h
  301.     db    0ch,18h,30h,60h,30h,18h,0ch,   0,0,0,7eh,0,7eh,0,0,0
  302.     db    30h,18h,0ch,06h,0ch,18h,30h,   0,3ch,66h,0ch,18h,18h,0,18h,0
  303.     db    3ch,66h,6eh,6ah,6eh,60h,3ch,   0,3ch,66h,66h,7eh,66h,66h,66h,0
  304.     db    7ch,66h,66h,7ch,66h,66h,7ch,   0,3ch,66h,60h,60h,60h,66h,3ch,0
  305.     db    78h,6ch,66h,66h,66h,6ch,78h,   0,7eh,60h,60h,7ch,60h,60h,7eh,0
  306.     db    7eh,60h,60h,7ch,60h,60h,60h,   0,3ch,66h,60h,6eh,66h,66h,3ch,0
  307.     db    66h,66h,66h,7eh,66h,66h,66h,   0,7eh,18h,18h,18h,18h,18h,7eh,0
  308.     db    3eh,0ch,0ch,0ch,0ch,6ch,38h,   0,66h,6ch,78h,70h,78h,6ch,66h,0
  309.     db    60h,60h,60h,60h,60h,60h,7eh,   0,63h,77h,7fh,6bh,6bh,63h,63h,0
  310.     db    66h,66h,76h,7eh,6eh,66h,66h,   0,3ch,66h,66h,66h,66h,66h,3ch,0
  311.     db    7ch,66h,66h,7ch,60h,60h,60h,   0,3ch,66h,66h,66h,6ah,6ch,36h,0
  312.     db    7ch,66h,66h,7ch,6ch,66h,66h,   0,3ch,66h,60h,3ch,06h,66h,3ch,0
  313.     db    7eh,18h,18h,18h,18h,18h,18h,   0,66h,66h,66h,66h,66h,66h,3ch,0
  314.     db    66h,66h,66h,66h,66h,3ch,18h,   0,63h,63h,6bh,6bh,7fh,77h,63h,0
  315.     db    66h,66h,3ch,18h,3ch,66h,66h,   0,66h,66h,66h,3ch,18h,18h,18h,0
  316.     db    7eh,06h,0ch,18h,30h,60h,7eh,   0,7ch,60h,60h,60h,60h,60h,7ch,0
  317.     db    0,60h,30h,18h,0ch,06h,0,0,     3eh,06h,06h,06h,06h,06h,3eh,0
  318.     db    18h,3ch,66h,42h,0,0,0,0,       0,0,0,0,0,0,0,0ffh
  319.     db    30h,18h,0ch,0,0,0,0,0,           0,0,3ch,06h,3eh,66h,3eh,0
  320.     db    60h,60h,7ch,66h,66h,66h,7ch,0, 0,0,3ch,66h,60h,66h,3ch,0
  321.     db    06h,06h,3eh,66h,66h,66h,3eh,0, 0,0,3ch,66h,7eh,60h,3ch,0
  322.     db    0eh,18h,18h,3ch,18h,18h,18h,0, 0,0,3eh,66h,66h,3eh,06h,3ch
  323.     db    60h,60h,7ch,66h,66h,66h,66h,0, 18h,0,38h,18h,18h,18h,3ch,0
  324.     db    18h,0,38h,18h,18h,18h,18h,70h, 60h,60h,66h,6ch,78h,6ch,66h,0
  325.     db    38h,18h,18h,18h,18h,18h,3ch,0, 0,0,76h,7fh,6bh,6bh,63h,0
  326.     db    0,0,7ch,66h,66h,66h,66h,0,     0,0,3ch,66h,66h,66h,3ch,0
  327.     db    0,0,7ch,66h,66h,7ch,60h,60h,0, 0,3eh,66h,66h,3eh,06h,07h
  328.     db    0,0,6ch,76h,60h,60h,60h,0,     0,0,3eh,60h,3ch,06h,7ch,0
  329.     db    30h,30h,7ch,30h,30h,30h,1ch,0, 0,0,66h,66h,66h,66h,3eh,0
  330.     db    0,0,66h,66h,66h,3ch,18h,0,     0,0,63h,6bh,6bh,7fh,36h,0
  331.     db    0,0,66h,3ch,18h,3ch,66h,0,     0,0,66h,66h,66h,3eh,06h,3ch
  332.     db    0,0,7eh,0ch,18h,30h,7eh,0,     0ch,18h,18h,70h,18h,18h,0ch,0
  333.     db    18h,18h,18h,0,18h,18h,18h,0,   30h,18h,18h,0eh,18h,18h,30h,0
  334.     db    31h,6bh,46h,0,0,0,0,0,           8 dup (0ffh)
  335. data   ends
  336.  
  337. code    segment public 'code'
  338.     extrn    outchr:near, beep:near, cmblnk:near
  339.     extrn    clrmod:near, cptchr:near
  340.     extrn    clrbuf:near, iseof:near, getflgs:near
  341.     extrn  termtog:near           ; toggle terminal type [jan]
  342.     assume    cs:code, ds:data, es:nothing
  343.  
  344. ; Initialise TEK mode by setting high resolution screen, etc
  345.  
  346. tekini    PROC NEAR
  347.     push    ax
  348.     push    bx
  349.     push    cx
  350.     push    dx
  351.     push    si
  352.     push    di
  353.     push    es
  354.     cmp bigscreen,0               ;1means big
  355.     je tekin1               ;eq means use defaults
  356.      mov xmult,1            ;512=(1/2) x 1024 big scrn [jan]
  357.      mov xdiv,2            ;512 columns on big screen
  358.      mov ymult,64            ;256=(64/195)*780
  359.      mov ydiv,195            ;256 rows on big screen
  360.      mov xmax,504            ;5-2-8 x coord of right most chr
  361.      mov ybot,255            ;256 lines on big screen
  362.      mov linelen,64               ;64 bytes per line
  363.      mov linebytes,64
  364.     jmp tekin2
  365. tekin1:     mov xmult,10        ;small screen stuff
  366.      mov xdiv,32        ;small is 320 x 240
  367.      mov ymult,12
  368.      mov ydiv,39
  369.      mov xmax,312
  370.      mov ybot,239
  371.      mov linelen,40
  372.      mov linebytes,40
  373.  
  374.  
  375. tekin2: mov    tekflg,1        ; starting Tek sub mode
  376. ;    cmp    inited,0        ; inited yet?
  377. ;    jne    tekin19            ; ne = yes, restore screen
  378.     mov    ttstate,offset tektxt    ; do displayable text
  379.     mov    prestate,offset tektxt    ; set a previous state of text
  380.     mov    inited,1        ; say we have initialized
  381. ;    call    tekcls            ; clear screen
  382. ;    jmp    short tekin20
  383. ;tekin19:call     tekrest         ; restore old graphics screen
  384. tekin21:clc                ; clear carry for success
  385. tekin23:pop    es
  386.     pop    di
  387.     pop    si
  388.     pop    dx
  389.     pop    cx
  390.     pop    bx
  391.     pop    ax
  392.     ret
  393. tekini    ENDP
  394.  
  395. TEKRINT proc    near            ; Tek reinitialization entry point
  396.     mov    inited,0        ; do complete reinitialization
  397.     jmp    tekini
  398. TEKRINT endp
  399.  
  400.  
  401. ;Terminal emulation. Enter with received character in AL.
  402.  
  403. TEKEMU PROC    NEAR            ; main emulator
  404.     cmp    tekflg,0        ; Tek mode active yet? (msz call)
  405.     jne    tektt1            ; ne = yes
  406.     call    tekini            ; init now
  407.     mov    ttstate,offset tektxt    ; initial state
  408.     mov    prestate,offset tektxt    ; set a previous state of text
  409.     jnc    tektt1            ; nc = succeeded
  410.     ret                ; else failed to init, just return
  411. tektt1: and    al,7fh            ; force Tek chars to be 7 bits
  412.     cmp    al,0            ; NUL char?
  413.     je    tekign            ; e = yes, ignore it before logging
  414.     push    ax
  415.     call    getflgs            ; get msy yflags into al
  416.     mov    yflags,al
  417.     test    al,capt            ; capturing output?
  418.     pop    ax
  419.     jz    tektt4            ; z = no, forget this part
  420.     push    ax            ; save char
  421.     call    cptchr            ; give it captured character
  422.     pop    ax            ; restore character and keep going
  423. tektt4: test    yflags,trnctl        ; debug? if so use tty mode
  424.     jz    tektt5            ; z = no
  425.     cmp    al,DEL            ; DEL char?
  426.     jne    tektt4a            ; ne = no
  427.     mov    al,5eh            ; make DEL a caret query mark
  428.     call    outscrn
  429.     mov    al,3fh            ; the query mark
  430.     call    outscrn
  431.     jmp    short tekign
  432. tektt4a:cmp    al,' '            ; control char?
  433.     jae    tektt4b            ; ne = no
  434.     push    ax
  435.     mov    al,5eh            ; caret
  436.     call    outscrn
  437.     pop    ax
  438.     add    al,'A'-1        ; make char printable
  439. tektt4b:call    outscrn
  440.  
  441. tekign: ret                ; Ignore this character
  442.  
  443. tektt5: call    tkscan            ; scan for "ESC [ ? 3 8 l" exit code
  444. tektt5a:cmp    al,0            ; null char response?
  445.     je    tekign            ; e = yes, ignore the character
  446.     cmp    al,' '            ; control code?
  447.     jb    tektt6            ; b = yes, decode
  448.     jmp    ttstate            ; no, do current state
  449.                     ; Control characters:
  450. tektt6: cmp    al,GS            ; Line plot command?
  451.     jne    tektt7            ; ne = no
  452.     mov    visible,0        ; Next move is invisible
  453.     and    status,not txtmode    ; set status report byte
  454.     mov    ttstate,offset tekline    ; expect coordinates next
  455.     jmp    tektt12
  456. tektt7: cmp    al,RS            ; Incremental dot command?
  457.     jne    tektt8            ; ne = no
  458.     and    status,not txtmode    ; set status report
  459.     mov    ttstate,offset tekrlin    ; expect pen command next
  460.     jmp    tektt12
  461. tektt8: cmp    al,FS            ; Point plot command?
  462.     jne    tektt9            ; ne = no
  463.     mov    visible,0        ; next move is invisible
  464.     and    status,not txtmode    ; set status report byte
  465.     mov    ttstate,offset tekpnt
  466.     jmp    tektt12
  467. tektt9: cmp    al,US            ; assert text mode? [bjh]
  468.     jne    tektt10            ; ne = no
  469.     or    status,txtmode        ; set status report byte
  470.     mov    ttstate,offset tektxt    ; Go to TEKTXT next time
  471.     mov    bypass,0        ; reset bypass condition
  472.     jmp    tektt12
  473. tektt10:cmp    al,ESCAPE        ; Escape?
  474.     jne    tektt11            ; ne = no
  475.     or    status,txtmode        ; set status report byte
  476.     cmp    ttstate,offset tekesc    ; already in escape state?
  477.     je    tektt14            ; e = yes, nest no further
  478.     push    ttstate            ; current state
  479.     pop    prestate        ; save here as previous state
  480.     mov    ttstate,offset tekesc    ; next state parses escapes
  481.     ret
  482. tektt11:cmp    al,CAN            ; Control X? (exits Tek sub mode)
  483.     jne    tektt13            ; ne = no, stay in current state
  484.     cmp    ttstate,offset tekesc    ; ESC Control-X?
  485.     je    tektt13            ; yes, parse it in tekesc code
  486.     mov    ttstate,offset tektxt    ; back to text mode
  487. ;    test    flags.vtflg,tttek    ; main Tek emulator?
  488.     test    denyflg,tekxflg        ;disable auto exit/entry [jan]
  489.     jnz    tektt12            ; nz = yes, ignore the ^X
  490.     call    tekend            ; else exit sub mode
  491.     mov    tekflg,0        ; clear Tek sub mode flag
  492. tektt12:mov    prestate,offset tektxt    ; make previous state text
  493. tektt14:ret
  494. tektt13:jmp    ttstate            ; let someone else worry about this
  495. TEKEMU    ENDP
  496.  
  497. ; End TEK emulation, recover previous screen
  498. TEKEND    PROC    NEAR
  499.     cmp    tekflg,0        ; Tek sub mode active?
  500.     jne    teknd0            ; ne = yes
  501.     ret                ; else return as is.
  502. teknd0: call termtog            ;toggle terminal
  503.     ret
  504. TEKEND    ENDP
  505.  
  506. ; State machine active while Tek is active. Senses ESC [ ? 3 8 l to exit
  507. ; Tek mode and return to either non-sub mode terminal or to a VT102.
  508. ; Plays back unmatched escape sequences. Enter with character in al.
  509.  
  510. tkscan    proc    near
  511.     and    al,7fh            ; strip high bit
  512.     cmp    al,byte ptr tkoff    ; start of Tek Off sequence?
  513.     jne    tkscn1            ; ne = no
  514.     call    tkscn4            ; playback previously matched chars
  515.     mov    tkcnt,1            ; count matched chars (one now)
  516.     mov    tkoffs,al        ; save full character, with high bit
  517.     mov    al,0            ; our temporary response
  518.     jmp    short tkscnx        ;  and exit
  519.  
  520. tkscn1: push    bx            ; check for char in Tek Off sequence
  521.     mov    bx,tkcnt        ; number of chars matched in Tek Off
  522.     mov    tkoffs[bx],al        ; save this char
  523.     cmp    al,byte ptr tkoff[bx]    ; match expected char in sequence?
  524.     pop    bx
  525.     jne    tkscn3            ; ne = no, play back partial match
  526.     inc    tkcnt            ; count new match
  527.     mov    al,0            ; our temporary response
  528.     cmp    tkcnt,tkofflen        ; matched all char in sequence?
  529.     jne    tkscnx            ; ne = not yet, wait for more
  530.     mov    tkcnt,0            ; clear counter
  531.     cmp    flags.vtflg,tttek    ;full terminal now?
  532.     jne    tkscn2            ; ne = no, a submode
  533.       ;     call     termtog         ; toggle terminal type[jan]
  534. tkscn2: mov    al,CAN            ; simulate arrival of Control-X
  535.     jmp    short tkscnx        ;  all done
  536.  
  537. tkscn3: call    tkscn4            ; playback previously matched chars
  538.     mov    tkcnt,0            ; reset to no match and exit
  539. tkscnx: ret                ; common exit
  540.  
  541.                     ; local worker procedure
  542. tkscn4: push    ax            ; save break char (in al)
  543.     push    cx            ; playback partial sequence to screen
  544.     mov    cx,tkcnt        ; number of chars matched before break
  545.     jcxz    tkscn4b            ; z = none
  546.     push    si
  547.     mov    si,offset tkoffs    ; string to be played back
  548. tkscn4a:cld
  549.     lodsb                ; get a char into al
  550.     push    cx
  551.     push    si            ; save these around tektt5a work
  552.     call    tektt5a            ; use it
  553.     pop    si
  554.     pop    cx
  555.     loop    tkscn4a            ; do all that came in previously
  556.     pop    si
  557. tkscn4b:pop    cx
  558.     pop    ax            ; recover break char
  559.     ret
  560. tkscan    endp
  561.  
  562.  
  563. TEKTXT    proc    near            ; Dispatch on text characters
  564.  
  565.     cmp    al,DEL            ; RUBOUT?
  566.     jne    tektx1            ; ne = no
  567.     mov    al,bs            ; make BS
  568.     jmp    short tektx7
  569. tektx1: cmp    al,CR            ; carriage return (^M)?
  570.     je    tektx9            ; e = yes
  571. tektx2: cmp    al,LF            ; line feed (^J)?
  572.     je    tektx9            ; e = yes
  573. tektx3: cmp    al,FF            ; form feed (^L)?
  574.     jne    tektx4            ; ne = no
  575.     call    tekcls            ; clear the screen
  576.     jmp    short tektx8
  577. tektx4: cmp    al,VT            ; vertical tab (^K)?
  578.     je    tektx7
  579.     cmp    al,bell            ; bell (^G)?
  580.     jne    tektx5            ; ne = no
  581.     call    beep
  582.     mov    bypass,0        ; clear GIN mode bypass condition
  583.     jmp    short tektx8
  584. tektx5: cmp    al,tab            ; horizontal tab (^I)?
  585.     je    tektx7            ; e = yes
  586. tektx6: cmp    al,BS            ; backspace (^H)?
  587.     je    tektx7            ; e = yes
  588.     cmp    al,' '            ; control char?
  589.     jb    tektx8            ; b = yes, ignore it
  590. tektx7: cmp    bypass,0        ; bypass mode off?
  591.     jne    tektx8            ; ne = no, it's on so skip display
  592.     call    OUTSCRN            ;output character to screen
  593.  
  594. tektx8: ret
  595. tektx9: mov    bypass,0        ; clear GIN mode bypass condition
  596.     jmp    short tektx7
  597. TEKTXT    endp
  598.  
  599. ; Process escape sequences. Callable from msz terminal emulator.
  600. ; Enter with received character in AL. Escape sequences are generally
  601. ; treated as interruptions to the current plotting/text command. Screen
  602. ; clearing is the exception by causing a general emulator reset.
  603. TEKESC    PROC    NEAR
  604.     mov    bypass,0        ; clear GIN mode bypass condition
  605.     mov    ttstate,offset tekesc    ; in case get here from msz file
  606.     cmp    tekflg,0        ; Tek mode active yet? (msz call)
  607.     jne    tekesc1            ; ne = yes
  608.     call    tekini            ; init now
  609.     mov    prestate,offset tektxt    ; set a previous state of text
  610.     jnc    tekesc1            ; nc = succeeded
  611.     ret                ; else failed to init, just return
  612.  
  613. tekesc1:cmp    al,'Z'            ; ESC-Z Identify?
  614.     jne    tekesc2            ; ne = no
  615. ;    call    SENDID            ; Send terminal identification
  616.     jmp    tekescx
  617.  
  618. tekesc2:cmp    al,FF            ; ESC-FF Clear screen?
  619.     jne    tekesc3            ; ne = no
  620.     call    tekcls            ; Clear screen
  621.     mov    prestate,offset tektxt    ; make previous state text mode
  622.     jmp    tekescx            ; Return to text mode after ESC-FF
  623.  
  624. tekesc3:cmp    al,ESCZ            ; ESC-^Z Enter GIN mode?
  625.     jne    tekesc4            ; ne = no
  626.     mov    bypass,1
  627.     call    CROSHAIR        ; Activate the cross-hairs
  628.     jmp    tekescx
  629. tekesc3a:call    beep            ; tell the user we are unhappy
  630.     jmp    tekescx            ; and ignore the command
  631.  
  632. tekesc4:cmp    al,ENQ            ; ESC-^E Enquiry for cursor position?
  633.     jne    tekesc5            ; ne = no
  634.     mov    bypass,1        ; set bypass mode
  635.     call    SENDSTAT        ; send status
  636.     jmp    tekescx
  637.  
  638. tekesc5:cmp    al,CAN            ; ESC Control-X?
  639.     jne    tekesc6            ; ne = no
  640.     mov    bypass,1        ; set bypass condition
  641.     jmp    tekescx
  642.  
  643. tekesc6:cmp    al,3fh            ; query mark? (ESC ? means DEL)
  644.     jne    tekesc7            ; ne = no
  645.     mov    al,DEL            ; replace with DEL code
  646.     jmp    tekescx            ; and process it as if received.
  647.  
  648. tekesc7:cmp    al,accent        ; accent grave, line pattern series?
  649.     jb    tekesc8            ; b = no
  650.     cmp    al,65h            ; lowercase e?
  651.     ja    tekescx            ; a = beyond line pattern series
  652.     push    bx
  653.     mov    bl,al
  654.     sub    bl,accent        ; remove bias
  655.     and    bl,7            ; eight patterns, roll over excess
  656.     mov    bh,0
  657.     shl    bx,1            ; make this a word index
  658.     mov    bx,linetab[bx]        ; get line pattern word
  659.     mov    linepat,bx        ; save in active word
  660.     pop    bx            ; return to previous mode
  661.  
  662. tekesc8:cmp    al,5bh            ; right square bracket?
  663.     jne    tekescx            ; ne = no
  664. ;    jmp    tekcol            ; no color on GRiD [jan]
  665.  
  666. tekescx:push    ax
  667.     mov    ax,prestate        ; get previous state
  668.     mov    ttstate,ax        ; restore it
  669.     or    ax,ax            ; test for none
  670.     pop    ax
  671.     jz    go2text            ; z = none, use text mode
  672.     clc
  673.     ret                ; resume previous state
  674.  
  675. go2text:mov    ttstate,offset tektxt    ; Go to TEKTXT next time
  676.     mov    lastc,0            ; clear last drawing coordinate flag
  677.     or    status,txtmode        ; set text mode in status byte
  678.     clc
  679.     ret
  680. TEKESC    ENDP
  681.  
  682.  
  683.  
  684. TEKLINE proc    near            ; GS line drawing
  685.     call    tekxyc            ; parse coordinates from input bytes
  686.     jnc    teklin1            ; nc = not done yet
  687.     mov    cl,visible        ; get moveto or drawto variable
  688.     call    tekdraw            ; move that point
  689.     mov    visible,1        ; say next time we draw
  690. teklin1:ret
  691. TEKLINE endp
  692.  
  693. TEKPNT    proc    near            ; FS plot single point
  694.     call    tekxyc            ; parse coordinates
  695.     jnc    tekpnt1            ; nc = not done yet
  696.     mov    cl,0            ; do not draw
  697.     call    tekdraw            ; move to the point
  698.     mov    ax,si            ; copy starting point to end point
  699.     mov    bx,di            ; ax,bx,si,di are in PC coordinates
  700.     mov    cl,1            ; make plot visible
  701.     call    line            ; draw the dot
  702.     mov    visible,0        ; return to invisibility
  703. tekpnt1:ret
  704. TEKPNT    endp
  705.  
  706. ; Decode graphics x,y components. Returns carry set to say have all
  707. ; components for a line, else carry clear. Understands 4014 lsb extensions.
  708. ; Permits embedded escape sequences.
  709. TEKXYC    proc    near
  710.     cmp    al,CR            ; Exit drawing on CR,LF,RS,US,FS,CAN
  711.     je    tekghx            ; e = yes, a cr
  712.     cmp    al,LF            ; these terminate line drawing cmds
  713.     je    tekghx
  714.     cmp    al,FS            ; <FS>
  715.     je    tekghx
  716.     cmp    al,RS            ; <RS>
  717.     je    tekghx
  718.     cmp    al,US            ; <US>
  719.     je    tekghx
  720.     cmp    al,CAN            ; and <CAN>
  721.     je    tekghx            ; BUT ignore other control chars
  722.     cmp    al,20h            ; Control char?
  723.     jb    tekgh0            ; b = yes, ignore it
  724.     cmp    al,40h
  725.     jb    tekgh2            ; 20-3F are HIX or HIY
  726.     cmp    al,60h            ; 40-5F are LOX (causes beam movement)
  727.     jb    tekgh4            ; 60-7F are LOY
  728.                     ; Extract low-order 5 bits of Y coord
  729.     mov    ah,tek_loy        ; Copy previous LOY to MSB (4014)
  730.     mov    tek_lsb,ah
  731.     and    al,1Fh            ; LOY is 5 bits
  732.     mov    tek_loy,al
  733.     cmp    lastc,loy        ; 2nd LOY in a row?
  734.     je    tekgh1            ; Yes, then LSB is valid
  735.     mov    tek_lsb,0        ; 1st one, clear LSB
  736. tekgh1: mov    lastc,loy        ; LOY seen, expect HIX (instead of HIY)
  737. tekgh0: clc                ; c clear = not completed yet
  738.     ret
  739. tekghx: jmp    go2text
  740.  
  741.             ; Extract high-order 5 bits (X or Y, depending on lastc)
  742. tekgh2: and    ax,1Fh            ; Just 5 bits
  743.     mov    cl,5
  744.     shl    ax,cl            ; Shift over 5 bits
  745.     cmp    lastc,loy        ; was last coordinate a low-y?
  746.     je    tekgh3            ; e = yes, parse hix
  747.     mov    tek_hiy,ax        ; this byte has HIY
  748.     mov    lastc,hiy
  749.     clc
  750.     ret
  751. tekgh3: mov    tek_hix,ax        ; This byte has HIX
  752.     mov    lastc,hix
  753.     clc
  754.     ret
  755. tekgh4: and    al,1Fh            ; Just 5 bits
  756.     mov    tek_lox,al
  757.     mov    lastc,lox
  758.     mov    ax,tek_hix        ; Combine HIX*32
  759.     or    al,tek_lox        ;  with LOX
  760.     mov    bx,tek_hiy        ; Same for Y
  761.     or    bl,tek_loy
  762.     stc                ; set c to say completed operation
  763.     ret
  764. TEKXYC    endp
  765.  
  766. TEKRLIN proc    near            ; RS relative line drawing
  767.     cmp    al,' '            ; Pen up command?
  768.     jne    tekrli1            ; ne = no, try pen down
  769.     mov    visible,0        ; do invisible movements
  770.     jmp    short tekrli2        ; do the command
  771. tekrli1:cmp    al,'P'            ; pen down command?
  772.     jne    tekrli3            ; ne = no, return to text mode
  773.     mov    visible,1        ; set visible moves
  774.  
  775. tekrli2:mov    ax,x_coord        ; PC x coordinate of pen
  776.     mov    bx,y_coord        ;    y coordinate
  777.     call    pctotek            ; get current pen position in Tek coor
  778.     mov    cl,0            ; invisible, moveto
  779.     call    tekdraw            ; move that point, set oldx and oldy
  780.     mov    ttstate,offset tekinc    ; next get incremental movement cmds
  781.     ret
  782.  
  783. tekrli3:mov    visible,0        ; bad char, reset visibility
  784.     push    prestate
  785.     pop    ttstate            ; restore previous state
  786.     jmp    tektt5            ; deal with the break char
  787. TEKRLIN endp
  788.                     ; interpret RS inc plot command byte
  789. TEKINC    proc    near            ; get movement character and do cmd
  790.     cmp    al,'A'            ; move right?
  791.     jne    tekinc1            ; ne = no
  792.     inc    oldx            ; adjust beam position
  793.     jmp    short tekinc9
  794. tekinc1:cmp    al,'E'            ; move right and up?
  795.     jne    tekinc2            ; ne = no
  796.     inc    oldx
  797.     inc    oldy
  798.     jmp    short tekinc9
  799. tekinc2:cmp    al,'D'            ; move up?
  800.     jne    tekinc3            ; ne = no
  801.     inc    oldy
  802.     jmp    short tekinc9
  803. tekinc3:cmp    al,'F'            ; move left and up?
  804.     jne    tekinc4            ; ne = no
  805.     dec    oldx
  806.     inc    oldy
  807.     jmp    short tekinc9
  808. tekinc4:cmp    al,'B'            ; move left?
  809.     jne    tekinc5            ; ne = no
  810.     dec    oldx
  811.     jmp    short tekinc9
  812. tekinc5:cmp    al,'J'            ; move left and down?
  813.     jne    tekinc6            ; ne = no
  814.     dec    oldx
  815.     dec    oldy
  816.     jmp    short tekinc9
  817. tekinc6:cmp    al,'H'            ; move down?
  818.     jne    tekinc7            ; ne = no
  819.     dec    oldy
  820.     jmp    short tekinc9
  821. tekinc7:cmp    al,'I'            ; move right and down?
  822.     jne    tekincb            ; ne = no, bad command
  823.     inc    oldx
  824.     dec    oldy
  825. tekinc9:cmp    oldx,0            ; too far left?
  826.     jge    tekinc10        ; ge = no
  827.     mov    oldx,0            ; else stop at the left margin
  828. tekinc10:cmp    oldx,maxtekx-1        ; too far left?
  829.     jle    tekinc11        ; le = no
  830.     mov    oldx,maxtekx-1        ; else stop that the left margin
  831. tekinc11:cmp    oldy,maxteky-1        ; above the top?
  832.     jle    tekinc12        ; le = no
  833.     mov    oldy,maxteky-1        ; else stop at the top
  834. tekinc12:cmp    oldy,0            ; below the bottom?
  835.     jge    tekinc13        ; ge = no
  836.     mov    oldy,0            ; else stop at the bottom
  837. tekinc13:mov    ax,oldx            ; ax is vector x end point
  838.     mov    bx,oldy            ; bx is vector y end point
  839.     mov    cl,visible
  840.     call    tekdraw            ; move/draw to that point
  841.     ret
  842. tekincb:push    prestate        ; bad character, exit inc plot mode
  843.     pop    ttstate            ; new state is previous state
  844.     mov    visible,0
  845.     jmp    tektt5            ; reparse the bad char
  846. TEKINC    endp
  847.  
  848.  
  849. ; Routine to trigger the crosshairs, wait for a key to be struck, and send
  850. ; the typed char (if printable ascii) plus four Tek encoded x,y position
  851. ; coordinates and then a carriage return.
  852. ; ax, cx, xcross, ycross operate in PC coordinates.
  853.  
  854. CROSHAIR PROC NEAR
  855.     push    linepat            ; save line drawing pattern
  856.     mov    linepat,0ffffh        ; reset line type to solid
  857.  
  858.     mov    ax,xmax            ; right margin minus 7 dots
  859.     add    ax,7
  860.     mov    temp,ax            ; right margin dot
  861. crosha1:call    crosdraw        ; draw the cross-hairs
  862.     call    iseof            ; is stdin at EOF?
  863.     jc    crosha2            ; c = yes, exit this mode now
  864.     mov    ah,coninq        ; DOS, quiet read char
  865.     int    dos
  866.     push    ax            ; save char for later
  867.     call    crosdraw        ; erase cross hairs
  868.     pop    ax
  869.     or    al,al            ; ascii or scan code returned
  870.     jnz    arrow5            ; nz = ascii char returned
  871.  
  872.     call    iseof            ; is stdin at EOF?
  873.     jc    crosha2            ; c = yes, exit this mode now
  874.     mov    ah,coninq        ; read scan code
  875.     int    dos
  876.     cmp    al,0            ; Control-Break?
  877.     jne    crosha3            ; ne = no, something else
  878. crosha2:pop    linepat            ; restore line pattern
  879.     ret                ; exit crosshairs mode
  880.  
  881. crosha3:cmp    al,homscn        ; is it 'home'?
  882.     jne    arrow1            ; ne = no, try other keys
  883.     mov    ax,temp            ; right margin
  884.     shr    ax,1            ; central position
  885.     mov    xcross,ax        ; save PC coord for crosshair
  886.     mov    ax,ybot            ; last scan line
  887.     shr    ax,1
  888.     mov    ycross,ax        ; this is the center of the screen
  889.     jmp    crosha1            ; home the crosshairs
  890.  
  891. arrow1: cmp    al,lftarr        ; left arrow?
  892.     jne    arrow2            ; ne = no
  893.     mov    cx,-1            ; left shift
  894.     jmp    short xkeys
  895. arrow2: cmp    al,rgtarr        ; right arrow?
  896.     jne    arrow3            ; ne = no
  897.     mov    cx,1            ; right shift
  898.     jmp    short xkeys
  899. arrow3: cmp    al,uparr        ; up arrow?
  900.     jne    arrow4            ; ne = no
  901.     mov    cx,-1            ; up shift
  902.     jmp    short vertkey
  903. arrow4: cmp    al,dnarr        ; down arrow?
  904.     jne    arrow7            ; ne = no, ignore it
  905.     mov    cx,1            ; down shift
  906.     jmp    short vertkey
  907.  
  908. arrow7: cmp    al,shuparr        ; shifted up arrow?
  909.     jne    arrow8            ; ne = no
  910.     mov    cx,-10            ; big up shift
  911.     jmp    short vertkey
  912. arrow8: cmp    al,shdnarr        ; shifted down arrow?
  913.     jne    badkey               ; ne = no, send this key as is
  914.     mov    cx,10            ; big down shift
  915.     jmp    short vertkey
  916.  
  917.  
  918. badkey: call    beep            ; tell user we don't understand
  919.     jmp    crosha1            ; keep going
  920.  
  921.                     ; Shifted keys yield ascii keycodes
  922. arrow5: cmp    al,'C' and 1fh        ; Control-C?
  923.     je    crosha2            ; e = yes, exit crosshairs mode now
  924.     cmp    al,shlftarr        ; shifted left arrow?
  925.     jne    arrow6            ; ne = no
  926.     mov    cx,-10            ; big left shift
  927.     jmp    short xkeys
  928. arrow6: cmp    al,shrgtarr        ; shifted right arrow?
  929.     jne    charkey             ; ne = no
  930.     mov    cx,10            ; big right shift
  931.     jmp    short xkeys
  932.  
  933. xkeys:    add    cx,xcross        ; add increment
  934.     jns    noxc            ; gone too far negative?
  935.     mov    cx,0            ; yes - then make it 0
  936. noxc:    cmp    cx,temp            ; too far right?
  937.     jb    xdraw9            ; b = no
  938.     mov    cx,temp            ; yes - then make it the right
  939. xdraw9: mov    xcross,cx        ; new x value for cross hairs
  940.     jmp    crosha1            ; and redraw
  941.  
  942. vertkey:add    cx,ycross        ; adjust cx
  943.     jns    noyc            ; gone negative?
  944.     mov    cx,0            ; yes then make 0
  945. noyc:    cmp    cx,ybot            ; too high?
  946.     jb    yok
  947.     mov    cx,ybot            ; make it maximum
  948. yok:    mov    ycross,cx        ; save new y crosshair
  949.     jmp    crosha1            ; and redraw
  950.  
  951. charkey:call    clrbuf            ; purge received data to date
  952.     call    outmodem        ; send the break character
  953.     mov    ax,xcross        ; set beam to xcross,ycross
  954.     mov    bx,ycross        ; must convert to Tek coordinates
  955.     call    pctotek            ; scale from PC screen coord to Tek
  956.     push    ax            ; save around drawing
  957.     push    bx
  958.     mov    cx,0            ; just a move
  959.     call    tekdraw            ; moveto ax,bx in Tek coord
  960.     pop    bx            ; recover Tek y
  961.     pop    ax            ; recover Tek x
  962.     call    sendpos            ; send position report to host
  963.     pop    linepat            ; recover current line drawing pattern
  964.     mov    ttstate,offset tektxt    ; Go to TEKTXT next time
  965.     mov    lastc,0            ; clear last drawing coordinate flag
  966.     or    status,txtmode        ; set text mode in status byte
  967.     ret
  968. CROSHAIR ENDP
  969.  
  970. ; CROSDRAW draws cross-hairs by XORing cross with picture.
  971. ; xcross and ycross are in PC coordinates.
  972. CROSDRAW PROC    NEAR
  973.     mov    si,xcross        ; move to (xcross, ycross-10)
  974.     mov    di,ycross
  975.     sub    di,10            ; half the size of the cross
  976.     jns    crosd1            ; no sign bit means ok
  977.     mov    di,0            ; else limit to start of screen
  978. crosd1: mov    ax,si            ; next, draw to (xcross, ycross+10)
  979.     mov    bx,ycross        ; make bottom stroke
  980.     add    bx,10
  981.     cmp    bx,ybot            ; too large?
  982.     jbe    crosd2            ; be = no
  983.     mov    bx,ybot            ; vertical line to (xcross,ybot)
  984. crosd2: mov    cx,0ffh            ; invert pixels
  985.     call    line            ; and draw vertical
  986.     sub    si,12            ; move to (xcross-12, ycross)
  987.     jns    crosd3            ; no sign means ok
  988.     mov    si,0            ; else limit to start of line
  989. crosd3: mov    di,ycross
  990.     mov    bx,di
  991.     mov    ax,xcross        ; draw to (xcross+12, ycross)
  992.     add    ax,12
  993.     cmp    ax,temp            ; temp is right margin, too large?
  994.     jbe    crosd4            ; be = no, ok
  995.     mov    ax,temp            ; max x value
  996. crosd4: mov    cx,0ffh            ; set XOR code
  997.     call    line            ; draw to (xcross+12, ycross)
  998.     ret
  999. CROSDRAW ENDP
  1000.  
  1001. ; SENDPOS sends position of cross-hairs to the host.
  1002. ; ax has Tek X and bx has Tek Y coord of center of crosshair
  1003. SENDPOS PROC NEAR
  1004.     push    bx            ; preserve register
  1005.     call    sendxy            ; send x coord
  1006.     pop    ax
  1007.     call    sendxy            ; send y coord
  1008.     mov    al,cr            ; follow up with cr
  1009.     call    outmodem
  1010.     ret
  1011. SENDPOS ENDP
  1012.  
  1013. ; SENDXY sends value of ax as Tek encoded bytes
  1014. ; ax is in Tek coordinates
  1015. SENDXY    PROC    NEAR
  1016.     shl    ax,1
  1017.     shl    ax,1            ; move all but lower 5 bits to ah
  1018.     shl    ax,1
  1019.     shr    al,1
  1020.     shr    al,1            ; move low five bits to low 5 bits
  1021.     shr    al,1
  1022.     or    ah,20h            ; make it a printing char as per TEK
  1023.     xchg    al,ah            ; send high 5 bits first
  1024.     call    outmodem
  1025.     xchg    al,ah            ; then low five bits
  1026.     or    al,20h
  1027.     call    outmodem
  1028.     xchg    ah,al            ; al is first sent byte
  1029.     ret
  1030. SENDXY    ENDP
  1031.  
  1032.  
  1033. SENDID    PROC NEAR            ; Pretend VT100 with graphics option
  1034.     mov    bx,IDSEQ        ; Get addr of string
  1035. sndid1: mov    al,[bx]            ; Get char from sequence
  1036.     cmp    al,0            ; End of sequence?
  1037.     jz    sndid0            ; Yes, return
  1038.     call    OUTMODEM        ; Send it out the port
  1039.     inc    bx
  1040.     jmp    sndid1
  1041. sndid0: ret
  1042. SENDID    ENDP
  1043.  
  1044. ; SENDSTAT - send status and cursor position to host
  1045.  
  1046. SENDSTAT PROC NEAR
  1047.     mov    al,STATUS        ; get tek status
  1048.     or    al,20h            ; make it printable
  1049.     call    OUTMODEM        ; and send it
  1050.     mov    ax,oldx            ; now send x coordinate (oldx is Tek)
  1051.     call    SENDXY
  1052.     mov    ax,oldy            ; and y coordinate (oldy is Tek coord)
  1053.     call    SENDXY
  1054.     mov    al,cr            ; end with a cr
  1055.     call    OUTMODEM
  1056.     ret
  1057. SENDSTAT ENDP
  1058.  
  1059. ; routine to send al to the modem port
  1060.  
  1061. OUTMODEM PROC    NEAR
  1062.     push    ax
  1063.     mov    ah,al
  1064.     call    outchr            ; outchr reads from ah
  1065.      nop                ; ignore errors
  1066.      nop
  1067.      nop
  1068.     pop    ax
  1069.     ret
  1070. OUTMODEM ENDP
  1071.  
  1072. ; Convert X and Y from PC coordinates to Tek coordinates. AX = X, BX = Y
  1073. ; for both input and output.
  1074. pctotek proc    near
  1075.     mul    xdiv            ; scale from PC screen coord to Tek
  1076.     div    xmult
  1077.     xchg    bx,ax            ; save Tek x coord in bx
  1078.     neg    ax            ; y axis. Turn upside down for Tek
  1079.     add    ax,ybot
  1080.     mul    ydiv            ; scale y from PC screen coord to Tek
  1081.     div    ymult
  1082.     xchg    ax,bx            ; ax has X, bx has Y in Tek coords
  1083.     ret
  1084. pctotek endp
  1085.  
  1086. ; Routine to output character in AL to the screen.
  1087.  
  1088. OUTSCRN PROC NEAR            ; Output one character to the screen
  1089.     cmp    bypass,0        ; GIN mode bypass off?
  1090.     je    outscp            ; e = yes
  1091.     ret                ;  else ignore characters
  1092. outscp:                    ; Set Translation Input filter
  1093.     cmp    rxtable+256,0        ; translation turned off?
  1094.     je    outsct            ; e = yes, no translation
  1095.     push    bx
  1096.     mov    bx,offset rxtable    ; address of translate table
  1097.     xlatb                ; new char is in al
  1098.     and    al,7fh            ; retain only lower seven bits
  1099.     pop    bx
  1100. outsct: mov    ccode,1            ; normal text [jan]
  1101.     mov    si,ybot            ; get last scan line
  1102.     inc    si            ; number of scan lines
  1103.     sub    si,y_coord        ; minus where char bottom needs to go
  1104.     jnc    outscc            ; nc = enough space for char
  1105.                     ; took out more stuff [jan]
  1106.     mov    y_coord,0        ; back to top of screen [jan]
  1107.  
  1108. outscc: push    ax
  1109.     mov    ax,xmax
  1110.     cmp    x_coord,ax        ; beyond right margin?
  1111.     jbe    outsc3            ; be = no
  1112.     mov    al,cr            ; else simulate cr/lf
  1113.     call    putc            ; before displaying current char
  1114.     mov    al,lf
  1115.     call    putc
  1116. outsc3: pop    ax
  1117.     call    putc            ; routine to draw characters
  1118.     ret
  1119. OUTSCRN ENDP
  1120.  
  1121.  
  1122.  
  1123.  
  1124. ; TEKCLS routine to clear the screen.
  1125. ; Entry point tekcls1 clears screen without resetting current point.
  1126. TEKCLS    PROC    NEAR
  1127.     cmp    tekflg,0        ; Tek sub mode active yet?
  1128.     jne    tekcls0            ; ne = yes
  1129.     ret                ; else ignore this call
  1130. tekcls0:mov    x_coord,0        ; starting text coordinates
  1131.     mov    y_coord,8
  1132.     mov    oldx,0            ; assumed cursor starting location
  1133.     mov    oldy,maxteky        ;  top right corner (Tek coord)
  1134.     mov    scalex,0        ; clear last plotted point (PC coord)
  1135.     mov    scaley,0
  1136.     mov    lastc,0            ; last parsed x,y coordinate
  1137.     mov    visible,0        ; make lines invisible
  1138.     mov    linepat,0ffffh        ; reset line pattern to solid
  1139.     mov    ccode,1            ; reset to ordinary writing
  1140.     mov    bypass,0        ; clear bypass condition
  1141.     mov    ttstate,offset tektxt    ; do displayable text
  1142.     push    ax
  1143.     mov    ax,xmax            ; right margin minus 7 dots
  1144.     add    ax,7            ; right most dot
  1145.     shr    ax,1            ; central position
  1146.     mov    xcross,ax        ; save PC coord for crosshair
  1147.     mov    ax,ybot            ; last scan line
  1148.     shr    ax,1
  1149.     mov    ycross,ax        ; this is the center of the screen
  1150.     pop    ax
  1151.  
  1152. tekcls1:push    ax            ; save registers
  1153.     push    cx
  1154.     call    cmblnk            ; clear the screen
  1155. tekcls7:mov    si,0            ; starting x  (in case screen is
  1156.     mov    di,0            ; starting y    cleared by user)
  1157.     pop    cx
  1158.     pop    ax
  1159.     ret
  1160. TEKCLS    ENDP
  1161.  
  1162.  
  1163.  
  1164. ; Routine to draw a line on the screen, using TEKTRONIX coordinates.
  1165. ; X coordinate in AX, 0=left edge of screen, 1023=right edge of screen.
  1166. ; Y coordinate in BX, 0=bottom of screen, 779=top of screen.
  1167. ; CL=0 - invisible move, CL=1 - draw a line, CL=0FFh - invert pixels on line
  1168.  
  1169. TEKDRAW PROC NEAR
  1170.     mov    si,scalex        ; get old x already scaled
  1171.     mov    di,scaley        ; get old y already scaled
  1172.     call    scale            ; scale new end point to PC coords
  1173.     cmp    cl,0            ; invisible drawing?
  1174.     je    moveto            ; z = just move, skip draw part
  1175.     call    LINE            ; draw the line
  1176. moveto: mov    x_coord,ax        ; update text coordinates to match
  1177.     mov    y_coord,bx        ;  last drawn point
  1178.     ret
  1179. TEKDRAW ENDP
  1180.  
  1181. ; Scale TEKTRONIX coordinates to the currently defined screen coordinates
  1182. ; AX holds X axis, BX holds Y axis. Both are changed from Tektronix coord
  1183. ; to PC coordinates by this procedure.
  1184. SCALE    PROC    NEAR
  1185.     push    dx
  1186.     push    si
  1187.     mov    oldx,ax            ; save current Tek x for next draw
  1188.     mov    oldy,bx            ; save current Tek y for next draw
  1189.     mul    xmult            ; scale x-coord
  1190.     mov    si,xdiv            ; get the divisor
  1191.     shr    si,1            ; halve it
  1192.     add    ax,si            ; add in - to round to nearest integer
  1193.     adc    dx,0
  1194.     div    xdiv
  1195.     cmp    oldx,maxtekx-1        ;at right of screen? [jan]
  1196.     jne    scale2               ;ne means not at edge [jan]
  1197.     mov    ax,xmax             ;right of display on PC [jan]
  1198.     add    ax,7             ;[jan]
  1199. scale2: push    ax
  1200.     mov    ax,bx
  1201.     mul    ymult            ; scale y-coord
  1202.     mov    si,ydiv            ; get divisor
  1203.     shr    si,1            ; halve it
  1204.     add    ax,si            ; add in - to round to nearest integer
  1205.     adc    dx,0
  1206.     div    ydiv
  1207.     mov    bx,ybot
  1208.     sub    bx,ax            ; Put new Y in right reg
  1209.     jns    scale3            ; ns = not too far
  1210.     mov    bx,0
  1211. scale3: pop    ax            ; Put new X in right reg
  1212.     mov    scalex,ax        ; save scaled values
  1213.     mov    scaley,bx
  1214.     pop    si
  1215.     pop    dx
  1216.     ret
  1217. SCALE    ENDP
  1218.  
  1219. ; LINE    Subroutine to plot a line with endpoints in AX,BX and SI,DI.
  1220. ;    fast line drawing routine for the IBM PC
  1221. ;
  1222. ; Registers at CALL
  1223. ; -----------------
  1224. ; SI=Start X coord, all in PC coordinates
  1225. ; DI=Start Y coord
  1226. ; AX=End X coord
  1227. ; BX=End Y coord
  1228. ; CL=Color code: 1=draw foreground, 0=draw background, 0ffh=invert
  1229. ; BP= line drawing pattern (is changed here by rotation)
  1230. ; registers are all unchanged
  1231.  
  1232. LINE    PROC    NEAR
  1233.     push    ax
  1234.     push    bx
  1235.     push    cx
  1236.     push    dx
  1237.     push    si
  1238.     push    di
  1239.     push    es
  1240.     mov    bp,linepat        ; store active line pattern word in BP
  1241.     mov    ccode,cl    ; save color code in ccode for use by plot()
  1242.             ; first get coord to achieve increasing x; deltax >= 0
  1243.     sub    ax,si            ; deltax = x2 - x1
  1244.     jge    line1            ; ge = going to the right, as desired
  1245.     neg    ax            ; make deltax non-negative
  1246.     sub    si,ax            ; swap the x coordinates
  1247.     xchg    bx,di            ; swap the y coordinates too
  1248.                 ; second, compute deltay. ax = deltax, si = x1
  1249. line1:    sub    bx,di            ; deltay = y2 - y1
  1250.     call    psetup            ; setup display adapter for plotting
  1251.                     ;  and setup es:di to screen memory
  1252.   ; Choose algorithm based on |deltay| < |deltax| (use shallow) else steep.
  1253.   ; We arrange matters such that both deltas are non-negative.
  1254.     cmp    bx,0            ; deltay
  1255.     jge    line2            ; ge = non-negative
  1256.     neg    linelen
  1257.     neg    bx            ; make non-negative
  1258. line2:    cmp    bx,ax            ; |deltay| versus |deltax|
  1259.     jbe    shallow            ; be = do shallow algorithm
  1260.     jmp    steep            ; else do steep algorithm
  1261.  
  1262.     ; shallow algorithm, move along x, di=y1, bx=deltay, si=x1, ax=deltax
  1263. shallow:add    bx,bx            ; bx = 2*deltay
  1264.     mov    cx,ax            ; cx = number of steps (deltax here)
  1265.     inc    cx            ; loop dec's cx before testing
  1266.     mov    dx,bx            ; dx holds error
  1267.     sub    dx,ax            ; error = 2*deltay - deltax
  1268.     add    ax,ax            ; ax = 2*|deltax|
  1269. shal1:    call    plotptr            ; Plot(x,y)
  1270.     cmp    dx,0
  1271.     jle    shal2            ; le =     error <= 0
  1272.     call    pincy            ; increment y by one scan line
  1273.     sub    dx,ax            ; error = error - 2*deltax
  1274. shal2:    add    dx,bx            ; error = error + 2*deltay
  1275.     inc    si            ; x = next dot right
  1276.     loop    shal1
  1277. shal3:    jmp    short plotex
  1278.  
  1279.     ; steep algorithm, move along y, di=y1, bx=deltay, si=x1, ax=deltax
  1280. steep:    add    ax,ax            ; ax = 2*deltax
  1281.     mov    dx,ax            ; dx holds error
  1282.     sub    dx,bx            ; error = 2*deltax(bx) - deltay (bx)
  1283.     mov    cx,bx            ; cx = number of steps (deltay here)
  1284.     inc    cx            ; loop dec's cx before testing
  1285.     add    bx,bx            ; bx = 2*|deltay|
  1286. stee1:    call    plotptr            ; Plot(x,y) x = ax, y = di
  1287.     cmp    dx,0
  1288.     jle    stee2            ; le  error <= 0
  1289.     inc    si            ; x = next dot right
  1290.     sub    dx,bx            ; error = error - 2*deltay
  1291. stee2:    add    dx,ax            ; error = error + 2*deltax
  1292.     call    pincy            ; increment y
  1293.     loop    stee1
  1294. stee3:;;;jmp    plotex
  1295.  
  1296. plotex: mov    ccode,1            ; reset to do foreground coloring
  1297.     pop    es
  1298.     pop    di
  1299.     pop    si
  1300.     pop    dx            ; restore the world
  1301.     pop    cx
  1302.     pop    bx
  1303.     pop    ax
  1304.     ret
  1305. LINE    ENDP
  1306.  
  1307.  
  1308.  
  1309. ;;;;;;;; CGA plot support routines
  1310. ; The CGA graphics memory mapping in mode 6 (640 by 200) is 8 dots per byte,
  1311. ; left most dot in the high bit, 80 bytes per scan line, scan line segments
  1312. ; alternating between 0b800h (even lines 0, 2, ...) and 0ba00h (odd lines).
  1313. psetupc proc    near            ; CGA setup for plotting
  1314.     push    ax
  1315.     push    cx
  1316.     mov    ax,linebytes
  1317.     mov    linelen,ax         ; 40 bytes per scan line
  1318.     mov    cx,segscn        ; small grid scn [jan]
  1319.     mov    es,cx
  1320.     mov    cx,di            ; save copy of di, start y line
  1321.                     ; compute starting point in regen buff
  1322.     mov    ax,linebytes        ;  bytes per line [jan]
  1323.     mul    di
  1324.     mov    di,ax            ; di = di * linebytes
  1325.     pop    cx
  1326.     pop    ax
  1327.     ret
  1328. psetupc endp
  1329.  
  1330. pincyc    proc    near            ; CGA inc y
  1331.     add    di,linelen        ; add a line
  1332.     ret
  1333. pincyc    endp
  1334.  
  1335. pltcga    proc    near        ; CGA plot(x,y). x is in si, y is in di
  1336.     push    bx        ; used for HGA plot also.
  1337.     push    si
  1338.     push    di
  1339.     rol    bp,1            ; rotate line pattern
  1340.     jnc    pltcg3            ; nc = no bit to be plotted
  1341.     mov    bx,si            ; want si/8 for bytes along line
  1342.     shr    si,1
  1343.     shr    si,1
  1344.     shr    si,1
  1345.     xor    si,1            ;bytes in hl order on GRiD [jan]
  1346.     add    di,si            ; starting point in regen buffer
  1347.     and    bx,0007h        ; leave lower 3 bits for bit in byte
  1348.                     ; di = offset in regen buffer
  1349.     mov    bh,masktab[bx]        ; 0-7 into bit mask in byte. x position
  1350.     mov    bl,ccode        ; get line type code
  1351.     cmp    bl,1            ; draw the bit?
  1352.     jne    pltcg1            ; ne = no
  1353.     or    es:[di],bh        ; drawn
  1354.     jmp    short pltcg3
  1355. pltcg1: cmp    bl,0            ; draw in background (erase)?
  1356.     jne    pltcg2            ; ne = no
  1357.     not    bh
  1358.     and    es:[di],bh        ; erase the dots
  1359.     jmp    short pltcg3
  1360. pltcg2: xor    es:[di],bh        ; xor in this color
  1361. pltcg3: pop    di
  1362.     pop    si
  1363.     pop    bx
  1364.     ret
  1365. pltcga    endp
  1366.  
  1367.  
  1368. ; GPUTC - a routine to send text characters from font to true graphics boards
  1369. ; such as EGA, Hercules or CGA. Char is in al. Drawing routine ptr is gcplot.
  1370.  
  1371. gputc    proc    near
  1372.  
  1373.     cmp    al,' '            ; control character?
  1374.     jae    gputc1            ; ae = no, display the char
  1375.     jmp    putctrl            ; else handle controls at putctrl
  1376. gputc1: push    ax            ; first save some registers
  1377.     push    bx
  1378.     push    cx
  1379.     push    es
  1380.     push    di
  1381.     mov    bl,al            ; now BL has char to be displayed
  1382.     and    bl,7fh            ; no high bits allowed here
  1383.                     ; set board mode
  1384.     mov    di,y_coord        ; get current y coord (char bottom)
  1385.     sub    di,8            ; start 8 lines higher
  1386.     jnc    gputc2            ; nc = ok
  1387.     mov    di,0            ; move up to first line
  1388.     mov    y_coord,8        ; and reset scan line indicator
  1389. gputc2: call    psetup        ; enter with di=line number, sets es:di to
  1390.                 ; start of line in display buf and
  1391.                 ; sets byte-wide plot mode
  1392.     mov    ax,x_coord        ; compute regen buffer byte
  1393.     shr    ax,1            ; want x_coord/8 for bytes along line
  1394.     shr    ax,1
  1395.     shr    ax,1
  1396.     xor    ax,1           ;bytes in hl order on grid [jan]
  1397.     add    di,ax            ; byte in regen buffer
  1398.     xor    bh,bh
  1399.     sub    bx,32            ; characters in font start at 32
  1400.     shl    bx,1
  1401.     shl    bx,1            ; 8 bytes per char - hence * 8
  1402.     shl    bx,1
  1403.     mov    cx,8            ; 8 bytes (scan lines) to transfer
  1404.     call    gcplot            ; call character plot routine
  1405.     call    incx            ; move to next char position
  1406.     pop    di
  1407.     pop    es
  1408.     pop    cx
  1409.     pop    bx
  1410.     pop    ax
  1411.     ret
  1412. gputc    endp
  1413.  
  1414. putctrl proc    near            ; CONTROL CHARS = cursor movement
  1415.     push    ax            ; save character
  1416.     cmp    al,FF            ; formfeed?
  1417.     jne    putct0            ; ne = no
  1418.     call    TEKCLS            ; FF clears the screen
  1419.     jmp    putctx
  1420. putct0: cmp    al,BS            ; BS? sends (logical) cursor back one
  1421.     jne    putct2            ; ne = no, try next
  1422.     mov    ax,x_coord
  1423.     sub    ax,8            ; so delete 8 dots (move left)
  1424.     jns    putct1            ; ns = non-negative
  1425.     mov    ax,0            ; but not less than 0
  1426. putct1: mov    x_coord,ax        ; and replace x coordinate
  1427.     mov    al,' '            ; send a space
  1428.     call    putc
  1429.     sub    x_coord,8        ; restore cursor
  1430.     jmp    putctx
  1431. putct2: cmp    al,tab            ; tabs move forward one char position
  1432.     jne    putct4            ; ne = not a tab
  1433.     call    incx            ; let incx move cursor right one col
  1434.     jmp    putctx
  1435. putct3: mov    x_coord,ax
  1436.     jmp    putctx
  1437. putct4: cmp    al,cr            ; <CR> means go to beginning of line
  1438.     jne    putct5
  1439.     mov    x_coord,0        ; zero the x coordinate
  1440.     jmp    putctx
  1441. putct5: cmp    al,lf            ; <LF> means go down 8 pixels (1 line)
  1442.     jne    putct7            ; ne = not LF
  1443.     add    y_coord,8        ; border managed by outscrn and incx
  1444.     jmp    putctx
  1445. putct7: cmp    al,vt            ; <VT> move up screen 1 line (8 pixels)
  1446.     jne    putctx
  1447.     sub    y_coord,8        ; subtract one line (8 pixels)
  1448.     jnc    putctx            ; nc = space left
  1449.     mov    y_coord,8        ; else set to top of screen
  1450. putctx: pop    ax
  1451.     ret
  1452. putctrl endp
  1453.  
  1454.  
  1455. incx    proc    near            ; move the logical cursor right
  1456.     mov    ax,x_coord        ; shift the (logical) cursor right
  1457.     add    ax,8            ;  one character cell
  1458.     mov    x_coord,ax
  1459.     cmp    ax,xmax            ; at end of the line?
  1460.     jbe    incx1            ; b = no
  1461.     mov    x_coord,0        ; wrap to next line
  1462.     add    y_coord,8        ; next row
  1463.     mov    ax,ybot            ; last scan line
  1464.     cmp    ax,y_coord        ; below bottom line?
  1465.     jge    incx1            ; ge = no
  1466.     mov    y_coord,ax        ; set to bottom row
  1467.     mov    al,lf            ; simulate a line feed operation
  1468.     call    outscrn            ; invoke More message
  1469. incx1:    ret
  1470. incx    endp
  1471.  
  1472.  
  1473. ; General Character plot routine. Enter with bx pointing at font array for
  1474. ; char, cx = number of bytes in char font, es:di = screen memory.
  1475. ; Worker for gputc.
  1476.  
  1477. gcgen    proc    near
  1478. gcgen1: mov    al,font[bx]        ; Non-EGA systems: get bits from font
  1479.     cmp    ccode,1            ; write in foreground?
  1480.     je    gcgen2            ; e = yes
  1481.     xor    es:[di],al        ; background or xor (same)
  1482.     jmp    short gcgen3
  1483. ;;;;    mov    es:[di],al        ; write desired pattern (no overwrite)
  1484. gcgen2: OR    es:[di],al        ; write desired pattern (no overwrite)
  1485. gcgen3: inc    bx            ; point to next byte of char pattern
  1486.     call    pincy            ; next scan line (linelen is preset)
  1487.     loop    gcgen1            ; and repeat until complete
  1488.     ret
  1489. gcgen    endp
  1490.  
  1491.  
  1492. teksave proc    near        ; saves graphics screen
  1493.                 ; mimic procedure in msxgri.asm [jan]
  1494.     ret
  1495. teksave endp
  1496.  
  1497. tekrest proc    near        ; saves graphics screen of page 0 in page 1
  1498.     push    si
  1499.     push    di
  1500. ; need to mimic the procedure in msxgri.asm for restoring a screen
  1501. tekresx:pop    di
  1502.     pop    si
  1503.     ret
  1504. tekrest endp
  1505.  
  1506. code    ends
  1507.     end
  1508.  
  1509.