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

  1.         NAME    msx55x
  2. ; File MSX55X.ASM
  3. ; Kermit system dependent module for Sanyo MBC-55x
  4. ; Sanyo mods by Robert W. Babcock and Joseph H. White
  5. ; For version which replaces the BIOS keycode translation table,
  6. ;  use -dMODIFIED flag to MASM.
  7. ; Edit History
  8. ; Last edit 16 Oct. 1988, only call pcwtst on first serini call
  9. ; 1 Jan 1988 version 2.30
  10. ; 24 Dec 1987 Revise selection of COM1 to use COM1 name but COM2 addresses
  11. ;  if base address of 02f8 (COM2) is found in 40:00h and display notice.
  12. ;  Restore state of IRQ interrupt line when finished with serial port. [jrd]
  13. ; 31 Oct 1987 Add terminal type Tek4010, with Tek submode Tekflg. [jrd]
  14. ; 24 Oct 1987 Enhance clrbuf to empty any intermediate (net) buffers. [jrd]
  15. ; 19 Oct 1987 Fix stray tab-set at column 32. [jrd]
  16. ; 2 Oct 1987 Add PCjr baud rate table, from Ted Medin. [jrd]
  17. ; 6 Sept 1987 Allow serial port serint to send xoff when buffer fills even
  18. ;  though user may have sent xoff by hand. [jrd]
  19. ; 27 Aug 1987 Skip timeout test in OUTCHR if receive timeout is zero. [jrd]
  20. ; 23 August 1987 Add vtemu.vtflgop to hold runtime terminal settings so that
  21. ;  a reset command restores them to the Setup values, vtemu.vtflgst. Show
  22. ;  displays the vtemu.vtflgop operational values. [jrd]
  23. ; 17 August 1987 Make timing adjustments for Token Passing and single buffered
  24. ;  network adapter boards. Byte netdbfr indicates presence of double buffering;
  25. ;  it is set in chknet as a vendor option. To test your boards force dbl buf
  26. ;  then look for missing 256 byte parts of long packets sent out; missing parts
  27. ;  mean new material overwrote not-yet-sent old == single buffering. [jrd]
  28. ; 8 August 1987 Add interrupt chaining in serint. [jrd]
  29. ; 23 July 1987 Clear xofsnt and xofrcv xon/xoff flags in ihost(s/r). [jrd]
  30. ; 9 July 1987 Cure confusion about COM1/2 for IBM PCjr (address of regular
  31. ;  COM2 in 40:0h slot for COM1) with info from John Neufeld. [jrd]
  32. ; 2 July 1987 Route NetBios cancels through separate scb for systems, such
  33. ;  as Novell NetWare, which object to having active scbs touched. [jrd]
  34. ; 25 June 1987 Add trapping of Int 14H (Bios RS232 procedure) to allow
  35. ;  CTTY command to function without too much inteference from DOS. [jrd]
  36. ; 17 June 1987 Enlarge tab setting to full 132 columns at all times. [jrd]
  37. ; 11 June 1987 Add Set Term Roll on/off to control auto roll back of screen
  38. ;  when new characters are displayed; default is off (no unwinding). [jrd]
  39. ; 20 May 1987 Remove rejection of NULL and DEL chars, let callers do it. [jrd]
  40. ; 16 May 1987 Add distinction between user typed and receiver threshold
  41. ;  controlled sending of XOFF. User level overrides buffer control.[jrd]
  42. ;  Add COM3 and COM4 support: examine memory 40:00h->40:07h for selected
  43. ;  port COM1..4, resp. If word is null then set flags.comflg to 0 to say
  44. ;  undefined port. Otherwise, use that word in seg 40h as base of UART i/o
  45. ;  ports. Assume IRQ4 for COM1 and COM3 (same except for port addresses)
  46. ;  and IRQ4 for  COM2 and COM4 (again, same except for port addresses).
  47. ;  Serial port info sturcture (not values) assumed identical for all ports.
  48. ; 25 April 1987 Add Netbios compatible local area network support. [jrd]
  49. ;  Set Port command expanded to syntax SET PORT NET nodename. Use nodename
  50. ;  if acting as a client to named remote node, leave blank if running in
  51. ;  Server mode. Byte 'ttyact' is controlled by msster.asm to indicate Connect
  52. ;  mode is being used. Byte 'netdone' (stored in mssker.asm) holds offset of
  53. ;  network hangup procedure 'netclose' to be done when leaving Kermit. Hangup
  54. ;  command extended to to network hangup as well. Network uses IBM Netbios
  55. ;  standard calls (Int 5Ch) and allows for extensions of AT&T STARLAN for
  56. ;  longer node names via Int 2Bh (the later is tested before use). Virtual
  57. ;  circuits are employed. The Redirector is not necessary. Kermit can operate
  58. ;  as either a terminal (does a CALL at Connect mode startup), a file receiver
  59. ;  (does a CALL at startup), or a Kermit server (does an anonomous LISTEN at
  60. ;  startup, hence no nodename). Clients should Set Timer Off.
  61. ; 16 April 1987 Add measurement and correction of software timer pcwait. [jrd]
  62. ; 5 April 1987 Keep DTR & RTS low for 1/2 second in serhng, suggested by
  63. ;  Jack Bryans. [jrd]
  64. ; 28 March 1987 Reference screen coord wrt low_rgt from msyibm, let number
  65. ;  of tabs be full screen width. [jrd]
  66. ; 22 March 1987 Fix bug in pcwait code, from Stefan Vogel. [jrd]
  67. ; 6 March 1987 Make PCWAIT a global procedure, add SENDBL to send Long
  68. ;  Break. [jrd]
  69. ; 21 Feb 1987 Merge operations for semi-clone machines (those identical to
  70. ;  IBM PC's except the serial port must be accessed via the Bios rather than
  71. ;  from the real UART hardware). Ports automatically checked for 8250. [jrd]
  72. ; 1 Oct 1986 Version 2.29a
  73. ; 30 Sept 1986 Reject DEL char at serial port reception level to avoid
  74. ;  problems when DEL is used as a filler char (by Emacs). [jrd]
  75. ; 4 Sept 1986 Add Bob Goeke's change to move comms port table to a system
  76. ;  dependent module (typ msx---) to allow 3+ ports and localized idents. [jrd]
  77. ; 26 August 1986 Use parity mask when testing for nulls & Xon/Xoff in serial
  78. ;  port interrupt routine. [jrd]
  79. ; 16 August 1986 Use observed screen attributes for mode line. [jrd]
  80. ; 9 August 1986 Revise SERINT to insert control-G for overrun chars, give
  81. ;  faster return of interrupts to system, remove use of BP in code. [jrd]
  82. ; 17 July 1986 Minor clean up of Terminal Status display routine. [jrd]
  83. ; 22 June 1986 Leave 8250 UART signal OUT1 low to avoid resetting Hayes
  84. ;  1200B modems (thanks to Neil Rickert). [jrd]
  85. ;  Skip sending null byte in ihosts and ihostr (thanks to Skip Russell). [jrd]
  86. ; 22 May 1986 Rewrite serial port interrupt procedure and proc prtchr
  87. ;  to avoid lockups with interrupts disabled, buffer corruption, and to
  88. ;  minimize lost clock interrupts. Flow control not needed at 9600 baud,
  89. ;  slow screen refresh, VT102 emulation, on a 4.77 MHz IBM PC clone.
  90. ;  Added buffer low water mark to give more xon/xoff hysterisis. [jrd]
  91. ; [2.29] code frozen on 6 May 1986 [jrd]
  92. ; Note -
  93. ; When the Bios is used for serial port i/o the modem signals DSR and CTS
  94. ; must be asserted low before the Bios will access the hardware. Jumpers
  95. ; from pin 20 (DTR) to pin 6 (DSR) and from pin 4 (RTS) to pin 5 (CTS)
  96. ; will probably be necessary.
  97. ;       From Glenn Everhart (who suggested using the Bios alternative)
  98. ;
  99.         public  serini, serrst, clrbuf, outchr, coms, vts, vtstat
  100.         public  dodel, ctlu, cmblnk, locate, prtchr, dobaud, clearl
  101.         public  dodisk, getbaud, beep, termtb, shomodem
  102.         public  count, xofsnt, puthlp, putmod, clrmod, poscur
  103.         public  sendbr, sendbl, machnam, setktab, setkhlp, lclini, showkey
  104.         public  ihosts, ihostr, dtrlow, serhng, comptab, pcwait
  105.         public  perrcnt         ; for debugging -- [jhw]
  106.         include mssdef.h
  107.  
  108. off     equ     0
  109. bufon   equ     1               ; buffer level xon/xoff on-state control flag
  110. usron   equ     2               ; user level xon/xoff on-state control flag
  111.  
  112. mntrgh  equ     bufsiz*3/4      ; High point = 3/4 of buffer full.
  113. mntrgl  equ     bufsiz/4        ; Low point = 1/4 buffer full
  114.  
  115. MCONF   EQU     11H             ; Bios Machine configuration s/ware interrupt.
  116. KEYB    EQU     16H             ; Bios keyboard software interrupt
  117. VIDEO   EQU     10H             ; Bios Video display software interrupt
  118. RS232   EQU     14H             ; Bios RS232 serial port s/ware interrupt
  119.  
  120. ; constants used by serial port handler
  121. MDMINP  equ     1       ; BIOS data ready mask flag
  122.  
  123. ; 8251A serial communications device
  124. BUF8251 EQU     028h            ; I/O address of 8251 in/out buffer
  125. CMD8251 EQU     02Ah            ; I/O address of 8251A command buffer
  126. STS8251 EQU     02Ah            ; I/O address of 8251A status buffer
  127. VEC8251 EQU     0FAh            ; 8251A interrupt vector number
  128. INT8251 EQU     0FBh            ; 8259A interrupt enable mask (int 2)
  129. ; 8251A Command instruction formats
  130. TxEN    EQU     1               ; transmit enable
  131. DTR     EQU     2               ; data terminal ready
  132. RxEN    EQU     4               ; receiver enable
  133. SBRK    EQU     8               ; send break
  134. ERRESET EQU     10h             ; error reset
  135. RTS     EQU     20h             ; request to send
  136. INTRLRS EQU     40h             ; internal reset
  137. ; 8251A Status read formats
  138. TxRDY   EQU     1               ; transmitter ready
  139. RxRDY   EQU     2               ; receiver ready
  140. TxEMPTY EQU     4               ; transmit buffer empty
  141. PARERR  EQU     8               ; parity error
  142. OVRRUN  EQU     10h             ; overrun error
  143. FRAMERR EQU     20h             ; framing error
  144. BRKDET  EQU     40h             ; break detect
  145. DSR     EQU     80h             ; data set ready
  146. ; 8253 timer device
  147. TIMER0DATA EQU  20h             ; I/O address of counter #0
  148. TIMER1DATA EQU  22h             ; I/O address of counter #1
  149. TIMER2DATA EQU  24h             ; I/O address of counter #2
  150. CMD8253 EQU     26h             ; I/O address of counter control
  151. ; 8259A interrupt controller
  152. CMA8259 EQU     0               ; I/O address of command buff 1
  153. CMB8259 EQU     2               ; I/O address of command buff 2
  154.  
  155. ; external variables used:
  156. ; drives - # of disk drives on system
  157. ; flags - global flags as per flginfo structure defined in pcdefs
  158. ; trans - global transmission parameters, trinfo struct defined in pcdefs
  159. ; portval - pointer to current portinfo structure (only port1) [rwb]
  160. ; port1 - portinfo structures for the port [rwb]
  161. ; low_rgt - low byte = last column (typ 79), high byte = last text row
  162. ;  (typ 23) in screen coordinates (start at 0), set by msyibm.
  163.  
  164. ; global variables defined in this module:
  165. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  166. ; setktab - keyword table for redefining keys (should contain a 0 if
  167. ;    not implemented)
  168. ; setkhlp - help for setktab.
  169.  
  170. datas   segment public 'datas'
  171.         extrn   drives:byte, flags:byte, trans:byte, ttyact:byte
  172.         extrn   portval:word, port1:byte, port2:byte, port3:byte, port4:byte
  173.         extrn   netdone:word, pcnet:byte
  174.         extrn   refresh:byte, scbattr:byte, low_rgt:word, vtemu:byte
  175.         extrn   vtroll:byte, tekflg:byte
  176.         extrn   crt_mode:byte                           ; [jhw]
  177.  
  178. ; structure for status information table sttab.
  179. stent   struc
  180. sttyp   dw      ?               ; type (actually routine to call)
  181. msg     dw      ?               ; message to print
  182. val2    dw      ?               ; needed value: another message, or tbl addr
  183. tstcel  dw      ?               ; address of cell to test, in data segment
  184. basval  dw      0               ; base value, if non-zero
  185. stent   ends
  186.  
  187. setktab db      0               ; superceded by msuibm code, return 0 here
  188. setkhlp db      '$'             ; and add empty help string
  189.  
  190. savsci  dd      ?               ; old serial port interrupt vector.
  191. sav232  dd      ?               ; Original Bios Int 14H address, in Code seg.
  192. savirq  db      ?               ; Original Interrupt mask for IRQ
  193. hngmsg  db      cr,lf,' The phone should have hungup.'
  194.         db      cr,lf,'$'
  195. nohngmsg db     cr,lf,' Command ineffective on this port.',cr,lf,'$'
  196. hnghlp  db      cr,lf,' The modem control lines DTR and RTS for the current'
  197.         db      ' port are forced low (off)'
  198.         db      cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  199.         db      ' high (on) when it exits.',cr,lf
  200.         db      '$'
  201. erms40  db      cr,lf,'?Warning: Unrecognized baud rate',cr,lf,'$'
  202. badbd   db      cr,lf,'Unimplemented baud rate$'
  203. prterr  db      '?Unrecognized value$'
  204. msmsg1  db      cr,lf,' Modem is not ready: DSR is off$'
  205. msmsg2  db      cr,lf,' Modem is ready:     DSR is on$'
  206.  
  207. machnam db      'Sanyo 55x'
  208. ifdef MODIFIED
  209.         db      ' (Modifies BIOS keycodes)'
  210. endif
  211.         db      '$'
  212. crlf    db      cr,lf,'$'
  213. delstr  db      BS,BS,'  ',BS,BS,'$'    ; Delete string
  214. clrlin  db      cr,'$'                  ; Clear line (just the cr part).
  215. onmsg   db      'on$'
  216. offmsg  db      'off$'
  217. portin  db      0               ; Has comm port been initialized
  218. xofsnt  db      0               ; Say if we sent an XOFF.
  219. xofrcv  db      0               ; Say if we received an XOFF.
  220. parmsk  db      ?               ; parity mask, 0ffh for no parity, 07fh with.
  221. flowoff db      ?               ; flow-off char, Xoff or null (if no flow)
  222. flowon  db      ?               ; flow-on char, Xon or null
  223. overrun db      ?               ; holds status of receiver overrun
  224. pcwcnt  dw      240             ; number of loops for 1 millisec in pcwait
  225. temp    dw      0
  226. tempsci dw      0               ; temp storage for serint
  227. tempdum dw      0               ; temp storage for serdum
  228. rdbuf   db      80 dup (?)      ; temporary storage
  229.                                         ; begin Terminal emulator data set
  230. termtb  db      tttypes                 ; entries for Status, not Set
  231.         mkeyw   'Heath-19',ttheath
  232.         mkeyw   'none',ttgenrc
  233.         mkeyw   'Tek4010',tttek
  234.         mkeyw   'VT102',ttvt100
  235.         mkeyw   'VT52',ttvt52
  236.  
  237. vttbl   db      15                      ; number of entries.
  238.         mkeyw   'Character-set',chaval
  239.         mkeyw   'Color',200H            ; screen fore/back colors; 200H=marker
  240.         mkeyw   'Cursor-style',curval
  241.         mkeyw   'Heath-19',ttheath+100H ; note 100H flag for decoding here
  242.         mkeyw   'Keyclick',keyval
  243.         mkeyw   'Margin-bell',marval
  244.         mkeyw   'None',ttgenrc+100H
  245.         mkeyw   'Newline',newval
  246.         mkeyw   'Rollback',400h         ; note 400H flag for decoding
  247.         mkeyw   'Screen-background',scrval
  248.         mkeyw   'Tabstops',tabval
  249.         mkeyw   'Tek4010',tttek+100H
  250.         mkeyw   'VT102',ttvt100+100H
  251.         mkeyw   'VT52',ttvt52+100H
  252.         mkeyw   'Wrap',wraval
  253.  
  254. scrtab  db      02H                     ; screen attributes
  255.         mkeyw   'normal',00H
  256.         mkeyw   'reverse',01H
  257.  
  258. curtab  db      02H                     ; cursor attributes
  259.         mkeyw   'block',00H
  260.         mkeyw   'underline',01H
  261.  
  262. chatab  db      02H                     ; character set (pound sign choice)
  263.         mkeyw   'UK-ascii',01H
  264.         mkeyw   'US-ascii',00H          ; US ASCII is default (0).
  265.  
  266. tabtab  db      02H                     ; label says it all!
  267.         mkeyw   'at',0FFH               ; For setting tab stops.
  268.         mkeyw   'Clear',00H             ; For clearing tab stops.
  269.  
  270. alltab  db      02H                     ; more tab command decoding
  271.         mkeyw   'all',00H
  272.         mkeyw   'at',01H
  273.  
  274. vtable  dw      ontab, curtab, chatab, ontab, ontab, ontab, scrtab, 0
  275.  
  276. vtsflg equ      this byte               ; define small digits xxxval
  277. newval  equ     $-vtsflg                ; and mask for bit in byte
  278.         db      vsnewline
  279. curval  equ     $-vtsflg
  280.         db      vscursor
  281. chaval  equ     $-vtsflg
  282.         db      vsshift3
  283. keyval  equ     $-vtsflg
  284.         db      vskeyclick
  285. wraval  equ     $-vtsflg
  286.         db      vswrap
  287. marval  equ     $-vtsflg
  288.         db      vsmarginbell
  289. scrval  equ     $-vtsflg
  290.         db      vsscreen
  291. numflgs equ     $-vtsflg
  292. tabval  equ     $-vtsflg
  293.         db      0
  294. vtrtns  dw      numflgs dup (flgset), tabset ; dispatch table for vtsflg
  295.  
  296. clrset  db      ?                       ; Temp for SET Term Tabstops xxx
  297. tmptabs db      80D dup (?)             ; Temporary for unconfirmed tabs.
  298.  
  299. vthlp   db      ' one of the following:',cr,lf
  300.       db '  terminal types of:  None, Heath-19, VT52, VT102, or Tek4010',cr,lf
  301.         db '  Newline-mode    Cursor-style        Character-set (US UK)',cr,lf
  302.         db '  Keyclick        Margin-bell         Screen-background'
  303.         db      ' (normal, reverse)',cr,lf
  304.         db '  Tabstops        Wrap (long lines)   Color (fore & background)'
  305.         db cr,lf,'  Roll (undo screen roll back before writing new chars,'
  306.         db      ' default=off)$'
  307.  
  308. clrhlp  db      ' one of the following:'
  309.         db      cr,lf,'  AT  #s  (to set tabs at column #s)'
  310.         db      cr,lf,'  Clear AT #s  or  Clear ALL  (to clear tabstops)'
  311.         db      cr,lf,'  Ex: Set Term Tab at 10, 20, 34        sets tabs'
  312.         db      cr,lf,'  Ex: Set Term Tab Clear at 9, 17, 65   clears tabs$'
  313. allhlp  db      ' one of the following:'
  314.         db      cr,lf,'  AT #s (to clear at specific columns)'
  315.         db      cr,lf,'  ALL   (to clear all tabstops)$'
  316. tbshlp  db      '  column number of tab stop to set, 1-79$'
  317. tbchlp  db      '  column number of tab stop to clear, 1-79$'
  318. tbserr  db      cr,lf,'?Column number is not in range 1-79$'
  319. colhlp  db      cr,lf,'  Set Term Color  value, value, value, ...'
  320.         db      '    commas are optional.'
  321.         db      cr,lf,'   0 selects normal white on black and'
  322.         db      ' no-snow mode on an IBM CGA (default).'
  323.         db      cr,lf,'   1 for high intensity foreground.'
  324.         db      cr,lf,'   2 for monochrome mode'
  325.         db      cr,lf,'   3 for color mode'
  326.         db      cr,lf,'  10 for fast screen updating.'
  327.         db      cr,lf,'  Foreground color (30-37) = 30 + colors'
  328.         db      cr,lf,'  Background color (40-47) = 40 + colors'
  329.         db      cr,lf,'    where colors are  1 = red, 2 = green, 4 = blue.'
  330.         db      cr,lf,'  Ex: 0, 1, 34, 47   IBM CGA(0), bright(1) blue(34)'
  331.         db      ' chars on a white(47) field.'
  332.         db      cr,lf,'  Attributes are applied in order of appearance.$'
  333. colerr  db      cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
  334. vtwrap  db      '  Term wrap-lines: $'
  335. vtbell  db      '  Term margin-bell: $'
  336. vtnewln db      '  Term newline: $'
  337. vtcur   db      '  Term cursor-style: $'
  338. vtcset  db      '  Term character-set: $'
  339. vtclik  db      '  Term key-click: $'
  340. vtscrn  db      '  Term screen-background: $'
  341. colst1  db      '  Term color  foreground:3$'
  342. colst2  db      ' background:4$'
  343.                                                         ; terminal emulator
  344. vtstbl  stent   <srchkb,vtwrap,ontab,,vtsflg+wraval>    ; VT100 line wrap
  345.         stent   <srchkb,vtbell,ontab,,vtsflg+marval>    ; VT100 margin bell
  346.         stent   <srchkb,vtcur,curtab,,vtsflg+curval>    ; VT100 cursor type
  347.         stent   <srchkb,vtnewln,ontab,,vtsflg+newval>   ; VT100 newline
  348.         stent   <srchkb,vtscrn,scrtab,,vtsflg+scrval>   ; VT100 screen
  349.         stent   <srchkb,vtcset,chatab,,vtsflg+chaval>   ; VT100 character set
  350.         stent   <srchkb,vtclik,ontab,,vtsflg+keyval>    ; VT100 keyclick
  351.         stent   <colstat>                               ; VT100 colors
  352.         stent   <tabstat>       ; VT100 tab status - needs one whole line
  353.         dw      0               ; end of table
  354.                                                 ; end of Terminal data set
  355.  
  356. ontab   db      2                       ; Two entries.
  357.         mkeyw   'off',0                 ; Should be alphabetized
  358.         mkeyw   'on',1
  359.  
  360. comptab db      2
  361.         mkeyw   '1',1
  362.         mkeyw   'COM1',1
  363.         mkeyw   '   ',0                 ; port is not present, for Status
  364.  
  365. ; this table is indexed by the baud rate definitions given in
  366. ; pcdefs.  Unsupported baud rates should contain FF.
  367. ; Baud rates above 4800 may be sufficiently inaccurate to cause problems. [rwb]
  368. ; The 8251 must be run in 16x mode for reliable reception, which leads [rwb]
  369. ; to small divisors and large errors.  The baud rate divisor is [rwb]
  370. ; calculated by 1,789,773 / (16 * baud rate). [rwb]
  371. ; Odd baud rates have not been tested [rwb]
  372. bddat   label   word
  373.         dw      2458            ; 45.5 baud
  374.         dw      2337            ; 50 baud
  375.         dw      1491            ; 75 baud
  376.         dw      1017            ; 110 baud
  377.         dw      832             ; 134.5 baud
  378.         dw      746             ; 150 baud
  379.         dw      373             ; 300 baud
  380.         dw      186             ; 600 baud
  381.                                 ; actual baud rates in parentheses
  382.         dw      93              ; 1200 baud (1202.8)
  383.         dw      62              ; 1800 baud (1804.2)
  384.         dw      56              ; 2000 baud (1997.5)
  385.         dw      47              ; 2400 baud (2380.0)
  386.         dw      23              ; 4800 baud (4863.5)
  387.         dw      12              ; 9600 baud (9321.7)
  388.         dw      6               ; 19200 baud (18643.5)
  389.         dw      0FFh            ; 38400 baud -- not supported, exceeds
  390.                                 ;               chip spec of 19.2K max
  391.         dw      0FFh            ; 56800 baud -- not supported
  392.         dw      0FFh            ; 113600 baud -- not supported
  393. baudlen equ     ($-bddat)/2     ; number of entries above
  394.  
  395. ; variables for serial interrupt handler
  396.  
  397. source  db      bufsiz+2 DUP(?) ; Buffer for data from port (+ 2 guard bytes).
  398. srcpnt  dw      source          ; Pointer in buffer (DI).
  399. count   dw      0               ; Number of chars in int buffer.
  400. perrcnt dw      0               ; count - missed interrupts dur. protocol xfer
  401.  
  402. datas   ends
  403.  
  404. code    segment public 'code'
  405.         extrn   comnd:near, dopar:near, defkey:near, lclyini:near
  406.         extrn   sleep:near, atsclr:near, scrseg:near,scrloc:near, scrsync:near
  407.         extrn   atoi:near, strlen:near, prtscr:near, scroff:near, scron:near
  408.         extrn   prompt:near
  409.         extrn   vtsound:near    ; [rwb]
  410. ifdef MODIFIED
  411.         extrn   rbtabl:near     ; [jhw]
  412. endif
  413.         assume  cs:code,ds:datas
  414.  
  415. ; local initialization
  416.  
  417. lclini  proc    near
  418.         mov     flags.comflg,1  ; assume COM1 for communications port
  419.         mov     ax,8            ; set default 1200 baud [rwb]
  420.         mov     bp,portval      ; [rwb]
  421.         mov     ds:[bp].baud,ax ; [rwb]
  422.         call    dobaud          ; programm default baud rate [rwb]
  423.         call    model           ; get model of IBM machine
  424.         call    lclyini         ; let other modules initialize too...
  425.         ret
  426. lclini  endp
  427.  
  428. ; this is called by Kermit initialization.  It checks the
  429. ; number of disks on the system, sets the drives variable
  430. ; appropriately.  Returns normally.
  431.  
  432. DODISK  PROC    NEAR
  433.         int     mconf                   ; Get equipment configuration.
  434. ; following lines commented out because Sanyo [rwb]
  435. ; VB BIOS reports no disk drives present [rwb]
  436. ;;      mov ah,al                       ; Store AL value for a bit.
  437. ;;      and al,01H                      ; First, look at bit 0.
  438. ;;      jz dodsk0                       ; No disk drives -- forget it.
  439. ;;      mov al,ah                       ; Get back original value.
  440.         mov     cl,6                    ; Shift over bits 6 and 7.
  441.         shr     al,cl                   ; To positions 0 and 1.
  442.         inc     al                      ; Want 1 thru 4 (not 0 thru 3).
  443. dodsk0: mov     drives,al               ; Remember how many.
  444.         ret
  445. DODISK  ENDP
  446.  
  447. model   proc    near            ; no model info, just return [rwb]
  448.         ret
  449. model   endp
  450.  
  451. ; show the definition of a key.  The terminal argument block (which contains
  452. ; the address and length of the definition tables) is passed in ax.
  453. ; Returns a string to print in AX, length of same in CX.
  454. ; Returns normally. Obsolete, name here for external reference only.
  455. showkey proc    near
  456.         ret                             ; return
  457. showkey endp
  458.  
  459. ; SHOW MODEM, displays current status of DSR (CD and CTS are not known)
  460. shomodem proc   near
  461.         mov     ah,cmcfm                ; get a confirm
  462.         call    comnd
  463.          jmp    r                       ; no confirm
  464.          nop
  465.         call    serini                  ; activate port to get status
  466.         call    serrst                  ; turn off port again
  467.         mov     ah,prstr
  468.         in      al,STS8251      ; get status
  469.         test    al,DSR          ; is DSR asserted?
  470.         jz      shomd1                  ; z = no
  471.         mov     dx,offset msmsg2        ; say not asserted
  472. shomd1: int     dos
  473.         jmp     rskp
  474. shomodem endp
  475.  
  476. ; Clear the input buffer. This throws away all the characters in the
  477. ; serial interrupt buffer.  This is particularly important when
  478. ; talking to servers, since NAKs can accumulate in the buffer.
  479. ; Returns normally.
  480.  
  481. CLRBUF  PROC    NEAR
  482.         cli
  483.         mov     srcpnt,offset source    ; receive circular buffer
  484.         mov     count,0                 ; receive circular buffer
  485.         sti
  486.         call    prtchr                  ; empty any intermediate (net) buffers
  487.          nop                            ; got a char, clear again
  488.          nop
  489.          nop
  490.         cli
  491.         mov     srcpnt,offset source    ; receive circular buffer
  492.         mov     count,0                 ; receive circular buffer
  493.         sti
  494.         ret
  495. CLRBUF  ENDP
  496.  
  497. ; Clear to the end of the current line.  Returns normally.
  498. ; Upgraded for Topview compatibility. [jrd]
  499. CLEARL  PROC    NEAR
  500.         push    ax
  501.         push    bx
  502.         push    dx
  503.         mov     ah,3                    ; Clear to end of line.
  504.         mov     bh,0
  505.         int     video                   ; Get current cursor position into dx
  506.         mov     ax,dx                   ; Topview compatible clear line
  507.         mov     bh,ah                   ; same row
  508.         mov     bl,byte ptr low_rgt     ; last column
  509.         call    atsclr                  ; clear from ax to bx, screen coord
  510.         pop     dx
  511.         pop     bx
  512.         pop     ax
  513.         ret
  514. CLEARL  ENDP
  515.  
  516. ; This routine blanks the screen.  Returns normally.
  517. ; Upgraded to Topview compatiblity. [jrd]
  518. CMBLNK  PROC    NEAR
  519.         push    ax
  520.         push    bx
  521.         xor     ax,ax                   ; from screen loc 0,0
  522.         mov     bx,low_rgt      ; to end of text screen (lower right corner)
  523.         inc     bh                      ; include status line
  524.         call    atsclr               ; do Topview compatible clear, in msyibm
  525.         pop     bx
  526.         pop     ax
  527.         ret
  528. CMBLNK  ENDP
  529.  
  530. ; Locate: homes the cursor.  Returns normally.
  531.  
  532. LOCATE  PROC    NEAR
  533.         mov dx,0                        ; Go to top left corner of screen.
  534.         jmp poscur
  535. LOCATE  ENDP
  536.  
  537. ; Position the cursor according to contents of DX:
  538. ; DH contains row, DL contains column.  Returns normally.
  539. POSCUR  PROC    NEAR
  540.         push    ax
  541.         push    bx
  542.         mov     ah,2                    ; Position cursor.
  543.         mov     bh,0                    ; page 0
  544.         int     video
  545.         pop     bx
  546.         pop     ax
  547.         ret
  548. POSCUR  ENDP
  549.  
  550. ; Delete a character from the terminal.  This works by printing
  551. ; backspaces and spaces.  Returns normally.
  552.  
  553. DODEL   PROC    NEAR
  554.         mov     ah,prstr
  555.         mov     dx,offset delstr        ; Erase weird character.
  556.         int     dos
  557.         ret
  558. DODEL   ENDP
  559.  
  560. ; Move the cursor to the left margin, then clear to end of line.
  561. ; Returns normally.
  562.  
  563. CTLU    PROC    NEAR
  564.         mov     ah,prstr
  565.         mov     dx,offset clrlin
  566.         int     dos
  567.         call    clearl
  568.         ret
  569. CTLU    ENDP
  570.  
  571.  
  572. BEEP    PROC    NEAR
  573.         push    bx              ; [rwb]
  574.         push    di              ; [rwb]
  575.         mov     bx,3            ; [rwb]
  576.         mov     di,8            ; [rwb]
  577.         call    vtsound         ; in msz55x [rwb]
  578.         pop     di              ; [rwb]
  579.         pop     bx              ; [rwb]
  580.         ret
  581. BEEP    ENDP
  582.  
  583. ; write a line in inverse video at the bottom of the screen...
  584. ; the line is passed in dx, terminated by a $.  Returns normally.
  585. putmod  proc    near
  586.         push    ax              ; save regs
  587.         push    bx
  588.         push    cx
  589.         push    dx              ; preserve message
  590.         mov     bl,scbattr      ; screen attributes at Kermit init time
  591.         and     bl,77h          ; get colors, omit bright and blink
  592.         rol     bl,1            ; interchange fore and background
  593.         rol     bl,1
  594.         rol     bl,1
  595.         rol     bl,1
  596.         mov     bh,0            ; preset page 0
  597.         mov     temp,bx         ; temp = page 0, reverse video
  598.         mov     dx,low_rgt      ; ending location is lower right corner
  599.         inc     dh              ;  of status line
  600.         mov     cx,dx           ; start is status left side
  601.         xor     cl,cl           ; left side
  602.         mov     ax,600h         ; scroll to clear the line
  603.         mov     bh,byte ptr temp ; set inverse video attributes
  604.         int     video
  605.         mov     dx,low_rgt      ; last text line
  606.         inc     dh              ; status line
  607.         xor     dl,dl           ; left side
  608.         call    poscur
  609.         pop     si              ; get message back
  610.         mov     cx,1            ; only one char at a time
  611.         xor     bh,bh           ; page 0
  612.         cld
  613. putmo1: lodsb                   ; get a byte
  614.         cmp     al,'$'          ; end of string?
  615.         je      putmo2
  616.         push    si              ; save si
  617.         push    ax              ; and the char
  618.         call    poscur
  619.         inc     dl              ; increment for next write
  620.         pop     ax              ; recover char
  621.         mov     ah,9            ; try this
  622.         mov     bx,temp         ; page 0, inverse video
  623.         int     video
  624.         pop     si              ; recover pointer
  625.         jmp     putmo1
  626. putmo2: pop     cx
  627.         pop     bx
  628.         pop     ax
  629.         ret
  630. putmod  endp
  631.  
  632. ; clear the mode line written by putmod.  Returns normally.
  633. clrmod  proc    near
  634.         push    ax              ; save regs
  635.         push    bx
  636.         push    cx
  637.         push    dx
  638.         mov     ax,600h         ; do a scroll up
  639.         mov     dx,low_rgt      ; ending location is lower right corner
  640.         inc     dh              ;  of status line
  641.         mov     cx,dx           ; start is status left side
  642.         xor     cl,cl           ; left side
  643.         mov     bh,scbattr      ; use screen attributes at Kermit init time
  644.         int     video
  645.         pop     dx
  646.         pop     cx
  647.         pop     bx
  648.         pop     ax
  649.         ret
  650. clrmod  endp
  651.  
  652. ; put a help message on the screen.  This one uses reverse video...
  653. ; pass the message in ax, terminated by a null.  Returns normally.
  654. puthlp  proc    near
  655.         push    bx              ; save regs
  656.         push    cx
  657.         push    dx
  658.         push    si
  659.         push    ax              ; preserve this
  660.         cld
  661.         mov     bl,scbattr      ; screen attributes at Kermit init time
  662.         and     bl,77h          ; get colors, omit bright and blink
  663.         rol     bl,1            ; interchange fore and background
  664.         rol     bl,1
  665.         rol     bl,1
  666.         rol     bl,1
  667.         mov     bh,0            ; preset page 0
  668.         mov     temp,bx         ; temp = page 0, reverse video
  669.  
  670.         mov     si,ax           ; point to it
  671.         mov     dh,1            ; init counter
  672. puthl1: lodsb                   ; get a byte
  673.         cmp     al,lf           ; linefeed?
  674.         jne     puthl2          ; no, keep going
  675.         inc     dh              ; count it
  676.         jmp     puthl1          ; and keep looping
  677. puthl2: cmp     al,0            ; end of string?
  678.         jne     puthl1          ; no, keep going
  679.         mov     ax,600h         ; scroll to clear window
  680.         xor     cx,cx           ; from top left
  681.         mov     dl,4fh          ; to bottom right of needed piece
  682.         mov     bh,70h          ; inverse video
  683.         mov     bh,bl           ; inverse video
  684.         int     video
  685.         call    locate          ; home cursor
  686.         mov     bx,0070h        ; bh = page 0, bl = inverse video
  687.         mov     bx,temp
  688.         mov     cx,1            ; one char at a time
  689.         cld                     ; scan direction is forward
  690.         pop     si              ; point to string again
  691. puthl3: lodsb                   ; get a byte
  692.         cmp     al,0            ; end of string?
  693.         je      puthl4          ; yes, stop
  694.         push    si              ; save around bios call
  695.         cmp     al,' '          ; printable?
  696.         jb      puth21          ; b = no
  697.         mov     ah,9            ; write char at current cursor position
  698.         int     video           ; do the Bios int 10h call
  699.         inc     dl              ; point to next column
  700.         jmp     puth23          ; move cursor there
  701. puth21: cmp     al,cr           ; carriage return?
  702.         jne     puth22          ; ne = no
  703.         xor     dl,dl           ; set to column zero
  704.         jmp     puth23
  705. puth22: cmp     al,lf           ; line feed?
  706.         jne     puth23
  707.         inc     dh              ; go to next line
  708. puth23: mov     ah,2            ; set cursor position to dx
  709.         int     video
  710.         pop     si              ; restore pointer
  711.         jmp     puthl3          ; and keep going
  712. puthl4: mov     dh,byte ptr low_rgt+1   ; go to last line
  713.         inc     dh
  714.         xor     dl,dl
  715.         call    poscur          ; position cursor
  716.         pop     si
  717.         pop     dx
  718.         pop     cx
  719.         pop     bx
  720.         ret
  721. puthlp  endp
  722.                                         ; begin Terminal set & status code
  723.  
  724. ; SET Term parameters, especially for use with VT100 emulator. [jrd]
  725. ; Taken from work done originally by James Harvey IUPUI.
  726. ; VTS is called only by mssset to set terminal type and characteristics.
  727.  
  728. VTS     proc    near                    ; SET TERM whatever
  729.         mov     ah,cmkey                ; Parse another keyword.
  730.         mov     bx,offset vthlp         ; Use this help
  731.         mov     dx,offset vttbl         ; Use this table
  732.         call    comnd
  733.          jmp    r                       ; Vsetup always returns +1.
  734.         cmp     bh,1H                   ; marker for terminal type?
  735.         je      vsetu0a                 ; e = yes
  736.         cmp     bh,4h                   ; marker for roll back control?
  737.         je      vsetu3                  ; e = yes
  738.         cmp     bh,2h                   ; marker for set term color?
  739.         je      vsetu2                  ; e = yes
  740.         jmp     short vsetu1            ; else dispatch on bl
  741. vsetu0a:push    bx                      ; yes
  742.         mov     ah,cmcfm
  743.         call    comnd                   ; Get a confirm.
  744.          jmp    vsetu0                  ; Didn't get a confirm.
  745.          nop
  746.         pop     bx
  747.         mov     flags.vtflg,bl          ; Set the terminal emulation type
  748.         mov     tekflg,0                ; clear Tek sub mode
  749.         ret
  750. vsetu0: pop bx
  751.         ret
  752.  
  753. vsetu3: mov     ah,cmkey                ; Set Term Roll On/Off, auto roll back
  754.         mov     bx,0                    ; Use on/off table as help
  755.         mov     dx,offset ontab         ; Use on/off table
  756.         call    comnd
  757.          jmp    r                       ; bad keyword
  758.         push    bx
  759.         mov     ah,cmcfm                ; get a confirm
  760.         call    comnd
  761.          jmp    vsetu0                  ; did not get a confirm
  762.          nop
  763.         pop     bx
  764.         mov     vtroll,bl               ; set roll state (0=no auto rollback)
  765.         jmp     rskp                    ; return successfully
  766.  
  767. vsetu1: sal     bx,1                    ; Make bx a word index.
  768.         call    vtrtns[bx]              ; Dispatch.
  769.          jmp    r                       ; Vsetup always returns +1.
  770.         jmp     r                       ; Vsetup always returns +1.
  771.  
  772.                                        ; Set Term Color foreground, background
  773. vsetu2: mov     ah,cmtxt                ; get number(s) after set term color
  774.         mov     dx,offset colhlp        ; use this help
  775.         mov     bx,offset rdbuf         ; temp buffer
  776.         mov     byte ptr [bx],0         ; clear the buffer
  777.         call    comnd
  778.          jmp    r
  779.         cmp     ah,0                    ; anything given?
  780.         jne     vsetu2a                 ; ne = yes.
  781.         jmp     r                       ; else give not confirmed msg
  782. vsetu2a:mov     ah,cmcfm                ; Parse confirm
  783.         mov     bx,0                    ; Use default help.
  784.         call    comnd
  785.          jmp    r                       ; not confirmed, complain.
  786.         mov     si,offset rdbuf         ; si = place where atoi wants text
  787. vsetu2c:mov     dx,si
  788.         call    strlen                  ; current length of text
  789.         jcxz    vsetu2x                 ; nothing left
  790.         mov     ah,cl                   ; put length where Atoi wants it
  791.         call    atoi                    ; convert text to numeric in ax
  792.          jmp    colbad                  ; no value available
  793.         cmp     ax,0                    ; reset all? regular IBM CGA refresh
  794.         jne     vse2cd                  ; cond. jmps modified to correct
  795.                                         ;   'out-of-range' errors      [jhw]
  796.         jmp     vsetu2j                 ; e = yes
  797. vse2cd: cmp     ax,1                    ; high intensity?
  798.         jne     vse2cc
  799.         jmp     vsetu2k                 ; e = yes
  800. vse2cc: cmp     ax,2                    ; set to mono mode (Sanyo)      [jhw]
  801.         jne     vse2ca                  ;                               [jhw]
  802.         jmp     vsetu2m                 ; e = yes                       [jhw]
  803. vse2ca: cmp     ax,3                    ; set to color mode (Sanyo)     [jhw]
  804.         jne     vse2cb                  ;                               [jhw]
  805.         jmp     vsetu2m                 ; e = yes                       [jhw]
  806. vse2cb: cmp     ax,10                   ; fast refresh?
  807.         cmp     ax,1                    ; high intensity?
  808.         je      vsetu2k                 ; e = yes
  809.         cmp     ax,10                   ; fast refresh?
  810.         je      vsetu2l                 ; e = yes
  811.         cmp     ax,30                   ; check range
  812.         jb      clbad                   ; b = too small. complain       [jhw]
  813.         cmp     ax,37
  814.         jna     vsetu2b                 ; 30-37 is foreground color
  815.         cmp     ax,40
  816.         jb      clbad                   ;                               [jhw]
  817.         cmp     ax,47                   ; Compare as unsigned.
  818.         jna     vsetu2b                 ; 40-47 is background
  819. clbad:  jmp     colbad                  ; else error                    [jhw]
  820. vsetu2x:jmp     rskp                    ; and return normally.
  821.  
  822. vsetu2b:push    bx
  823.         mov     bx,vtemu.att_ptr        ; Get address of attributes byte
  824.         cmp     al,40                   ; background (40-47)?
  825.         jnb     vsetu2f                 ; nb = yes
  826.         sub     al,30                   ; remove foreground bias
  827.         and     byte ptr [bx],not 07H   ; clear foreground bits
  828.         test    al,1                    ; ANSI red?
  829.         jz      vsetu2d                 ; z = no
  830.         or      byte ptr [bx],4         ; set IBM foreground red
  831. vsetu2d:test    al,2                    ; ANSI & IBM green?
  832.         jz      vsetu2e                 ; z = no
  833.         or      byte ptr [bx],2         ; set green foreground
  834. vsetu2e:test    al,4                    ; ANSI Blue?
  835.         jz      vsetu2i                 ; z = no
  836.         or      byte ptr [bx],1         ; set IBM blue
  837.         jmp     vsetu2i                 ; done with foreground settings
  838. vsetu2f:sub     al,40                   ; remove background bias
  839.         and     byte ptr [bx],not 70H   ; clear background attributes
  840.         test    al,1                    ; ANSI red?
  841.         jz      vsetu2g                 ; z = no
  842.         or      byte ptr [bx],40h       ; set IBM background red
  843. vsetu2g:test    al,2                    ; ANSI & IBM green?
  844.         jz      vsetu2h                 ; z = no
  845.         or      byte ptr [bx],20h       ; set green background
  846. vsetu2h:test    al,4                    ; ANSI Blue?
  847.         jz      vsetu2i                 ; z = no
  848.         or      byte ptr [bx],10h       ; set IBM blue
  849. vsetu2i:pop     bx
  850.         jmp     vsetu2c                 ; get any next value
  851. vsetu2j:mov     refresh,0               ; Regular (slow) screen refresh
  852.         mov     bx,vtemu.att_ptr        ; Get address of attributes byte
  853.         mov     byte ptr [bx],07h       ; clear all, set white on black.
  854.         jmp     vsetu2c                 ; get next value
  855. vsetu2k:mov     bx,vtemu.att_ptr        ; Get address of attributes byte
  856.         or      byte ptr [bx],08h       ; set high intensity
  857.         jmp     vsetu2c                 ; get next value
  858. vsetu2l:mov     refresh,1               ; Fast screen refresh
  859.         jmp     vsetu2c
  860. vsetu2m:                                ; Set screen mode (color/mono)  [jhw]
  861.         mov     crt_mode,al             ; remember the mode             [jhw]
  862.         int     video                   ; AX contained 2 or 3 already   [jhw]
  863.         jmp     vsetu2c                 ;                               [jhw]
  864. ;
  865.  
  866. colbad: cmp     byte ptr [si],0         ; at end of text?
  867.         je      colbad1                 ; e = yes, not an error
  868.         mov     ah,prstr                ; Not in range - complain and exit.
  869.         mov     dx,offset colerr
  870.         int     dos
  871. colbad1:jmp     rskp
  872.  
  873. ; SET Term flags. These are the (near) equivalent of VT100 Setup mode values.
  874.  
  875. flgset: push    bx                      ; Save bx for a second.
  876.         mov     ah,cmkey                ; Another keyword.
  877.         mov     dx,vtable[bx]           ; The table to use.
  878.         mov     bx,0                    ; Use default help.
  879.         call    comnd
  880.          jmp    flgse3
  881.         push    bx                      ; Save switch value.
  882.         mov     ah,cmcfm                ; Confirm it.
  883.         call    comnd
  884.          jmp    flgse2
  885.         pop     dx                      ; Restore switch value.
  886.         pop     bx                      ; And index.
  887.         sar     bx,1                    ; Make it a byte index.
  888.         mov     al,vtsflg[bx]           ; Get the flag.
  889.         cmp     dx,0                    ; Set or clear?
  890.         je      flgse1                  ; Go clear it.
  891.         or      vtemu.vtflgst,al        ; Set the flag.
  892.         or      vtemu.vtflgop,al        ; in runtime flags too
  893.         jmp     rskp                    ; Give good return.
  894.  
  895. flgse1: not     al                      ; Complement
  896.         and     vtemu.vtflgst,al        ; Clear the indicated setup flag.
  897.         and     vtemu.vtflgop,al        ; Clear the indicated runtime flag.
  898.         jmp     rskp                    ; Give good return.
  899. flgse2: pop     bx                      ; error exits
  900. flgse3: pop     bx
  901.         ret
  902.  
  903. ;       SET Term Tabstops Clear ALL
  904. ;       SET Term Tabstops Clear AT n1, n2, ..., nx
  905. ;       SET Term Tabstops At n1, n2, ..., nx
  906.  
  907. tabset: cld                             ; Make sure this is clear.
  908.         mov     di,offset tmptabs       ; clear our temp work area here.
  909.         mov     cx,132                  ; 132 columns
  910.         mov     al,0                    ; set "not touched" indicator
  911.         rep     stosb                   ; in all tmptabs slots
  912.         mov     ah,cmkey                ; Parse keyword.
  913.         mov     bx,offset clrhlp        ; Use this help text.
  914.         mov     dx,offset tabtab        ; This table.
  915.         call    comnd
  916.          jmp    r
  917.         mov     clrset,2                ; code for set a tab
  918.         cmp     bl,0                    ; Was it set or clear?
  919.         jne     tabse1                  ; SET - go parse column number(s).
  920.         mov     clrset,1                ; code for clear at/all tab(s)
  921.         mov     ah,cmkey                ; CLEAR - parse ALL or AT
  922.         mov     bx,offset allhlp        ; Use this help text.
  923.         mov     dx,offset alltab        ; Parse ALL or AT.
  924.         call    comnd
  925.          jmp    r
  926.         cmp     bx,0                    ; ALL?
  927.         jne     tabse1                  ; ne = AT, clear at specific places.
  928.         mov     al,1                    ; ALL, means clear all tab stops.
  929.         mov     cx,132                  ; use 132 columns
  930.         mov     di,offset tmptabs
  931.         rep     stosb
  932.         mov     ah,cmcfm                ; Confirm it.
  933.         call    comnd
  934.          jmp    r
  935.         jmp     tabcpy                  ; update active & coldstart tabs
  936.  
  937. tabse1: mov     dx,offset tbshlp        ; Tell them we want a column number.
  938.         cmp     clrset,1                ; Clearing?
  939.         jne     tabse2                  ; ne = Set. we guessed right on help.
  940.         mov     dx,offset tbchlp        ; Yes - use this help instead.
  941. tabse2: mov     ah,cmtxt                ; get text w/o white space
  942.         mov     bx,offset rdbuf         ; temp buffer
  943.         call    comnd
  944.          jmp    r
  945.         cmp     ah,0                    ; anything given?
  946.         jne     tabse4                  ; ne = yes.
  947.         jmp     r                       ; else give not confirmed msg
  948. tabse4: mov     ah,cmcfm                ; Parse confirm
  949.         mov     bx,0                    ; Use default help.
  950.         call    comnd
  951.          jmp    r                       ; not confirmed, complain.
  952.         mov     si,offset rdbuf         ; si = place where atoi wants text
  953. tabse5: mov     dx,si
  954.         call    strlen                  ; current length of text
  955.         mov     ah,cl                   ; put length where Atoi wants it
  956.         jcxz    tabcpy                  ; nothing left
  957.         call    atoi                    ; convert text to numeric in ax
  958.          jmp    tabcpy                  ;  no number available
  959.         mov     bx,ax                   ; for subscripting in code below
  960.         dec     bx                      ; Put column in range 0-79
  961.         cmp     bx,0                    ; check range (1-80 --> 0-79)
  962.         jl      tbsbad                  ; l = too small. complain
  963.         cmp     bl,132-1                ; more than the right most column?
  964.         jna     tabse3                  ; na = no, is ok
  965. tbsbad: mov     ah,prstr                ; Not in range - complain and exit.
  966.         mov     dx,offset tbserr
  967.         int     dos
  968.         jmp     rskp
  969.  
  970. tabse3: mov     al,clrset               ; Get value for setting or clearing.
  971.         mov     tmptabs[bx],al          ; store in tabs temp work array
  972.         jmp     short tabse5            ; look for more
  973.  
  974. tabcpy: mov     cx,132                  ; update all active tab stops
  975.         mov     si,vtemu.vttbst         ; in terminal emulator's active buffer
  976.         mov     di,vtemu.vttbs          ; and in the cold-start buffer.
  977.         mov     bx,0                    ; subscript
  978. tabcpy1:mov     al,byte ptr tmptabs [bx] ; get a table entry into al
  979.         or      al,al                   ; what is the code?
  980.         jz      tabcpy3                 ; z = do not touch
  981.         cmp     al,2                    ; set a tab?
  982.         je      tabcpy2                 ; e = set the tab
  983.         mov     byte ptr [bx+si],0      ; clear the tab
  984.         mov     byte ptr [bx+di],0      ; clear the tab
  985.         jmp     short tabcpy3
  986. tabcpy2:mov     byte ptr [bx+si],0ffh   ; set the tab
  987.         mov     byte ptr [bx+di],0ffh   ; set the tab
  988. tabcpy3:inc     bx                      ; inc subscript
  989.         loop    tabcpy1
  990.         jmp     rskp                    ; Give good return.
  991.  
  992. VTS     endp                            ; end of Set Term things.
  993.  
  994.               ; Terminal Status display, called within STAT0: in MSSSET.[jrd]
  995. VTSTAT  proc    near                ;enter with di within sttbuf, save bx, di
  996.         push    bx
  997.         push    di
  998.         mov     bx,ds
  999.         mov     es,bx
  1000.         cld
  1001.         mov     bx,offset vtstbl        ; table of things to show
  1002.         xor     cx,cx
  1003. vtsta1: cmp     word ptr [bx],0         ; end of table?
  1004.         je      vtstax                  ; e = yes
  1005.         push    bx
  1006.         call    [bx].sttyp              ; call appropriate routine
  1007.         pop     bx                      ; cx incremented by output count
  1008.         cmp     cx,38                   ; place for second display
  1009.         jbe     vtsta2                  ; le = only half full
  1010.         mov     dx,offset crlf          ; over half full. send cr/lf
  1011.         mov     ah,prstr
  1012.         int     dos
  1013.         xor     cx,cx                   ; say line is empty now
  1014.         jmp     short vtsta4
  1015. vtsta2: mov     ax,cx
  1016.         mov     cx,38                   ; where we want to be next time
  1017.         sub     cx,ax                   ; compute number of filler spaces
  1018.         jcxz    vtsta4                  ; nothing to do
  1019.         mov     ah,conout
  1020.         mov     dl,' '
  1021. vtsta3: int     dos                     ; fill with spaces
  1022.         loop    vtsta3                  ; do cx times
  1023.         mov     cx,38                   ; current column number
  1024. vtsta4: add     bx,size stent           ; look at next entry
  1025.         jmp     vtsta1                  ; and do it
  1026. vtstax: pop     di
  1027.         pop     bx
  1028.         ret                             ; return to STAT0: in MSSSET.
  1029.  
  1030.                                         ; foreground/background color status
  1031. colstat proc    near
  1032.         mov     dx,offset colst1
  1033.         mov     ah,prstr
  1034.         int     dos                     ; print first part of msg
  1035.         xor     ax,ax
  1036.         mov     bx,vtemu.att_ptr        ; pointer to attributes byte
  1037.         test    byte ptr [bx],1         ; IBM blue foregound?
  1038.         jz      colsta1                 ; z = no
  1039.         or      al,4                    ; set blue bit
  1040. colsta1:test    byte ptr [bx],2         ; IBM green foreground?
  1041.         jz      colsta2
  1042.         or      al,2
  1043. colsta2:test    byte ptr [bx],4         ; IBM red foreground?
  1044.         jz      colsta3
  1045.         or      al,1
  1046. colsta3:add     al,'0'                  ; add ascii bias
  1047.         mov     dl,al                   ; move to DOS place
  1048.         mov     ah,conout
  1049.         int     dos                     ; print the last digit
  1050.         mov     dx,offset colst2        ; now do background
  1051.         mov     ah,prstr
  1052.         int     dos                     ; print second part of msg
  1053.         xor     ax,ax
  1054.         test    byte ptr [bx],10h       ; IBM blue background?
  1055.         jz      colsta4                 ; z = no
  1056.         or      al,4                    ; set blue bit
  1057. colsta4:test    byte ptr [bx],20h       ; IBM green background?
  1058.         jz      colsta5
  1059.         or      al,2                    ; set green bit
  1060. colsta5:test    byte ptr [bx],40h       ; IBM red background?
  1061.         jz      colsta6
  1062.         or      al,1                    ; set red bit
  1063. colsta6:add     al,'0'                  ; add ascii bias
  1064.         mov     dl,al                   ; move to DOS place
  1065.         mov     ah,conout
  1066.         int     dos
  1067.         add     cx,45                   ; about the # columns we used
  1068.         ret
  1069. colstat endp
  1070.                                         ; Tabs Status display
  1071. tabstat proc    near                    ; display tabs ruler for Status
  1072.         push    dx
  1073.         jcxz    tabsta0                 ; empty line, as it should be
  1074.         xor     cx,cx                   ; used line, empty it
  1075.         mov     dx,offset crlf          ; cr, lf
  1076.         mov     ah,prstr
  1077.         int     dos
  1078. tabsta0:mov     si,vtemu.vttbst         ; active tabs address, not shadow
  1079.         mov     cl,byte ptr low_rgt     ; loop screen width-1 times
  1080.         xor     ch,ch                   ; clear high byte
  1081.         dec     si                      ; dec for inc below
  1082.         xor     ax,ax                   ; tens counter
  1083. tabsta1:mov     dl,'.'                  ; default position symbol
  1084.         inc     si                      ; start with position 1
  1085.         inc     al
  1086.         cmp     al,10                   ; time to roll over?
  1087.         jb      tabsta2                 ; b = not yet
  1088.         mov     al,0                    ; modulo 10
  1089.         inc     ah
  1090.         mov     dl,ah                   ; display a tens-digit
  1091.         add     dl,'0'
  1092.         cmp     dl,'9'                  ; larger than 90?
  1093.         jbe     tabsta2                 ; be = no
  1094.         sub     dl,10                   ; roll over to 0, 1, etc
  1095. tabsta2:cmp     byte ptr [si],0         ; is tab set?
  1096.         je      tabsta3                 ; e = no
  1097.         mov     dl,'T'                  ; yes, display a 'T'
  1098. tabsta3:push    ax
  1099.         mov     ah,conout               ; console output
  1100.         int     dos
  1101.         pop     ax
  1102.         loop    tabsta1                 ; loop til done (cx has count)
  1103.         pop     dx
  1104.         mov     cx,38                   ; say line is used
  1105.         ret
  1106. tabstat endp
  1107.  
  1108. ; handler routines for status. All are called with bx/ stat ptr.
  1109.  
  1110. onoff   proc    near
  1111.         call    stmsg                   ; print the message
  1112.         mov     si,[bx].basval          ; get base value
  1113.         cmp     si,0                    ; any there?
  1114.         je      onoff1                  ; e = no
  1115.         mov     si,[si]                 ; yes, use as base address
  1116. onoff1: add     si,[bx].tstcel          ; add offset of test cell
  1117.         mov     al,[si]
  1118.         mov     dx,offset onmsg
  1119.         add     cx,2                    ; assume two byte on message
  1120.         or      al,al                   ; test value
  1121.         jnz     onoff2                  ; nz = on
  1122.         mov     dx,offset offmsg
  1123.         inc     cx                      ; three byte message
  1124. onoff2: mov     ah,prstr                ; display the message
  1125.         int     dos
  1126.         ret
  1127. onoff   endp
  1128.  
  1129. ; search a keyword table for a bit value, print that value. [jrd]
  1130. srchkb  proc    near
  1131.         call    stmsg                   ; first print message
  1132.         call    stbval                  ; get bit set or reset
  1133.         mov     ah,0                    ; al has 0/1, high order is 0
  1134.         mov     bx,[bx].val2            ; this is table address
  1135.         jmp     prttab                  ; and look in table.
  1136. srchkb  endp
  1137.  
  1138. ; get address of test value in stent.  Returns address in si. [jrd]
  1139. stbval  proc    near
  1140.         mov     si,[bx].basval          ; get address of test value
  1141.         cmp     si,0                    ; any there?
  1142.         je      stbva1                  ; no, quit with no match
  1143.         mov     al,byte ptr [si]        ; get byte value
  1144.         mov     ah,0
  1145.         test    al,vtemu.vtflgop ; bit test value against emulator flags byte
  1146.         jz      stbva1                  ; z = they don't match
  1147.         mov     al,1                    ;  match
  1148.         ret
  1149. stbva1: mov     al,0                    ; no match
  1150.         ret                             ; and return it
  1151. stbval  endp
  1152.  
  1153. ; get address of test value in stent.  Returns address in si
  1154. stval   proc    near
  1155.         mov     si,[bx].basval          ; get base value
  1156.         cmp     si,0                    ; any there?
  1157.         je      stva1                   ; no, keep going
  1158.         mov     si,[si]                 ; yes, use as base address
  1159. stva1:  add     si,[bx].tstcel          ; add offset of test cell
  1160.         ret                             ; and return it
  1161. stval   endp
  1162.  
  1163. ; copy the message to the screen
  1164. stmsg   proc    near
  1165.         mov     si,[bx].msg             ; get message address
  1166. stms1:  lodsb                           ; get a byte
  1167.         cmp     al,'$'                  ; end of message?
  1168.         je      stms2                   ; e = yes
  1169.         mov     dl,al                   ; display the character
  1170.         mov     ah,conout
  1171.         int     dos
  1172.         inc     cx                      ; count output chars
  1173.         jmp     stms1
  1174. stms2:  ret
  1175. stmsg   endp
  1176.  
  1177. ; Print value from table.  BX/address of table, AL/value of variable.
  1178. prttab: push    cx                      ; save column count
  1179.         mov cl,[bx]                     ; Number of entries in our table.
  1180.         inc     bx                      ; Point to the data.
  1181. prtt0:  mov     dl,[bx]                 ; Length of keyword.
  1182.         inc     bx                      ; Point to keyword.
  1183.         mov     dh,0
  1184.         inc     dx                      ; Account for "$" in table.
  1185.         mov     si,dx                   ; Put to index register.
  1186.         cmp     ax,[bx+si]              ; Is this the one?
  1187.         je      prtt1
  1188.         add     bx,dx                   ; Go to end of keyword.
  1189.         add     bx,2                    ; Point to next keyword.
  1190.         dec     cl                      ; Any more keywords to check?
  1191.         jnz     prtt0                   ; Yes, go to it.
  1192.         mov     bx,offset prterr
  1193. prtt1:  mov     si,bx
  1194.         pop     cx                      ; recover column count
  1195.         jmp     stms1                   ; copy in message
  1196.         ret                             ; and return
  1197. VTSTAT  endp                            ; end of Terminal set & status code
  1198.  
  1199. ; Compute number of iterations needed in procedure pcwait inner loop
  1200. ; to do one millisecond delay increments. Uses Intel 8253 timer chip
  1201. ; (timer #2) to measure elapsed time assuming 1.78977 MHz clock.
  1202. ; Called by serini below. For Sanyo 55x this is the baud rate generator,
  1203. ; so call dobaud to reset the baud rate.
  1204. ; Regs preserved. 16 April 87 [jrd]
  1205. pcwtst  proc    near
  1206.         push    ax
  1207.         push    cx
  1208.         push    dx
  1209. ; 10 = timer 2, 11 = load low byte then high byte, 010 = mode 2, 0 = binary
  1210.         mov     al,10110100B    ; command byte
  1211.         out     CMD8253,al      ; timer command port
  1212.         xor     al,al   ; clear initial count for count-down
  1213.         out     TIMER2DATA,al   ; low order byte of count preset
  1214.         out     TIMER2DATA,al   ; high order byte, to the same place
  1215.         mov     ax,8    ; wait 8 millisec
  1216.         call    pcwait  ; call the software timer
  1217. ; 10 = timer 2, 00 = latching command, 0000 = don't cares
  1218.         mov     al,10000000B    ; command byte
  1219.         out     CMD8253,al
  1220.         in      al,timer2data   ; read count down value
  1221.         xchg    al,ah           ; save low order byte
  1222.         in      al,timer2data   ; get high order byte
  1223.         xchg    ah,al           ; put in correct sequence
  1224.         neg     ax              ; subtract from zero to get elapsed tics
  1225.         add     ax,1789-2       ; round up
  1226.         xor     dx,dx           ; clear high order divisor
  1227.         mov     cx,1789 ; tics per millisec
  1228.         div     cx              ; count / 1193 yields millisecs, quo=ax
  1229.         push    ax              ; retain whole number of milliseconds
  1230.         mov     ax,pcwcnt       ; get current pcwait inner loop count
  1231.         mov     cl,3
  1232.         shl     ax,cl           ; current counter times 8 loops
  1233.         pop     cx              ; recover millisec for the 8 loop test
  1234.         xor     dx,dx           ; clear high order field for division
  1235.         div     cx              ; divide by observed milliseconds
  1236.         mov     pcwcnt,ax       ; store quotient as new inner loop counter
  1237.         call    dobaud  ; fix the baud rate we messed up
  1238.         pop     dx
  1239.         pop     cx
  1240.         pop     ax
  1241.         ret
  1242. pcwtst  endp
  1243.  
  1244. ;; Wait for the # of milliseconds in ax, for non-IBM compatibles.
  1245. ;; Thanks to Bernie Eiben for this one. Modified to use adjustable
  1246. ; inner loop counter (pcwcnt, adjusted by proc pcwtst) by [jrd].
  1247. pcwait  proc    near
  1248.         mov     cx,pcwcnt       ; inner loop counter for 1 ms (240 @ 4.77 MHz)
  1249. pcwai1: sub     cx,1            ; inner loop takes 20 clock cycles
  1250.         jnz     pcwai1
  1251.         dec     ax              ; outer loop counter
  1252.         jnz     pcwait          ; wait another millisecond
  1253.         ret
  1254. pcwait  endp
  1255.  
  1256. ; set the current port (only port 1 available on Sanyo)
  1257.  
  1258. COMS    PROC    NEAR
  1259.         mov     portval,offset port1
  1260.         clc                             ; return success
  1261.         ret
  1262. COMS    ENDP
  1263.  
  1264. ; Test presently selected serial port for having a real 8250 UART.
  1265. ; Return carry clear and clone = 0 if 8250 present,
  1266. ;  else carry set and clone = 'B' for system Bios or
  1267. ;  carry set and clone = 'N' for network.
  1268. ; Method is to check UART's Interrupt Identification Register for high
  1269. ; five bits being zero; IBM does it this way. Assumes port structure
  1270. ; has been initialized with addresses of UART.  21 Feb 1987 [jrd]
  1271. ; 29 May 1987 Add double check by reading Line Status Register. [jrd]
  1272.  
  1273. chkport proc    near
  1274.         clc                             ; clear carry (say 8250)
  1275.         ret
  1276. chkport endp
  1277.  
  1278. ; Set the baud rate for the current port, based on the value
  1279. ; in the portinfo structure.  Returns normally.
  1280.  
  1281. DOBAUD  PROC    NEAR
  1282.         push    ax                      ; save some regs
  1283.         push    bx
  1284.         push    dx
  1285.         mov     bx,portval              ; pointer to port data structure
  1286.         mov     temp,ax                 ; Don't overwrite previous rate
  1287.         mov     ax,[bx].baud            ; Check if new rate is valid
  1288.         shl     ax,1                    ; make a word index
  1289.         mov     bx,offset bddat         ; Start of table.
  1290. dobd0a: add     bx,ax
  1291.         mov     ax,[bx]                 ; The data to output to port.
  1292.         cmp     ax,0FFH                 ; Unimplemented baud rate.
  1293.         jne dobd2
  1294.         mov     ah,prstr
  1295.         mov     dx,offset badbd         ; Give an error message.
  1296.         int     dos
  1297.         jmp     dobd1
  1298.  
  1299. dobd2:  mov temp,ax             ; Remember value to output. [25]
  1300.         out TIMER2DATA,al       ; [rwb]
  1301.         mov al,ah               ; [rwb]
  1302.         out TIMER2DATA,al       ; [rwb]
  1303. dobd1:  pop     dx                      ; restore regs
  1304.         pop     bx
  1305.         pop     ax
  1306.         ret
  1307. DOBAUD  ENDP
  1308.  
  1309. ; Get the current baud rate from the serial card and set it
  1310. ; in the portinfo structure for the current port.  Returns normally.
  1311. ; This is used during initialization.
  1312. ; This function is not possible with the Sanyo hardware, so just return. [rwb]
  1313.  
  1314. GETBAUD PROC    NEAR
  1315.         ret
  1316. GETBAUD ENDP
  1317.  
  1318. ; Get Char from serial port buffer.
  1319. ; skip returns if no character available at port,
  1320. ; otherwise returns with char in al, # of chars in buffer in dx.
  1321. ; Revised 22 May 1986, and again slightly 2 August 1986 by [jrd]
  1322. ; 21 Feb 1987 Add support for Bios calls (Clone) [jrd]
  1323. ; 25 April 1987 Add Netbios support, remove test for NUL and DEL. [jrd]
  1324. PRTCHR  PROC    NEAR
  1325.         call    chkxon                  ; see if we need to xon
  1326. ifdef DEBUG
  1327.         jmp     prtc00                  ; dummy jump to be changed by debug
  1328. prtc00:
  1329. endif
  1330.         in      al,cmd8251              ; get port status
  1331.         test    al,rxrdy                ; is character in 8251?
  1332.         jz      prtc01                  ; no, go on
  1333.         cli                             ; yes, hold interrupts and
  1334.         int     0fah                    ; call the interrupt service routine
  1335.         sti                             ; re-enable interrupts
  1336.         inc     perrcnt                 ; count the errors
  1337. prtc01:
  1338.  
  1339.         cmp     count,0                 ; any characters available?
  1340.         jnz     prtch1                  ; nz = yes, get one
  1341. prtch0: mov     dx,0                    ; return count of zero
  1342.         jmp     rskp                    ; No data - check console.
  1343. prtch1: push    si                      ; save si
  1344.         cli             ; interrupts off, to keep srcpnt & count consistent
  1345.         mov     si,srcpnt           ; address of next available slot in buffer
  1346.         sub     si,count            ; minus number of unread chars in buffer
  1347.         cmp     si,offset source        ; located before start of buf?
  1348.         jae     prtch2                  ; ae = no
  1349.         add     si,bufsiz               ; else do arithmetic modulo bufsiz
  1350. prtch2: mov     al,byte ptr [si]        ; get a character into al
  1351.         dec     count                   ; one less unread char now
  1352.         sti                             ; interrupts back on now.
  1353.         pop     si
  1354.         mov     dx,count                ; return # of chars in buffer
  1355.         ret
  1356. PRTCHR  ENDP
  1357.  
  1358. ; Put the char in AH to the serial port.  This assumes the
  1359. ; port has been initialized.  Should honor xon/xoff.  Skip returns on
  1360. ; success, returns normally if the character cannot be written.
  1361. ; 21 Feb 1987 Add support for Bios calls (Clone) [jrd]
  1362. ; 25 April 1987 Add Netbios support [jrd]
  1363. ; 16 May 1987 Add entry point OUTCH2 for non-flow controlled sending to
  1364. ; prevent confusion of flow control logic at top of outchr; used by receiver
  1365. ; buffer high/low water mark flow control code. [jrd]
  1366. OUTCHR  PROC    NEAR
  1367.         cmp     flowoff,0               ; Are we doing flow control.
  1368.         je      outch2                  ; No, just continue.
  1369.         cmp     ah,flowoff              ; sending xoff?
  1370.         jne     outch1                  ; ne = no
  1371.         mov     xofsnt,usron            ; indicate user level xoff being sent
  1372.         jmp     outch1b
  1373. outch1: cmp     ah,flowon               ; user sending xon?
  1374.         jne     outch1b                 ; ne = no
  1375.         mov     xofsnt,off           ; say an xon has been sent (cancels xoff)
  1376. outch1b:cmp     xofrcv,off              ; Are we being held (xoff received)?
  1377.         je      outch2                  ; e = no - it's OK to go on.
  1378.         cmp     flags.timflg,0          ; is timer off?
  1379.         je      outch2                  ; e = yes, no timeout period
  1380.         push    cx                      ; save reg
  1381.         mov     cl,trans.rtime          ; receive timeout interval
  1382.         mov     ch,0
  1383.         jcxz    outch1c                 ; z = no timeout wanted.
  1384. outch1a:cmp     xofrcv,off              ; Are we being held (xoff received)?
  1385.         je      outch1c                 ; e = no - it's OK to go on.
  1386.         mov     al,1                    ; else sleep for a second
  1387.         call    sleep
  1388.         loop    outch1a                 ; and try it again
  1389.         mov     xofrcv,off              ; timed out, force it off and fall thru
  1390. outch1c:pop     cx                      ; end of flow control section
  1391.                      ; OUTCH2 is entry point for sending without flow control
  1392. OUTCH2: mov     al,ah                   ; Parity routine works on AL.
  1393.         call    dopar                   ; Set parity appropriately.
  1394.         mov     ah,al                   ; Don't overwrite character with status
  1395. outch3a:push    cx                      ; Save registers
  1396.         push    dx
  1397.         sub     cx,cx
  1398. outch3b: in al,STS8251          ; get status [rwb]
  1399.         test al,TxEMPTY         ; Transmitter ready? [rwb]
  1400.         jnz     outch4                  ; Yes
  1401.         jmp     $+2                     ; use time, prevent overdriving UART
  1402.         jmp     $+2
  1403.         loop    outch3b
  1404.          jmp    outch5                  ; Timeout
  1405. outch4: cli                     ; can't tolerate receiver ints here
  1406.         mov al,(TxEN+DTR+RxEN+ERRESET+RTS) ; enable transmit [rwb]
  1407.         out CMD8251,al          ; [rwb]
  1408.         jmp $+2                 ; waste some time [rwb]
  1409.         mov al,ah               ; Now send it out [rwb]
  1410.         out BUF8251,al          ; [rwb]
  1411.         jmp $+2                 ; waste some time [rwb]
  1412.         mov al,(DTR+RxEN+ERRESET+RTS) ; back to receive-only mode [rwb]
  1413.         out CMD8251,al          ; [rwb]
  1414.         sti
  1415.         pop     dx                      ; exit success
  1416.         pop     cx
  1417.         jmp     rskp
  1418. outch5: pop     dx                      ; exit failure
  1419.         pop     cx
  1420.         ret
  1421. OUTCHR  ENDP
  1422.  
  1423.  
  1424. hexout  proc    near                    ; display byte in al as hex value
  1425.         push    ax                      ; all regs preserved
  1426.         push    cx
  1427.         push    dx
  1428.         mov     cx,2                    ; two nibbles
  1429. hexout1:push    cx                      ; save counter
  1430.         mov     cl,4                    ; high nibble
  1431.         ror     al,cl                   ; put in low order field
  1432.         mov     dl,al
  1433.         xchg    ch,al                   ; save al byte in ch
  1434.         and     dl,0fh                  ; four bits
  1435.         cmp     dl,9                    ; too big?
  1436.         jbe     hexout2                 ; be = no
  1437.         add     dl,'A'-'9'-1            ; bump up to A-F
  1438. hexout2:add     dl,'0'
  1439.         mov     ah,conout
  1440.         int     dos
  1441.         xchg    ch,al                   ; recover data byte
  1442.         pop     cx
  1443.         loop    hexout1                 ; do second nibble
  1444.         mov     dl,'H'                  ; add a final hex ident
  1445.         int     dos
  1446.         pop     ax
  1447.         pop     cx
  1448.         pop     dx
  1449.         ret
  1450. hexout  endp
  1451.  
  1452. ; local routine to see if we have to transmit an xon
  1453. chkxon  proc    near
  1454.         cmp     flowon,0                ; doing flow control?
  1455.         je      chkxo1                  ; no, skip all this
  1456.         test    xofsnt,usron            ; did user send an xoff?
  1457.         jnz     chkxo1                  ; nz = yes, don't contradict it here
  1458.         test    xofsnt,bufon            ; have we sent a buffer level xoff?
  1459.         jz      chkxo1                  ; z = no, forget it
  1460.         cmp     count,mntrgl            ; below (low water mark) trigger?
  1461.         jae     chkxo1                  ; no, forget it
  1462.         mov     ah,flowon               ; ah gets xon
  1463.         and     xofsnt,off              ; remember we've sent the xon.
  1464.         call    outch2              ; send via non-flow controlled entry point
  1465.          nop
  1466.          nop
  1467.          nop                            ; in case it skips
  1468. chkxo1: ret
  1469. chkxon  endp
  1470.  
  1471. ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
  1472. ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
  1473. ; else repeat cycle. Requires that the port be initialized before hand.
  1474. ; Ihosts is used by the local send-file routine just after initializing
  1475. ; the serial port.
  1476. ; 22 March 1986 [jrd]
  1477. ; 22 June 1986 Don't send null char if not using flow control. [jrd]
  1478.  
  1479. IHOSTS  PROC    NEAR
  1480.         push    ax              ; save the registers
  1481.         push    cx
  1482.         push    dx
  1483.         mov     xofrcv,off      ; clear old xoff received flag
  1484.         mov     xofsnt,off      ; and old xoff sent flag
  1485.         mov     ah,flowon       ; put Go-ahead flow control char in ah
  1486.         or      ah,ah           ; check for null char
  1487.         jz      ihosts1         ; z = null, don't send it.
  1488.         call    outchr          ; send it (release Host's output queue)
  1489.          nop                    ; outchr can do skip return
  1490.          nop
  1491.          nop
  1492. ihosts1:call    clrbuf          ; clear out interrupt buffer
  1493. ;;      mov     ax,1            ; sleep for 1 second
  1494. ;;      call    sleep           ; procedure sleep is in msscom.asm
  1495. ;;      call    prtchr          ; check for char at port
  1496. ;;       jmp    ihosts1         ; have a char in al, repeat wait/read cycle
  1497. ;;       nop                    ; prtchr does skip return on empty buffer
  1498.         pop     dx              ; empty buffer. we are done here.
  1499.         pop     cx
  1500.         pop     ax
  1501.         ret
  1502. IHOSTS  ENDP
  1503.  
  1504. ; IHOSTR - initialize the remote host for our reception of a file by
  1505. ; sending the flow-on character (XON typically) to release any held
  1506. ; data. Called by receive-file code just after initializing the serial
  1507. ; port.         22 March 1986 [jrd]
  1508. ; 22 June 1986 Don't send null char if not using flow control. [jrd]
  1509. IHOSTR  PROC    NEAR
  1510.         push    ax              ; save regs
  1511.         push    cx
  1512.         mov     xofrcv,off      ; clear old xoff received flag
  1513.         mov     xofsnt,off      ; and old xoff sent flag
  1514.         mov     ah,flowon       ; put Go-ahead flow control char in ah
  1515.         or      ah,ah           ; check for null char
  1516.         jz      ihostr1         ; z = null, don't send it
  1517.         call    outchr          ; send it (release Host's output queue)
  1518.          nop                    ; outchr can do skip return
  1519.          nop
  1520.          nop
  1521. ihostr1:pop     cx
  1522.         pop     ax
  1523.         ret
  1524. IHOSTR  ENDP
  1525.  
  1526. ; Send a break out the current serial port.  Returns normally.
  1527. ; Do both regular and long Break. 6 March 1987 [jrd]
  1528.  
  1529. SENDBR  PROC    NEAR
  1530.         push    cx              ; Regular Break entry point
  1531.         mov     cx,275          ; 275 milliseconds in regular Break
  1532.         call    sendbw          ; call worker routine to do it
  1533.         pop     cx
  1534.         clc                     ; don't exit Connect mode
  1535.         ret
  1536. SENDBL: push    cx              ; Long Break entry point
  1537.         mov     cx,1800         ; 1.8 second long break
  1538.         call    sendbw          ; call worker routine to do it
  1539.         pop     cx
  1540.         clc                     ; don't exit Connect mode
  1541.         ret
  1542.                                 ; worker - send Break for cx millisec
  1543. sendbw:
  1544.         push ax
  1545.         mov al,(TxEN+DTR+RxEN+RTS)      ; [rwb]
  1546.         out CMD8251,al                  ; [rwb]
  1547.         mov al,(TxEN+DTR+RxEN+SBRK+RTS) ; [rwb]
  1548.         out CMD8251,al                  ; [rwb]
  1549.         mov ax,cx                       ; # of ms to wait
  1550.         call pcwait                     ; hold break for desired interval
  1551.         mov al,(TxEN+DTR+RxEN+RTS)      ; [rwb]
  1552.         out CMD8251,al                  ; [rwb]
  1553.         mov al,(DTR+RxEN+ERRESET+RTS)   ; [rwb]
  1554.         out CMD8251,al                  ; [rwb]
  1555.         pop ax
  1556.         ret
  1557. SENDBR  ENDP
  1558.  
  1559. ; Initialization for using serial port.  This routine performs
  1560. ; any initialization necessary for using the serial port, including
  1561. ; setting up interrupt routines, setting buffer pointers, etc.
  1562. ; Doing this twice in a row should be harmless (this version checks
  1563. ; a flag and returns if initialization has already been done).
  1564. ; SERRST below should restore any interrupt vectors that this changes.
  1565. ;
  1566. ; Revised slightly by Joe R. Doupnik 22 Dec 1985 to prevent interrupts
  1567. ; being enabled until we're done, to stop interrupts from occurring when
  1568. ; TX holding buffer becomes empty (a useless interrupt for us), and to
  1569. ; shorten the time between enabling interrupts and our exit. [jrd]
  1570. ; Returns normally.
  1571. ; 22 June 1986 Leave OUT1 low to avoid resetting Hayes 1200B's. [jrd]
  1572. ; 21 Feb 1987 Add support for Bios calls (Clone) [jrd]
  1573. ; 24 April 1987 Add PCnet support calls [jrd]
  1574. ; 17 May 1987 Redo for COM3/4 support. [jrd]
  1575. SERINI  PROC    NEAR
  1576.         cmp     portin,0                ; Did we initialize port already?
  1577.         je      serin0                  ; e = no, not yet
  1578.         ret                             ; Yes, so just leave
  1579. serin0:
  1580.         call pcwtst             ; calibrate timer (only on first call)
  1581. serin2a:push    bx
  1582.         push    es
  1583.         mov al,VEC8251          ; serial interrupt vector
  1584.         mov     ah,35H                  ; Int 21H, function 35H = Get Vector.
  1585.         int     dos                     ; get vector in es:bx
  1586.         mov     word ptr savsci,bx    ; save offset address of original vector
  1587.         mov     word ptr savsci+2,es    ;  and its segment.
  1588.         mov al,VEC8251          ; serial interrupt vector
  1589.         mov     dx,offset serint        ; offset of our interrupt routine
  1590.         push    ds                      ; save ds around next DOS call.
  1591.         mov     bx,seg serint           ; compose full address of our routine.
  1592.         mov     ds,bx                   ; segment is the code segment.
  1593.         mov     ah,25H                  ; set interrupt address from ds:dx
  1594.         int     dos
  1595.         pop     ds
  1596.         mov     al,rs232                ; interrupt number for Bios serial port
  1597.         mov     ah,35H                  ; get vector into es:bx
  1598.         int     dos
  1599.         mov     word ptr sav232,bx      ; save offset
  1600.         mov     word ptr sav232+2,es    ; save segment
  1601.         mov     dx,offset serdum        ; offset of our interrupt routine
  1602.         push    ds                      ; save ds around next DOS call.
  1603.         mov     bx,seg serdum           ; compose full address of our routine.
  1604.         mov     ds,bx                   ; segment is the code segment.
  1605.         mov     ah,25H                  ; set interrupt address from ds:dx
  1606.         int     dos
  1607.         pop     ds
  1608.         pop     es
  1609.         pop     bx
  1610.         mov     portin,1                ; Remember port has been initialized.
  1611.         cli                             ; Disable interrupts
  1612.         cld                             ; Do increments in string operations
  1613.         mov al,INTRLRS          ; 8251 reset command [rwb]
  1614.         out CMD8251,al          ; [rwb]
  1615.         jmp $+2                 ; waste some time [rwb]
  1616.         mov al,04Eh             ; 8-bit, no parity, 1 stop, 16x clock [rwb]
  1617.         out CMD8251,al          ; [rwb]
  1618.         jmp $+2                 ; waste time again [rwb]
  1619.         mov al,(DTR+RxEN+ERRESET+RTS)  ; enable receive [rwb]
  1620.         out CMD8251,al          ; [rwb]
  1621.         in al,CMB8259           ; get interrupt mask [rwb]
  1622.         and al,INT8251          ; enable RS-232 interrupt [rwb]
  1623.         out CMB8259,al          ; [rwb]
  1624.         sti                       ; Allow interrupts (AFTER next instr)
  1625.  
  1626. serin4: push    bx
  1627.         mov     bx,portval              ; get port
  1628.         mov     parmsk,0ffh             ; parity mask, assume parity is None.
  1629.         cmp     [bx].parflg,parnon      ; is it None?
  1630.         je      serin1                  ; e = yes
  1631.         mov     parmsk,07fh             ; no, pass lower 7 bits as data
  1632. serin1: mov     bx,[bx].flowc           ; get flow control chars
  1633.         mov     flowoff,bl              ; xoff or null
  1634.         mov     flowon,bh               ; xon or null
  1635.         mov     xofrcv,off              ; clear xoff received flag
  1636.         pop     bx
  1637.         mov     portin,1                ; say initialized
  1638.         ret                             ; We're done
  1639. SERINI  ENDP
  1640.  
  1641. ; Reset the serial port.  This is the opposite of serini.  Calling
  1642. ; this twice without intervening calls to serini should be harmless.
  1643. ; Moved push/pop es code to do quicker exit before interrupts enabled. [jrd]
  1644. ; Returns normally.
  1645. ; 22 June 1986 Leave OUT1 low to avoid resetting Hayes 1200B's. [jrd]
  1646. ; 21 Feb 1987 Add support for Bios calls (Clone) [jrd]
  1647. ; 17 May 1987 Redo for COM3/4 support [jrd]
  1648. SERRST  PROC    NEAR
  1649.         cmp     portin,0        ; Reset already?
  1650.         je      srst1           ; Yes, just leave.
  1651.         cli                     ; Disable interrupts
  1652. ; Leave receive and transmit enabled (that's how DOS sets them initially) [rwb]
  1653. ; Also leave interrupt enabled, DOS will handle any interrupts
  1654.         mov al,(DTR+RxEN+TxEN+ERRESET+RTS)  ; enable transmit and receive [rwb]
  1655.         out CMD8251,al          ; [rwb]
  1656.         sti                     ; replace original IRQ interrupt vector
  1657.         push    bx
  1658.         mov al,VEC8251          ; Restore the serial card int vector
  1659.         mov     dx,word ptr savsci ; offset part
  1660.         push    ds
  1661.         mov     bx,word ptr savsci+2 ; segment part
  1662.         mov     ds,bx           ; ds:dx has interrupt vector
  1663.         mov     ah,25H          ; set interrupt vector
  1664.         int     dos             ; replaced.
  1665.         pop     ds
  1666.         mov     al,rs232        ; Bios serial port interrupt vector to restore
  1667.         mov     dx,word ptr sav232   ; offset part
  1668.         push    ds
  1669.         mov     bx,word ptr sav232+2 ; segment part
  1670.         mov     ds,bx
  1671.         mov     ah,25h          ; set interrupt vector
  1672.         int     dos
  1673.         pop     ds
  1674.         pop     bx
  1675. srst3:  mov     portin,0        ; Reset flag.
  1676. srst1:
  1677. ifdef MODIFIED
  1678.         call rbtabl             ; make sure BIOS key translation table ptr is
  1679.                                 ;   reset upon exit.  Didn't know where else to
  1680.                                 ;   put this in the machine dependent code [jhw]
  1681. endif
  1682.         ret                     ; All done.
  1683. SERRST  ENDP
  1684.  
  1685. ; Dummy Interrupt 14H to defeat DOS interference with serial port when CTTY
  1686. ; and Kermit use the port simultaneously. If ports differ then chain DOS to
  1687. ; original Int 14H Bios code. Else return dummy status=ok reports and
  1688. ; Backspace for Read, ignore char for Write.
  1689. ; Entered with AH = function request, AL = char to be sent, DX = com port num
  1690. ; CS is our code segment, DS is DOS's, SS is ours or DOS's, interrupts off.
  1691. ; 25 June 1987 [jrd]
  1692. SERDUM  PROC    FAR
  1693.         push    ds                      ; preserve all registers.
  1694.         push    ax
  1695.         mov     ax,seg datas            ; get our data segment
  1696.         mov     ds,ax
  1697.         pop     ax                      ; recover request parameters
  1698.         pop     ds
  1699.         cmp     ah,0                    ; initialization request?
  1700.         je      serdu3                  ; e = yes, return dummy status=ok rpt
  1701.         cmp     ah,1                    ; send char in al?
  1702.         jne     serdu2                  ; ne = no
  1703.         mov     ah,60h                  ; yes, set line status=ok in ah
  1704.         iret
  1705. serdu2: cmp     ah,2                    ; receive char (and wait for it)?
  1706.         jne     serdu3                  ; ne = no, return dummy report
  1707.         mov     al,bs                   ; yes, return ascii BS to DOS
  1708.         mov     ah,0                    ; ah = errors (none here)
  1709.         iret
  1710. serdu3: mov     ax,60b0h                ; dummy status report:xmtr empty, CD,
  1711.         iret                            ;  DSR, and CTS are on.
  1712.  
  1713. SERDUM  ENDP
  1714.  
  1715. ; serial port interrupt routine.  This is not accessible outside this
  1716. ; module, handles serial port receiver interrupts.
  1717. ; Revised on 22 May 1986, again 2 August 1986 to run at 38.4kb on PC's. [jrd]
  1718. ; Srcpnt holds offset, within buffer Source, where next rcv'd char goes.
  1719. ; Count is number of chars now in buffer, and oldest char is srcpnt-count
  1720. ; done modulo size of Source. All pointer management is handled here.
  1721. ; Control-G char substituted for char(s) lost in overrun condition. [jrd]
  1722. ; Upgraded to read cause of interrupt from interrupt ident reg (accepts only
  1723. ;  data ready), chain to old interrupt if source is not our device. [jrd]
  1724.  
  1725. SERINT  PROC  FAR
  1726.         push    ax                      ; save registers
  1727.         push    dx                      ;
  1728.         push    ds
  1729.         mov     ax,seg datas
  1730.         mov     ds,ax                   ; address data segment
  1731. ; IBM version sends EOI command to 8259 interrupt controller at this [rwb]
  1732. ; point, but Sanyo normally runs in auto EOI mode, so no EOI is needed [rwb]
  1733.         in al,STS8251           ; [rwb]
  1734.         test al,RxRDY           ; Data available? [rwb]
  1735.         jnz srint0a             ; nz = yes
  1736. srint0: sti                             ; else turn on interrupts
  1737.         jmp     retint                  ;  and exit now (common jump point)
  1738.  
  1739. srint0a:and al,OVRRUN           ; select overrun bit [rwb]
  1740.         mov     overrun,al              ; save it for later
  1741.         in al,BUF8251           ; [rwb]
  1742.         cmp     flowoff,0               ; flow control active?
  1743.         je      srint2                  ; e = no
  1744.         mov     ah,al              ; ah = working copy. Check null, flow cntl.
  1745.         and     ah,parmsk               ; strip parity temporarily, if any.
  1746.         jz      srint2                  ; if null skip flow control
  1747.         cmp     ah,flowoff              ; acting on Xoff?
  1748.         jne     srint1                  ; ne = Nope, go on.
  1749.         mov     xofrcv,bufon            ; Set the flag saying XOFF received.
  1750.         jmp     srint0                  ;  and exit
  1751. srint1: cmp     ah,flowon               ; acting on Xon?
  1752.         jne     srint2                  ; ne = no, go on.
  1753.         mov     xofrcv,off              ; Clear the XOFF received flag.
  1754.         jmp     srint0                  ;  and exit
  1755. srint2: push    bx                      ; save register
  1756.         mov     ah,overrun              ; get overrun flag
  1757.         or      ah,ah                   ; overrun?
  1758.         jz      srint2a                 ; z = no
  1759.         mov     ah,al                   ; yes, save present char
  1760.         mov al,(DTR+RxEN+ERRESET+RTS)  ; [rwb]
  1761.         out CMD8251,al          ; clear overrun status in 8251 [rwb]
  1762.         mov     al,bell                 ; insert control-G for missing char
  1763. srint2a:mov     bx,srcpnt               ; address of buffer storage slot
  1764.         mov     byte ptr [bx],al        ; store the new char in buffer "source"
  1765.         inc     srcpnt                  ; point to next slot
  1766.         inc     bx
  1767.         cmp     bx,offset source + bufsiz ; beyond end of buffer?
  1768.         jb      srint3                  ; b = not past end
  1769.         mov     srcpnt,offset source ; wrap buffer around
  1770. srint3: cmp     count,bufsiz            ; filled already?
  1771.         jae     srint4                  ; ae = yes
  1772.         inc     count                   ; no, add a char
  1773. srint4: or      ah,ah                   ; anything in overrun storage?
  1774.         jz      srint4a                 ; z = no
  1775.         mov     al,ah                   ; recover any recent char from overrun
  1776.         xor     ah,ah                   ; clear overrun storage
  1777.         jmp     srint2a                 ; yes, go store real second char
  1778. srint4a:pop     bx                      ; restore reg
  1779.         sti                          ; ok to allow interrupts now, not before
  1780.         cmp     count,mntrgh            ; past the high trigger point?
  1781.         jbe     retint                  ; be = no, we're within our limit
  1782.         test    xofsnt,bufon        ; Has an XOFF been sent by buffer control?
  1783.         jnz     retint                  ; nz = Yes.
  1784.         mov     al,flowoff              ; get the flow off char (Xoff or null)
  1785.         or      al,al                   ; don't send nul chars
  1786.         jz      retint                  ; z = null, nothing to send
  1787.         call    dopar                   ; Set parity appropriately.
  1788.         mov     ah,al                  ; Don't overwrite character with status
  1789.         push    cx                      ; save reg
  1790.         xor     cx,cx                   ; loop counter
  1791. srint5: in al,STS8251           ; Get port status. [rwb]
  1792.         test al,TxEMPTY         ; Transmitter ready?
  1793.         jnz     srint6                  ; nz = yes
  1794.         jmp     $+2                     ; use time, prevent overdriving UART
  1795.         loop    srint5                  ; else wait loop, cx times
  1796.          jmp    srint7                  ; Timeout
  1797. srint6: cli
  1798.         mov al,(TxEN+DTR+RxEN+ERRESET+RTS) ; enable output command [rwb]
  1799.         out CMD8251,al          ; [rwb]
  1800.         mov al,ah               ; Now send out the flow control char
  1801.         out BUF8251,al
  1802.         push cx                 ; save reg [jrd]
  1803.         xor cx,cx               ; loop counter [jrd]
  1804. srint6a: in al,STS8251          ; Get port status. [rwb]
  1805.         test al,TxEMPTY         ; Transmitter done?
  1806.         jnz srint6b             ; nz = yes
  1807.         jmp $+2                 ; use time, prevent overdriving UART
  1808.         loop srint6a            ; else wait loop, cx times
  1809.                                 ; on timeout, kill transmitter
  1810. srint6b: mov al,(DTR+RxEN+ERRESET+RTS) ; command to enable only receive [rwb]
  1811.         out CMD8251,al
  1812.         pop cx
  1813.         sti                     ; Enable interrupts after next instruct. [jrd]
  1814.         mov     xofsnt,bufon       ; Remember we sent an XOFF at buffer level
  1815. srint7: pop     cx                      ; restore reg
  1816. retint: pop     ds
  1817.         pop     dx
  1818.         pop     ax
  1819.         iret
  1820. SERINT  ENDP
  1821.  
  1822. DTRLOW  PROC    NEAR            ; Global proc to Hangup the Phone or Network
  1823.                                 ; by making DTR and RTS low (phone). [jrd]
  1824.         mov     ah,cmtxt        ; allow text, to be able to display help
  1825.         mov     bx,offset rdbuf         ; dummy buffer
  1826.         mov     dx,offset hnghlp        ; help message
  1827.         call    comnd                   ; get a confirm
  1828.          jmp    r
  1829.         call    serhng                  ; drop DTR and RTS
  1830.         mov     ah,prstr                ; give a nice message
  1831.         mov     dx,offset hngmsg
  1832.         int     dos
  1833.         jmp     rskp
  1834. DTRLOW  ENDP
  1835.  
  1836. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  1837. ; to terminate the connection. 29 March 1986 [jrd]
  1838. ; 5 April 1987 Add 500 millisec wait with lines low before returning. [jrd]
  1839. ; Calling this twice without intervening calls to serini should be harmless.
  1840. ; If network then call nethangup procedure to hangup the session without
  1841. ; losing local name information.
  1842. ; Returns normally.
  1843.  
  1844. serhng  proc    near    ; clear modem's delta status bits and lower DTR & RTS
  1845. shng1:  cli                             ; Disable interrupts
  1846.         push    ax
  1847.         mov al,(RxEN+ERRESET)   ; DTR and RTS low [rwb]
  1848.         out CMD8251,al          ; [rwb]
  1849. shngx:  sti                             ; Enable interrupts
  1850.         mov     ax,500                  ; 500 millisec, for pcwait
  1851.         call    pcwait              ; keep lines low for at least 500 millisec
  1852.         pop     ax
  1853.         ret
  1854. serhng  endp
  1855.  
  1856. ; Jumping to this location is like retskp.  It assumes the instruction
  1857. ;   after the call is a jmp addr.
  1858.  
  1859. RSKP    PROC    NEAR
  1860.         pop     bp
  1861.         add     bp,3
  1862.         push    bp
  1863.         ret
  1864. RSKP    ENDP
  1865.  
  1866. ; Jumping here is the same as a ret.
  1867.  
  1868. R       PROC    NEAR
  1869.         ret
  1870. R       ENDP
  1871.  
  1872. code    ends
  1873.         end
  1874.