home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / extra / nyenhuis2.arc / MSXGEN.ASM < prev    next >
Assembly Source File  |  1989-05-14  |  28KB  |  940 lines

  1.     name    msxgen
  2. ; File MSXGEN.ASM
  3.     include mssdef.h
  4. ; Generic MS DOS Kermit module, does i/o via DOS calls.
  5. ; Use with file MSUGEN.ASM (Generic keyboard translator)
  6. ; Last edit: 14 May 1989
  7. ; 1 July 1988 Version 2.31
  8. ; 8 Jan 1988 version 2.30
  9. ;
  10. ; Note: the biggest difficulty using this Generic Kermit is loss of one
  11. ; or two incoming characters when the screen must scroll. IBM PC's and
  12. ; relatives do this. If possible, replace the DOS screen write with faster
  13. ; calls specific to your system. Procedure Sleep call (uses system time of
  14. ; day clock) is commented out below for systems lacking such a clock. [jrd]
  15.  
  16.     public    serini, serrst, clrbuf, outchr, coms, vts, vtstat, dodel
  17.     public    ctlu, cmblnk, locate, lclini, prtchr, baudst, clearl
  18.     public    getbaud, beep, trnprs, pcwait, termtb
  19.     public    count, xofsnt, puthlp, putmod, clrmod, poscur
  20.     public    sendbr, sendbl, term, machnam, setktab, setkhlp, showkey
  21.     public    ihosts, ihostr, dtrlow, serhng, dumpscr, comptab
  22.     public    chrout, cstatus, cquit, cquery, chang    ; kbd action verbs
  23.     public    snull, kdos, klogof, klogon
  24.      public    shomodem, getmodem, mdmhand
  25.     public    portval, port1, port2, port3, port4, bdtab
  26.      include mssdef.h
  27.  
  28. false    equ    0
  29. true    equ    1
  30. instat    equ    6
  31. print_out equ    5            ; dos function to print to printer
  32. prtscr    equ    80h            ; screen printing active
  33.  
  34. ; external variables used:
  35. ; flags - global flags as per flginfo structure defined in pcdefs
  36. ; trans - global transmission parameters, trinfo struct defined in pcdefs
  37. ; portval - pointer to current portinfo structure (currently either port1
  38. ;    or port2)
  39. ; port1, port2 - portinfo structures for the corresponding ports
  40.  
  41. ; global variables defined in this module:
  42. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  43.  
  44. data     segment    public 'data'
  45.     extrn    flags:byte, trans:byte
  46.     extrn    comand:byte, dmpname:byte, npages:word
  47.     extrn    kbdflg:byte, rxtable:byte
  48.  
  49. machnam    db    'Generic MS-DOS $'
  50. erms41    db    cr,lf,'?Warning: Cannot open com port$'
  51. erms50    db    cr,lf,'Error reading from device$'
  52. hnd1    db    cr,lf,'Enter a file handle.  Check your DOS manual if you are '
  53.     db    cr,lf,'not certain what value to supply (generally 3).$'
  54. hnd2    db    cr,lf,'Handle: $'
  55. hnderr    db    cr,lf,'Warning: Handle not known.'
  56. deverr    db    cr,lf,'Any routine using the communications port will'
  57.     db    cr,lf,'probably not work.$'
  58. hndhlp    db    cr,lf,'A one to four digit file handle $'
  59. dev1    db    cr,lf,'Device: $'
  60. devhlp    db    cr,lf,'Name for your systems auxiliary port $'
  61. badbd    db    cr,lf,'Unimplemented baud rate$'
  62. noimp    db    cr,lf,'Command not implemented.$'
  63. hngmsg    db    cr,lf,' The phone should have hungup.',cr,lf,'$'
  64. hnghlp    db    cr,lf,' The modem control lines DTR and RTS for the current'
  65.     db    ' port are forced low (off)'
  66.     db    cr,lf,' to hangup the phone. Normally, Kermit leaves them'
  67.     db    ' high (on) when it exits.'
  68.     db    cr,lf,'$'
  69. msmsg1    db    cr,lf,' Communications port is not ready.$'
  70. msmsg2    db    cr,lf,' Communications port is ready.$'
  71. rdbuf    db    80 dup (?)            ; temp buf
  72.  
  73. shkmsg    db    'Not implemented'
  74. shklen    equ    $-shkmsg
  75. setktab    db    0
  76. setkhlp    db    0
  77. crlf    db      cr,lf,'$'
  78. delstr  db      BS,BS,'  ',BS,BS,'$'    ; Delete string
  79. ; If delete code moves cursor then BS over code, BS over bad char, space
  80. ; over both to erase from screen, BS twice to restore cursor position. 
  81. argadr    dw    ?        ; address of arg blk from msster.asm
  82. parmsk    db    ?        ; 8/7 bit parity mask, for reception
  83. flowoff    db    ?        ; flow-off char, Xoff or null (if no flow)
  84. flowon    db    ?        ; flow-on char, Xon or null
  85. captrtn    dw    ?        ; routine to call for captured output
  86. xofsnt    db    0        ; Say if we sent an XOFF
  87. xofrcv    db    0        ; Say if we received an XOFF
  88. count    dw    0        ; Number of chars in int buffer
  89. fairness dw    0
  90. mdmhand    db    0        ; Modem status register, current
  91. prthnd    dw    0        ; Port handle
  92. prttab    dw    com1,com2
  93. com1    db    'COM1',0
  94. com2    db    'COM2',0
  95. tmp    db    ?,'$'
  96. temp    dw    0
  97. prtstr    db    20 dup(?)    ; Name of auxiliary device
  98.  
  99. portmax    equ    4            ; number of predefined ports
  100.  
  101. port1    prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  102. port2    prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  103. port3     prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  104. port4    prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  105.     rept    portmax-4
  106.     prtinfo    <0FFFH,0,defpar,1,0,defhand,floxon>
  107.     endm
  108. portval    dw    port1            ; Default is to use port 1
  109. ; Entries for choosing communications port
  110. comptab    db    6            ; Number of options
  111.     mkeyw    '1',1
  112.     mkeyw    '2',2
  113.     mkeyw    'COM1',1
  114.     mkeyw    'COM2',2
  115.     mkeyw    'Device',3
  116.     mkeyw    'File-handle',4
  117.  
  118. bdtab    db    0            ; baud rate table, number of entries
  119.  
  120. ourarg    termarg    <>
  121.  
  122. termtb    db    tttypes            ; entries for Status, not Set
  123.     mkeyw    'Heath-19',ttheath
  124.     mkeyw    'none',ttgenrc
  125.     mkeyw    'Tek4014',tttek
  126.     mkeyw    'VT102',ttvt100        
  127.     mkeyw    'VT52',ttvt52
  128. data    ends
  129.  
  130. code    segment    public 'code'
  131.     extrn    comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
  132.     extrn    sleep:near, msuinit:near, keybd:near
  133.     assume    cs:code, ds:data
  134.  
  135. ; Clear the input buffer. This throws away all the characters in the
  136. ; serial interrupt buffer.  This is particularly important when
  137. ; talking to servers, since NAKs can accumulate in the buffer.
  138. ; Do nothing since we are not interrupt driven.  Returns normally.
  139.  
  140. CLRBUF    PROC    NEAR
  141.     cmp    prthnd,0        ; got a port handle yet?
  142.     jne    clrbu1            ; ne = yes
  143.     ret                ; else just return
  144. clrbu1:    call    prtchr            ; read from comms port
  145.     jnc    clrbu1            ; nc = char available
  146.     ret                ; no data
  147. CLRBUF    ENDP
  148.  
  149. ; Clear to the end of the current line.  Returns normally.
  150.  
  151. CLEARL    PROC    NEAR
  152.     push    ax
  153.     push    dx
  154.     mov    ah,prstr
  155.     mov    dx,offset crlf
  156.     int    dos
  157.     pop    dx
  158.     pop    ax
  159.     ret
  160. CLEARL    ENDP
  161.  
  162. shomodem proc    near
  163.     mov    ah,cmeol        ; get a confirm
  164.     call    comnd
  165.     jc    shmodx            ; c = no confirm
  166.     cmp    prthnd,0        ; got a handle yet?
  167.     jne    shmod0            ; ne = yes, just go on
  168.     call    opnprt            ; else 'open' the port
  169. shmod0:    mov    dx,offset msmsg1    ; say port is not ready
  170.     mov    bx,prthnd
  171.     mov    al,7            ; output status command
  172.     mov    ah,ioctl        ; ask DOS to look for us
  173.     int    dos
  174.     jc    shmod1            ; c = call failed, device not ready
  175.     or    al,al
  176.     jz    shmod1            ; z = not ready
  177.     mov    dx,offset msmsg2    ; say port is ready
  178. shmod1:    mov    ah,prstr
  179.     int    dos
  180.     clc
  181. shmodx:    ret
  182. shomodem endp
  183.  
  184. getmodem proc near
  185.     mov    al,0
  186.     clc
  187.     ret
  188. getmodem endp
  189.  
  190. ; Put the char in AH to the serial port.  This assumes the port has been
  191. ; initialized. Returns carry clear if success, else carry set if the
  192. ; character cannot be written.
  193.  
  194. OUTCHR    PROC    NEAR
  195.     push    cx        ; save regs
  196.     or    ah,ah        ; sending a null?
  197.     jz    outch2        ; z = yes
  198.     xor    cx,cx        ; clear counter
  199.     cmp    ah,flowoff    ; sending xoff?
  200.     jne    outch1        ; ne = no
  201.     mov    xofsnt,false    ; supress xon from chkxon buffer routine
  202. outch1:    cmp    xofrcv,true    ; are we being held?
  203.     jne    outch2        ; ne = no, it's OK to go on
  204.     loop    outch1        ; held, try for a while
  205.     mov    xofrcv,false    ; timed out, force it off and fall thru
  206. outch2:    push    dx        ; save register
  207.     mov    al,ah        ; parity routine works on AL
  208.     call    dopar        ; set parity appropriately
  209.     mov    byte ptr temp,al ; put data there
  210.     cmp    prthnd,0    ; got a handle yet?
  211.     jne    outch3        ; ne = yes
  212.     call    opnprt        ; else 'open' the port
  213. outch3:    push    bx
  214.     mov    bx,prthnd    ; port handle
  215.     mov    cx,1        ; one byte to write
  216.     mov    dx,offset temp    ; place where data will be found
  217.     mov    ah,write2    ; write to file/device
  218.     int    dos
  219.     pop    bx
  220.     pop    dx
  221.     pop    cx
  222.     clc
  223.     ret
  224. OUTCHR    ENDP 
  225.  
  226. ; This routine blanks the screen.  Returns normally.
  227.  
  228. CMBLNK    PROC    NEAR
  229.     push    ax            ; save some registers
  230.     push    dx
  231.     mov    ah,prstr
  232.     mov    dx,offset crlf        ; carriage return plus line feed
  233.     pop    dx
  234.     pop    ax 
  235.     ret
  236. CMBLNK     ENDP
  237.  
  238. ; Homes the cursor.  Returns normally.
  239.  
  240. LOCATE  PROC    NEAR
  241.     mov    dx,0            ; Go to top left corner of screen
  242.     jmp    poscur
  243. LOCATE  ENDP
  244.  
  245. ; Write a line at the bottom of the screen
  246. ; the line is passed in dx, terminated by a $.  Returns normally.
  247. putmod    proc    near
  248.     push    dx        ; preserve message
  249.     mov    dx,1800h    ; now address line 24
  250.     call    poscur
  251.     pop    dx        ; get message back
  252.     mov    ah,prstr
  253.     int    dos        ; write it out
  254.     ret            ; and return
  255. putmod    endp
  256.  
  257. ; clear the mode line written by putmod.  Returns normally.
  258. clrmod    proc    near
  259.     mov    dx,1800h
  260.     call    poscur        ; Go to bottom row
  261.     call    clearl        ; Clear to end of line
  262.     ret
  263. clrmod    endp
  264.  
  265. ; Put a help message on the screen.  
  266. ; Pass the message in ax, terminated by a null.  Returns normally.
  267. puthlp    proc    near
  268.     push    dx        ; save regs
  269.     push    si
  270.     push    ax        ; preserve this
  271.     mov     ah,prstr
  272.     mov     dx,offset crlf
  273.     int     dos
  274.     pop    si        ; point to string again
  275.     cld
  276. puthl3:    lodsb            ; get a byte
  277.     cmp    al,0        ; end of string?
  278.     je    puthl4        ; yes, stop
  279.     mov     dl,al
  280.     mov    ah,dconio
  281.     int    dos        ; else write to screen
  282.     jmp    puthl3        ; and keep going
  283. puthl4:    mov     ah,prstr
  284.     mov     dx,offset crlf
  285.     int     dos
  286.     pop    si
  287.     pop    dx
  288.     ret
  289. puthlp    endp
  290.  
  291. ; Set the baud rate for the current port, based on the value
  292. ; in the portinfo structure.  Returns normally.
  293.  
  294. BAUDST    PROC    NEAR
  295.     mov    ah,prstr
  296.     mov    dx,offset noimp        ; Say it's not implemented
  297.     int    dos
  298.     push    bx            ; save reg
  299.     mov    bx,portval
  300.     mov    [bx].baud,0FFFFH    ; So it's not a recognized value
  301.     pop    bx
  302.     ret
  303. BAUDST    ENDP
  304.  
  305. ; Get the current baud rate from the serial card and set it
  306. ; in the portinfo structure for the current port.  Returns normally.
  307. ; This is used during initialization.
  308.  
  309. GETBAUD    PROC    NEAR
  310.     stc
  311.     ret                ; Can't do this
  312. GETBAUD    ENDP
  313.  
  314. ; Use for DOS 2.0 and above.  Check the port status.  If no data, return
  315. ; carry set; else read a char into AL and return carry clear.
  316. ; Note added by [jrd]: The test for char-at-input-port is int 21h function
  317. ; 44h (ioctl) sub function 6 (get input status). On many systems an FFH will
  318. ; be reported (meaning Ready) even though no char is available; the Ready
  319. ; indication is misleading. In such cases the system will wait for a char
  320. ; and will appear to be hung. A preferrable method is to use the ROM Bios
  321. ; call int 14H function 3 (get port status) and if the lsb of the returned
  322. ; 8 bits in AH is 1 then a char is availble at the port; this assumes that
  323. ; the machine emulates this ROM Bios operation.
  324. ; Lastly, if the current code is used and the system hangs then reboot
  325. ; and say  ECHO Hello >COM1  before running Kermit; this should make MSDOS
  326. ; truely aware of the port's actual status. Dark grey magic. Good luck! [jrd]
  327. PRTCHR    PROC    NEAR
  328.     push    bx
  329.     push    cx
  330.     cmp    prthnd,0    ; got a handle yet?
  331.     jne    prtch0        ; ne = yes
  332.     call    opnprt        ; else 'open' the port
  333. prtch0:    call    chkxon
  334.     mov    bx,prthnd
  335.     mov    al,instat    ; input status command
  336.     mov    ah,ioctl    ; see note above
  337.     int    dos
  338.     jc    prtch4        ; c = call failed, device not ready
  339.     or    al,al
  340.     jz    prtch4        ; not ready
  341.     mov    bx,prthnd    ; the file handle
  342.     mov    ah,readf2    ; read file/device
  343.     mov    cx,1        ; want just one character
  344.     mov    dx,offset rdbuf    ; where to store it
  345.     int    dos
  346.     jnc    prtch1        ; nc = no error
  347.     cmp    al,5        ; Error condition
  348.     je    prt3x
  349.     cmp    al,6        ; Error condition
  350.     je    prt3x
  351.     jmp    prtch4        ; else report no char present
  352. prtch1:;;;mov    count,0        ; update count (always 0 for one char reads)
  353.     mov    dx,ax        ; needed to obey rules
  354.     or    ax,ax        ; reading from end of file?
  355.     jz    prtch4        ; z = yes
  356.     mov    al,rdbuf    ; recover char
  357. prtch3:    pop    cx
  358.     pop    bx
  359.     clc
  360.     ret            ; return success (char is in al)
  361. prt3x:    mov    ah,prstr
  362.     mov    dx,offset erms50
  363.     int    dos
  364. prtch4:    pop    cx
  365.     pop    bx
  366.     stc            ; no chars
  367.     ret
  368. PRTCHR  ENDP
  369.  
  370. ; Local routine to see if we have to transmit an xon
  371. chkxon    proc    near
  372.     push    bx
  373.     mov    bx,portval
  374.     cmp    [bx].floflg,0    ; doing flow control?
  375.     je    chkxo1        ; no, skip all this
  376.     cmp    xofsnt,false    ; have we sent an xoff?
  377.     je    chkxo1        ; no, forget it
  378.     mov    ax,[bx].flowc    ; ah gets xon
  379.     call    outchr        ; send it
  380.     mov    xofsnt,false    ; remember we've sent the xon
  381. chkxo1:    pop    bx        ; restore register
  382.     ret            ; and return
  383. chkxon    endp
  384.  
  385. ; IHOSTS - Initialize the host by sending XON, or equivalent, and enter the
  386. ; cycle of clear input buffer, wait 1 second, test if buffer empty then exit
  387. ; else repeat cycle. Requires that the port be initialized before hand.
  388. ; Ihosts is used by the local send-file routine just after initializing
  389. ; the serial port.
  390. ; 22 March 1986 [jrd]
  391.  
  392. IHOSTS    PROC    NEAR
  393.     push    ax        ; save the registers
  394.     push    bx
  395.     push    cx
  396.     push    dx
  397.     mov    bx,portval    ; port indicator
  398.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  399.     or    ah,ah        ; don't send null if flow = none
  400.     jz    ihosts1        ; z = null
  401.     call    outchr        ; send it (release Host's output queue)
  402. ihosts1:call    clrbuf        ; clear out interrupt buffer
  403.     mov    ax,1        ; sleep for 1 second
  404.     call    prtchr        ; check for char at port
  405.     jnc    ihosts1        ; nc=have a char in al, repeat wait/read cycle
  406.     pop    dx            ; empty buffer. we are done here
  407.     pop    cx
  408.     pop    bx
  409.     pop    ax
  410.     ret
  411. IHOSTS    ENDP
  412.  
  413. ; IHOSTR - initialize the remote host for our reception of a file by
  414. ; sending the flow-on character (XON typically) to release any held
  415. ; data. Called by receive-file code just after initializing the serial
  416. ; port.        22 March 1986 [jrd]
  417. IHOSTR    PROC    NEAR
  418.     push    ax        ; save regs
  419.     push    bx
  420.     push    cx
  421.     mov    bx,portval    ; port indicator
  422.     mov    ax,[bx].flowc    ; put Go-ahead flow control char in ah
  423.     or    ah,ah        ; don't send null if flow = null
  424.     jz    ihostr1        ; z = null
  425.     call    outchr        ; send it (release Host's output queue)
  426. ihostr1:pop    cx
  427.     pop    bx
  428.     pop    ax
  429.     ret
  430. IHOSTR    ENDP
  431.  
  432. DTRLOW    PROC    NEAR        ; Global proc to Hangup the Phone by making
  433.                 ; DTR and RTS low
  434.     mov    ah,cmline    ; allow text to be able to display help
  435.     mov    bx,offset rdbuf        ; dummy buffer
  436.     mov    dx,offset hnghlp    ; help message
  437.     call    comnd            ; get a confirm
  438.     jc    dtrlowx
  439. ; not yet imp.    call serhng        ; drop DTR and RTS
  440.     mov    ah,prstr        ; give a nice message
  441. ; not yet imp.    mov dx,offset hngmsg
  442.     mov    dx,offset noimp        ; for now
  443.     int    dos
  444.     clc
  445. dtrlowx:ret
  446. DTRLOW    ENDP
  447.  
  448. ; Hang up the Phone. Similar to SERRST except it just forces DTR and RTS low
  449. ; to terminate the connection. 29 March 1986 [jrd]
  450. ; Calling this twice without intervening calls to serini should be harmless.
  451. ; Returns normally.
  452. ; SERHNG is Not Yet Implemented.
  453.  
  454. SERHNG    PROC NEAR
  455.     clc
  456.     ret
  457. SERHNG    ENDP
  458.  
  459. ; Wait for the # of milliseconds in ax, for non-IBM compatibles.
  460. ; Based on 4.77 Mhz 8088 processor speeds.
  461. ; Thanks to Bernie Eiben for this one.
  462. pcwait    proc    near
  463.     mov    cx,240        ; inner loop counter for 1 millisecond
  464. pcwai1:    sub    cx,1        ; inner loop takes 20 clock cycles
  465.     jnz    pcwai1
  466.     dec    ax        ; outer loop counter
  467.     jnz    pcwait        ; wait another millisecond
  468.     ret
  469. pcwait    endp
  470.  
  471.  
  472. ; Send a break out the current serial port.  Returns normally.
  473. SENDBR    PROC    NEAR            ; Normal Break
  474.     clc
  475.     ret
  476. SENDBR    ENDP
  477. SENDBL    PROC    NEAR            ; Long Break
  478.     clc
  479.     ret
  480. SENDBL    ENDP
  481.  
  482. ; Position the cursor according to contents of DX:
  483. ; DH contains row, DL contains column.  Returns normally.
  484. POSCUR    PROC    NEAR
  485.     clc
  486.     ret
  487. POSCUR    ENDP
  488.  
  489. ; Delete a character from the terminal.  This works by printing
  490. ; backspaces and spaces.  Returns normally.
  491.  
  492. DODEL    PROC    NEAR
  493.     mov    ah,prstr
  494.     mov    dx,offset delstr    ; Erase character
  495.     int    dos            
  496.     ret
  497. DODEL    ENDP
  498.  
  499. ; Move the cursor to the left margin, then clear to end of line.
  500. ; Returns normally.
  501.  
  502. CTLU    PROC    NEAR
  503.     push    ax
  504.     push    cx
  505.     push    dx
  506.     mov    ah,conout
  507.     mov    dl,cr            ; cursor to left margin
  508.     int    dos
  509.     mov    cx,79
  510.     mov    dl,' '            ; send 79 spaces to clear line
  511. ctlu1:    int    dos
  512.     loop    ctlu1
  513.     mov    dl,cr            ; cursor to left margin again
  514.     int    dos
  515.     pop    dx
  516.     pop    cx
  517.     pop    ax
  518.     ret
  519. CTLU    ENDP
  520.  
  521. ; Set the current port.  
  522.  
  523. COMS    PROC    NEAR
  524.         mov    dx,offset comptab    ; the table to examine
  525.         mov    bx,0            ; use keywords as help
  526.         mov    ah,cmkey        ; parse keyword from comptab
  527.         call    comnd
  528.         jc    comsx            ; c = no match
  529.         push    bx            ; value following the located keyword
  530.         mov    ah,cmeol
  531.         call    comnd            ; get a confirm
  532.     pop bx
  533.     jc    comsx
  534.     cmp    bl,3            ; set device name?
  535.     je    coms3            ; e = yes, go get name
  536.     jle    coms1a
  537.     jmp    coms4            ; g = pick up file handle
  538. coms1a:    mov    flags.comflg,bl        ; set the comm port flag
  539.     cmp    bl,1            ; using Com 1?
  540.     jne    coms2            ; ne = no
  541.     mov    portval,offset port1
  542.     ret
  543. coms2:    cmp    flags.comflg,2        ; using Com2?
  544.     jne    coms3            ; ne = no
  545.     mov    portval,offset port2
  546.     clc
  547. comsx:    ret
  548. coms3:    mov    dx,offset dev1        ; ask user for device name
  549.     call    prompt
  550.     mov    ah,cmline        ; parse string, returns asciiz string
  551.     mov    bx,offset prtstr    ; put name here
  552.     mov    dx,offset devhlp    ; help message if question mark
  553.     call    comnd
  554.     jc    comsx            ; c = error
  555.     mov    dx,offset prtstr    ; point to string
  556.     mov    ah,open2        ; open port as a file
  557.     mov    al,2            ; for reading and writing
  558.     int    dos
  559.     jc    coms31            ; c = failure
  560.     mov    portval,offset port3    ; port info structure
  561.     mov    flags.comflg,3        ; set port ident
  562.     jmp    short coms32        ; success
  563. coms31:    mov    ah,prstr
  564.     mov    dx,offset erms41
  565.     int    dos
  566.     mov    dx,offset deverr
  567.     int    dos
  568.     clc
  569.     ret
  570. coms32:    mov    prthnd,ax        ; save handle
  571.     mov    ah,ioctl
  572.     mov    al,00h            ; get device info
  573.     xor    dx,dx
  574.     mov    bx,prthnd        ; port's handle
  575.     int    dos
  576.     jc    coms41            ; c = error
  577.     or    dl,20h            ; set binary mode in device info
  578.     mov    dh,0
  579.     mov    ah,ioctl        
  580.     mov    al,01h            ; set device info
  581.     int    dos
  582.     jc    coms41            ; c = error
  583.     ret
  584. coms4:    mov    dx,offset hnd2        ; ask user for file handle
  585.     call    prompt
  586.     mov    ah,cmline
  587.     mov    bx,offset rdbuf        ; where to put input
  588.     mov    dx,offset hndhlp    ; in case user wants help
  589.     call    comnd
  590.     jc    coms42
  591.     cmp    ah,4            ; correct amount of data?
  592.     ja    coms41            ; a = too many chars
  593.     mov    si,offset rdbuf
  594.     call    atoi            ; convert to real number in ax
  595.     jc    coms42            ; c = failure
  596.     mov    portval,offset port4    ; port info structure
  597.     mov    flags.comflg,4        ; set port ident
  598.     jmp    coms32            ; go complete processing
  599. coms41:    mov    ah,prstr        ; else, issue a warning
  600.     mov    dx,offset hnderr
  601.     int    dos
  602.     clc
  603. coms42:    ret                ; fail
  604. COMS    ENDP
  605.  
  606. ; Set heath emulation on/off.
  607.  
  608. VTS    PROC    NEAR
  609.     jmp    notimp            ; not implemented
  610. VTS    ENDP
  611.  
  612.  
  613. VTSTAT    PROC    NEAR            ; for Status display
  614.     ret                ; no emulator status to display
  615. VTSTAT    ENDP 
  616.  
  617. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  618. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  619. ; is determined by mssset and is passed as pointer dmpname.
  620.  
  621. DUMPSCR    PROC    NEAR    ; Dumps screen contents to a file. Just Beeps here
  622.     call    beep
  623.     clc
  624.     ret
  625. DUMPSCR    ENDP
  626.  
  627. notimp:    mov    ah,prstr
  628.     mov    dx,offset noimp
  629.     int    dos
  630.     jmp    prserr
  631.  
  632. ; Initialize variables to values used by the generic MS DOS version.
  633.  
  634. lclini:    mov    flags.vtflg,0        ; don't do terminal emulation
  635.     mov    prthnd,0        ; no handle yet
  636.     mov    flags.remflg,dserial     ; set serial display mode
  637. ;;    call    opnprt            ; get file handle for comm port
  638.     call    msuinit            ; declare keyboard translator present
  639.     ret
  640.  
  641. ; Get a file handle for the communications port.  Use DOS call to get the
  642. ; next available handle.  If it fails, ask user what value to use (there
  643. ; should be a predefined handle for the port, generally 3).  The open
  644. ; will fail if the system uses names other than "COM1" or "COM2".
  645. opnprt:    mov    al,flags.comflg
  646.     dec    al            ; com1 is 1, com2 is 2, etc
  647.     mov    ah,0
  648.     push    si
  649.     mov    si,ax
  650.     shl    si,1            ; double index
  651.     mov    dx,prttab[si]        ; table of port names
  652.     pop    si
  653.     mov    ah,open2        ; open file/device
  654.     mov    al,2            ; for reading/writing
  655.     int    dos
  656.     jnc    opnpr2            ; nc = no error so far
  657.     mov    ah,prstr        ; It didn't like the string
  658.     mov    dx,offset erms41
  659.     int    dos
  660.     mov    dx,offset hnd1
  661.     int    dos
  662. opnpr0:    mov    dx,offset hnd2        ; ask user for the handle
  663.     call    prompt                       
  664.     mov    ah,cmline
  665.     mov    bx,offset rdbuf        ; where to put input
  666.     mov    dx,offset hndhlp    ; in case user wants help
  667.     call    comnd
  668.     jc    opnpr1            ; c = error
  669.     mov    si,offset rdbuf
  670.     call    atoi            ; convert to real number
  671.     jc    opnpr1            ; c = error
  672.     mov    prthnd,ax        ; value returned in AX
  673.     clc                ; carry clear for success
  674. opnpr1:    ret
  675. opnpr2:    mov    prthnd,ax        ; call succeeded
  676.     mov    ah,ioctl
  677.     mov    al,00h            ; get device info
  678.     xor    dx,dx
  679.     mov    bx,prthnd        ; port's handle
  680.     int    dos
  681.     or    dl,20h            ; set binary mode in device info
  682.     mov    dh,0
  683.     mov    ah,ioctl
  684.     mov    al,01h            ; set device info
  685.     int    dos
  686.     clc
  687.     ret                ; carry clear for success
  688.  
  689. showkey:mov    ax,offset shkmsg
  690.     mov    cx,shklen
  691.     ret
  692.     
  693. ; Initialization for using serial port.  Returns normally.
  694. ; Attempts to put port device in binary mode. [jrd]
  695. SERINI    PROC    NEAR
  696.     cmp    prthnd,0        ; got a handle yet?
  697.     jne    serin0            ; ne = yes, just go on
  698.     push    bx
  699.     call    opnprt            ; else 'open' the port
  700.     pop    bx
  701.     jc    serin2            ; c = failure
  702. serin0:    push    bx
  703.     mov    bx,portval        ; get port
  704.     mov    parmsk,0ffh        ; parity mask, assume parity is None
  705.     cmp    [bx].parflg,parnon    ; is it None?
  706.     je    serin1            ; e = yes
  707.     mov    parmsk,07fh        ; no, pass lower 7 bits as data
  708. serin1:    mov    bx,[bx].flowc        ; get flow control chars
  709.     mov    flowoff,bl        ; xoff or null
  710.     mov    flowon,bh        ; xon or null
  711.     pop    bx
  712.     clc                ; carry clear for success
  713. serin2:    ret
  714. SERINI    ENDP
  715.  
  716. ; Reset the serial port.  This is the opposite of serini.  Calling
  717. ; this twice without intervening calls to serini should be harmless.
  718. ; Returns normally.
  719.  
  720. SERRST    PROC    NEAR
  721.     clc
  722.     ret
  723. SERRST    ENDP
  724.  
  725. ; Produce a short beep.  The PC DOS bell is long enough to cause a loss
  726. ; of data at the port.  Returns normally.
  727.  
  728. BEEP    PROC    NEAR
  729.     mov    dl,bell
  730.     mov    ah,dconio
  731.     int    dos
  732.     clc
  733.     ret
  734. BEEP    ENDP 
  735.  
  736. ; Dumb terminal emulator.  Doesn't work too well above 1200 baud (and
  737. ; even at 1200 baud you sometimes lose the first one or two characters
  738. ; on a line). Does capture (logging), local echo, debug display, tests
  739. ; for printer/logging device not ready. Uses keyboard translator
  740. ; 20 March 1987 [jrd]. 
  741. term    proc    near
  742.     mov    argadr,ax        ; save argument ptr
  743.     mov    si,ax            ; this is source
  744.     mov    di,offset ourarg    ; place to store arguments
  745.     mov    ax,ds
  746.     mov    es,ax            ; address destination segment
  747.     mov    cx,size termarg
  748.     cld
  749.     rep    movsb            ; copy into our arg blk
  750.     and    ourarg.flgs,not (prtscr) ; no screen printing at startup
  751.     mov    ax,ourarg.captr
  752.     mov    captrtn,ax        ; buffer capture routine
  753.     mov    parmsk,0ffh        ; parity mask, assume parity = None
  754.     cmp    ourarg.parity,parnon    ; is parity None?
  755.     je    term1            ; e = yes, keep all 8 bits
  756.     mov    parmsk,07fh        ; else keep lower 7 bits
  757.  
  758. term1:    call    portchr               ; get char from port, apply parity mask
  759.     jnc    short term3        ; nc = char
  760. term2:    mov    fairness,0        ; say kbd was examined
  761.     call    keybd            ; call keyboard translator in msu
  762.     jnc    term1            ; nc = no char or have processed it
  763.     jmp    short term4        ; carry set = quit connect mode
  764. term3:    and    al,parmsk        ; apply 8/7 bit parity mask
  765.     call    outtty            ; print on terminal
  766.     inc    fairness        ; say read port but not kbd, again
  767.     cmp    fairness,100        ; this many port reads before kbd?
  768.     jb    term1            ; b = no, read port again
  769.     jmp    short term2        ; yes, let user have a chance too
  770. term4:    ret
  771. term    endp
  772.  
  773. ; keyboard translator action routines, system dependent, called from msugen.
  774. ; These are invoked by a jump instruction. Return carry clear for normal
  775. ; processing, return carry set exit Connect mode (kbdflg has transfer char).
  776.  
  777. chrout: call    outprt            ; put char in al to serial port
  778.     clc                ; stay in Connect mode
  779.     ret
  780.  
  781. trnprs:    push    ax            ; toggle Copy screen to printer
  782.     test    ourarg.flgs,prtscr    ; are we currently printing?
  783.     jnz    trnpr2            ; nz = yes, its on and going off
  784.     mov    ah,ioctl
  785.     mov    al,7            ; get output status of printer
  786.     push    bx
  787.     mov    bx,4            ; file handle for system printer
  788.     int    dos
  789.     pop    bx
  790.     jc    trnpr1            ; c = printer not ready
  791.     cmp    al,0ffh            ; Ready status?
  792.     je    trnpr2            ; e = Ready    
  793. trnpr1:    call    beep            ; Not Ready, complain
  794.     jmp    trnpr3            ; and ignore request
  795. trnpr2:    xor    ourarg.flgs,prtscr    ; flip the flag
  796. trnpr3:    pop    ax
  797.     clc
  798.     ret
  799.  
  800.  
  801. klogon    proc    near            ; resume logging (if any)
  802.     test    flags.capflg,logses    ; session logging enabled?
  803.     jz    klogn            ; z = no, forget it
  804.     or    ourarg.flgs,capt    ; turn on capture flag
  805. klogn:    clc
  806.     ret
  807. klogon    endp
  808.  
  809. klogof    proc    near            ; suspend logging (if any)
  810.     and    argadr.flgs,not capt    ; stop capturing
  811. klogo:    clc
  812.     ret
  813. klogof    endp
  814.  
  815. snull:    mov    ah,0            ; send a null
  816.     call    outchr            ; send without echo or logging
  817.     clc
  818.     ret
  819.  
  820. kdos:    mov    al,'P'            ; Push to DOS
  821.     jmp    short cmdcom
  822. cstatus:mov    al,'S'            ; these commands exit Connect mode
  823.     jmp    short cmdcom
  824. cquit:    mov    al,'C'
  825.     jmp    short cmdcom
  826. cquery:    mov    al,'?'
  827.     jmp    short cmdcom
  828. chang:    mov    al,'H'            ; Hangup, drop DTR & RTS
  829. ;;;    jmp    short cmdcom
  830. cmdcom:    mov    kbdflg,al        ; pass char to msster.asm via kbdflg
  831.     stc                ; say exit Connect mode
  832.     ret
  833.                     ;; end of action routines
  834.  
  835. ; put the character in al to the screen, do capture and printing,
  836. ; does translation for Set Input command.
  837. ; Adapted from msyibm.asm
  838. outtty    proc    near
  839.     test    flags.remflg,d8bit    ; keep 8 bits for displays?
  840.     jnz    outnp8            ; nz = yes, 8 bits if possible
  841.     and    al,7fh            ; remove high bit
  842. outnp8:    cmp    rxtable+256,0        ; is translation off?
  843.     je    outnp7            ; e = yes, off
  844.     push    bx            ; Translate incoming char
  845.     mov    bx,offset rxtable    ; address of translate table
  846.     xlatb                ; new char is in al
  847.     pop    bx
  848. outnp7:
  849.     push    bx
  850.     mov    bx,argadr        ; args from msster directly
  851.     test    [bx].flgs,capt        ; capturing output? Can be shut off
  852.     pop    bx            ;  if out device becomes not ready
  853.     jz    outnoc            ; no, forget this part
  854.     push    ax            ; save char
  855.     call    captrtn            ; give it captured character
  856.     pop    ax            ; restore character and keep going
  857. outnoc:    test    ourarg.flgs,prtscr    ; should we be printing?
  858.     jz    outnop            ; no, keep going
  859.     push    ax
  860.     mov    ah,print_out        ; write to system printer device
  861.     mov    dl,al
  862.     int    dos
  863.     pop    ax
  864.     jnc    outnop            ; nc = successful print
  865.     push    ax
  866.     call    beep            ; else make a noise and
  867.     call    trnprs            ;  turn off printing
  868.     pop    ax
  869. outnop:    cmp    flags.vtflg,0        ; emulating a terminal?
  870.     jnz    outnop1            ; nz = yup, go do something smart
  871.     test    ourarg.flgs,trnctl    ; debug? if so use dos tty mode
  872.     jz    outnp4            ; z = no
  873.     mov    ah,conout
  874.     cmp    al,7fh            ; Ascii Del char or greater?
  875.     jb    outnp1            ; b = no
  876.     je    outnp0            ; e = Del char
  877.     push    ax            ; save the char
  878.     mov    dl,7eh            ; output a tilde for 8th bit
  879.     int    dos
  880.     pop    ax            ; restore char
  881.     and    al,7fh            ; strip high bit
  882. outnp0:    cmp    al,7fh            ; is char now a DEL?
  883.     jne    outnp1            ; ne = no
  884.     and    al,3fH            ; strip next highest bit (Del --> '?')
  885.     jmp    outnp2            ; send, preceded by caret
  886. outnp1:    cmp    al,' '            ; control char?
  887.     jae    outnp3            ; ae = no
  888.     add    al,'A'-1        ; make visible
  889. outnp2:    push    ax            ; save char
  890.     mov    dl,5eh            ; caret
  891.     int    dos            ; display it
  892.     pop    ax            ; recover the non-printable char
  893. outnp3:    mov    dl,al
  894.     int    dos
  895.     ret
  896. outnp4:    cmp    al,bell            ; bell (Control G)?
  897.     jne    outnp5            ; ne = no
  898.     jmp    beep            ; use short beep, avoid char loss
  899. outnop1:
  900. outnp5:    test    flags.remflg,d8bit    ; keep 8 bits for displays?
  901.     jnz    outnp9            ; nz = yes, 8 bits if possible
  902.     and    al,7fh            ; remove high bit
  903. outnp9:    mov    ah,conout        ; dostty screen mode
  904.     mov    dl,al            ; write without intervention
  905.     int    dos            ; else let dos display char
  906.     ret                ; and return
  907. outtty    endp
  908.  
  909.  
  910. ; send the character in al out to the serial port; handle echoing.
  911. ; Can send an 8 bit char while displaying only 7 bits locally.
  912. outprt    proc    near
  913.     test    ourarg.flgs,lclecho    ; echoing?
  914.     jz    outpr1            ; z = no, forget it
  915.     push    ax            ; save char
  916.     call    outtty            ; print it
  917.     pop    ax            ; restore
  918. outpr1:    mov    ah,al            ; this is where outchr expects it
  919.     call    outchr            ; output to the port
  920.     ret
  921. outprt    endp
  922.  
  923. ; Get a char from the serial port manager
  924. ; returns with carry clear if a character is available
  925. portchr    proc    near
  926.     call    prtchr            ; character at port?
  927.     jnc    portc1            ; nc = yes
  928. portc0:    stc                ; carry -> no character
  929.     ret                ; and return
  930. portc1:    and    al,parmsk        ; apply 8/7 bit parity mask
  931.     or    al,al            ; catch nulls
  932.     jz    portc0            ; z = null, ignore it
  933.     cmp    al,del            ; catch dels
  934.     je    portc0            ; e = del, ignore it
  935. portc2:    clc                ; have a character, in AL
  936.     ret
  937. portchr    endp
  938. code    ends 
  939.     end
  940.