home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msxz10.asm < prev    next >
Assembly Source File  |  2020-01-01  |  63KB  |  2,157 lines

  1.     NAME    msxz10
  2. ; File MSXZ10.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1991, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; Kermit system dependent module for Heath/Zenith Z100
  9. ; Edit history
  10. ; 2 March 1991 version 3.10
  11. ; Last change:    3 November 1990.
  12. ; OUTCH2 defined as far label.
  13. ; Replay code in PRTCHR modified per ibm pc version and call serrst added at
  14. ; label coms0.    These two last changes are for version 3.02.
  15. ; New code for VTS and VTSTAT added and under revision but not active.    These
  16. ; two routines and corresponding data really belong in msy but the routines
  17. ; and some of their data are kept here to make msy small enough to assemble
  18. ; with MASM 4.    DUMPSCR moved to msyz10.asm.
  19. ; A number of calls to SPRTCH added in order to allow windowing for the non
  20. ; interupt driven S-100 modem ports COM3/COM4.    Some very limited success at
  21. ; 1200 baud would indicate that it might work at 300 (untested).
  22. ; SERISR optimized and performance improved for COM1/COM2.  However, there are
  23. ; still some problems from 19200 baud and up, in particular with windowing.
  24. ; OUTCHR significantly rewritten.  Modified CHKXON (COM1/2) and CHKXOF (COM3/4)
  25. ; to call OUTCH5 and OUTCH2 respectively rather than OUTCHAR.
  26. ; SERISR significantly modified to improve flow control for COM1/2 and SPRTCH
  27. ; fixed to ignore flow control for COM3/4 if not called for.
  28. ; Minor correction to WAIT01.  CLEARL and CTLU merged.
  29. ; PUTHLP display routine improved and replay command implemented.
  30. ; Increased size of buffilen and buffolen.  Added register save to BEEP.
  31. ; Added routines ENA_WRP and DIS_WRP and several calls to these to make serial
  32. ; display behave.  Help message for 'set port' improved.
  33. ; Various cosmetic changes.
  34. ;
  35. ; First version of this file for MS-Kermit 3.0:     8 May 1990.
  36. ; Bo Gedda
  37. ;
  38. ; Support for 2 US Robotics S-100 modems at ports 20H (com3) and 2EH (com4).
  39. ; com1 (1 in status list) means serial port B.
  40. ; com2 (2 in status list) means serial port A.
  41. ; com3 (3 in status list) means S-100 port 1 (20H).
  42. ; com4 (4 in status list) means S-100 port 2 (2EH).
  43.     public    getbaud, serini, serrst, clrbuf, outchr, coms, vts, vtstat
  44.     public    ctlu, cmblnk, locate, prtchr, baudst, clearl, bdtab, dodel
  45.     public    beep, sprtch, klen, ktab, krpl, getivec, setivec, dupflg
  46.     public    count, xofsnt, puthlp, putmod, clrmod, poscur, pcwait
  47.     public    sendbr, sendbl, machnam, lclini, outch2, dis_scan
  48.     public    ihosts, ihostr, dtrlow, mdmhand, shomodem, getmodem
  49.     public    portval, port1, port2, port3, port4, serhng, ena_scan
  50.     public    flowon, flowoff, sescur, sesdisp, setnbios, peekcom, parmsk
  51.  
  52. off    equ    0
  53. false    equ    0
  54. true    equ    1
  55. bufon    equ    1        ; buffer level xon/xoff on-state control flag
  56. usron    equ    2        ; user level xon/xoff on-state control flag
  57. mntrgh    equ    bufsiz*3/4    ; High point = 3/4 of buffer full
  58. mntrgl    equ    bufsiz/4    ; Low point = 1/4 buffer full
  59. xoftime equ    15        ; 15 seconds time out for xoff, see timer
  60.  
  61. ; constants used by serial port handler
  62.  
  63. ; Z-100 standard serial ports A (J1) and B (J2), called COM2 and COM1 here.
  64. ; Note that A=J1=COM2=2 and B=J2=COM1=1.  Port B is the standard modem port
  65. ; similar to an IBM PC port.  Thats why.
  66. ; serial port information
  67. TSRE    EQU    004H
  68. THBE    EQU    001H
  69. DTR    EQU    002H
  70. DTROFF    EQU    0fdH
  71. RTS    EQU    020H
  72. RTSOFF    EQU    0dfH
  73. DCD    EQU    040H
  74. DSR    EQU    080H
  75. RDA    EQU    002H
  76. J1_ADDR EQU    0e8H
  77. J2_ADDR EQU    0ecH
  78. PDATA    EQU    0
  79. PSTATUS EQU    1
  80. PMODE    EQU    2
  81. PCOMM    EQU    3
  82. TXON    EQU    001H
  83. TXOFF    EQU    0feH
  84. RXON    EQU    004H
  85. RXOFF    EQU    0fbH
  86. MODE1    EQU    04dH
  87. MODE2    EQU    030H    ;  must be ORed with appropriate baud rate
  88. Z8259    EQU    0f2H
  89. EOI    EQU    020H
  90. J1INT    EQU    68
  91. J2INT    EQU    69
  92. BUFILEN EQU    bufsiz
  93. BUFOLEN EQU    bufsiz/2
  94.  
  95. BRKBIT    EQU    048H        ; Send-break bit.
  96.  
  97. mdmdat1 equ    J2_ADDR        ; Address of serial port B (J2)
  98. mdmcom1 equ    J2_ADDR + PCOMM ; Address of serial port B command
  99. mdmdat2 equ    J1_ADDR        ; Address of serial port A (J1)
  100. mdmcom2 equ    J1_ADDR + PCOMM ; Address of serial port A command
  101.  
  102. ;US Robotics S-100 modem using 8251A USART data
  103. mdmdat3 equ    020h        ; Address of USR S-100 port 1
  104. mdmcom3 equ    mdmdat3 + 1    ; Address of USR S-100 command port
  105. mdmdat4 equ    02eh        ; Address of USR S-100 port 2
  106. mdmcom4 equ    mdmdat4 + 1    ; Address of USR S-100 command port
  107. modsndb equ    1h        ; Bit to test for send S-100 modem
  108. modrcvb equ    2h        ; Bit to test for receive S-100 modem
  109. modperb equ    8h        ; Parity error detect bit S-100 modem
  110. modorub    equ    10h        ; Overrun error detect bit
  111. moddcdb equ    80h        ; Carrier detect bit S-100 modem
  112.  
  113. COLUMNS EQU    80        ; Characters per screen line.
  114. ROWS    EQU    24        ; Text lines per screen
  115. VID_CMD EQU    0d8h        ; Video-memory control port.
  116. PAR_GRN EQU    0e000h        ; Green video plane segment address.
  117.  
  118. ; external variables used:
  119. ; flags - global flags as per flginfo structure defined in pcdefs
  120. ; trans - global transmission parameters, trinfo struct defined in pcdefs
  121. ; portval - pointer to current portinfo structure (currently either port1,
  122. ;    port2, port3 or port4 )
  123. ; port1, port2, port3, port4 - portinfo structures for the corresponding ports
  124. ; monmode - color/monochrome mode of monitor
  125. ; dmpname - file name for screen dump file
  126.  
  127. ; global variables defined in this module:
  128. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  129.  
  130. BIOS_SEG SEGMENT AT 40H        ; Define segment where BIOS really is
  131.     ORG    1*3
  132. BIOS_STATUS    LABEL FAR    ; Console input status
  133.     ORG    2*3
  134. BIOS_CONIN    LABEL FAR    ; Console input
  135.     ORG    3*3
  136. BIOS_CONOUT    LABEL FAR    ; Console output
  137.     ORG    4*3
  138. BIOS_PRINT    LABEL FAR    ; Printer output
  139.     ORG    6*3
  140. BIOS_AUXOUT    LABEL FAR    ; AUX output routine
  141.     ORG    25*3
  142. BIOS_PRNFUNC    LABEL FAR    ; PRN: FUNCTION
  143.     ORG    26*3
  144. BIOS_AUXFUNC    LABEL FAR    ; AUX: function
  145.     ORG    27*3
  146. BIOS_CONFUNC    LABEL FAR    ; CON: function
  147. BIOS_SEG ENDS
  148.  
  149. ;  Define functions of BIOS_CONFUNC, BIOS_PRNFUNC, and BIOS_AUXFUNC
  150. CHR_WRITE    EQU 0        ; Write function
  151. CHR_READ    EQU CHR_WRITE+1 ; Read function
  152. CHR_STATUS    EQU CHR_READ+1    ; Status function
  153.   CHR_SFGS      EQU 0          ; Get status subfunction
  154.     CHRS_WA        EQU 00000001B   ; <ETX> sent, waiting for <ACK>
  155.     CHRS_WD        EQU 00000010B   ; <DC3> seen, waiting for <DC1>
  156.     CHRS_SN        EQU 00000100B   ; Sending nulls
  157.     CHRS_TXR        EQU 10000000B   ; Transmitter ready to send data
  158.     CHRS_RXR        EQU 01000000B   ; Receiver has data 
  159.     CHRS_RXOF        EQU 00100000B   ; Receiver queue overflow
  160.     CHRS_RXE        EQU 00010000B   ; Other type of reciver error
  161.     CHRS_TXE        EQU 00001000B   ; Transmitter error
  162.   CHR_SFGC      EQU CHR_SFGS+1  ; Get configuration info subfunction
  163. CHR_CONTROL    EQU CHR_STATUS+1 ; Control function
  164.   CHR_CFSU      EQU 0          ; Setup new configuration parms subfunction
  165.   CHR_CFCI      EQU CHR_CFSU+1  ; Clear input subfunction
  166.   CHR_CFCO      EQU CHR_CFCI+1  ; Clear output subfunction
  167. CHR_LOOK    EQU CHR_CONTROL+1; Nondestructive read function
  168. CHR_FMAX    EQU CHR_LOOK    ; Maximum function number
  169.  
  170. ; storage for port configuration
  171. cfginfo struc
  172. cfclass db    0
  173. cfattr    db    0
  174. cfport    dw    0
  175. cfbaud    db    0
  176. cfhshk    db    0
  177. cfbctl    db    0
  178. cfecnt    db    0
  179. cfncnt    db    0
  180. cfnchr    db    0
  181. cfres    db    6 dup(?)
  182. cfsize    db    0
  183. cfginfo ends
  184.  
  185. ; structure for status information table sttab.
  186. stent    struc
  187. sttyp    dw    ?        ; type (actually routine to call)
  188. msg    dw    ?        ; message to print
  189. val2    dw    ?        ; needed value: another message, or tbl addr
  190. tstcel    dw    ?        ; address of cell to test, in data segment
  191. basval    dw    0        ; base value, if non-zero
  192. stent    ends
  193.  
  194. data    segment
  195.     extrn    flags:byte, trans:byte, taklev:byte, verident:byte
  196.     extrn    comptab:byte, termtb:byte, ontab:byte, scrtab:byte
  197.     extrn    cntltab:byte, beltab:byte, curtab:byte, chatab:byte
  198.     extrn    kpamtab:byte, dirtab:byte, doscol:byte
  199.     extrn    lclsusp:word, lclrest:word, lclexit:word, dosflg:byte
  200.     extrn    dosflg1:byte, repflg:byte, diskio:byte, kstatus:byte
  201.     extrn    holdscr:byte, vtemu:word, lincur:word
  202.     extrn    belltype:byte, vtroll:byte
  203.  
  204. oldoff    dw    0
  205. oldseg    dw    0
  206. sescur    dw    0
  207. dupflg    db    0        ; full (0) or half (1) duplex on port
  208. brkval    db    0        ; What to send for a break.
  209. brkdur    dw    0        ; Length of break in centiseconds
  210. badbd    db    cr,lf,'Unimplemented baud rate$'
  211. noimp    db    cr,lf,'Not implemented$'
  212. coms0msg db    cr,lf,'No US Robotics S-100 modem detected at this port!'
  213.     db    cr,lf,'$'
  214. comsmsg db    ' One of the following:'
  215.     db    cr,lf,'  1  2  3  4  COM1  COM2  COM3  COM4  A  B  J1  J2'
  216.     db    cr,lf,lf,'Where'
  217.     db    cr,lf,'  1 = COM1 = Serial Port B = J2'
  218.     db    cr,lf,'  2 = COM2 = Serial Port A = J1'
  219.     db    cr,lf,'  3 = COM3 = US Robotics S-100 modem at port 20H'
  220.     db    cr,lf,'  4 = COM4 = US Robotics S-100 modem at port 2EH$'
  221. vtsmsg    db    cr,lf,'The Z-100 terminal has inherent HEATH-19 support.'
  222.     db    cr,lf,' Set terminal none activates native Heath-19 '
  223.     db    'properties.',cr,lf
  224.     db    ' This deactivates key mapping and scan codes.$' 
  225. msmsg0    db    cr,lf,'  Modem may be ready: DSR is unknown$'
  226. msmsg1    db    cr,lf,'  Modem is not ready: DSR is off$'
  227. msmsg2    db    cr,lf,'  Modem is ready:     DSR is on$'
  228. msmsg3    db    cr,lf,'  no Carrier Detect:  CD  is off$'
  229. msmsg4    db    cr,lf,'  Carrier Detect:     CD  is on$'
  230. msmsg5    db    cr,lf,'  no Clear To Send:   CTS is off$'
  231. msmsg6    db    cr,lf,'  Clear To Send:      CTS is on$'
  232. msmsg7    db    cr,lf,'  Modem is not used by the Network$'
  233. not_z    db    'Sorry, wrong software!',cr,lf
  234.     db    'This Kermit will only run on the Z-100 -- a non '
  235.     db    'IBM PC compatible',cr,lf,lf
  236. machnam db    'Heath-Zenith_Z-100$'
  237. com3ms    db    'Carrier detected at S-100 Port 20H, COM3',cr,lf,'$'
  238. com4ms    db    'Carrier detected at S-100 Port 2EH, COM4',cr,lf,'$'
  239. com3ms1 db    'Modem   detected at S-100 Port 20H, COM3',cr,lf,'$'
  240. com4ms1 db    'Modem   detected at S-100 Port 2EH, COM4'
  241. crlf    db    cr,lf,'$'
  242. infmsg    db    'S-100 MODEM INITIALIZATION FAILURE',cr,lf,'$'
  243. wmsg    db    cr,lf,' CARRIER detected  --  disconnecting',cr,lf,'$'
  244. dscmsg    db    cr,lf,' DISCONNECTED',cr,lf,'$'
  245. ndscmsg db    cr,lf,' !!!  WARNING  >>>  NOT DISCONNECTED  !!!',cr,lf,'$'
  246. hngstr    db    '+++$'
  247. hngmsg    db    cr,lf,' The phone should have hungup.',cr,lf,'$' ; [jrd]
  248. hnghlp    db    cr,lf,' The modem control lines DTR and RTS for the current'
  249.     db    ' port are forced low (off)'
  250.     db    cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  251.     db    ' high (on) when it exits.'
  252.     db    cr,lf,lf,' The USR S-100 modem is hung up using "+++".'
  253.     db    cr,lf,'$'                       
  254. rdbuf    db    80 dup (?)    ; temp buf [jrd]
  255. delstr    db    BS,BS,'  ',BS,BS,'$'    ; Delete string
  256. clrlin    db    BS,BS,'  ',cr,'$'    ; Clear line (just the cr part)
  257. home    db    ESCAPE,'H$'    ; Home cursor
  258. clrstr    db    ESCAPE,'E$'    ; Home cursor and erase entire display
  259. eeolstr db    ESCAPE,'K$'    ; Erase to end of line
  260. enamod    db    ESCAPE,'x1$'    ; Enable 25th line
  261. dismod    db    ESCAPE,'y1$'    ; Disable 25th line
  262. enascan db    ESCAPE,'y?$'    ; Enable scan codes, disable key expansion
  263. disscan db    ESCAPE,'x?$'    ; Disable scan codes, enable key expansion
  264. begrev    db    ESCAPE,'p$'    ; Enter reverse video
  265. endrev    db    ESCAPE,'q$'    ; Exit reverse video
  266. lin25    db    ESCAPE,'Y8 $'    ; Column 1 row 25
  267. savcur    db    ESCAPE,'j$'    ; Save current cursor position
  268. precur    db    ESCAPE,'k$'    ; Restore cursor to previous position
  269. monstr    db    ESCAPE,'i0$'    ; Return montior information
  270. portin    db    -1        ; Has comm port been initialized?
  271.                 ; -1=has not used, 1=is used, 0=has been used
  272. xofsnt    db    0        ; Say if we sent an XOFF
  273. xofrcv    db    0        ; Say if we received an XOFF
  274. parmsk    db    0ffh        ; parity mask, 0ffh for no parity, 07fh with
  275. flowoff db    0        ; flow-off char, Xoff or null (if no flow)
  276. flowon    db    0        ; flow-on char, Xon or null
  277. tmp    db    0,'$'
  278. temp    dw    0        ; Temporary storage.
  279. mddat0    dw    0        ; Storage for modem data port
  280. mdstat0 dw    0        ; Storage for modem status port
  281. savedi    dw    offset source    ; Temporary storage for di
  282. srcpnt    dw    offset source    ; where to read next serial port byte
  283. source    db    bufsiz dup(0)    ; S-100 port input buffer
  284. timer    db    0
  285. timer0    db    0
  286.                 ; begin Terminal emulator data set
  287. portmax equ    4        ; number of predefined ports
  288.  
  289. port1    prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
  290. port2    prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
  291. port3    prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
  292. port4    prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
  293.     rept    portmax-4
  294.     prtinfo <0FFFH,0,defpar,1,0,defhand,floxon,0>
  295.     endm
  296. portval dw    port1        ; Default is to use port 1
  297.  
  298. bdtab    db    16        ; 16 entries
  299.     mkeyw    '45.5',0
  300.     mkeyw    '50 ',1
  301.     mkeyw    '75 ',2
  302.     mkeyw    '110 ',3
  303.     mkeyw    '134.5',4
  304.     mkeyw    '150',5
  305.     mkeyw    '300',6
  306.     mkeyw    '600',7
  307.     mkeyw    '1200',8
  308.     mkeyw    '1800',9
  309.     mkeyw    '2000',10
  310.     mkeyw    '2400',11
  311.     mkeyw    '4800',12
  312.     mkeyw    '9600',13
  313.     mkeyw    '19200',14
  314.     mkeyw    '38400',15
  315.  
  316. bdtab12 db    16        ; 16 (yes 16) entries for com1 and com2 
  317.     mkeyw    '45.5',0
  318.     mkeyw    '50 ',1
  319.     mkeyw    '75 ',2
  320.     mkeyw    '110 ',3
  321. lbdtab12  equ    $-bdtab12    ; length of table
  322.  
  323.  
  324. bdtab34 db    4        ; 4 entries for com3 and com4, s-100 modem 
  325.     mkeyw    '150 ',0
  326.     mkeyw    '300',1
  327.     mkeyw    '600',2
  328.     mkeyw    '1200',3
  329.  
  330. ; this table is indexed by the baud rate definitions given in
  331. ; bdtab.  Unsupported baud rates should contain 0FFH.
  332. bddat    label    word
  333.     dw    0        ; 45.5 baud
  334.     dw    1        ; 50 baud
  335.     dw    2        ; 75 baud
  336.     dw    3        ; 110 baud
  337.     dw    4        ; 134.5 baud
  338.     dw    5        ; 150 baud
  339.     dw    6        ; 300 baud
  340.     dw    7        ; 600 baud
  341.     dw    8        ; 1200 baud
  342.     dw    9        ; 1800 baud
  343.     dw    10        ; 2000 baud
  344.     dw    11        ; 2400 baud
  345.     dw    12        ; 4800 baud
  346.     dw    13        ; 9600 baud
  347.     dw    14        ; 19200 baud
  348.     dw    15        ; 38400 baud
  349. lbddat    equ    $-bddat        ; length of table
  350.  
  351. bddat12 label    word        ; for com1 and com2 
  352.     dw    0        ; 45.5 baud
  353.     dw    1        ; 50 baud
  354.     dw    2        ; 75 baud
  355.     dw    3        ; 110 baud
  356.     dw    4        ; 134.5 baud
  357.     dw    5        ; 150 baud
  358.     dw    6        ; 300 baud
  359.     dw    7        ; 600 baud
  360.     dw    8        ; 1200 baud
  361.     dw    9        ; 1800 baud
  362.     dw    10        ; 2000 baud
  363.     dw    11        ; 2400 baud
  364.     dw    12        ; 4800 baud
  365.     dw    13        ; 9600 baud
  366.     dw    14        ; 19200 baud
  367.     dw    15        ; 38400 baud
  368.  
  369. bddat34 label    word        ; for com3 and com4, s-100 modem
  370.     dw    0        ; 150 baud
  371.     dw    1        ; 300 baud
  372.     dw    2        ; 600 baud
  373.     dw    3        ; 1200 baud
  374.     dw    0ffh 
  375.     dw    0ffh 
  376.     dw    0ffh 
  377.     dw    0ffh 
  378.     dw    0ffh 
  379.     dw    0ffh 
  380.     dw    0ffh 
  381.     dw    0ffh 
  382.     dw    0ffh 
  383.     dw    0ffh 
  384.     dw    0ffh 
  385.     dw    0ffh 
  386.  
  387. ; baud rate data for S-100 modem
  388. bd150    db    4fh        ; Low speed mode byte     (150/300)   
  389.     db    17h        ; Low speed command byte (150/600)
  390. bd300    db    4fh        ; Low speed mode byte     (150/300)
  391.     db    37h        ; High speed command byte(300/1200)
  392. bd600    db    4eh        ; High speed mode byte     (600/1200)
  393.     db    17h        ; Low speed command byte (150/600)
  394. bd1200    db    4eh        ; High speed mode byte     (300/1200)
  395.     db    37h        ; High speed command byte(300/1200)
  396.  
  397. ; S-100 COM3/COM4 default baud rate: 0=150, 1=300, 2=600, 3=1200 baud
  398. bds100    equ    3        ; Set to 0, 1, 2, or 3
  399.  
  400. ; S-100 modem set up string
  401. ; echo commands, use extended result codes, do not answer call
  402. set_str db    'ATE1X1S0=0',cr,'$'
  403.  
  404. auxconf cfginfo <>
  405.  
  406. ; variables for serial interrupt handler
  407.  
  408. count    dw    0        ; Number of chars in int buffer.
  409. buffin    db    BUFILEN+2 dup(?)  ; input buffer
  410. bufibeg dw    0
  411. bufiend dw    0
  412. buffout db    BUFOLEN+2 dup(?)  ; output buffer
  413. bufobeg dw    0
  414. bufoend dw    0
  415. portadr dw    0
  416. intin    db    0        ; port int installed flag
  417. mdmhand db    0        ; Modem status
  418.  
  419.  
  420. ourarg    termarg <>
  421.  
  422. klen    dw    ?        ; length of key redefinition table
  423. ktab    dw    ?        ; address of key redefinition table
  424. krpl    dw    ?        ; address of key replacement table
  425.  
  426. colortb    db    0,4,2,6,1,5,3,7        ; color reversed-bit setting bytes
  427. clrset    db    ?            ; Temp for SET Term Tabstops xxx
  428.  
  429. ; This is data for the extended set terminal parameters.  It was put here
  430. ; in order to keep the size of msyz10.asm within limits for assembly by
  431. ; MASM 4.  The corresponding code is conatained in VTS and VTSTAT below.
  432. erms41    db    cr,lf,'?More parameters are needed$'
  433. vthlp    db    ' one of the following:',cr,lf
  434.     db '  terminal types of: None, Heath-19, VT52, VT102, VT320,'
  435.     db    ' or Tek4010',cr,lf
  436.     db '  Newline-mode    Cursor-style        Character-set'
  437.     db     cr,lf
  438.     db '  Keyclick        Margin-bell         Screen-background'
  439.     db    ' (normal, reverse)',cr,lf
  440.     db '  Tabstops        Wrap (long lines)   Color (fore & background)'
  441.     db    cr,lf,'  Bell  audible or visual'
  442.     db    cr,lf,'  Clear-screen  (clears old startup screen)'
  443.     db    cr,lf,'  Controls 7-bit or 8-bit  (permits VT320 to use'
  444.     db    ' 8-bit control sequences (C1))'
  445.     db    cr,lf,'  Direction Left-to-right or Right-to-left'
  446.     db    ' (screen writing direction)'
  447.     db    cr,lf,'  Graphics  (type of display adapter when in Tek4010'
  448.     db    ' mode)'
  449.     db    cr,lf,'  Keypad numeric (normal) or application mode'
  450.     db     cr,lf,'  Replay filespec (display a file through the emulator)'
  451.     db    cr,lf,'  Rollback  (undo screen roll back before writing new'
  452.     db    ' chars, default=off)$'
  453. clrhlp    db    ' one of the following:'
  454.     db    cr,lf,'  AT #s  (to set tabs at column #s)    or'
  455.     db    ' AT start-column:spacing'
  456.     db    cr,lf,'  Clear AT #s (clears individual tabs) or'
  457.     db    ' AT start-column:spacing'
  458.     db    cr,lf,'  Clear ALL  (to clear all tabstops)'
  459.     db    cr,lf,'  Ex: Set term tab at 10, 20, 34        sets tabs'
  460.     db    cr,lf,'  Ex: Set term tab at 1:8        sets tabs at 1, 9,'
  461.     db    cr,lf,'  Ex: Set term tab clear at 9, 17, 65   clears tabs'
  462.     db    cr,lf,'  Ex: Set term tab clear at 1:8  clears tabs at 1, 9,'
  463.     db    ' 17,...$'
  464. tbserr    db    cr,lf,'?Column number is not in range 1 to screen width-1$'
  465. colhlp    db    cr,lf,'  Set Term Color  value, value, value, ...'
  466.     db    cr,lf,'   0 no-snow mode on an IBM CGA and white on black'
  467.     db    cr,lf,'   1 for high intensity foreground'
  468.     db    cr,lf,'  10 for fast CGA screen updating (may cause snow)'
  469.     db    cr,lf,'  Foreground color (30-37) = 30 + sum of colors'
  470.     db    cr,lf,'  Background color (40-47) = 40 + sum of colors'
  471.     db    cr,lf,'    where colors are  1 = red, 2 = green, 4 = blue'
  472.     db    cr,lf,'  Ex: 0, 1, 37, 44   IBM CGA(0), bright(1) white(37)'
  473.     db    ' chars on a blue(44) field'
  474.     db    cr,lf,'  Attributes are applied in order of appearance.$'
  475. colerr    db    cr,lf,'?Value not in range of 0, 1, 10, 30-37, or 40-47$'
  476. vtwrap    db    'Term wrap-lines: $'
  477. vtbellm    db    'Term margin-bell: $'
  478. vtnewln db    'Term newline: $'
  479. vtcur    db    'Term cursor-style: $'
  480. vtcset    db    'Term character-set: $'
  481. vtclik    db    'Term key-click: $'
  482. vtscrn    db    'Term screen-background: $'
  483. colst1    db    'Term color  foregnd:3$'
  484. colst2    db    ' backgnd:4$'
  485. vtrolst    db    'Term rollback: $'
  486. vtdir    db    'Term direction: $'
  487. vtcntst    db    'Term controls: $'
  488. vtkpst    db    'Term keypad: $'
  489. vtbset    db    'Term bell: $'
  490. vtgchst    db    'Term graph char: $'
  491.                         ; terminal emulator
  492. vtstbl    stent    <srchkw,vtcset,chatab,vtemu.vtchset>        ; char set
  493.     stent    <srchkb,vtclik,ontab,vskeyclick,vtemu.vtflgop>    ; keyclick
  494.     stent    <srchkb,vtwrap,ontab,vswrap,vtemu.vtflgop>    ; line wrap
  495.     stent    <srchkb,vtcntst,cntltab,vscntl,vtemu.vtflgop>    ; controls
  496.     stent    <srchkb,vtbellm,ontab,vsmarginbell,vtemu.vtflgop>;margin bell
  497.     stent    <srchkb,vtcur,curtab,vscursor,vtemu.vtflgop>    ; cursor type
  498.     stent    <srchkw,vtbset,beltab,belltype>            ; bell
  499.      stent    <srchkb,vtdir,dirtab,vswdir,vtemu.vtflgop>    ; write direct
  500.     stent    <srchkb,vtnewln,ontab,vsnewline,vtemu.vtflgop>    ; newline
  501.     stent    <srchkw,vtrolst,ontab,vtroll>            ; rollback
  502.     stent    <srchkb,vtkpst,kpamtab,deckpam,vtemu.vtflgop>    ; keypad
  503.     stent    <srchkb,vtscrn,scrtab,vsscreen,vtemu.vtflgop>    ; screen 
  504.     dw    0        ; end of table
  505.                         ; end of Terminal data set
  506.  
  507. vttbl    db    19            ; number of entries
  508.     mkeyw    'Bell',8800h        ; note 8800 flag for decoding
  509.     mkeyw    'Character-set',chaval+8300h
  510.     mkeyw    'Clear-screen',8500h    ; 8500h = marker here
  511.     mkeyw    'Color',8200H        ; screen fore/back colors; 200H=marker
  512.     mkeyw    'Controls',cntlval
  513.     mkeyw    'Cursor-style',curval
  514.     mkeyw    'Direction',dirval
  515.     mkeyw    'Graphics',8600h    ; Tek graphics board, 800h=marker
  516.     mkeyw    'Heath-19',ttheath+8100H; note 8100H flag for decoding here
  517.     mkeyw    'Keyclick',keyval
  518.     mkeyw    'Keypad',kpamval
  519.     mkeyw    'Margin-bell',marval
  520.     mkeyw    'None',ttgenrc+8100H
  521.     mkeyw    'Newline',newval
  522.     mkeyw    'Replay',8700h        ; note 8700H flag for file replaying
  523.     mkeyw    'Rollback',8400h    ; note 8400H flag for decoding
  524.     mkeyw    'Screen-background',scrval
  525.     mkeyw    'Tabstops',tabval
  526.     mkeyw    'Wrap',wraval
  527.  
  528. vtsflg equ    this word        ; define small digits xxxval
  529. newval    equ    $-vtsflg        ; 0   and mask for bit in byte
  530.     dw    vsnewline        ;  1
  531. wraval    equ    $-vtsflg        ; 2
  532.     dw    vswrap            ;  2
  533. chaval    equ    $-vtsflg        ; 4
  534.     dw    vsnrcm            ;  4
  535. dirval    equ    $-vtsflg        ; 6
  536.     dw    vswdir            ;  8
  537. keyval    equ    $-vtsflg        ; 8
  538.     dw    vskeyclick        ;  10h
  539. marval    equ    $-vtsflg        ; 10
  540.     dw    vsmarginbell        ;  20h
  541. curval    equ    $-vtsflg        ; 12
  542.     dw    vscursor        ;  40h
  543. scrval    equ    $-vtsflg        ; 14
  544.     dw    vsscreen        ;  80h
  545. cntlval    equ    $-vtsflg        ; 16
  546.     dw    vscntl            ;  100h
  547. kpamval    equ    $-vtsflg        ; 18
  548.     dw    deckpam            ;  400h
  549. numflgs equ    ($-vtsflg)/2        ;  10
  550. tabval    equ    $-vtsflg        ; 20
  551.     dw    0
  552. ;vtrtns    dw    numflgs dup (flgset), tabmod ; dispatch table for vtsflg
  553.  
  554. data    ends
  555.  
  556. code    segment public
  557.     extrn    comnd:near, dopar:near, defkey:near, getpos:near, atsclr:near
  558.     extrn    lclyini:near, setcol:near, srchkb:near, srchkw:near
  559.     extrn    csrtype:near
  560.     assume    cs:code, ds:data, es:nothing
  561.  
  562. ; local initialization
  563. LCLINI    proc    near
  564.     jmp    lclini1            ; Bypass the exit code
  565. not_z10:mov    ah,prstr
  566.     mov    dx,offset not_z        ; This is not a Z-100, IBM PC maybe?
  567.     int    dos            ; This program is for
  568.     mov    dx,offset verident    ; display version header
  569.     int    dos
  570.     mov    ah,4ch            ; terminate process
  571.     int    dos
  572. ; Find out if this is a Z-100
  573. ; We are doing that by looking for 0E9H at locations 0040:0000H
  574. ; and 0040:0003H which are in the Z-100 bios jump table.
  575. lclini1:mov    bx,BIOS_SEG    ; The segment at 40h        
  576.     mov    ax,es        ; Save es
  577.     mov    es,bx        ; Set up the extra segment
  578.     cmp    byte ptr es:0,0e9h ; Z-100?
  579.     jnz    not_z10        ; No, it's probably IBM compatible
  580.     cmp    byte ptr es:3,0e9h ;Z-100?
  581.     jnz    not_z10        ; No, it's probably IBM compatible
  582.     mov    es,ax        ; Restore es
  583. ;
  584.     mov    flags.vtflg,ttheath ; Set Heath-19 emulation mode, allows macs
  585.     mov    brkval,BRKBIT    ; What to send for a break
  586.     in    al,mdmcom4    ; Check this port
  587.     and    al,modperb    ; Is it there?
  588.     jnz    lclini3        ; No, skip
  589.     mov    dx,offset com4ms1
  590.     mov    ah,prstr    ; Tell user it is there
  591.     int    dos
  592.     in    al,mdmcom4    ; Check again    
  593.     and    al,moddcdb    ; Carrier?
  594.     jz    lclini3        ; No, skip
  595.     mov    flags.comflg,4    ; Indicate s-100 port 2 for now
  596.     mov    portval,offset port4
  597.     mov    mddat0,mdmdat4
  598.     mov    mdstat0,mdmcom4
  599.     mov    ah,prstr    ; Tell user
  600.     mov    dx,offset com4ms
  601.     int    dos
  602. lclini3:in    al,mdmcom3    ; Check this port
  603.     and    al,modperb    ; Is it there?
  604.     jnz    lclini4        ; No, skip
  605.     mov    dx,offset com3ms1
  606.     mov    ah,prstr    ; Tell user it is there
  607.     int    dos
  608.     in    al,mdmcom3    ; Check again    
  609.     and    al,moddcdb    ; Carrier?
  610.     jz    lclini4        ; No, skip
  611.     mov    flags.comflg,3    ; Indicate s-100 port 1
  612.     mov    portval,offset port3
  613.     mov    mddat0,mdmdat3
  614.     mov    mdstat0,mdmcom3
  615.     mov    ah,prstr    ; Tell user
  616.     mov    dx,offset com3ms
  617.     int    dos
  618. lclini4:
  619.     call    getbaud        ; Which port of COM1/COM2 is default?
  620.                 ; Get baud rate from UARTs for this
  621.     call    baudref        ; Set up baud rate references bdtab, bddat
  622.     mov    port3.baud,bds100  ; and put in default baud rate
  623.     mov    port4.baud,bds100  ; and put in default baud rate
  624.     mov    lclsusp,offset suspend ; call this when suspending to DOS
  625.     mov    lclrest,offset restore ; call this when returning from DOS
  626.     mov    lclexit,offset finexit ; call this when exiting Kermit
  627.      call    ena_wrp        ; Make terminal wrap to next line at line end
  628.     call    lclyini        ; let other modules initialize too...
  629.     ret            ; We are all done with lclini
  630. ;
  631. baudref:push    di        ; Rearrange bdtab and bddat
  632.     push    si
  633.     push    es
  634.     mov    ax,ds        ; Set up
  635.     mov    es,ax        ;  pointers
  636.     mov    di,offset bddat ;  to move baud
  637.     mov    si,offset bddat12 ; rate selection
  638.     mov    cx,lbddat    ;  length of table
  639.     cmp    flags.comflg,2    ; Ports 1/2
  640.     jle    lclini5        ;  or ports 3/4?
  641.     mov    si,offset bddat34 ;Port 4! 
  642. lclini5:cld            
  643.     rep    movsb        ; Move array
  644.     mov    di,offset bdtab ; This too
  645.     mov    si,offset bdtab12
  646.     mov    cx,lbdtab12    ; Length of table 
  647.     cmp    flags.comflg,2    ; Ports 1/2
  648.     jle    lclini6        ;  or ports 3/4?
  649.     mov    si,offset bdtab34 ;Port 4! 
  650. lclini6:rep    movsb        ; Move array
  651.     pop    es        ; Restore registers
  652.     pop    si
  653.     pop    di
  654.     ret            ; We're done
  655. LCLINI    endp
  656.  
  657. ; Call these routines when suspending Kermit to go to DOS
  658. suspend proc    near
  659.     call    ihosts        ; suspend the host
  660.     call    serrst
  661.     call    dis_scan    ; disable scan code generation
  662.     call    dis_wrp        ; disable sreen line wrap around
  663.     ret
  664. suspend endp
  665.  
  666. ; Call these routines when returning to Kermit from DOS
  667. restore proc    near
  668.     call    serini        ; reinit serial port
  669.     call    ihostr        ; resume the host
  670.     call    ena_wrp        ; enable screen line wrap around
  671.     ret
  672. restore endp
  673.  
  674. ; Call these routines when doing final exit of Kermit
  675. finexit proc    near
  676.     call    serrst        ; reset serial port
  677.     call    dis_scan    ; disable scan code generation
  678.     call    dis_wrp        ; disable sreen line wrap around
  679.     ret
  680. finexit endp
  681.  
  682. ; This routine, ena_scan, enables Z-100 scan code generation.  It also
  683. ; disables extended key code generation.  Modifies ax.
  684. ENA_SCAN PROC    NEAR
  685.     push    dx
  686.     mov    ah,prstr
  687.     mov    dx,offset enascan
  688.     int    dos 
  689.     or    dosflg1,1        ; say scan codes enabled
  690.     pop    dx
  691.     ret
  692. ENA_SCAN ENDP
  693.  
  694. ; This routine, dis_scan, disables Z-100 scan code generation.    It also
  695. ; enables extended key code generatin.    Modifies ax.
  696. DIS_SCAN PROC    NEAR
  697.     push    dx
  698.     mov    ah,prstr
  699.     mov    dx,offset disscan
  700.     int    dos 
  701.     and    dosflg1,0feh        ; say scan codes disabled
  702.     pop    dx
  703.     ret
  704. DIS_SCAN ENDP
  705.  
  706. ; This routine, ena_wrp, enables wrap around at end of line.
  707. ; Modifies ax.
  708. ENA_WRP PROC NEAR
  709.     push    dx
  710.     mov    ah,conout
  711.     mov    dl,ESCAPE
  712.     int    dos
  713.     mov    dl,'v'
  714.     int    dos
  715.     pop    dx
  716.     ret
  717. ENA_WRP ENDP
  718.  
  719. ; This routine, dis_wrp, disables wrap around at end of line.
  720. ; Modifies ax.
  721. DIS_WRP PROC NEAR
  722.     push    dx
  723.     mov    ah,conout
  724.     mov    dl,ESCAPE
  725.     int    dos
  726.     mov    dl,'w'
  727.     int    dos
  728.     pop    dx
  729.     ret
  730. DIS_WRP ENDP
  731.  
  732. ; SHOW MODEM, displays current status of lines DSR, CD, and CTS.
  733. ; Uses byte mdmhand, the modem line status register. [jrd]
  734. shomodem proc    near
  735.     mov    ah,cmeol        ; get a confirm
  736.     call    comnd
  737.     jc    shomd5            ; c = failure
  738.     mov    dx,offset msmsg7    ; no modem status for network
  739.     call    getmodem        ; get modem status
  740.     mov    ah,prstr
  741.     cmp    flags.comflg,2        ; port 1 or 2
  742.     jle    shomd0            ; yes, jump
  743.     mov    dx,offset msmsg0    ; not supported function
  744.     jmp    shomd1
  745. shomd0: mov    dx,offset msmsg1    ; modem not ready msg
  746.     test    mdmhand,20h        ; is DSR asserted?
  747.     jz    shomd1            ; z = not ready
  748.     mov    dx,offset msmsg2    ; modem ready msg
  749. shomd1: int    dos
  750.     mov    dx,offset msmsg3    ; CD not asserted msg
  751.     test    mdmhand,80h        ; CD asserted?
  752.     jz    shomd2            ; z = not asserted
  753.     mov    dx,offset msmsg4    ; CD asserted msg
  754. shomd2: int    dos
  755.     clc
  756. shomd5: ret
  757. shomodem endp
  758.  
  759. ; Get modem status and set global byte mdmhand. Preserve all registers but dx.
  760. ; Returns with byte mdmhand in al, ah=0.
  761. getmodem proc    near        ; gets modem status upon request
  762.     cmp    flags.comflg,2    ; COM1 or COM2?
  763.     jna    getmodem2    ; na = yes, jump to handle these
  764.     mov    dx,mdstat0    ; Port address
  765.     in    al,dx        ; Get status
  766.     and    al,moddcdb    ; Carrier?
  767.     mov    mdmhand,0    ; Everything off
  768.     jz    getmodem1    ; z = yes, no carrier, done
  769.     mov    mdmhand,80h    ; No, carrier detected
  770. getmodem1:jmp    getmodem4    ; Done with COM3/COM4
  771. getmodem2:mov    dx,portadr
  772.     add    dx,PSTATUS
  773.     in    al,dx
  774.     mov    mdmhand,0    ; Everything off
  775.     test    al,DSR        ; DSR indicated?
  776.     jz    getmodem3    ; z = no, go on
  777.     mov    mdmhand,20h    ; Indicate DSR
  778. getmodem3:test    al,DCD        ; CD indicated?
  779.     jz    getmodem4    ; z = no, go on
  780.     or    mdmhand,80h    ; Indicate CD, don't touch DSR
  781. getmodem4:mov    al,mdmhand    ; Promised it here
  782.     xor    ah,ah        ; A promise too
  783.     clc            ; Success
  784.     ret
  785. getmodem endp
  786.  
  787. ; Clear the input buffer. This throws away all the characters in the
  788. ; serial interrupt buffer.  This is particularly important when
  789. ; talking to servers, since NAKs can accumulate in the buffer.
  790. CLRBUF    PROC    NEAR
  791.     cmp    flags.comflg,2    ; Ports 1/2?
  792.     jg    clrbuf1        ; g = no, do S-100 stuff
  793.     cli
  794.     push    bx
  795.     xor    bx,bx
  796.     mov    bufoend,bx
  797.     mov    bufobeg,bx
  798.     mov    bufiend,bx
  799.     mov    bufibeg,bx
  800.     pop    bx
  801.     mov    count,0
  802.     sti    
  803.     ret
  804. clrbuf1:push    ax            ; First empty port
  805.     push    dx
  806.     mov    dx,mddat0        ; Get possible
  807.     in    al,dx            ;  character
  808.     pop    dx
  809.     pop    ax            ;  then do it
  810.     mov    count,0            ; Nothing in buffer
  811.     mov    srcpnt,offset source    ; Reset buffer
  812.     mov    savedi,offset source    ;  pointers
  813.     ret
  814. CLRBUF    ENDP
  815.  
  816. ; Put the char in AH to the serial port, assumimg the port is active.
  817. ; Returns carry clear if success, else carry set.
  818. ; 16 May 1987 Add entry point OUTCH2 for non-flow controlled sending to
  819. ; prevent confusion of flow control logic at top of outchr; used by receiver
  820. ; buffer high/low water mark flow control code. [jrd]
  821. ; 14 September 1990 add entry point OUTCH5 for priority sending of xon;
  822. ; used by CHKXON and SERISR.
  823. OUTCHR    PROC    NEAR
  824.     cmp    flowoff,0        ; Are we doing flow control
  825.     je    outch2            ; No, just continue
  826.     cmp    ah,flowoff        ; sending xoff?
  827.     jne    outch1            ; ne = no
  828.     mov    xofsnt,usron        ; indicate user level xoff being sent
  829.     jmp    outch12
  830. outch1:and    xofsnt,not usron    ; cancel user level xoff
  831.     cmp    ah,flowon        ; user sending xon?
  832.     jne    outch12            ; ne = no
  833.     mov    xofsnt,off    ; say an xon has been sent (cancels xoff)
  834. outch12:mov    timer,xoftime+1    ; Set delay to xoftime minimum, maximum+1 sec
  835. outch14:cmp    xofrcv,true    ; Are we being held (xoff received)?
  836.     jnz    outch2        ; no - it's OK to go on
  837.     cmp    flags.comflg,2    ; Check if S-100 ports
  838.     push    ax        ; Save regs
  839.     push    bx
  840.     push    cx
  841.     push    dx
  842.     jle    outch16        ; No, make it simple
  843.     push    es
  844.     mov    cx,1        ; No delay for sprtch
  845.     call    sprtch        ; Get possible char at port com3/4
  846.     pop    es
  847. outch16:mov    ah,gettim    ; Get time function
  848.     int    dos
  849.     cmp    dl,timer0    ; Normally 0
  850.     pop    dx
  851.     pop    cx
  852.     pop    bx
  853.     pop    ax
  854.     jnz    outch14        ; No, go loop
  855.     xor    timer0,50    ; Yes, move target 1/2 second
  856.     cmp    timer0,0    ; This is only true every second
  857.     jnz    outch14        ; No, continue looping
  858.     dec    timer        ; Yes, one second has passed (unless 1st time)
  859.     jnz    outch14        ; No, have more seconds left, try again
  860.     mov    xofrcv,off    ; Timed out, force it off and fall thru.
  861. OUTCH2    LABEL    NEAR           ; outch2 entry point without flow control
  862.     mov    al,ah        ; Routine works on AL.
  863.     call    dopar        ; Set parity appropriately.
  864.     cmp    repflg,0    ; Doing REPLAY from a file?
  865.     je    outch24        ; e = no
  866.     and    al,7fh        ; Strip parity
  867.     cmp    al,'C'-40h    ; Control-C? (to exit playback mode)
  868.     je    outch22        ; e = yes, return failure
  869.     clc            ; Return success, send nothing
  870.     ret
  871. outch22:stc            ; Return failure to exit playback mode
  872.     ret
  873. ;
  874. outch24:push    bx
  875.     push    dx
  876.     cmp    flags.comflg,2    ; Ports J1/J2
  877.     jle    outch4        ; Yes, go handle J1/J2
  878.     mov    bl,al        ; No, do S-100, save byte to send
  879.     push    cx
  880.     xor    cx,cx        ; Set loop counter
  881. outch26:push    bx        ; Check on input
  882.     push    cx
  883.     push    es
  884.     mov    cx,1        ; No delay
  885.     call    sprtch        ; Get char from port if any
  886.     pop    es
  887.     pop    cx
  888.     pop    bx
  889.     mov    dx,mdstat0
  890.     in    al,dx        ; Check this port
  891.     and    al,modsndb    ;  for ready
  892.     jnz    outch28        ; Ready, continue
  893.     loop    outch26        ; Not ready, loop until ready or timeout
  894.     jmp    short outch44    ; Timed out, return with carry set
  895. outch28:pop    cx
  896.     mov    al,bl        ; Get back byte to send
  897.     mov    dx,mddat0
  898.     out    dx,al        ; Send it out
  899.     jmp    outch8        ; All done S-100 modem    
  900. ;
  901. outch4: push    cx
  902.     xor    cx,cx        ; Set loop counter
  903. outch40:mov    bx,bufobeg    ; get pointer to beginning of que
  904.     sub    bx,bufoend    ; where are we?
  905.     jnl    outch42        ; we did not wrap
  906.     add    bx,BUFOLEN    ; we have wrapped
  907. outch42:cmp    bx,BUFOLEN-2    ; we have bx char in buffer; is it full?
  908.     jnae    outch53        ; no, go on
  909.     loop    outch40        ; yes, loop until there is space or timeout
  910. outch44:pop    cx        ; timed out
  911.     pop    dx
  912.     pop    bx
  913.     stc
  914.     ret
  915. ;
  916. outch5: push    bx        ; OUTCH5 entry for SERISR and CHKXON
  917.     push    dx        ;  ah will contain xon or xoff only
  918.     push    cx
  919.     xor    cx,cx        ; Set loop counter
  920. outch50:mov    bx,bufobeg    ; get pointer to beginning of que
  921.     sub    bx,bufoend    ; where are we?
  922.     jnl    outch51        ; we did not wrap
  923.     add    bx,BUFOLEN    ; we have wrapped
  924. outch51:cmp    bx,BUFOLEN    ; we have bx char in buffer; is it full?
  925.     jne    outch52        ; no, go on
  926.     loop    outch50        ; yes, loop until there is space or timeout
  927.     jmp    short outch44    ; timed out, no space
  928. outch52:mov    al,ah        ; Routine works on AL.
  929.     call    dopar        ; Set parity appropriately.
  930.     pop    cx
  931.     jmp    short outch54
  932.                 ;
  933. outch53:pop    cx        ; restore stack
  934.     cmp    bx,0        ; buffer empty?
  935.     jz    outch58        ; yes, skip
  936.     cmp    flowoff,0    ; Are we doing flow control
  937.     je    outch58        ; No, skip
  938.     cmp    al,flowoff    ; Is it xoff?
  939.     je    outch54        ; Yes, this is priority, expedite
  940.     cmp    al,flowon     ; Is it xon?
  941.     jne    outch58        ; No, skip
  942.                 ;
  943. outch54:cli
  944.     mov    bx,bufobeg    ; beginning of que
  945.     dec    bx        ; we want space in between, bx still >= 0
  946.     jae    outch56        ; yes, go on
  947.      mov    bx,BUFOLEN    ; wrap
  948. outch56:mov    bufobeg,bx    ; new beginning
  949.     mov    byte ptr buffout[bx],al     ; put char in it
  950.     sti
  951.     jmp    short outch6
  952.  
  953. outch58:mov    bx,bufoend
  954.     mov    byte ptr buffout[bx],al     ; put char in it
  955.     inc    bx        ; point to next spot in que
  956.     cmp    bx,BUFOLEN    ; looking at end of que ?
  957.     jne    outch6        ; no, OK
  958.     xor    bx,bx        ; yes, reset pointer
  959. outch6: mov    bufoend,bx    ; store new value
  960.     mov    dx,portadr
  961.     add    dx,PCOMM
  962.     cli
  963.     in    al,dx
  964.     test    al,TXON        ; TX already on ?
  965.     jnz    outch7        ; yes, OK
  966.     or    al,TXON        ; no, turn it on
  967.     out    dx,al        ;   it's on
  968. outch7: sti            ; done with 2661
  969. outch8: pop    dx
  970.     pop    bx
  971.     clc            ; success, return with carry cleared
  972.     ret
  973. OUTCHR    ENDP
  974.  
  975. ; Move the cursor to the left margin, then clear to end of line.
  976. CTLU    PROC    NEAR
  977.     mov    ah,prstr
  978.     mov    dx,offset clrlin
  979.     int    dos
  980.  
  981. ; Clear to the end of the current line
  982. CLEARL    PROC    NEAR
  983.     push    ax
  984.     push    dx
  985.     mov    ah,prstr
  986.     mov    dx,offset eeolstr    ; Erase to end of line
  987.     int    dos
  988.     pop    dx
  989.     pop    ax
  990.     ret
  991. CLEARL    ENDP
  992. CTLU    ENDP
  993.  
  994. ; This routine blanks the screen and homes the cursor.    Uses ax and dx.
  995. CMBLNK    PROC    NEAR
  996.     mov    ah,prstr
  997.     mov    dx,offset clrstr    ; Home cursor, blank screen
  998.     int    dos
  999.     ret
  1000. CMBLNK    ENDP
  1001.  
  1002. ; Locate: homes the cursor.  Uses ax and dx.
  1003. LOCATE    PROC    NEAR
  1004.     mov    ah,prstr
  1005.     mov    dx,offset home        ; Go to top left corner of screen.
  1006.     int    dos
  1007. LOCATE    ENDP
  1008.  
  1009. ; write a line in inverse video at the bottom of the screen...
  1010. ; the line is passed in dx, terminated by a $.
  1011. PUTMOD    PROC    NEAR
  1012.     push    ax        ; save regs
  1013.     push    dx        ; preserve message
  1014.     mov    ah,prstr
  1015.     mov    dx,offset savcur
  1016.     int    dos
  1017.     mov    dx,offset enamod
  1018.     int    dos
  1019.     mov    dx,offset lin25
  1020.     int    dos
  1021.     mov    dx,offset begrev
  1022.     int    dos
  1023.     pop    dx        ; get message back
  1024.     int    dos        ; write it out
  1025.     mov    dx,offset endrev
  1026.     int    dos
  1027.     mov    dx,offset precur
  1028.     int    dos
  1029.     pop    ax
  1030.     ret            ; and return
  1031. PUTMOD    ENDP
  1032.  
  1033. ; clear the mode line written by putmod.
  1034. CLRMOD    PROC    NEAR
  1035.     mov    ah,prstr
  1036.     mov    dx,offset dismod
  1037.     int    dos
  1038.     ret
  1039. CLRMOD    ENDP
  1040.  
  1041. BEEP    PROC    NEAR
  1042.     push    ax        ; save regs
  1043.     push    dx        ; preserve message
  1044.     mov    ah,conout
  1045.     mov    dl,BELL        ; ASCII BEL
  1046.     int    dos        ; Ring it
  1047.     pop    dx
  1048.     pop    ax
  1049.     clc
  1050.     ret
  1051. BEEP    ENDP
  1052.  
  1053. ; Put a help message on the screen.  This one uses reverse video...
  1054. ; pass the message in ax, terminated by a null.     Messes up ax, bx, cx, dx.
  1055. PUTHLP    PROC    NEAR
  1056.     push    si
  1057.     push    ax        ; preserve this
  1058.     mov    dx,offset crlf
  1059.     int    dos
  1060.     pop    si        ; point to string again
  1061.     jmp    short puthl3    ; assume message begins with cr and lf
  1062. puthl2:    call    getpos        ; get cursor pos into dx
  1063.     mov    ax,dx        ; from row ah, col al
  1064.     mov    bx,dx
  1065.     mov    bl,COLUMNS    ;  to row bh, col bl
  1066.     mov    dx,word ptr doscol ; dos color reversed
  1067.     call    setcol        ; set this color
  1068.     call    atsclr        ;  and clear the line
  1069. puthl3: mov    cx,COLUMNS - 1    ; characters on a line less one (starts at 0)
  1070. puthl4: lodsb            ; get a byte
  1071.     mov    ah,conout    ; print char
  1072.     cmp    al,0        ; end of string?
  1073.     je    puthl5        ; yes, stop
  1074.     cmp    al,lf        ; lf ?
  1075.     je    puthl7         ; end of line, do new one
  1076.     cmp    cx,0        ; last column
  1077.     je    puthl6        ; no more space on line, get new one
  1078.     mov    dl,al        ; else, print char
  1079.     int    dos
  1080.     jmp    short puthl3    ; get next char
  1081. puthl5: pop    si
  1082.     ret
  1083. puthl6: mov    dl,cr
  1084.     int    dos
  1085. puthl7: mov    dl,lf
  1086.     int    dos
  1087.     jmp    short puthl2
  1088.  
  1089. PUTHLP    ENDP
  1090.  
  1091. ; Set the baud rate for the current port, based on the value
  1092. ; in the portinfo structure.  Returns carry clear.
  1093. BAUDST    PROC    NEAR
  1094.     mov    dx,offset bdtab        ; baud rate table, ascii
  1095.     xor    bx,bx            ; help is the table itself
  1096.     mov    ah,cmkey        ; get keyword
  1097.     call    comnd
  1098.     jc    baudst1            ; c = failure
  1099.     push    bx            ; save result
  1100.     mov    ah,cmeol        ; get confirmation
  1101.     call    comnd
  1102.     pop    bx
  1103.     jc    baudst1            ; c = failure
  1104.     push    si
  1105.     mov    si,portval
  1106.     mov    ax,[si].baud        ; remember original value
  1107.     mov    [si].baud,bx        ; set the baud rate
  1108.     pop    si
  1109.     call    dobaud            ; use common code
  1110.     clc
  1111. baudst1:ret
  1112. BAUDST    ENDP
  1113.  
  1114. DOBAUD    PROC    NEAR
  1115.     push    ax            ; save some regs
  1116.     push    bx
  1117.     push    cx
  1118.     push    dx
  1119.     mov    bp,portval    ; Pointer to port data structure
  1120.     mov    temp,ax        ; Don't overwrite previous rate
  1121.     mov    ax,ds:[bp].baud ; Check if new rate is valid
  1122.     shl    ax,1        ; Get index into baud table
  1123.     mov    bx,offset bddat ; Start of table.
  1124.     add    bx,ax
  1125.     mov    ax,[bx]        ; The data to output to port.
  1126.     cmp    ax,0FFH        ; Unimplemented baud rate.
  1127.     jne    dobd0
  1128.     mov    ax,temp        ; Get back orginal value.
  1129.     mov    ds:[bp].baud,ax ; Leave baud rate as is.
  1130.     mov    ah,prstr
  1131.     mov    dx,offset badbd ; Give an error message.
  1132.     int    dos
  1133.     stc            ; Failure
  1134.     jmp    dobd2
  1135. dobd0:    mov    ds:[bp].baud,ax ; Put in new baud rate
  1136.     cmp    flags.comflg,2    ; is it J1/J2?
  1137.     jle    dobd1        ; yes, go do J1/J2 stuff
  1138.     call    serini        ; go set rate in S-100 modem
  1139.  
  1140.     jmp    dobd2
  1141. dobd1:    mov    dx,portadr    ; get addr to send it
  1142.     add    dx,PMODE
  1143.     push    ax        ; save baud
  1144.     mov    al,MODE1
  1145.     cli            ; none while setting 2661
  1146.     out    dx,al        ; mode reg 1/2
  1147.     pop    ax        ; get baud back
  1148.     and    al,0fH        ; make sure it's clean
  1149.     or    al,MODE2    ; make complete mode 2/2 command
  1150.     out    dx,al        ; set mode reg 2/2
  1151.     sti            ; done with 2661
  1152.     clc            ; Success
  1153. dobd2:    pop    dx        ; restore regs
  1154.     pop    cx
  1155.     pop    bx
  1156.     pop    ax
  1157.     ret
  1158. DOBAUD    ENDP
  1159.  
  1160. ; Get the current baud rate from the serial card and set it
  1161. ; in the portinfo structure for the current port.
  1162. ; Also finds out which serial port, A (COM2) or B (COM1), is defined
  1163. ; as default by Zenith Configur.
  1164. ; This is used during initialization.
  1165. GETBAUD PROC    NEAR
  1166.     cmp    flags.comflg,2    ; J1/J2?
  1167.     jg    getbau3        ; No, all done
  1168.     
  1169.     push    ax
  1170.     push    bx
  1171.     push    dx
  1172.     push    di
  1173.     cmp    portadr,0    ; Just started Kermit?
  1174.     jnz    getbau2        ; No, skip this
  1175.     mov    bx,ds        ; Set up pointer to config info
  1176.     mov    es,bx
  1177.     mov    bx,offset auxconf
  1178.     mov    ah,chr_status
  1179.     mov    al,chr_sfgc    ; Get current config info
  1180.     call    bios_auxfunc
  1181.     cmp    auxconf.cfport,mdmdat1 ; Is it B?
  1182.     jne    getbau1        ; ne = no
  1183.     mov    flags.comflg,1    ; Set flag to indicate port B
  1184.     mov    portval,offset port1
  1185.     mov    mddat0,mdmdat1
  1186.     mov    portadr,mdmdat1
  1187.     mov    mdstat0,mdmcom1
  1188.     jmp    getbau2
  1189. getbau1:mov    flags.comflg,2    ; Set flag to indicate port A
  1190.     mov    portval,offset port2
  1191.     mov    mddat0,mdmdat2
  1192.     mov    portadr,mdmdat2
  1193.     mov    mdstat0,mdmcom2           
  1194. getbau2:mov    dx,portadr    ; Get addr to retrieve mode from
  1195.     add    dx,PMODE
  1196.     in    al,dx        ; Read and discard mode 1/2
  1197.     in    al,dx        ; mode 2/2 has baud rate
  1198.     and    ax,000fH    ; Clean it up
  1199.     mov    bp,portval
  1200.     mov    ds:[bp].baud,ax ; Put it in portinfo struct
  1201.     pop    di
  1202.     pop    dx
  1203.     pop    bx
  1204.     pop    ax
  1205. getbau3:ret
  1206. GETBAUD ENDP
  1207.  
  1208. ; Get Char from serial port buffer.
  1209. ; returns carry set if no character available at port, otherwise prtchr
  1210. ; returns carry clear with char in al, # of chars in buffer in dx and count.
  1211. PRTCHR    PROC    NEAR
  1212.     cmp    flags.comflg,2    ; check if S-100 ports
  1213.     jg    prtch4        ; Yes, go do S-100 stuff
  1214.     call    chkxon        ; see if we need to xon
  1215.     cmp    repflg,0    ; REPLAY?
  1216.     je    prtch0        ; e = no
  1217.      jmp    prtch30        ; yes, do replay file reading
  1218. prtch0: cli            ; dont let intterrupts touch buffers
  1219.     mov    dx,bufiend    ; compute number of chars in
  1220.     sub    dx,bufibeg    ;   input que
  1221.     jge    prtch1        ; is it wrapped around
  1222.     add    dx,BUFILEN    ; yes, make it +
  1223. prtch1: cmp    dx,0        ; anything in there ?
  1224.     jne    prtch2        ; ne = yes. [jrd]
  1225.     mov    count,dx
  1226.     sti
  1227.     stc            ; no
  1228.     ret
  1229. prtch2: mov    bx,bufibeg    ; yes, get the char, get the position
  1230.     mov    al,byte ptr buffin[bx]    ; get the char
  1231.     inc    bx        ; bump the position ptr
  1232.     cmp    bx,BUFILEN    ; wrap it ?
  1233.     jne    prtch3
  1234.     xor    bx,bx        ; yes, reset pointer
  1235. prtch3: mov    bufibeg,bx    ; store new value
  1236.     dec    dx        ; we took one char out
  1237.     mov    count,dx    ; save
  1238.     sti
  1239.     clc            ; yes, got it
  1240.     ret
  1241. prtch4: 
  1242.     push    ax        ; First check port for possible input
  1243.     push    bx
  1244.     push    cx
  1245.     push    es
  1246.     mov    cx,1        ; Parameter for sprtch, cx=1 means don't loop
  1247.     call    sprtch        ; Read port
  1248.     pop    es
  1249.     pop    cx
  1250.     pop    bx
  1251.     pop    ax
  1252.     cmp    repflg,0    ; REPLAY?
  1253.     je    prtch41        ; e = no
  1254.      jmp    prtch30        ; yes, do replay file reading
  1255. prtch41:cmp    count,0        ; Buffer empty?
  1256.     jne    prtch5        ; ne = no, get char
  1257.     mov    dx,0        ; Nothing there        Is this needed?
  1258.     stc            ; Got nothing
  1259.     ret
  1260. prtch5: push    si        ; Don't mess up, used by spack
  1261.     mov    si,srcpnt    ; Point to next character in que
  1262.     cld
  1263.     lodsb            ; Get the next one
  1264.     cmp    si,offset source + bufsiz ; Bigger than buffer?
  1265.     jb    prtch6        ; No, keep going
  1266.     mov    si,offset source ; Yes, wrap around
  1267. prtch6: dec    count
  1268.     mov    dx,count
  1269.     mov    srcpnt,si
  1270.     pop    si        ; Left in good shape
  1271.     clc            ; Yes, got it
  1272.     ret
  1273. prtch30:cmp    repflg,2        ; at EOF already?
  1274.     jne    prtch31            ; ne = no
  1275.     stc                ; yes, return with no char
  1276.     ret
  1277. prtch31:push    bx            ; REPLAY, read char from a file
  1278.     push    cx
  1279.     xor    dx,dx
  1280.     test    xofsnt,usron        ; user level xoff sent?
  1281.     jz    prtch32            ; z = no
  1282.     pop    cx            ; suppress reading here
  1283.     pop    bx
  1284.     stc                ; return with no char
  1285.     ret
  1286. prtch32:mov    ax,100
  1287.     mov    bx,1
  1288.     jmp    $+2            ; flush lookahead buffer
  1289.     div    bx            ; burn some cpu cycles
  1290.     div    bx            ; because a 1 ms wait is too long
  1291.     div    bx
  1292.     div    bx
  1293.     mov    ah,readf2
  1294.     mov    bx,diskio.handle    ; file handle
  1295.     mov    cx,1            ; read one char
  1296.     mov    dx,offset rdbuf        ; to this buffer
  1297.     int    dos
  1298.     jc    prtch34            ; c = read failure
  1299.     cmp    ax,cx            ; read the byte?
  1300.     jne    prtch34            ; ne = no
  1301.     pop    cx
  1302.     pop    bx
  1303.     mov    al,rdbuf        ; get the char into al
  1304.     mov    dx,1            ; external char count
  1305.     clc
  1306.     ret                ; return it
  1307. prtch34:call    beep
  1308.     mov    ax,40            ; wait 40 millisec
  1309.     call    pcwait
  1310.     call    beep
  1311.     mov    repflg,2        ; say at EOF
  1312.     pop    cx
  1313.     pop    bx
  1314.     stc                ; say no char
  1315.     ret
  1316. PRTCHR    ENDP
  1317.  
  1318. ; Examine incoming communications stream for a packet SOP character.
  1319. ; Return CX= count of bytes starting at the SOP character (includes SOP)
  1320. ; and carry clear. Return CX = 0 and carry set if SOP is not present.
  1321. ; Destroys AL.
  1322. peekcom proc far
  1323.     mov    cx,count        ; qty in circular buffer
  1324.     cmp    cx,6            ; basic NAK
  1325.     jb    peekc4            ; b = two few chars, get more
  1326.     push    bx
  1327.     cli        ; interrupts off, to keep srcpnt & count consistent
  1328.     mov    bx,srcpnt        ; address of next available slot in buffer
  1329.     sub    bx,cx            ; minus number of unread chars in buffer
  1330.     cmp    bx,offset source    ; located before start of buf?
  1331.     jae    peekc1            ; ae = no
  1332.     add    bx,bufsiz        ; else do arithmetic modulo bufsiz
  1333. peekc1:    mov    al,[bx]
  1334.     cmp    al,trans.rsoh        ; packet receive SOP?
  1335.     je    peekc3            ; e = yes
  1336.     inc    bx
  1337.     cmp    bx,offset source+bufsiz ; beyond end of buffer?
  1338.     jb    peekc2            ; b = no
  1339.     mov    bx,offset source    ; wrap around
  1340. peekc2:    loop    peekc1            ; keep looking
  1341.     sti
  1342.     pop    bx
  1343.     stc                ; set carry for no SOP
  1344.     ret
  1345. peekc3:    sti                ; interrupts back on now
  1346.     pop    bx
  1347.     inc    cx            ; include SOP in count
  1348.     clc                ; say SOP found
  1349.     ret                ; CX has count remaining
  1350.     
  1351. peekc4:    xor    cx,cx            ; return count of zero
  1352.     stc                ; say no data
  1353.     ret
  1354. peekcom endp
  1355.  
  1356.  
  1357. ; local routine to see if we have to transmit an xon when com1/2
  1358. chkxon    proc    near
  1359.     cmp    xofsnt,false    ; have we sent an xoff?
  1360.     je    chkxo1        ; no, forget it
  1361.     cmp    flowoff,0    ; Are wo doing flow control?
  1362.     je    chkxo1        ; no, skip all this
  1363.     test    xofsnt,usron    ; did user send an xoff?
  1364.     jnz    chkxo1        ; nz = yes, don't contradict it here
  1365.     test    xofsnt,bufon    ; have we sent a buffer level xoff?
  1366.     jz    chkxo1        ; z = no, forget it
  1367.     cmp    count,mntrgl    ; below trigger?
  1368.     jae    chkxo1        ; no, forget it
  1369.     mov    ah,flowon    ; xon
  1370.     call    outch5        ; send it
  1371.     jc    chkxo1        ; failure
  1372.     and    xofsnt,false    ; remember we've sent the xon.
  1373. chkxo1: ret            ; and return
  1374. chkxon    endp
  1375.  
  1376. ; Local routine to see if we have to transmit an xoff or xon when com3/4
  1377. ; this is probably overdoing it
  1378. ; called by sprtch
  1379. chkxof    proc    near
  1380.     cmp    flowoff,0    ; Are wo doing flow control?
  1381.     je    chkxof1        ; no, skip all this
  1382.     test    xofsnt,usron    ; did user send an xoff?
  1383.     jnz    chkxof1        ; nz = yes, don't contradict it here
  1384.     test    xofsnt,bufon    ; have we sent a buffer level xoff?
  1385.     jz    chkxof1        ; z = no, forget it
  1386.     cmp    count,mntrgh    ; Buffer filling up?
  1387.     jb    chkxof3        ; no, go check that xon sent
  1388.     cmp    xofsnt,true    ; yes, have we sent an xoff?
  1389.     je    chkxof1        ; yes, all done
  1390.     mov    ah,flowoff    ; xoff
  1391.     mov    xofsnt,true    ; remember we've sent the xoff.
  1392.     jmp    short chkxof2    ; go send xoff
  1393. chkxof3:cmp    count,mntrgl    ; below trigger
  1394.     jae    chkxof1        ; no, forget it
  1395.     cmp    xofsnt,false    ; xon sent?
  1396.     je    chkxof1        ; all done
  1397.     mov    ah,flowon    ; xon
  1398. chkxof2:call    outch2        ; send it
  1399. chkxof1:ret            ; and return
  1400. chkxof    endp
  1401.  
  1402. ; Read the serial port for the S-100 modem and put input in buffer.
  1403. ; Call with delay loop count in cx, c = 1 means no delay.
  1404. ; Input stream is monitored for xon/xoff.
  1405. ; Called by outchr, prtchr and outtty.
  1406. ; Destroys ax, bx, cx, dx, es
  1407. SPRTCH    PROC    NEAR
  1408.     mov    bx,ds        ; Point to data segment
  1409.     mov    es,bx
  1410.     mov    dx,mdstat0    ; Check 
  1411.     in    al,dx        ;  status
  1412.     and    al,modrcvb    ; Character at port?
  1413.     jnz    sprtch2        ; Yes, go get it
  1414.     call    chkxof
  1415.     loop    sprtch0        ; Keep checking port if cx not=1
  1416.     ret            ; No data 
  1417.  
  1418. sprtch0:push    cx
  1419.     xor    cx,cx        ; This is a delay loop to expand the delay for
  1420.     mov    cl,trans.rtime    ;  screen escape sequencies and capture.
  1421.     or    cx,cx        ; avoid 0, it will loop for ever
  1422.     jnz    sprtch1
  1423.     inc    cx
  1424. sprtch1:loop    sprtch1        ;  The delay time is controlled through the
  1425.     pop    cx        ;   receive timeout setting.
  1426.     jmp    sprtch
  1427.  
  1428. sprtch2:mov    dx,mddat0    ; Get
  1429.     in    al,dx        ;  character
  1430.     mov    ah,al        ; Make working copy
  1431.     and    ah,parmsk    ; Strip parity
  1432.     mov    bx,portval
  1433.     cmp    [bx].floflg,0    ; Are we doing flow control.
  1434.     jz    sprtch4        ; No, skip
  1435.     mov    dx,[bx].flowc
  1436.     cmp    ah,dh        ; xon?
  1437.     jne    sprtch3        ; No, check xoff
  1438.     mov    xofrcv,off    ; Set flag to indicate xoff not received (xon)
  1439.     jmp    short sprtch6    ; Get the next char
  1440.  
  1441. sprtch3:cmp    ah,dl        ; xoff?
  1442.     jne    sprtch4        ; No, go do normal buffer handling
  1443.     mov    xofrcv,true    ; Set flag to indicatae xoff received
  1444.     jmp    short sprtch6    ; Get the next char
  1445.  
  1446. sprtch4:push    di
  1447.     mov    di,savedi    ; Point to last received char
  1448.     cld
  1449.     stosb            ; Save the next one
  1450.     cmp    di,offset source + bufsiz ; Bigger than buffer?
  1451.     jb    sprtch5        ; No, keep going
  1452.     mov    di,offset source ; Yes, wrap around
  1453. sprtch5:inc    count
  1454.     mov    savedi,di
  1455.     pop    di
  1456. sprtch6:call    chkxof
  1457.     loop    sprtch0        ; Keep checking port if cx not=0
  1458.     ret
  1459. SPRTCH    ENDP
  1460.  
  1461. ; IHOSTS - Initialize the host by sending XOFF, or equivalent.
  1462. ; Requires that the port be initialized before hand.
  1463. ; Do not send flow control if doing half duplex.
  1464. IHOSTS    PROC    NEAR
  1465.     push    ax        ; save the registers
  1466.     push    cx
  1467.     push    dx
  1468.     mov    xofrcv,off    ; clear old xoff received flag
  1469.     mov    xofsnt,off    ; and old xoff sent flag
  1470.     mov    ah,flowoff    ; put wait flow control char in ah
  1471.     or    ah,ah        ; check for null char
  1472.     jz    ihosts1        ; z = null, don't send it
  1473.     cmp    dupflg,0    ; full duplex?
  1474.     jne    ihosts1        ; ne = no, half
  1475.     call    outchr        ; send it
  1476. ihosts1:call    clrbuf        ; clear out interrupt buffer
  1477.     pop    dx        ; empty buffer. we are done here
  1478.     pop    cx
  1479.     pop    ax
  1480.     ret
  1481. IHOSTS    ENDP
  1482.  
  1483. ; IHOSTR - initialize the remote host for our reception of a file by
  1484. ; sending the flow-on character (XON typically) to release any held
  1485. ; data. Called by receive-file code just after initializing the serial
  1486. ; port.        22 March 1986 [jrd]
  1487. IHOSTR    PROC    NEAR
  1488.     push    ax        ; save regs
  1489.     push    bx
  1490.     push    cx
  1491.     mov    bx,portval    ; port indicator
  1492.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  1493.     or    ah,ah        ; check for null char
  1494.     jz    ihostr1        ; z = null, don't send it
  1495.     call    outchr        ; send it (release Host's output queue)
  1496. ihostr1:pop    cx
  1497.     pop    bx
  1498.     pop    ax
  1499.     ret
  1500. IHOSTR    ENDP
  1501.  
  1502.  
  1503. ; Global proc to Hangup the Phone or Network by making DTR and
  1504. ; RTS low (phone).
  1505. DTRLOW    PROC    NEAR
  1506.     mov    ah,cmline    ; allow text, to be able to display help
  1507.     mov    bx,offset rdbuf        ; dummy buffer
  1508.     mov    dx,offset hnghlp    ; help message
  1509.     call    comnd            ; get a confirm
  1510.     jc    dtrlow3            ; c = failure
  1511.     cmp    flags.comflg,'0'    ; Bios?
  1512.     jb    dtrlow1            ; b = no, UART
  1513.     cmp    flags.comflg,'4'    ; Bios?
  1514.     jbe    dtrlow2            ; be = yes, can't access modem lines
  1515. dtrlow1:call    serhng            ; drop DTR and RTS
  1516.     cmp    taklev,0        ; in a Take file or macro?
  1517.     jne    dtrlow2            ; ne = yes, no message
  1518.     mov    ah,prstr        ; give a nice message
  1519.     mov    dx,offset hngmsg
  1520.     int    dos
  1521. dtrlow2:clc                ; success
  1522. dtrlow3:ret
  1523. DTRLOW    ENDP
  1524.  
  1525. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  1526. ; to terminate the connection. (com1 and com2)
  1527. ; The USR S-100 modem will not respond to dropping of DTR.  Instead the +++
  1528. ; sequence must be sent.
  1529. ; Calling this twice without intervening calls to serini should be harmless.
  1530. SERHNG    PROC    NEAR
  1531.     cmp    flags.comflg,2    ; Which port?
  1532.     jg    serhng1
  1533.     cli
  1534.     call    porton        ; Insure that DTR and RTS are high
  1535.     sti
  1536.     mov    dx,portadr
  1537.     add    dx,PCOMM
  1538.     in    al,dx
  1539.     xor    al,DTR        ; Drop DTR
  1540.     xor    al,RTS        ; Drop RTS 
  1541.     out    dx,al
  1542.     mov    ax,500        ; 500 millisec, for pcwait
  1543.     call    pcwait        ; keep lines low for at least 500 millisec
  1544.     clc
  1545.     ret
  1546. serhng1:mov    dx,mdstat0    ; Port address.     [19b]
  1547.     in    al,dx        ; Get status
  1548.     and    al,moddcdb    ; Carrier?
  1549.     jz    serhng4        ; No, tell user
  1550.     mov    ah,prstr    ; Yes, tell user to wait
  1551.     mov    dx,offset wmsg
  1552.     int    dos
  1553.     mov    ax,1100        ; 1100 milliseconds
  1554.     call    pcwait        ; Wait before sending '+++'
  1555.     push    si
  1556.     mov    si,offset hngstr  ; Point to '+++'
  1557.     cld
  1558.     lodsb            ; Get the first byte of string
  1559. serhng2:push    ax        ; We need the loaded byte later
  1560.     mov    dx,mdstat0    ; The status port
  1561. serhng3:in    al,dx        ; Get status
  1562.     and    al,modsndb    ; Mask for ready
  1563.     jz    serhng3        ; No, go on
  1564.     pop    ax        ; Get byte back
  1565.     mov    dx,mddat0    ; The data port
  1566.     out    dx,al        ; Send it out
  1567.     lodsb            ; Load next byte
  1568.     cmp    al,'$'        ; Finished?
  1569.     jnz    serhng2        ; No, process next
  1570.     pop    si
  1571.     mov    ax,1100        ; 1100 milliseconds
  1572.     call    pcwait        ; Wait after sending '+++'
  1573.     mov    dx,mdstat0    ; Port address.     [19b]
  1574.     in    al,dx        ; Get status
  1575.     and    al,moddcdb    ; Carrier?
  1576. serhng4:mov    ah,prstr
  1577.     mov    dx,offset dscmsg ; Point to message
  1578.     clc
  1579.     jz    serhng5        ; Yes, no carrier, go tell user
  1580.     inc    cl        ; No, carrier detected
  1581.     cmp    cl,3        ; Try three times
  1582.     jnz    serhng1        ; No, go try again
  1583.     mov    dx,offset ndscmsg ; Warn user
  1584. serhng5:int    dos        ;  all done 
  1585.     ret
  1586. SERHNG    ENDP
  1587.  
  1588. ; Send a break out the current serial port.
  1589. SENDBR    PROC    NEAR
  1590.     mov    brkdur,28        ; Normal break 280ms
  1591.     jmp    sendbr1
  1592. sendbl: mov    brkdur,180        ; Long break 1800ms
  1593.     jmp    sendbr1
  1594. sendbr1:push    cx
  1595.     push    dx
  1596.     push    ax
  1597.     mov    dx,mdstat0    ; Port address
  1598.     cmp    flags.comflg,2    ; Which port?
  1599.     jg    sendbr3         
  1600.     in    al,dx        ; Get current setting
  1601.     or    al,brkval    ; Set send-break bit(s)
  1602.     out    dx,al        ; Start the break
  1603.     mov    bx,brkdur    ; wait this long
  1604.     call    wait01        ; hold break for desired interval
  1605.     xor    al,brkval    ; Clear send-break bit(s)
  1606.     out    dx,al        ; Stop the break
  1607. sendbr2:pop    ax
  1608.     pop    dx
  1609.     pop    cx
  1610.     ret
  1611. sendbr3:call    pickspd        ; Point to speed
  1612.     mov    al,[bx+1]    ; Command byte
  1613.     sub    al,8h        ; Break byte 8h lower (1fh and 3fh)
  1614.     cmp    al,1fh
  1615.     je    sendbr4
  1616.     mov    al,3fh        
  1617. sendbr4:out    dx,al
  1618.     mov    bx,brkdur    ; wait this long
  1619.     call    wait01
  1620.     call    initmod
  1621.     jmp    sendbr2
  1622. SENDBR    ENDP
  1623.  
  1624. ; Position the cursor according to contents of DX:
  1625. ; DH contains row, DL contains column.
  1626. POSCUR    PROC    NEAR
  1627.     push    ax
  1628.     push    dx
  1629.     cmp    flags.comflg,2    ; Ports 1/2
  1630.     jna    poscur1        ; Yes, skip this
  1631.     push    bx        ; No, check input port
  1632.     push    cx
  1633.     push    es
  1634.     mov    cx,1        ; No delay
  1635.     call    sprtch        ; Get char from port if any
  1636.     pop    es
  1637.     pop    cx
  1638.     pop    bx
  1639. poscur1:mov    ah,conout
  1640.     mov    dl,ESCAPE
  1641.     int    dos
  1642.     mov    dl,'Y'
  1643.     int    dos
  1644.     pop    dx
  1645.     push    dx
  1646.     mov    dl,dh
  1647.     add    dl,' '
  1648.     int    dos
  1649.     pop    dx
  1650.     add    dl,' '
  1651.     int    dos
  1652.     pop    ax
  1653.     ret
  1654. POSCUR    ENDP
  1655.  
  1656.  
  1657. ; Delete a character from the terminal.     This works by printing
  1658. ; backspaces and spaces.
  1659. DODEL    PROC    NEAR
  1660.     mov    ah,prstr
  1661.     mov    dx,offset delstr ; Erase weird character.
  1662.     int    dos
  1663.     ret
  1664. DODEL    ENDP
  1665.  
  1666. ; select port to be current.  Returns with carry clear if success.
  1667. COMS    PROC    NEAR
  1668. ;    mov    kstatus,0        ; global status, success
  1669.     mov    dx,offset comptab    ; table of legal comms ports
  1670.     mov    bx,offset comsmsg    ; point to comsmsg
  1671.     mov    ah,cmkey        ; parse key word
  1672.     call    comnd
  1673.     jnc    coms0            ; nc = success
  1674.     ret                ; failure
  1675. coms0:    call    serrst            ; uninstall interrupt
  1676.     call    comstrt
  1677.     jnc    coms1
  1678.     mov    ah,prstr
  1679.     mov    dx,offset coms0msg    ; Point to no S-100 modem msg
  1680.     int    dos
  1681. coms1:    clc
  1682.     ret
  1683.  
  1684. comstrt:mov    al,flags.comflg
  1685.     mov    tmp,al            ; Save the old one in case
  1686.     mov    flags.comflg,bl        ; Set the comm port flag.
  1687.     cmp    bl,1            ; COM1 (port B)?
  1688.     je    coms2            ; Yes
  1689.     cmp    bl,2            ; COM2 (port A)?
  1690.     je    coms3            ; Yes        
  1691.     cmp    bl,3            ; COM3 (S-100 modem port 1)
  1692.     je    coms4            ; Yes
  1693.     in    al,mdmcom4        ; Check this port
  1694.     and    al,modperb        ; Is it there?
  1695.     jnz    coms6            ; No, skip
  1696.     mov    portval,offset port4    ; Must be COM4
  1697.     mov    mddat0,mdmdat4
  1698.     mov    mdstat0,mdmcom4
  1699.     jmp    coms5    
  1700. coms4:    in    al,mdmcom3        ; Check this port
  1701.     and    al,modperb        ; Is it there?
  1702.     jnz    coms6            ; No, skip
  1703.     mov    portval,offset port3
  1704.     mov    mddat0,mdmdat3
  1705.     mov    mdstat0,mdmcom3
  1706.     jmp    coms5        
  1707. coms2:    mov    mdstat0,mdmcom1        ; Set break address for B
  1708.     mov    portadr,mdmdat1        ; Set address for B
  1709.     mov    portval,offset port1    ; Point to portinfo for B
  1710.     jmp    coms5
  1711. coms3:    mov    mdstat0,mdmcom2        ; Set break address for A
  1712.     mov    portadr,mdmdat2        ; Set address for A
  1713.     mov    portval,offset port2    ; Point to portinfo for A
  1714. coms5:    call    baudref            ; Set up bdtab and bddat
  1715.     call    getbaud            ; See what is in the port now set
  1716.     clc                ; Success
  1717.     ret    
  1718. coms6:    mov    al,tmp
  1719.     mov    flags.comflg,al        ; Get the old one back
  1720.     stc                ; Failure
  1721.     ret
  1722. COMS    ENDP
  1723.  
  1724. ; Set heath emulation on/off.
  1725. ; SET Term parameters, especially for use with VT100 emulator. [jrd]
  1726. ; Taken from work done originally by James Harvey IUPUI.
  1727. ; VTS is called only by mssset to set terminal type and characteristics.
  1728. ; Enter via direct jmp. Exit ret with carry set for failure, else carry
  1729. ; cleared.
  1730. VTS    proc    near            ; SET TERM whatever
  1731.     mov    dx,offset termtb    ; terminal table, ascii
  1732.     xor    bx,bx            ; help is the table itself
  1733.     mov    ah,cmkey        ; get keyword
  1734.     call    comnd
  1735.     jnc    vset1            ; nc = success
  1736.     ret                ; failure
  1737. vset1:    mov    flags.vtflg,bx        ; Set the Heath emulation flag
  1738.     and    bx,bx            ; emulating?
  1739.     mov    dosflg,0ffh        ; set the flag, disable scan codes
  1740.     mov    flags.xltkbd,0        ; key translation disabled
  1741.     jz    vset2            ; nz=yes
  1742.     mov    dosflg,0        ; clear the flag, enable scan codes
  1743.     mov    flags.xltkbd,1        ; key translation enabled
  1744. vset2:    mov    dx,offset vtsmsg
  1745.     mov    ah,prstr
  1746.     int    dos
  1747.     clc                ; success
  1748.     ret
  1749. VTS    ENDP
  1750.  
  1751. VTSTAT    PROC    NEAR        ; For Status display [jrd]
  1752.     ret            ; no emulator status to display
  1753. VTSTAT    ENDP
  1754.  
  1755.  
  1756. ; simple routine to insure that the port has RXON and DTR high
  1757. ;  assumes int are off
  1758. porton    proc    near
  1759.     push    dx
  1760.     push    ax
  1761.     mov    dx,portadr
  1762.     add    dx,PCOMM
  1763.     in    al,dx
  1764.     or    al,RXON
  1765.     or    al,DTR
  1766.     or    al,RTS
  1767.     out    dx,al
  1768.     pop    ax
  1769.     pop    dx
  1770.     ret
  1771. porton    endp
  1772.  
  1773. ; routine to retrieve current int vector
  1774. ;  inputs:  al = int number
  1775. ;  outputs: cx = seg for current isr
  1776. ;        dx = offset for current isr
  1777. getivec proc    near
  1778.     push    es        ; save registers
  1779.     push    bx
  1780.     mov    ah,35H        ; Int 21H, function 35H = Get Vector.
  1781.     int    dos        ; get vector in es:bx
  1782.     mov    cx,es        ; addr of org vector (seg)
  1783.     mov    dx,bx        ;   and offset
  1784.     pop    bx
  1785.     pop    es
  1786.     ret
  1787. getivec endp
  1788.  
  1789. ; routine to set int vector
  1790. ;  inputs:  al = int number
  1791. ;        cx = seg for isr
  1792. ;        dx = offset for isr
  1793. setivec proc    near
  1794.     push    ds        ; save ds around next DOS call.
  1795.     mov    ds,cx
  1796.     mov    ah,25H        ; set interrupt address from ds:dx
  1797.     int    dos
  1798.     pop    ds
  1799.     ret
  1800. setivec endp
  1801.  
  1802.  
  1803. ; initialization for using serial port.     This routine performs
  1804. ; any initialization necessary for using the serial port, including
  1805. ; setting up interrupt routines, setting buffer pointers, etc.
  1806. ; Doing this twice in a row should be harmless (this version checks
  1807. ; a flag and returns if initialization has already been done).
  1808. ; SERRST below should restore any interrupt vectors that this changes.
  1809. SERINI    PROC    NEAR
  1810.     cmp    portin,0    ; did we initialize port already?
  1811.     je    serin1        ; e = yes
  1812.     jl    serin0        ; l = no, not yet
  1813.     jmp    serin2
  1814. serin0: mov    bl,flags.comflg ; pass current port ident
  1815.     call    comstrt        ; do SET PORT now
  1816.     jnc    serin1        ; nc = success
  1817.     ret            ; failed, exit now
  1818. serin1: cmp    flags.comflg,2    ; COM1 or COM2?
  1819.     jle    serini1        ; Go do COM1/COM2 stuff
  1820. serin2: cmp    flags.comflg,2    ; COM1 or COM2?
  1821.     jg    serini2        ; Go do COM3/COM4 stuff
  1822.     jmp    serini3        ; Update flow and leave
  1823. initmod:            ; The S-100 modem set up routine
  1824. serini2:call    pickspd        ; Select baud and speed info
  1825.     xor    al,al        ; Use this to reset modem
  1826.     mov    dx,mdstat0    ; Status port
  1827.     out    dx,al        ; Send to port
  1828.     jmp    $+2        ; Wait a little
  1829.     out    dx,al
  1830.     jmp    $+2        ; Wait a little
  1831.     out    dx,al
  1832.     jmp    $+2        ; Wait a little
  1833.     mov    al,40h
  1834.     out    dx,al
  1835.     jmp    $+2        ; Wait a little
  1836.     mov    al,[bx]
  1837.     out    dx,al
  1838.     jmp    $+2        ; Wait a little
  1839.     mov    al,[bx+1]
  1840.     out    dx,al
  1841.     jmp    $+2
  1842.     in    al,dx        ; Check port
  1843.     and    al,moddcdb    ;  for carrier
  1844.     jnz    serini0        ; Yes, don't do AT stuff
  1845.     mov    bx,10        ; Wait 10/100 seconds
  1846.     call    wait01        ; Call wait routine
  1847.     push    si
  1848.     mov    si,offset set_str;ATE1X1S0=0 sets up modem: echo commands, use
  1849.     cld            ;  extended response codes, don't answer
  1850.     lodsb            ; Get the first byte of string
  1851. serini5:push    ax        ; We need the loaded byte later
  1852. serini6:xor    cx,cx        ; Reset loop counter.  Loop to avoid hanging
  1853.     mov    dx,mdstat0    ; The status port
  1854. serini7:in    al,dx        ; Get status
  1855.     and    al,modsndb    ; Mask for ready
  1856.     jnz    serini8        ; Yes, go on
  1857.     inc    cx        ; No 
  1858.     or    cx,cx        ; Run out?
  1859.     jnz    serini7        ; No, try again
  1860.     mov    ah,prstr    ; Yes, tell user failure in initialization
  1861.     mov    dx,offset infmsg; Tell user init failed
  1862.     int    dos
  1863.     pop    ax        ; Restore stack
  1864.     pop    si
  1865.     stc            ; Failure
  1866.     ret
  1867. serini8:pop    ax        ; Get byte back
  1868.     mov    dx,mddat0    ; The data port
  1869.     out    dx,al        ; Send it out
  1870.     lodsb            ; Load next byte
  1871.     cmp    al,'$'        ; Finished?
  1872.     jnz    serini5        ; No, process next
  1873.     pop    si        ; Left in good order
  1874.     mov    bx,25        ; Wait 25/100 seconds
  1875.     call    wait01        ; Call wait routine
  1876.     call    prtchr        ; Purge modem
  1877.     jmp    serini3        ; Success
  1878.  
  1879. serini1:mov    ax,portval
  1880.     cmp    ax,offset port2
  1881.     je    seri2        ; setup for J1
  1882.     cmp    intin,2
  1883.     jne    seri0
  1884. serini0:clc            ; Success
  1885.     ret            ; J2 (com3, com4) already set up
  1886. seri0:    cmp    intin,1
  1887.     jne    seri1        ; J1 currently installed
  1888.     call    serrst        ; de-install current int
  1889. seri1:    mov    al,J2INT
  1890.     call    getivec
  1891.     mov    oldseg,cx
  1892.     mov    oldoff,dx
  1893.     mov    cx,cs
  1894.     mov    dx,offset serisr
  1895.     mov    al,J2INT
  1896.     call    setivec
  1897.     mov    portadr,J2_ADDR
  1898.     call    clrbuf
  1899.     call    porton
  1900.     mov    intin,2        ; show J2 installed
  1901.     jmp    serini3        ; Success
  1902. seri2:    cmp    intin,1
  1903.     jne    seri3
  1904.     clc            ; Success
  1905.     ret            ; J1 already set up
  1906. seri3:    cmp    intin,2
  1907.     jne    seri4        ; J2 currently installed
  1908.     call    serrst        ; de-install current int
  1909. seri4:    mov    al,J1INT
  1910.     call    getivec
  1911.     mov    oldseg,cx
  1912.     mov    oldoff,dx
  1913.     mov    cx,cs
  1914.     mov    dx,offset serisr
  1915.     mov    al,J1INT
  1916.     call    setivec
  1917.     mov    portadr,J1_ADDR
  1918.     call    clrbuf
  1919.     call    porton
  1920.     mov    intin,1        ; show J1 installed
  1921.  
  1922. serini3:push    bx
  1923.     mov    bx,portval        ; get port data structure
  1924.     mov    [bx].portrdy,1        ; say the comms port is ready
  1925.     mov    parmsk,0ffh        ; parity mask, assume parity is None
  1926.     cmp    [bx].parflg,parnon    ; is it None?
  1927.     je    serini3a        ; e = yes
  1928.     mov    parmsk,07fh        ; no, pass lower 7 bits as data
  1929. serini3a:xor    ax,ax
  1930.     cmp    [bx].floflg,0        ; flow control is off?
  1931.     je    serini3b        ; e = yes
  1932.     mov    ax,[bx].flowc        ; get flow control chars
  1933. serini3b:mov    flowoff,al        ; xoff or null
  1934.     mov    flowon,ah        ; xon or null
  1935.     mov    xofrcv,off        ; clear xoff received flag
  1936.     pop    bx
  1937.     mov    portin,1        ; say initialized
  1938.     clc                ; carry clear for success
  1939.     ret                ; We're done
  1940.  
  1941. pickspd:mov    bp,portval    ; Get speed for S-100 modem 'from' portval
  1942.     cmp    ds:[bp].baud,0    ; 150 baud?
  1943.     mov    bx,offset bd150
  1944.     jz    serini4
  1945.     cmp    ds:[bp].baud,1    ; 300 baud?
  1946.     mov    bx,offset bd300
  1947.     jz    serini4
  1948.     cmp    ds:[bp].baud,2    ; 600 baud?
  1949.     mov    bx,offset bd600
  1950.     jz    serini4
  1951.     mov    bx,offset bd1200; Default to 1200 baud
  1952. serini4:ret
  1953. SERINI    ENDP
  1954.  
  1955. ; Reset the serial port.  This is the opposite of serini.  Calling
  1956. ; this twice without intervening calls to serini should be harmless.
  1957. SERRST    PROC    NEAR
  1958.     cmp    portin,0    ; Reset already? 
  1959.     jg    serr0        ; g = no
  1960.     clc
  1961.     ret            ; e = yes, l=not used yet, just leave
  1962. serr0:    push    dx
  1963.     cmp    intin,0        ; is any isr installed
  1964.     je    serr2        ; no, all done
  1965.     push    cx
  1966.     push    ax
  1967.     mov    ax,J2INT    ; guess it's J2
  1968.     cmp    intin,2        ; yes,
  1969.     je    serr1        ;   reset it
  1970.     mov    ax,J1INT    ; no, must be J1
  1971. serr1:    mov    cx,oldseg    ; original isr
  1972.     mov    dx,oldoff    ;   address
  1973.     call    setivec        ; do it
  1974.     mov    intin,0        ; show nothing installed
  1975.     call    porton        ; Insure that DTR and RTS are high
  1976.     pop    ax
  1977.     pop    cx
  1978. serr2:    pop    dx
  1979.     mov    portin,0        ; reset flag
  1980.     push    bx
  1981.     mov    bx,portval        ; port data structure
  1982.     mov    [bx].portrdy,0        ; say port is not ready
  1983.     pop    bx
  1984.     clc
  1985.     ret
  1986. SERRST    ENDP
  1987.  
  1988. ; the serial port interrupt service routine
  1989. ;  this routine does int driven input and output
  1990. ;   once installed, it displaces the Z-100 serial isr
  1991. serisr: push    ax            ; Save regs
  1992.     push    bx
  1993.     push    cx
  1994.     push    dx
  1995.     push    ds            ; Save data seg
  1996.     mov    ax,seg data        ; Set our
  1997.     mov    ds,ax            ;  data seg
  1998.                     ;
  1999.     mov    dx,portadr        ; Get the port address
  2000.     mov    cx,dx            ;  and save a copy
  2001.     add    dx,PSTATUS
  2002.     in    al,dx                    ; Get port status
  2003.     mov    ah,al            ; Save it
  2004.     test    ah,RDA                   ; Check for data available
  2005.     jz    isr5            ; No, nothing to receive, go send
  2006.                     ;
  2007.     mov    dx,cx            ; Port address
  2008.     in    al,dx            ; Get the data
  2009.     cmp    flowoff,0        ; Are wo doing flow control?
  2010.     jz    isr2               ; No, skip
  2011.                     ;
  2012.      mov    ch,al            ; Make working copy of data
  2013.     and    ch,parmsk        ; Strip parity, if any
  2014.     cmp    ch,flowon         ; xon?
  2015.     jne    isr1            ; No, check xoff
  2016.     mov    xofrcv,false        ; Indicate xoff not received (xon)
  2017.                             ; Done with receiver
  2018.     jmp    short isr5        ;  there should be time for send
  2019. isr1:    cmp    ch,flowoff        ; xoff?
  2020.     mov    ch,0            ; We need this later in cx
  2021.     jnz    isr2            ; No, put regular char in buffer
  2022.       cmp    xofsnt,true         ; Did we send an outstanding xoff?
  2023.       jz     isr5                    ; Yes, ignore (possible echo), go send
  2024.     mov    xofrcv,true        ; Set flag to indicatae xoff received
  2025.                             ; Done with receiver
  2026.     jmp    short isr5        ;  there should still be time for send
  2027. isr2:    mov    bx,bufiend        ; Get where to put it
  2028.     cmp    count,BUFILEN        ; Buffer full?
  2029.     jne    isr3            ; No, jump
  2030.     dec    bx            ; Don't overwrite que
  2031.     mov    byte ptr buffin[bx],bell; Put Ctrl-G in the que as marker
  2032.     jmp    short isr5        ; We missed it anyway
  2033. isr3:    mov    byte ptr buffin[bx],al     ; Stick it in the que
  2034.     inc    bx            ; Bump que pointer
  2035.     inc    count            ; One more in que
  2036.     cmp    bx,BUFILEN        ; Pointing to end of que?
  2037.     jne    isr4             ; No, go on
  2038.     xor    bx,bx            ; Reset pointer
  2039. isr4:    mov    bufiend,bx        ; Store new pointer
  2040. ;    jmp    short isr12    ; Pick    ; We won't take time to send now
  2041.     jmp    short isr5    ;  one    ; There should still be time for send
  2042.                     ;
  2043. isr5:    test    ah,TSRE+THBE        ; Ready to send?
  2044.     jz    isr12             ; No, almost done
  2045.     mov    bx,bufobeg        ; Pointer to beginning of output buffer
  2046.     cmp    count,mntrgh        ; Past the high trigger point?
  2047.     jnae    isr6            ;  no, make it simple
  2048.     cmp    flowoff,0        ; Are we doing flow control?
  2049.     jz    isr6            ;  no, make it simple
  2050.     cmp    xofsnt,true         ; Did we send an xoff already?
  2051.     jz    isr6            ;  yes, make it simple
  2052.     mov    al,flowoff        ; xoff
  2053.     or    al,al            ; Null?
  2054.     jz    isr6            ; Don't send null
  2055.     call    dopar
  2056.     mov    dx,cx            ; Port address
  2057.     out    dx,al            ; Send the xoff out
  2058.     mov    xofsnt,true        ; Remember
  2059.     cmp    bx,bufoend        ; Buffer empty?
  2060.     jz    isr11             ; Yes, turn transmitter off
  2061.     jmp    short isr12               ; We have used transmitter already,
  2062.                     ;  so we need to go
  2063. isr6:    cmp    bx,bufoend        ; Buffer empty?
  2064.     jz    isr11             ; Yes, turn transmitter off
  2065.     mov    al,byte ptr buffout[bx] ; Get char to send
  2066.     cmp    flowoff,0        ; Are we doing flow control?
  2067.     jz    isr7            ; No, just go on
  2068.     mov    ah,al            ; Working copy
  2069.     and    ah,parmsk        ; Strip parity
  2070.     cmp    ah,flowoff        ; xoff?
  2071.     jz    isr7            ; Just send it
  2072.     cmp    ah,flowon         ; xon?
  2073.     jz    isr7            ; Just send it
  2074.     cmp     xofrcv,true        ; Being held?
  2075.     jz     isr12              ; Yes, don't send
  2076. isr7:    mov    dx,cx            ; Port address
  2077.     out    dx,al            ; Send it
  2078.     inc    bx            ; Point to next char to send
  2079.     cmp    bx,BUFOLEN        ; Pointing to end of que?
  2080.     jne    isr10
  2081.     xor    bx,bx             ; Reset pointer
  2082. isr10:    mov    bufobeg,bx        ; Save it
  2083.     jmp    short isr12        ; Almost done
  2084.                     ;
  2085. isr11:    mov    dx,cx            ; Port address
  2086.     add    dx,PCOMM
  2087.     in    al,dx            ; Get current mode
  2088.     and    al,TXOFF        ; Turn xmitter off
  2089.     out    dx,al            ; Do it.
  2090.                     ;
  2091. isr12:    mov    al,EOI            ; Tell interrupt controller
  2092.     out    Z8259,al        ;   that interrupt serviced
  2093.                     ;
  2094.     pop    ds            ; Restore regs
  2095.     pop    dx
  2096.     pop    cx
  2097.     pop    bx
  2098.     pop    ax
  2099.     iret
  2100.   
  2101. ;; Wait for the # of milliseconds in ax, for non-IBM compatibles.
  2102. pcwait    proc    near
  2103.     cmp    ax,0
  2104.     jz    pcwait2        ; no wait
  2105.     push    bx
  2106.     push    cx
  2107.     push    dx
  2108.     xor    dx,dx
  2109.     mov    cx,10        ; we can not make it finer than 10ms
  2110.     div    cx
  2111.     cmp    ax,0
  2112.     jnz    pcwait1
  2113.     inc    ax        ; make it 10ms for 1 to 9
  2114. pcwait1:mov    bx,ax        ; and 10ms for 10 to 19, 20ms for 20 to 29
  2115.     call    wait01        ; 10ms => 10 to 20ms by wait01
  2116.     pop    dx        ; 20ms => 20 to 30ms by wait01
  2117.     pop    cx
  2118.     pop    bx
  2119. pcwait2:ret
  2120. pcwait    endp
  2121.  
  2122. ; Wait for the # of hundredths seconds in bx. Range 1 to 0ffffh.
  2123. ; Accuracy within 10ms due to use of system clock.
  2124. ; This uses dos calls and is compatible with all msdos systems.
  2125. ; Preserves all registers.
  2126. wait01    proc    near
  2127.     push    ax
  2128.     push    cx
  2129.     push    dx
  2130.     push    di
  2131.     mov    ah,gettim    ; Get time function
  2132.     int    dos
  2133. wait011:mov    di,dx        ; Preset/reset di
  2134. wait012:int    dos
  2135.     cmp    dx,di        ; Changed?
  2136.     je    wait012        ; Yes, continue
  2137.     dec    bx        ; 1/100 second passed
  2138.     jnz    wait011        ; Did not time out, keep waiting
  2139.     pop    di        ; Timed out
  2140.     pop    dx
  2141.     pop    cx
  2142.     pop    ax
  2143.     ret
  2144. wait01    endp
  2145.  
  2146. ; Service SET NETBIOS-NAME name   command at Kermit prompt level
  2147. setnbios proc    near
  2148.     ret
  2149. setnbios endp
  2150. sesdisp    proc    near
  2151.     ret
  2152. sesdisp    endp
  2153. code    ends
  2154.     end
  2155.