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

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