home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / MSKERMIT.ZIP / MSXGEN.ASM < prev    next >
Encoding:
Assembly Source File  |  1986-05-17  |  11.8 KB  |  489 lines

  1. ; Generic MS DOS Kermit module
  2.  
  3.     public    serini, serrst, clrbuf, outchr, coms, vts, dodel,
  4.     public    ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl,
  5.     public    dodisk, getbaud, beep
  6.     public    count, xofsnt, puthlp, putmod, clrmod, poscur
  7.     public    sendbr, term, machnam, setktab, setkhlp, showkey
  8.     include msdefs.h
  9.  
  10. false    equ    0
  11. true    equ    1
  12. instat    equ    6
  13. rddev    equ    3fH
  14. open    equ    3dH
  15.  
  16. ; external variables used:
  17. ; drives - # of disk drives on system
  18. ; flags - global flags as per flginfo structure defined in pcdefs
  19. ; trans - global transmission parameters, trinfo struct defined in pcdefs
  20. ; portval - pointer to current portinfo structure (currently either port1
  21. ;    or port2)
  22. ; port1, port2 - portinfo structures for the corresponding ports
  23.  
  24. ; global variables defined in this module:
  25. ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
  26.  
  27. datas    segment public 'datas'
  28.     extrn    drives:byte,flags:byte, trans:byte
  29.     extrn    portval:word, port1:byte, port2:byte
  30.  
  31. machnam db    'Generic MS-DOS 2.0$'
  32. erms20    db    cr,lf,'?Warning: System has no disk drives$' ; [21a]
  33. erms40    db    cr,lf,'?Warning: Unrecognized baud rate$'
  34. erms41    db    cr,lf,'?Warning: Cannot open com port$'
  35. erms50    db    cr,lf,'Error reading from device$'
  36. hnd1    db    cr,lf,'Enter a file handle.  Check your DOS manual if you are '
  37.     db    cr,lf,'not certain what value to supply (generally 3).$'
  38. hnd2    db    cr,lf,'Handle: $'
  39. hnderr    db    cr,lf,'Warning: Handle not known.  Any routine using the '
  40.     db    cr,lf,'communications port will probably not work.$'
  41. hndhlp    db    cr,lf,'A four digit file handle $'
  42. badbd    db    cr,lf,'Unimplemented baud rate$'
  43. noimp    db    cr,lf,'Command not implemented.$'
  44. shkmsg    db    'Not implemented.'
  45. shklen    equ    $-shkmsg
  46. setktab db    0
  47. setkhlp db    0
  48. crlf    db    cr,lf,'$'
  49. delstr    db    BS,BS,'  ',BS,BS,'$'    ; Delete string. [21d]
  50. clrlin    db    cr,'$'                  ; Clear line (just the cr part).
  51. clreol    db    '^U',cr,lf,'$'          ; Clear line.
  52. telflg    db    0        ; non-zero if we're a terminal.
  53. xofsnt    db    0        ; Say if we sent an XOFF.
  54. xofrcv    db    0        ; Say if we received an XOFF.
  55. count    dw    0        ; Number of chars in int buffer.
  56. prthnd    dw    0        ; Port handle.
  57. prttab    dw    com2,com1
  58. com1    db    'COM1',0
  59. com2    db    'COM2',0
  60. tmp    db    ?,'$'
  61. temp    dw    0
  62. temp1    dw    ?        ; Temporary storage.
  63. temp2    dw    ?        ; Temporary storage.
  64. rdbuf    db    20 dup(?)    ; Buffer for input.
  65.  
  66. ; Entries for choosing communications port. [19b]
  67. comptab db    04H
  68.     db    01H,'1$'
  69.     dw    01H
  70.     db    01H,'2$'
  71.     dw    00H
  72.     db    04H,'COM1$'
  73.     dw    01H
  74.     db    04H,'COM2$'
  75.     dw    00H
  76.  
  77. ourarg    termarg <>
  78.  
  79. datas    ends
  80.  
  81. code    segment public
  82.     extrn    comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
  83.     assume    cs:code,ds:datas
  84.  
  85. ; this is called by Kermit initialization.  It checks the
  86. ; number of disks on the system, sets the drives variable
  87. ; appropriately.  Returns normally.
  88.  
  89. DODISK    PROC    NEAR
  90.     mov ah,gcurdsk            ; Current disk value to AL.
  91.     int dos
  92.     mov dl,al            ; Put current disk in DL.
  93.     mov ah,seldsk            ; Select current disk.
  94.     int dos             ; Get number of drives in AL.
  95.     mov drives,al
  96.     ret
  97. DODISK    ENDP
  98.  
  99. ; Clear the input buffer. This throws away all the characters in the
  100. ; serial interrupt buffer.  This is particularly important when
  101. ; talking to servers, since NAKs can accumulate in the buffer.
  102. ; Do nothing since we are not interrupt driven.  Returns normally.
  103.  
  104. CLRBUF    PROC    NEAR
  105.     ret
  106. CLRBUF    ENDP
  107.  
  108. ; Clear to the end of the current line.  Returns normally.
  109.  
  110. CLEARL    PROC    NEAR
  111.     mov ah,prstr
  112.     mov dx,offset clreol
  113.     int dos
  114.     ret
  115. CLEARL    ENDP
  116.  
  117. ; Put the char in AH to the serial port.  This assumes the
  118. ; port has been initialized.  Should honor xon/xoff.  Skip returns on
  119. ; success, returns normally if the character cannot be written.
  120.  
  121. outchr: mov bp,portval
  122.     cmp ds:[bp].floflg,0    ; Are we doing flow control.
  123.     je outch2        ; No, just continue.
  124.     xor cx,cx        ; clear counter
  125. outch1: cmp xofrcv,true     ; Are we being held?
  126.     jne outch2        ; No - it's OK to go on.
  127.     loop outch1        ; held, try for a while
  128.     mov xofrcv,false    ; timed out, force it off and fall thru.
  129. outch2: push dx         ; Save register.
  130.     mov al,ah        ; Parity routine works on AL.
  131.     call dopar        ; Set parity appropriately.
  132.     mov dl,al
  133.     mov ah,punout        ; Output char in DL to comm port.
  134.     int dos
  135.     pop dx
  136.     jmp rskp
  137.  
  138. ; This routine blanks the screen.  Returns normally.
  139.  
  140. CMBLNK    PROC    NEAR
  141.     mov ah,prstr
  142.     mov dx,offset crlf    ; Can't do anything else.
  143.     int dos
  144.     ret
  145. CMBLNK    ENDP
  146.  
  147. ; Homes the cursor.  Returns normally.
  148.  
  149. LOCATE    PROC    NEAR
  150.     mov dx,0        ; Go to top left corner of screen.
  151.     jmp poscur
  152. LOCATE    ENDP
  153.  
  154. ; Write a line at the bottom of the screen...
  155. ; the line is passed in dx, terminated by a $.    Returns normally.
  156. putmod    proc    near
  157.     push    dx        ; preserve message
  158.     mov    dx,1800h    ; now address line 24
  159.     call    poscur
  160.     pop    dx        ; get message back
  161.     mov    ah,prstr
  162.     int    dos        ; write it out
  163.     ret            ; and return
  164. putmod    endp
  165.  
  166. ; clear the mode line written by putmod.  Returns normally.
  167. clrmod    proc    near
  168.     mov    dx,1800h
  169.     call    poscur        ; Go to bottom row.
  170.     call    clearl        ; Clear to end of line.
  171.     ret
  172. clrmod    endp
  173.  
  174. ; Put a help message on the screen.
  175. ; Pass the message in ax, terminated by a null.  Returns normally.
  176. puthlp    proc    near
  177.     push    ax        ; preserve this
  178.     mov    ah,prstr
  179.     mov    dx,offset crlf
  180.     int    dos
  181.     pop    si        ; point to string again
  182. puthl3: lodsb            ; get a byte
  183.     cmp    al,0        ; end of string?
  184.     je    puthl4        ; yes, stop
  185.     mov    dl,al
  186.     mov    ah,dconio
  187.     int    dos        ; else write to screen
  188.     jmp    puthl3        ; and keep going
  189. puthl4: mov    ah,prstr
  190.     mov    dx,offset crlf
  191.     int    dos
  192.     ret
  193. puthlp    endp
  194.  
  195. ; Set the baud rate for the current port, based on the value
  196. ; in the portinfo structure.  Returns normally.
  197.  
  198. DOBAUD    PROC    NEAR
  199.     mov ah,prstr
  200.     mov dx,offset noimp    ; Say it's not implemented.
  201.     int dos
  202.     mov bx,portval
  203.     mov [bx].baud,0FFFFH    ; So it's not a recognized value.
  204.     ret            ; Must be set before starting Kermit.
  205. DOBAUD    ENDP
  206.  
  207. ; Get the current baud rate from the serial card and set it
  208. ; in the portinfo structure for the current port.  Returns normally.
  209. ; This is used during initialization.
  210.  
  211. GETBAUD PROC    NEAR
  212.     ret            ; Can't do this.
  213. GETBAUD ENDP
  214.  
  215.  
  216. ; Use for DOS 2.0 and above.  Check the port status.  If no data, skip
  217. ; return.  Else, read in a char and return.
  218. PRTCHR    PROC    NEAR
  219.     push bx
  220.     push cx
  221.     push si
  222.     push bp
  223.     call chkxon
  224.     mov bx,prthnd
  225.     mov al,instat
  226.     mov ah,ioctl
  227.     int dos
  228.     or al,al
  229.     jz prtch4        ; not ready...
  230.     mov bx,prthnd
  231.     mov ah,rddev
  232.     mov cx,1
  233.     mov dx,offset temp
  234.     int dos
  235.     cmp al,5        ; Error condition.
  236.     je prt3x
  237.     cmp al,6        ; Error condition
  238.     je prt3x
  239.     mov al,byte ptr temp
  240.     mov bp,portval
  241.     cmp ds:[bp].parflg,PARNON    ; no parity?
  242.     je prtch3        ; then don't strip
  243.     and al,7fh        ; else turn off parity
  244. prtch3: pop bp
  245.     pop si
  246.     pop cx
  247.     pop bx
  248.     ret
  249. prt3x:    mov ah,prstr
  250.     mov dx,offset erms50
  251.     int dos
  252. prtch4: pop bp
  253.     pop si
  254.     pop cx
  255.     pop bx
  256.     jmp rskp        ; no chars...
  257. PRTCHR    ENDP
  258.  
  259. ; Local routine to see if we have to transmit an xon
  260. chkxon    proc    near
  261.     push    bx
  262.     mov    bx,portval
  263.     cmp    [bx].floflg,0    ; doing flow control?
  264.     je    chkxo1        ; no, skip all this
  265.     cmp    xofsnt,false    ; have we sent an xoff?
  266.     je    chkxo1        ; no, forget it
  267.     mov    ax,[bx].flowc    ; ah gets xon
  268.     call    outchr        ; send it
  269.     nop
  270.     nop
  271.     nop            ; in case it skips
  272.     mov    xofsnt,false    ; remember we've sent the xon.
  273. chkxo1: pop    bx        ; restore register
  274.     ret            ; and return
  275. chkxon    endp
  276.  
  277. ; Send a break out the current serial port.  Returns normally.
  278. SENDBR    PROC    NEAR
  279.     ret
  280. SENDBR    ENDP
  281.  
  282. ; Position the cursor according to contents of DX:
  283. ; DH contains row, DL contains column.    Returns normally.
  284. POSCUR    PROC    NEAR
  285.     ret
  286. POSCUR    ENDP
  287.  
  288. ; Delete a character from the terminal.  This works by printing
  289. ; backspaces and spaces.  Returns normally.
  290.  
  291. DODEL    PROC    NEAR
  292.     mov ah,prstr
  293.     mov dx,offset delstr    ; Erase weird character.
  294.     int dos
  295.     ret
  296. DODEL    ENDP
  297.  
  298. ; Move the cursor to the left margin, then clear to end of line.
  299. ; Returns normally.
  300.  
  301. CTLU    PROC    NEAR
  302.     mov ah,prstr
  303.     mov dx,offset clrlin
  304.     int dos
  305.     call clearl
  306.     ret
  307. CTLU    ENDP
  308.  
  309. ; Set the current port.
  310.  
  311. COMS    PROC    NEAR
  312.     mov dx,offset comptab
  313.     mov bx,0
  314.     mov ah,cmkey
  315.     call comnd
  316.      jmp r
  317.     push bx
  318.     mov ah,cmcfm
  319.     call comnd        ; Get a confirm.
  320.      jmp comx        ;  Didn't get a confirm.
  321.      nop
  322.     pop bx
  323.     mov flags.comflg,bl    ; Set the comm port flag.
  324.     cmp flags.comflg,1    ; Using Com 1?
  325.     jne coms0        ; Nope.
  326.     mov ax,offset port1
  327.     mov portval,ax
  328.     ret
  329. coms0:    mov ax,offset port2
  330.     mov portval,ax
  331.     ret
  332. comx:    pop bx
  333.     ret
  334. COMS    ENDP
  335.  
  336. ; Set heath emulation on/off.
  337.  
  338. VTS    PROC    NEAR
  339.     jmp notimp
  340. VTS    ENDP
  341.  
  342. notimp: mov ah,prstr
  343.     mov dx,offset noimp
  344.     int dos
  345.     jmp prserr
  346.  
  347. ; Initialize variables to values used by the generic MS DOS version.
  348.  
  349. lclini: mov flags.vtflg,0    ; Don't to terminal emulation.
  350.     call opnprt        ; Get file handle for comm port.
  351.     ret
  352.  
  353. ; Get a file handle for the communications port.  Use DOS call to get the
  354. ; next available handle.  If it fails, ask user what value to use (there
  355. ; should be a predefined handle for the port, generally 3).  The open
  356. ; will fail if the system uses names other than "COM1" or "COM2".
  357. opnprt: mov al,flags.comflg
  358.     mov ah,0
  359.     mov si,ax
  360.     shl si,1        ; double index
  361.     mov dx,prttab[si]
  362.     mov ah,open
  363.     mov al,2
  364.     int dos
  365.     jnc opnpr2
  366.     mov ah,prstr        ; It didn't like the string.
  367.     mov dx,offset erms41
  368.     int dos
  369.     mov dx,offset hnd1
  370.     int dos
  371. opnpr0: mov dx,offset hnd2    ; Ask user to supply the handle.
  372.     call prompt
  373.     mov ah,cmtxt
  374.     mov bx,offset rdbuf    ; Where to put input.
  375.     mov dx,offset hndhlp    ; In case user wants help.
  376.     call comnd
  377.      jmp opnpr3        ; Maybe user typed a ^C.
  378.      nop
  379.     mov si,offset rdbuf
  380.     call atoi        ; Convert to real number
  381.      jmp opnpr0        ; Keep trying.
  382.      nop
  383.     mov prthnd,ax        ; Value returned in AX
  384.     ret
  385. opnpr2: mov prthnd,ax        ; Call succeeded.
  386.     ret
  387. opnpr3: cmp flags.cxzflg,'C'    ; Did user type a ^C?
  388.     jne opnpr4        ; No, don't say anything.
  389.     mov ah,prstr        ; Else, issue a warning.
  390.     mov dx,offset hnderr
  391.     int dos
  392. opnpr4: ret            ; Yes, fail.
  393.  
  394. showkey:
  395.     mov ax,offset shkmsg
  396.     mov cx,shklen
  397.     ret
  398.  
  399. ; Initialization for using serial port.  Returns normally.
  400. SERINI    PROC    NEAR
  401.     cld            ; Do increments in string operations
  402.     call clrbuf        ; Clear input buffer.
  403.     ret            ; We're done.
  404. SERINI    ENDP
  405.  
  406. ; Reset the serial port.  This is the opposite of serini.  Calling
  407. ; this twice without intervening calls to serini should be harmless.
  408. ; Returns normally.
  409.  
  410. SERRST    PROC    NEAR
  411.     ret            ; All done.
  412. SERRST    ENDP
  413.  
  414. ; Produce a short beep.  The PC DOS bell is long enough to cause a loss
  415. ; of data at the port.    Returns normally.
  416.  
  417. BEEP    PROC    NEAR
  418.     mov dl,bell
  419.     mov ah,dconio
  420.     int dos
  421.     ret
  422. BEEP    ENDP
  423.  
  424. ; Dumb terminal emulator.  Doesn't work too well above 1200 baud (and
  425. ; even at 1200 baud you sometimes lose the first one or two characters
  426. ; on a line).
  427. term    proc    near
  428.     mov si,ax        ; this is source
  429.     mov di,offset ourarg    ; place to store arguments
  430.     mov ax,ds
  431.     mov es,ax        ; address destination segment
  432.     mov cx,size termarg
  433.     rep movsb        ; copy into our arg blk
  434. term1:    call prtchr
  435.     jmp short term2     ; have a char...
  436.     nop
  437.     nop
  438.     jmp short term3     ; no char, go on
  439. term2:    push ax
  440.     and al,7fh        ; mask off parity for terminal
  441.     mov dl,al
  442.     mov ah,conout
  443.     int dos         ; go print it
  444.     pop ax
  445.     test ourarg.flgs,capt    ; capturing output?
  446.     jz term3        ; no, forget it
  447.     call ourarg.captr    ; else call the routine
  448. term3:    mov ah,dconio
  449.     mov dl,0ffh
  450.     int dos
  451.     jz term1        ; no character, go on
  452.     cmp al,ourarg.escc    ; escape char?
  453.     je term4        ; yes, exit
  454.     push ax         ; save char
  455.     mov ah,al
  456.     or ah,80H        ; turn on hi bit so DOS doesn't interfere
  457.     call outchr        ; output the character
  458.     nop
  459.     nop
  460.     nop
  461.     pop ax
  462.     test ourarg.flgs,lclecho ; echoing?
  463.     jz term1        ; no, continue loop
  464.     mov dl,al
  465.     mov ah,dconio
  466.     int dos
  467.     jmp term1        ; else echo and keep going
  468. term4:    ret
  469. term    endp
  470.  
  471. ; Jumping to this location is like retskp.  It assumes the instruction
  472. ;   after the call is a jmp addr.
  473.  
  474. RSKP    PROC    NEAR
  475.     pop bp
  476.     add bp,3
  477.     push bp
  478.     ret
  479. RSKP    ENDP
  480.  
  481. ; Jumping here is the same as a ret.
  482.  
  483. R    PROC    NEAR
  484.     ret
  485. R    ENDP
  486.  
  487. code    ends
  488.     end
  489.