home *** CD-ROM | disk | FTP | other *** search
- ; Generic MS DOS Kermit module
-
- public serini, serrst, clrbuf, outchr, coms, vts, dodel,
- public ctlu, cmblnk, locate, lclini, prtchr, dobaud, clearl,
- public dodisk, getbaud, beep
- public count, xofsnt, puthlp, putmod, clrmod, poscur
- public sendbr, term, machnam, setktab, setkhlp, showkey
- include msdefs.h
-
- false equ 0
- true equ 1
- instat equ 6
- rddev equ 3fH
- open equ 3dH
-
- ; external variables used:
- ; drives - # of disk drives on system
- ; flags - global flags as per flginfo structure defined in pcdefs
- ; trans - global transmission parameters, trinfo struct defined in pcdefs
- ; portval - pointer to current portinfo structure (currently either port1
- ; or port2)
- ; port1, port2 - portinfo structures for the corresponding ports
-
- ; global variables defined in this module:
- ; xofsnt, xofrcv - tell whether we saw or sent an xoff.
-
- datas segment public 'datas'
- extrn drives:byte,flags:byte, trans:byte
- extrn portval:word, port1:byte, port2:byte
-
- machnam db 'Generic MS-DOS 2.0$'
- erms20 db cr,lf,'?Warning: System has no disk drives$' ; [21a]
- erms40 db cr,lf,'?Warning: Unrecognized baud rate$'
- erms41 db cr,lf,'?Warning: Cannot open com port$'
- erms50 db cr,lf,'Error reading from device$'
- hnd1 db cr,lf,'Enter a file handle. Check your DOS manual if you are '
- db cr,lf,'not certain what value to supply (generally 3).$'
- hnd2 db cr,lf,'Handle: $'
- hnderr db cr,lf,'Warning: Handle not known. Any routine using the '
- db cr,lf,'communications port will probably not work.$'
- hndhlp db cr,lf,'A four digit file handle $'
- badbd db cr,lf,'Unimplemented baud rate$'
- noimp db cr,lf,'Command not implemented.$'
- shkmsg db 'Not implemented.'
- shklen equ $-shkmsg
- setktab db 0
- setkhlp db 0
- crlf db cr,lf,'$'
- delstr db BS,BS,' ',BS,BS,'$' ; Delete string. [21d]
- clrlin db cr,'$' ; Clear line (just the cr part).
- clreol db '^U',cr,lf,'$' ; Clear line.
- telflg db 0 ; non-zero if we're a terminal.
- xofsnt db 0 ; Say if we sent an XOFF.
- xofrcv db 0 ; Say if we received an XOFF.
- count dw 0 ; Number of chars in int buffer.
- prthnd dw 0 ; Port handle.
- prttab dw com2,com1
- com1 db 'COM1',0
- com2 db 'COM2',0
- tmp db ?,'$'
- temp dw 0
- temp1 dw ? ; Temporary storage.
- temp2 dw ? ; Temporary storage.
- rdbuf db 20 dup(?) ; Buffer for input.
-
- ; Entries for choosing communications port. [19b]
- comptab db 04H
- db 01H,'1$'
- dw 01H
- db 01H,'2$'
- dw 00H
- db 04H,'COM1$'
- dw 01H
- db 04H,'COM2$'
- dw 00H
-
- ourarg termarg <>
-
- datas ends
-
- code segment public
- extrn comnd:near, dopar:near, prserr:near, atoi:near, prompt:near
- assume cs:code,ds:datas
-
- ; this is called by Kermit initialization. It checks the
- ; number of disks on the system, sets the drives variable
- ; appropriately. Returns normally.
-
- DODISK PROC NEAR
- mov ah,gcurdsk ; Current disk value to AL.
- int dos
- mov dl,al ; Put current disk in DL.
- mov ah,seldsk ; Select current disk.
- int dos ; Get number of drives in AL.
- mov drives,al
- ret
- DODISK ENDP
-
- ; Clear the input buffer. This throws away all the characters in the
- ; serial interrupt buffer. This is particularly important when
- ; talking to servers, since NAKs can accumulate in the buffer.
- ; Do nothing since we are not interrupt driven. Returns normally.
-
- CLRBUF PROC NEAR
- ret
- CLRBUF ENDP
-
- ; Clear to the end of the current line. Returns normally.
-
- CLEARL PROC NEAR
- mov ah,prstr
- mov dx,offset clreol
- int dos
- ret
- CLEARL ENDP
-
- ; Put the char in AH to the serial port. This assumes the
- ; port has been initialized. Should honor xon/xoff. Skip returns on
- ; success, returns normally if the character cannot be written.
-
- outchr: mov bp,portval
- cmp ds:[bp].floflg,0 ; Are we doing flow control.
- je outch2 ; No, just continue.
- xor cx,cx ; clear counter
- outch1: cmp xofrcv,true ; Are we being held?
- jne outch2 ; No - it's OK to go on.
- loop outch1 ; held, try for a while
- mov xofrcv,false ; timed out, force it off and fall thru.
- outch2: push dx ; Save register.
- mov al,ah ; Parity routine works on AL.
- call dopar ; Set parity appropriately.
- mov dl,al
- mov ah,punout ; Output char in DL to comm port.
- int dos
- pop dx
- jmp rskp
-
- ; This routine blanks the screen. Returns normally.
-
- CMBLNK PROC NEAR
- mov ah,prstr
- mov dx,offset crlf ; Can't do anything else.
- int dos
- ret
- CMBLNK ENDP
-
- ; Homes the cursor. Returns normally.
-
- LOCATE PROC NEAR
- mov dx,0 ; Go to top left corner of screen.
- jmp poscur
- LOCATE ENDP
-
- ; Write a line at the bottom of the screen...
- ; the line is passed in dx, terminated by a $. Returns normally.
- putmod proc near
- push dx ; preserve message
- mov dx,1800h ; now address line 24
- call poscur
- pop dx ; get message back
- mov ah,prstr
- int dos ; write it out
- ret ; and return
- putmod endp
-
- ; clear the mode line written by putmod. Returns normally.
- clrmod proc near
- mov dx,1800h
- call poscur ; Go to bottom row.
- call clearl ; Clear to end of line.
- ret
- clrmod endp
-
- ; Put a help message on the screen.
- ; Pass the message in ax, terminated by a null. Returns normally.
- puthlp proc near
- push ax ; preserve this
- mov ah,prstr
- mov dx,offset crlf
- int dos
- pop si ; point to string again
- puthl3: lodsb ; get a byte
- cmp al,0 ; end of string?
- je puthl4 ; yes, stop
- mov dl,al
- mov ah,dconio
- int dos ; else write to screen
- jmp puthl3 ; and keep going
- puthl4: mov ah,prstr
- mov dx,offset crlf
- int dos
- ret
- puthlp endp
-
- ; Set the baud rate for the current port, based on the value
- ; in the portinfo structure. Returns normally.
-
- DOBAUD PROC NEAR
- mov ah,prstr
- mov dx,offset noimp ; Say it's not implemented.
- int dos
- mov bx,portval
- mov [bx].baud,0FFFFH ; So it's not a recognized value.
- ret ; Must be set before starting Kermit.
- DOBAUD ENDP
-
- ; Get the current baud rate from the serial card and set it
- ; in the portinfo structure for the current port. Returns normally.
- ; This is used during initialization.
-
- GETBAUD PROC NEAR
- ret ; Can't do this.
- GETBAUD ENDP
-
-
- ; Use for DOS 2.0 and above. Check the port status. If no data, skip
- ; return. Else, read in a char and return.
- PRTCHR PROC NEAR
- push bx
- push cx
- push si
- push bp
- call chkxon
- mov bx,prthnd
- mov al,instat
- mov ah,ioctl
- int dos
- or al,al
- jz prtch4 ; not ready...
- mov bx,prthnd
- mov ah,rddev
- mov cx,1
- mov dx,offset temp
- int dos
- cmp al,5 ; Error condition.
- je prt3x
- cmp al,6 ; Error condition
- je prt3x
- mov al,byte ptr temp
- mov bp,portval
- cmp ds:[bp].parflg,PARNON ; no parity?
- je prtch3 ; then don't strip
- and al,7fh ; else turn off parity
- prtch3: pop bp
- pop si
- pop cx
- pop bx
- ret
- prt3x: mov ah,prstr
- mov dx,offset erms50
- int dos
- prtch4: pop bp
- pop si
- pop cx
- pop bx
- jmp rskp ; no chars...
- PRTCHR ENDP
-
- ; Local routine to see if we have to transmit an xon
- chkxon proc near
- push bx
- mov bx,portval
- cmp [bx].floflg,0 ; doing flow control?
- je chkxo1 ; no, skip all this
- cmp xofsnt,false ; have we sent an xoff?
- je chkxo1 ; no, forget it
- mov ax,[bx].flowc ; ah gets xon
- call outchr ; send it
- nop
- nop
- nop ; in case it skips
- mov xofsnt,false ; remember we've sent the xon.
- chkxo1: pop bx ; restore register
- ret ; and return
- chkxon endp
-
- ; Send a break out the current serial port. Returns normally.
- SENDBR PROC NEAR
- ret
- SENDBR ENDP
-
- ; Position the cursor according to contents of DX:
- ; DH contains row, DL contains column. Returns normally.
- POSCUR PROC NEAR
- ret
- POSCUR ENDP
-
- ; Delete a character from the terminal. This works by printing
- ; backspaces and spaces. Returns normally.
-
- DODEL PROC NEAR
- mov ah,prstr
- mov dx,offset delstr ; Erase weird character.
- int dos
- ret
- DODEL ENDP
-
- ; Move the cursor to the left margin, then clear to end of line.
- ; Returns normally.
-
- CTLU PROC NEAR
- mov ah,prstr
- mov dx,offset clrlin
- int dos
- call clearl
- ret
- CTLU ENDP
-
- ; Set the current port.
-
- COMS PROC NEAR
- mov dx,offset comptab
- mov bx,0
- mov ah,cmkey
- call comnd
- jmp r
- push bx
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp comx ; Didn't get a confirm.
- nop
- pop bx
- mov flags.comflg,bl ; Set the comm port flag.
- cmp flags.comflg,1 ; Using Com 1?
- jne coms0 ; Nope.
- mov ax,offset port1
- mov portval,ax
- ret
- coms0: mov ax,offset port2
- mov portval,ax
- ret
- comx: pop bx
- ret
- COMS ENDP
-
- ; Set heath emulation on/off.
-
- VTS PROC NEAR
- jmp notimp
- VTS ENDP
-
- notimp: mov ah,prstr
- mov dx,offset noimp
- int dos
- jmp prserr
-
- ; Initialize variables to values used by the generic MS DOS version.
-
- lclini: mov flags.vtflg,0 ; Don't to terminal emulation.
- call opnprt ; Get file handle for comm port.
- ret
-
- ; Get a file handle for the communications port. Use DOS call to get the
- ; next available handle. If it fails, ask user what value to use (there
- ; should be a predefined handle for the port, generally 3). The open
- ; will fail if the system uses names other than "COM1" or "COM2".
- opnprt: mov al,flags.comflg
- mov ah,0
- mov si,ax
- shl si,1 ; double index
- mov dx,prttab[si]
- mov ah,open
- mov al,2
- int dos
- jnc opnpr2
- mov ah,prstr ; It didn't like the string.
- mov dx,offset erms41
- int dos
- mov dx,offset hnd1
- int dos
- opnpr0: mov dx,offset hnd2 ; Ask user to supply the handle.
- call prompt
- mov ah,cmtxt
- mov bx,offset rdbuf ; Where to put input.
- mov dx,offset hndhlp ; In case user wants help.
- call comnd
- jmp opnpr3 ; Maybe user typed a ^C.
- nop
- mov si,offset rdbuf
- call atoi ; Convert to real number
- jmp opnpr0 ; Keep trying.
- nop
- mov prthnd,ax ; Value returned in AX
- ret
- opnpr2: mov prthnd,ax ; Call succeeded.
- ret
- opnpr3: cmp flags.cxzflg,'C' ; Did user type a ^C?
- jne opnpr4 ; No, don't say anything.
- mov ah,prstr ; Else, issue a warning.
- mov dx,offset hnderr
- int dos
- opnpr4: ret ; Yes, fail.
-
- showkey:
- mov ax,offset shkmsg
- mov cx,shklen
- ret
-
- ; Initialization for using serial port. Returns normally.
- SERINI PROC NEAR
- cld ; Do increments in string operations
- call clrbuf ; Clear input buffer.
- ret ; We're done.
- SERINI ENDP
-
- ; Reset the serial port. This is the opposite of serini. Calling
- ; this twice without intervening calls to serini should be harmless.
- ; Returns normally.
-
- SERRST PROC NEAR
- ret ; All done.
- SERRST ENDP
-
- ; Produce a short beep. The PC DOS bell is long enough to cause a loss
- ; of data at the port. Returns normally.
-
- BEEP PROC NEAR
- mov dl,bell
- mov ah,dconio
- int dos
- ret
- BEEP ENDP
-
- ; Dumb terminal emulator. Doesn't work too well above 1200 baud (and
- ; even at 1200 baud you sometimes lose the first one or two characters
- ; on a line).
- term proc near
- mov si,ax ; this is source
- mov di,offset ourarg ; place to store arguments
- mov ax,ds
- mov es,ax ; address destination segment
- mov cx,size termarg
- rep movsb ; copy into our arg blk
- term1: call prtchr
- jmp short term2 ; have a char...
- nop
- nop
- jmp short term3 ; no char, go on
- term2: push ax
- and al,7fh ; mask off parity for terminal
- mov dl,al
- mov ah,conout
- int dos ; go print it
- pop ax
- test ourarg.flgs,capt ; capturing output?
- jz term3 ; no, forget it
- call ourarg.captr ; else call the routine
- term3: mov ah,dconio
- mov dl,0ffh
- int dos
- jz term1 ; no character, go on
- cmp al,ourarg.escc ; escape char?
- je term4 ; yes, exit
- push ax ; save char
- mov ah,al
- or ah,80H ; turn on hi bit so DOS doesn't interfere
- call outchr ; output the character
- nop
- nop
- nop
- pop ax
- test ourarg.flgs,lclecho ; echoing?
- jz term1 ; no, continue loop
- mov dl,al
- mov ah,dconio
- int dos
- jmp term1 ; else echo and keep going
- term4: ret
- term endp
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
- end