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

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