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

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