home *** CD-ROM | disk | FTP | other *** search
- public spar, rpar, error, error1, nout, send, flags, trans, pack
- public dodec, doenc, curchk, inichk, packlen, send11
- include msdefs.h
-
- spmin equ 20 ; Minimum packet size.
- spmax equ 94 ; Maximum packet size.
-
- datas segment public 'datas'
- extrn buff:byte, data:byte, fcb:byte, cpfcb:byte, filbuf:byte
- extrn decbuf:byte, chrcnt:word, bufpnt:word, comand:byte
- extrn rptq:byte, origr:byte, rptct:byte, rptval:byte
-
- flags flginfo <>
- trans trinfo <>
- pack pktinfo <>
- crlf db cr,lf,'$'
- ender db bell,bell,'$' ; [4]
- erms14 db '?Unable to receive an acknowledgment from the host$'
- erms15 db '?Unable to find file$'
- erms20 db 'Unable to send init packet$'
- erms21 db 'Unable to send file header$'
- erms22 db 'Unable to send data$'
- erms23 db 'Unable to send end-of-file packet$'
- erms24 db 'Unable to send break packet$'
- infms2 db cr,' Sending: In progress$'
- infms3 db 'Completed$'
- infms4 db 'Failed$'
- infms6 db 'Interrupted$'
- infms7 db cr,' Percent transferred: 100%$'
- remmsg1 db 'Kermit-MS: File not found$'
- filhlp db ' Input file spec (possibly wild) $'
- filmsg db ' File name to use on target system or confirm with'
- db ' a carriage return $'
-
- curchk db 0 ; Use to store checksum length.
- inichk db 1 ; Original or set checksum length.
- chrptr dw ? ; Position in character buffer.
- fcbpt dw ? ; Position in FCB.
- datptr dw ? ; Position in packet data buffer.
- siz dw ? ; Size of data from gtchr.
- temp dw 0
- temp4 dw 0
- sendas dw 50 dup(0) ; Buffer for file name.
- difnam db 0 ; Send under different name?
- difsiz db 0 ; Size of new file name.
- asmsg db ' as $'
- datas ends
-
- code segment public
- extrn serini:near, serrst:near, comnd:near, init:near
- extrn spack:near, rpack:near, gtnfil:near, gtchr:near
- extrn getfil:near, clrfln:near, nppos:near, rprpos:near
- extrn erpos:near, rtpos:near, cxmsg:near, stpos:near
- extrn encode:near, nulref:near, decode:near, nulr:near
- extrn errpack:near, updrtr:near, clrmod:near, fcbcpy:near
- extrn perpos:near
- assume cs:code,ds:datas
-
- ; This routine sets up the data for init packet (either the
- ; Send_init or ACK packet).
-
- RPAR PROC NEAR
- mov ah,trans.rpsiz ; Get the receive packet size.
- add ah,' ' ; Add a space to make it printable.
- mov [bx],ah ; Put it in the packet.
- mov ah,trans.rtime ; Get the receive packet time out.
- add ah,' ' ; Add a space.
- mov 1[bx],ah ; Put it in the packet.
- mov ah,trans.rpad ; Get the number of padding chars.
- add ah,' '
- mov 2[bx],ah ; Put it in the packet.
- mov ah,trans.rpadch ; Get the padding char.
- add ah,100O ; Uncontrol it.
- and ah,7FH
- mov 3[bx],ah ; Put it in the packet.
- mov ah,trans.reol ; Get the EOL char.
- add ah,' '
- mov 4[bx],ah ; Put it in the packet.
- mov ah,trans.rquote ; Get the quote char.
- mov 5[bx],ah ; Put it in the packet.
- mov ah,trans.ebquot ; Get 8-bit quote char. [21b]
- mov 6[bx],ah ; Add it to the packet. [21b]
- mov ah,trans.chklen ; Length of checksum.
- add ah,48 ; Make into a real digit.
- mov 7[bx],ah
- mov ah,rptq ; Repeat quote char.
- cmp ah,0 ; Null means no.
- jne rpar0
- mov ah,' ' ; Send a blank instead.
- rpar0: mov 8[bx],ah
- mov ah,09H ; Nine pieces of data.
- ret
- RPAR ENDP
-
- ; This routine reads in all the send_init packet information.
-
- SPAR PROC NEAR
- cmp ax,1
- jge sparx
- mov ah,dspsiz ; Data not supplied by host, use default.
- jmp sparx2
- sparx: mov temp4,ax ; Save the number of arguments.
- mov ah,trans.spsiz
- cmp ah,dspsiz ; Is current value the default?
- jne sparx2 ; No, assume changed by user.
- mov ah,[bx] ; Get the max packet size.
- sub ah,' ' ; Subtract a space.
- cmp ah,spmin ; Can't be below the minimum.
- jge sparx1
- mov ah,spmin
- jmp sparx2
- sparx1: cmp ah,spmax ; Or above the maximum.
- jle sparx2
- mov ah,spmax
- sparx2: mov trans.spsiz,ah ; Save it.
- mov ax,temp4
- cmp al,2 ; Fewer than two pieces?
- jge spar0
- mov ah,dstime ; Data not supplied by host, use default.
- jmp spar02
- spar0: mov ah,trans.stime
- cmp ah,dstime ; Is current value the default?
- jne spar02 ; No, assume changed by user.
- mov ah,1[bx] ; Get the timeout value.
- sub ah,' ' ; Subtract a space.
- cmp ah,0
- ja spar01 ; Must be non-negative.
- mov ah,0
- spar01: cmp ah,trans.rtime ; Same as other side's timeout.
- jne spar02
- add ah,5 ; If so, make it a little different.
- spar02: mov trans.stime,ah ; Save it.
- mov ax,temp4
- cmp al,3 ; Fewer than three pieces?
- jge spar1
- mov ah,dspad ; Data not supplied by host, use default.
- jmp spar11
- spar1: mov ah,trans.spad
- cmp ah,dspad ; Is current value the default?
- jne spar11 ; No, assume changed by user.
- mov ah,2[bx] ; Get the number of padding chars.
- sub ah,' '
- cmp ah,0
- ja spar11 ; Must be non-negative.
- mov ah,0
- spar11: mov trans.spad,ah
- mov ax,temp4
- cmp al,4 ; Fewer than four pieces?
- jge spar2
- mov ah,dspadc ; Data not supplied by host, use default.
- jmp spar21
- spar2: mov ah,trans.spadch
- cmp ah,dspadc ; Is current value the default?
- jne spar21 ; No, assume changed by user.
- mov ah,3[bx] ; Get the padding char.
- add ah,100O ; Re-controlify it.
- and ah,7FH
- cmp ah,del ; Delete?
- je spar21 ; Yes, then it's OK.
- cmp ah,0
- jge spar20
- mov ah,0 ; Below zero is no good.
- jmp spar21 ; Use zero (null).
- spar20: cmp ah,31 ; Is it a control char?
- jle spar21 ; Yes, then OK.
- mov ah,0 ; No, use null.
- spar21: mov trans.spadch,ah
- mov ax,temp4
- cmp al,5 ; Fewer than five pieces?
- jge spar3
- mov ah,dseol ; Data not supplied by host, use default.
- jmp spar31
- spar3: mov ah,trans.seol
- cmp ah,dseol ; Is current value the default?
- jne spar31 ; No, assume changed by user.
- mov ah,4[bx] ; Get the EOL char.
- sub ah,' '
- cmp ah,0
- jge spar30 ; Cannot be negative.
- mov ah,cr ; If it is, use default of carriage return.
- jmp spar31
- spar30: cmp ah,31 ; Is it a control char?
- jle spar31 ; Yes, then use it.
- mov ah,cr ; Else, use the default.
- spar31: mov trans.seol,ah
- mov ax,temp4
- cmp al,6 ; Fewer than six pieces?
- jge spar4
- mov ah,dsquot ; Data not supplied by host, use default.
- jmp spar41
- spar4: mov ah,trans.squote
- cmp ah,dsquot ; Is current value the default?
- jne spar41 ; No, assume changed by user.
- mov ah,5[bx] ; Get the quote char.
- cmp ah,' ' ; Less than a space?
- jge spar40
- mov ah,dsquot ; Yes, use default.
- jmp spar41
- spar40: cmp ah,'~' ; Must also be less then a tilde.
- jle spar41
- mov ah,dsquot ; Else, use default.
- spar41: mov trans.squote,ah
- cmp al,7 ; Fewer than seven pieces? [21b begin]
- jge spar5
- mov trans.ebquot,'Y' ; Data not supplied by host, use default.
- jmp spar51
- spar5: mov ah,6[bx] ; Get other sides 8-bit quote request.
- call doquo ; And set quote char. [21b end]
- spar51: cmp al,8 ; Fewer than eight pieces?
- jge spar6
- mov trans.chklen,1
- jmp spar61
- spar6: mov ah,inichk
- mov trans.chklen,ah ; Checksum length we really want to use.
- mov ah,7[bx] ; Get other sides checksum length.
- call dochk ; Determine what size to use.
- spar61: cmp al,9 ; Fewer than nine pieces?
- jge spar7
- mov rptq,0
- ret
- spar7: mov ah,8[bx] ; Get other sides repeat count prefix.
- mov ch,drpt
- mov rptq,0
- call dorpt
- ret
- SPAR ENDP
-
- ; Set 8-bit quote character based on my capabilities and the other
- ; Kermit's request. [21b]
-
- DOQUO PROC NEAR
- cmp trans.ebquot,'N' ; Can I do 8-bit quoting at all?
- je dq3 ; No - so forget it.
- cmp trans.ebquot,'Y' ; Can I do it if requested?
- jne dq0 ; No - it's a must that I do it.
- mov trans.ebquot,ah ; Do whatever he wants.
- jmp dq1
- dq0: cmp ah,'Y' ; I need quoting - can he do it?
- je dq1 ; Yes - then all is settled.
- cmp ah,'N' ; No - then don't quote.
- je dq3
- cmp ah,trans.ebquot ; Both need quoting - chars must match.
- jne dq3
- dq1: mov ah,trans.ebquot
- cmp ah,'Y' ; If Y or N, don't validate prefix.
- je dq2
- cmp ah,'N'
- je dq2
- call prechk ; Is it in range 33-62, 96-126?
- mov ah,'Y' ; Failed, don't do quoting.
- nop
- cmp ah,trans.rquote ; Same prefix?
- je dq3 ; Not allowed, so don't do quoting.
- cmp ah,trans.squote ; Same prefix here?
- je dq3 ; This is illegal too.
- mov trans.ebquot,ah ; Remember what we decided on.
- dq2: ret
- dq3: mov trans.ebquot,'N' ; Quoting will not be done.
- ret
- DOQUO ENDP
-
- ; Check if prefix in AH is in the proper range: 33-62, 96-126.
- ; RSKP if so else RETURN.
- prechk: cmp ah,33
- jge prec0 ; It's above 33.
- ret
- prec0: cmp ah,62
- jg prec1
- jmp rskp ; And below 62. OK.
- prec1: cmp ah,96
- jge prec2 ; It's above 96.
- ret
- prec2: cmp ah,126
- jg prec3
- jmp rskp ; And below 126. OK.
- prec3: ret
-
- ; Set checksum length.
- dochk: cmp ah,'1' ; Must be 1, 2, or 3.
- jl doc1
- cmp ah,'3'
- jle doc2
- doc1: mov ah,'1'
- doc2: sub ah,48 ; Don't want it printable.
- cmp ah,trans.chklen ; Do we want the same thing?
- je dochk0 ; Yes, then we're done.
- mov trans.chklen,1 ; No, use single character checksum.
- dochk0: ret ; Just return for now.
-
- ; Set repeat count quote character. The one used must be different than
- ; the control and eight-bit quote characters. Also, both sides must
- ; use the same character.
- dorpt: call prechk ; Is it in the valid range?
- mov ah,0 ; No, don't use their value.
- nop
- cmp ah,trans.squote ; Same as the control quote char?
- je dorpt0 ; Yes, that's illegal, no repeats.
- cmp ah,trans.rquote ; How about this one?
- je dorpt0 ; No good.
- cmp ah,trans.ebquot ; Same as eight bit quote char?
- je dorpt0 ; Yes, that's illegal too, no repeats.
- cmp ah,ch ; Are we planning to use the same char?
- jne dorpt0 ; No, that's no good either.
- mov rptq,ch ; Use repeat quote char now.
- dorpt0: ret
-
- ; Send command
-
- SEND PROC NEAR
- mov comand.cmcr,0 ; Filename must be specified.
- mov difnam,0 ; Assume we'll use original filename.
- mov flags.wldflg,0 ; Re-initialize every time.
- mov ah,cmifi ; Parse an input file spec.
- mov dx,offset fcb ; Give the address for the FCB.
- mov bx,offset filhlp ; Text of help message.
- call comnd
- jmp r ; Give up on bad parse.
- cmp flags.wldflg,0FFH ; Any wildcards seen?
- je send1 ; Yes, get a confirm.
- mov bx,offset sendas ; See if want to send file under dif name.
- mov dx,offset filmsg ; In case user needs help.
- mov ah,cmtxt
- call comnd
- jmp r
- cmp ah,0 ; Different name supplied?
- je send11 ; No - keep as it.
- mov difnam,1 ; Yes - send different filename.
- mov difsiz,ah ; Remember length of new name.
- jmp send11
- send1: mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
- send11: mov flags.droflg,0 ; Reset flags from fn parsing. [21a]
- mov flags.nmoflg,0 ; Reset flags from fn parsing. [21a]
- mov ah,sfirst ; Get the first file.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Any found?
- jne send12
- cmp pack.state,'R' ; was this from a remote GET?
- jne sen11a ; no, print error and continue
- mov bx,offset remmsg1 ; else get error message
- call errpack ; go complain
- jmp abort ; and abort this
- sen11a: mov ah,prstr
- mov dx,offset crlf
- int dos
- mov ah,prstr
- mov dx,offset erms15
- int dos
- ret
- send12: cmp flags.wldflg,0 ; Any wildcards. [7 start]
- je send16 ; Nope, so no problem.
- mov bx,offset fcb ; Remember what FCB looked like.
- mov di,offset cpfcb
- mov cl,37 ; Size of FCB.
- call fcbcpy
- mov di,offset fcb+1 ; Copy filename from DTA to FCB.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy ; [7 end]
- send16: call serini ; Initialize serial port. [14]
- mov pack.pktnum,0 ; Set the packet number to zero.
- mov pack.numtry,0 ; Set the number of tries to zero.
- mov pack.numpkt,0 ; Set the number of packets to zero.
- mov pack.numrtr,0 ; Set the number of retries to zero.
- mov pack.state,'S' ; Set the state to receive initiate.
- cmp flags.remflg,0 ; remote mode?
- jne send2a ; yes, continue below.
- call init ; Clear the line and initialize the buffers.
- call rtpos ; Position cursor.
- mov ax,0
- call nout ; Write the number of retries.
- call stpos ; Print status of file transfer.
- mov ah,prstr ; Be informative.
- mov dx,offset infms2
- int dos
- send2: cmp flags.remflg,0 ; remote mode?
- jne send2a ; yes, skip printing
- call nppos ; Number of packets sent.
- mov ax,pack.numpkt
- call nout ; Write the packet number.
- send2a: cmp pack.state,'D' ; Are we in the data send state?
- jne send3
- call sdata
- jmp send2
- send3: cmp pack.state,'F' ; Are we in the file send state?
- jne send4
- call sfile ; Call send file.
- jmp send2
- send4: cmp pack.state,'Z' ; Are we in the EOF state?
- jne send5
- call seof
- jmp send2
- send5: cmp pack.state,'S' ; Are we in the send initiate state?
- jne send6
- call sinit
- jmp send2
- send6: cmp pack.state,'B' ; Are we in the eot state?
- jne send7
- call seot
- jmp send2
- send7: cmp pack.state,'C' ; Are we in the send complete state?
- jne send8
- call serrst ; Reset serial port. [14]
- cmp flags.remflg,0 ; remote mode?
- jne send7a ; yes, no printing.
- cmp flags.cxzflg,0 ; completed normally?
- jne send7b ; no, don't bother with this
- call perpos
- mov ah,prstr
- mov dx,offset infms7
- int dos
- send7b: call stpos
- mov ah,prstr
- mov dx,offset infms3 ; Plus a little cuteness.
- cmp flags.cxzflg,0 ; Completed or interrupted?
- je snd71 ; Ended normally.
- mov dx,offset infms6 ; Say was interrupted.
- snd71: int dos ; New label.
- cmp flags.belflg,0 ; Bell desired? [17a]
- je sendnb ; [17a]
- mov dx,offset ender ; Ring them bells. [4]
- int dos
- sendnb: call clrmod
- call rprpos
- send7a: jmp rskp
- send8: call serrst ; Reset serial port. [14]
- cmp flags.remflg,0 ; remote mode?
- jne send9a ; no, no printing.
- call stpos
- mov ah,prstr
- mov dx,offset infms4 ; Plus a little cuteness.
- int dos
- cmp flags.belflg,0 ; Bell desired? [17a]
- je send9 ; No. [17a]
- mov dx,offset ender ; Ring them bells. [4]
- int dos ; [4]
- send9: call clrmod
- call rprpos
- send9a: jmp rskp
- SEND ENDP
-
-
- ; Send routines
-
- ; Send initiate
-
-
- SINIT PROC NEAR
- cmp pack.numtry,imxtry ; Have we reached the maximum number of tries?
- jl sinit2
- call erpos
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- mov bx,offset erms20
- call errpack ; Send error packet just in case.
- jmp abort ; Change the state to abort.
- sinit2: inc pack.numtry ; Save the updated number of tries.
- mov bx,offset data ; Get a pointer to our data block.
- call rpar ; Set up the parameter information.
- xchg ah,al
- mov ah,0
- mov pack.argbk1,ax ; Save the number of arguments.
- mov ax,pack.numpkt ; Get the packet number.
- mov pack.argblk,ax
- mov ah,trans.chklen
- mov curchk,ah ; Store checksum length we want to use.
- mov trans.chklen,1 ; Send init checksum is always 1 char.
- mov ah,'S' ; Send initiate packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp sini23 ; Trashed packet don't change state, retry.
- push ax
- mov ah,curchk
- mov trans.chklen,ah ; Checksum length we want to use.
- pop ax
- cmp ah,'Y' ; ACK?
- jne sinit3 ; If not try next.
- mov ax,pack.pktnum ; Get the packet number.
- cmp ax,pack.argblk ; Is it the right packet number?
- je sini22
- ret ; If not try again.
- sini22: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pack.pktnum,ax ; Save modulo 64 of the number.
- inc pack.numpkt ; Increment the number of packets.
- mov ax,pack.argbk1 ; Get the number of pieces of data.
- mov bx,offset data ; Pointer to the data.
- call spar ; Read in the data.
- call packlen ; Get max send packet size. [21b]
- mov ah,pack.numtry ; Get the number of tries.
- mov pack.oldtry,ah ; Save it.
- mov pack.numtry,0 ; Reset the number of tries.
- mov pack.state,'F' ; Set the state to file send.
- call getfil ; Open the file.
- jmp abort ; Something is wrong, die.
- ret
- sini23: mov ah,curchk ; Restore desired checksum length.
- mov trans.chklen,ah
- call updrtr ; Update retry counter.
- ret ; And retry.
- sinit3: cmp ah,'N' ; NAK?
- jne sinit4 ; If not see if its an error.
- call rtpos ; Position cursor.
- inc pack.numrtr ; Increment the number of retries
- mov ax,pack.numrtr
- call nout ; Write the number of retries.
- ret
- sinit4: cmp ah,'E' ; Is it an error packet.
- jne sinit5
- call error
- sinit5: jmp abort
- SINIT ENDP
-
-
-
- ; Send file header
-
- SFILE PROC NEAR
- cmp pack.numtry,maxtry ; Have we reached the maximum number of tries?
- jl sfile1
- call erpos
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- mov bx,offset erms21
- call errpack ; Send error packet just in case.
- jmp abort ; Change the state to abort.
- sfile1: inc pack.numtry ; Increment it.
- mov flags.cxzflg,0 ; Clear ^X,^Z flag.
- mov datptr,offset data ; Get a pointer to our data block.
- mov bx,offset fcb+1 ; Pointer to file name in FCB.
- mov fcbpt,bx ; Save position in FCB.
- mov cl,0 ; Counter for chars in file name.
- mov ch,0 ; Counter for number of chars in FCB.
- sfil11: cmp ch,8H ; Ninth char?
- jne sfil12
- mov ah,'.'
- mov bx,datptr
- mov [bx],ah ; Put dot in data packet.
- inc bx
- mov datptr,bx ; Save new position in data packet.
- inc cl
- sfil12: inc ch
- cmp ch,0CH ; Twelve?
- jns sfil13
- mov bx,fcbpt
- mov ah,[bx] ; Get char of filename.
- inc bx
- mov fcbpt,bx ; Save position in FCB.
- cmp ah,'!' ; Is it a good char?
- jl sfil11 ; If not, get the next.
- mov bx,datptr
- mov [bx],ah ; Put char in data buffer.
- inc cl ; Increment counter.
- inc bx
- mov datptr,bx ; Save new position.
- jmp sfil11 ; Get another char.
- sfil13: mov ch,0
- cmp flags.remflg,0 ; remote mode?
- jne sfil13a ; yes, no printing.
- push cx ; Don't forget the size.
- mov bx,datptr
- mov ah,'$'
- mov [bx],ah ; Put dollar sign for printing.
- call clrfln
- mov ah,prstr
- mov dx,offset data ; Print file name.
- int dos
- pop cx
- sfil13a:cmp difnam,0 ; Sending file under different name.
- je sfl13x ; No, so don't give new name.
- call newfn
- sfl13x: call doenc ; Do encoding.
- mov ax,pack.pktnum ; Get the packet number.
- mov pack.argblk,ax
- mov ah,'F' ; File header packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp tryagn ; Trashed packet don't change state, retry.
- call dodec ; Do all decoding.
- cmp ah,'Y' ; ACK?
- jne sfile2 ; If not try next.
- mov ax,pack.pktnum ; Get the packet number.
- cmp ax,pack.argblk
- je sfil14
- ret ; If not hold out for the right one.
- sfil14: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pack.pktnum,ax ; Save modulo 64 of the number.
- inc pack.numpkt ; Increment the number of packets.
- mov ah,pack.numtry ; Get the number of tries.
- mov pack.oldtry,ah ; Save it.
- mov pack.numtry,0 ; Reset the number of tries.
-
- sfil15: mov ah,0 ; Get a zero.
- mov bx,offset fcb
- add bx,20H
- mov [bx],ah ; Set the record number to zero.
- ; mov flags.eoflag,ah ; Indicate not EOF. (Done in GETFIL).
- mov ah,0FFH
- mov flags.filflg,ah ; Indicate file buffer empty.
- call gtchr
- jmp sfil16 ; Error go see if its EOF.
- nop
- jmp sfil17 ; Got the chars, proceed.
- sfil16: cmp ah,0FFH ; Is it EOF?
- je sfl161
- jmp abort ; If not give up.
- sfl161: mov ah,'Z' ; Set the state to EOF.
- mov pack.state,ah
- ret
- sfil17: mov siz,ax
-
- mov pack.state,'D' ; Set the state to data send.
- ret
- sfile2: cmp ah,'N' ; NAK?
- jne sfile3 ; Try if error packet.
- call rtpos ; Position cursor.
- inc pack.numrtr ; Increment the number of retries
- mov ax,pack.numrtr
- call nout ; Write the number of retries.
- mov ax,pack.pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,pack.argblk ; Is the packet's number one more than now?
- jz sfil14 ; Just as good as a ACK; go to the ACK code.
- ret ; If not go try again.
- sfile3: cmp ah,'E' ; Is it an error packet.
- jne sfile4
- call error
- sfile4: jmp abort
- SFILE ENDP
-
-
- ; Send data
-
- SDATA PROC NEAR
- cmp flags.cxzflg,0 ; Have we seen ^X or ^Z?
- je sdata2 ; Nope, just continue.
- cmp flags.cxzflg,'C' ; Stop it all? [25]
- jne sdata1 ; It was a ^X or ^Z.
- mov pack.state,'A' ; It was a ^C -- abort [25]
- ret
- sdata1: mov pack.state,'Z' ; Else, abort sending the file.
- ret
- sdata2: cmp pack.numtry,maxtry ; Have we reached the maximum number of tries?
- jl sdata3
- call erpos
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- mov bx,offset erms22
- call errpack ; Send error packet just in case.
- jmp abort ; Change the state to abort.
- sdata3: inc pack.numtry ; Increment it.
- mov datptr,offset data ; Get a pointer to our data block.
- mov chrptr,offset filbuf ; Pointer to chars to be sent.
- mov cx,siz ; number to transfer
- mov si,chrptr ; source of characters
- mov di,datptr ; destination
- cmp flags.eofcz,0 ; stopping on ctl-z's?
- jz sdata6 ; no, do blind copy
- sdata4: lodsb ; get a byte
- cmp al,'Z'-40H ; is it a ctl-z?
- je sdata5 ; yes, break loop
- stosb ; else copy it
- loop sdata4 ; and keep going
- sdata5: mov ax,siz ; size to send
- sub ax,cx ; minus actually sent...
- jmp short sdata7
- sdata6: rep movsb ; just copy data
- mov ax,siz ; this is how many were moved
- sdata7: mov pack.argbk1,ax
- mov ax,pack.pktnum ; Get the packet number.
- mov pack.argblk,ax
- mov ah,'D' ; Data packet.
- call spack ; Send the packet.
- jmp tryagn ; if can't send it, retry before giving up
- call rpack ; Get a packet.
- jmp tryagn ; Trashed packet don't change state, retry.
- call dodec ; Do all decoding.
- cmp ah,'Y' ; ACK?
- jne sdat14 ; If not try next.
- mov ax,pack.pktnum ; Get the packet number.
- cmp ax,pack.argblk ; Is it the right packet number?
- jz sdata8
- ret ; If not hold out for the right one.
- sdata8: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pack.pktnum,ax ; Save modulo 64 of the number.
- inc pack.numpkt ; Increment the number of packets.
- mov ah,pack.numtry ; Get the number of tries.
- mov pack.oldtry,ah ; Save it.
- mov pack.numtry,0 ; Reset the number of tries.
- cmp pack.argbk1,1 ; Does the ACK contain data?
- jne sdat11 ; Nope, so continue.
- mov bx,offset data ; If yes, check the data field.
- mov ah,[bx] ; Pick it up.
- cmp ah,'X' ; Other side requests ^X?
- jne sdata9 ; Nope.
- jmp sdat10 ; And leave.
- sdata9: cmp ah,'Z' ; Other side requests ^Z?
- jne sdat11 ; Nope.
- sdat10: mov flags.cxzflg,ah ; Yes remember it.
- mov pack.state,'Z' ; Abort sending file(s).
- ret
- sdat11: call gtchr
- jmp sdat12 ; Error go see if its EOF.
- mov siz,ax ; Save the size of the data gotten.
- ret
-
- sdat12: cmp ah,0FFH ; Is it EOF?
- je sdat13
- jmp abort ; If not give up.
-
- sdat13: mov pack.state,'Z' ; Set the state to EOF.
- ret
- sdat14: cmp ah,'N' ; NAK?
- jne sdat15 ; See if is an error packet.
- call rtpos ; Position cursor.
- inc pack.numrtr ; Increment the number of retries
- mov ax,pack.numrtr
- call nout ; Write the number of retries.
- mov ax,pack.pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,pack.argblk ; Is the packet's number one more than now?
- jz sdata8 ; Just as good as ACK; goto ACK code.
- ret ; If not go try again.
- sdat15: cmp ah,'E' ; Is it an error packet.
- jne sdat16
- call error
- sdat16: jmp abort
- SDATA ENDP
-
-
- ; Send EOF
-
- SEOF PROC NEAR
- cmp pack.numtry,maxtry ; Have we reached the maximum number of tries?
- jl seof1
- call erpos ; Position cursor.
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- mov bx,offset erms23
- call errpack ; Send error packet just in case.
- jmp abort ; Change the state to abort.
- seof1: inc pack.numtry ; Increment it.
- mov ax,pack.pktnum ; Get the packet number.
- mov pack.argblk,ax
- mov pack.argbk1,0 ; No data.
- cmp flags.cxzflg,0 ; Seen a ^X or ^Z?
- je seof11 ; Nope, send normal EOF packet.
- mov bx,offset data ; Get data area of packet.
- mov ah,'D' ; Use "D" for discard.
- mov [bx],ah ; And add it to the packet.
- mov pack.argbk1,1 ; Set data size to 1.
- seof11: mov cx,pack.argbk1 ; Put size in CX.
- call doenc ; Encode the packet.
- mov ah,'Z' ; EOF packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp tryagn ; Trashed packet don't change state, retry.
- call dodec ; Do decoding.
- cmp ah,'Y' ; ACK?
- jne seof2 ; If not try next.
- mov ax,pack.pktnum ; Get the packet number.
- cmp ax,pack.argblk ; Is it the right packet number?
- jz seof12
- ret ; If not hold out for the right one.
- seof12: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pack.pktnum,ax ; Save modulo 64 of the number.
- inc pack.numpkt ; Increment the number of packets.
- mov ah,pack.numtry ; Get the number of tries.
- mov pack.oldtry,ah ; Save it.
- mov pack.numtry,0 ; Reset the number of tries.
- mov ah,closf ; Close the file.
- mov dx,offset fcb
- int dos
- call gtnfil ; Get the next file.
- jmp seof13 ; No more.
- mov pack.state,'F' ; Set the state to file send.
- cmp flags.cxzflg,'X' ; Control-X seen?
- jne seof14
- call cxmsg ; Clear out the interrupt msg.
- seof14: mov flags.cxzflg,0 ; Reset the flag.
- ret
- seof13: mov pack.state,'B' ; Set the state to EOT.
- ret
- seof2: cmp ah,'N' ; NAK?
- jne seof3 ; Try and see if its an error packet.
- call rtpos ; Position cursor.
- inc pack.numrtr ; Increment the number of retries
- mov ax,pack.numrtr
- call nout ; Write the number of retries.
- mov ax,pack.pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,pack.argblk ; Is the packet's number one more than now?
- jz seof12 ; Just as good as a ACK; go to the ACK code.
- ret ; If not go try again.
- seof3: cmp ah,'E' ; Is it an error packet?
- jne seof4
- call error
- seof4: jmp abort
- SEOF ENDP
-
-
- ; Send EOT
-
- SEOT PROC NEAR
- cmp pack.numtry,maxtry ; Have we reached the maximum number of tries?
- jl seot1
- call erpos ; Position cursor.
- mov dx,offset erms14
- mov ah,prstr
- int dos ; Print an error message.
- mov bx,offset erms24
- call errpack ; Send error packet just in case.
- jmp abort ; Change the state to abort.
- seot1: inc pack.numtry ; Increment it.
- mov ax,pack.pktnum ; Get the packet number.
- mov pack.argblk,ax
- mov pack.argbk1,0 ; No data.
- mov cx,pack.argbk1
- call doenc ; Encode packet.
- mov ah,'B' ; EOF packet.
- call spack ; Send the packet.
- jmp abort
- call rpack ; Get a packet.
- jmp tryagn ; Trashed packet don't change state, retry.
- call dodec ; Decode packet.
- cmp ah,'Y' ; ACK?
- jne seot2 ; If not try next.
- mov ax,pack.pktnum ; Get the packet number.
- cmp ax,pack.argblk ; Is it the right packet number?
- jz seot12
- ret ; If not hold out for the right one.
- seot12: inc ax ; Increment the packet number.
- and ax,3FH ; Turn off the two high order bits.
- mov pack.pktnum,ax ; Save modulo 64 of the number.
- inc pack.numpkt ; Increment the number of packets.
- mov ah,pack.numtry ; Get the number of tries.
- mov pack.oldtry,ah ; Save it.
- mov pack.numtry,0 ; Reset the number of tries.
- mov pack.state,'C' ; Set the state to file send.
- ret
- seot2: cmp ah,'N' ; NAK?
- jne seot3 ; Is it error.
- call rtpos ; Position cursor.
- inc pack.numrtr ; Increment the number of retries
- mov ax,pack.numrtr
- call nout ; Write the number of retries.
- mov ax,pack.pktnum ; Get the present packet number.
- inc ax ; Increment.
- and ax,03FH ; Account for wraparound. [18]
- cmp ax,pack.argblk ; Is the packet's number one more than now?
- jz seot12 ; Just as good as a ACK; go to the ACK code.
- ret ; If not go try again.
- seot3: cmp ah,'E' ; Is it an error packet.
- jne seot4
- call error
- seot4: jmp abort
- SEOT ENDP
-
- tryagn: call updrtr
- ret
-
- newfn: mov ah,prstr
- mov dx,offset asmsg
- int dos
- mov ah,dconio
- mov si,offset sendas ; Buffer where the name is.
- mov di,offset data
- mov ch,0
- mov cl,difsiz ; Length of name.
- newf0: lodsb ; Get a char.
- cmp al,61H
- jb newf1 ; Leave alone if less than 'a'?
- cmp al,7AH
- ja newf1 ; Leave alone if over 'z'.
- sub al,20H ; Uppercase the letters.
- newf1: stosb
- mov dl,al
- cmp flags.remflg,0 ; should we print?
- jne newf2 ; no, we're in remote mode.
- int dos ; Print them.
- newf2: loop newf0
- mov ch,0
- mov cl,difsiz ; Reset the length field.
- ret
-
- ; Do encoding. Expectx CX to be the data size.
- doenc: jcxz doen0
- mov chrcnt,cx ; Number of chars in filename.
- mov bx,offset data ; Source of data.
- mov bufpnt,bx
- mov bx,offset nulref ; Null routine for refilling buffer.
- mov ah,rptq
- mov origr,ah ; Save repeat prefix here.
- mov rptct,1 ; Number of times char is repeated.
- mov rptval,0 ; Value of repeated char.
- call encode ; Make a packet with size in AX.
- nop
- nop
- nop
- mov pack.argbk1,ax ; Save number of char in filename.
- mov cx,ax
- call movpak ; Move to data part of packet.
- doen0: ret
-
- ; CX is set before this is called.
- movpak: push es
- mov ax,ds
- mov es,ax
- mov si,offset filbuf ; Move from here
- mov di,offset data ; to here
- repne movsb
- pop es
- ret
-
- ; Do decoding.
- dodec: cmp pack.argbk1,0
- je dodc0
- push ax ; Save packet size.
- mov cx,pack.argbk1 ; Size of data.
- mov bx,offset data ; Address of data.
- mov ax,offset nulr ; Routine to dump buffer (null routine).
- mov bufpnt,offset decbuf ; Where to put output.
- mov chrcnt,80H ; Buffer size.
- call decode
- nop
- nop
- nop
- call decmov ; Move decoded data back to "data" buffer.
- pop ax
- dodc0: ret
-
- ; Move decoded data from decode buffer back to "data".
- decmov: push si
- push di
- push es
- mov ax,ds
- mov es,ax
- mov cx,bufpnt ; Last char we added.
- sub cx,offset decbuf ; Get actual number of characters.
- mov pack.argbk1,cx ; Remember size of real data.
- lea si,decbuf ; Data is here.
- lea di,data ; Move to here.
- repne movsb ; Copy the data.
- pop es
- pop di
- pop si
- ret
-
- ; Abort
-
- ABORT PROC NEAR
- mov pack.state,'A' ; Otherwise abort.
- ret
- ABORT ENDP
-
- ; This is where we go if we get an error packet. A call to ERROR
- ; positions the cursor and prints the message. A call to ERROR1
- ; just prints a CRLF and then the message. [8]
-
- ERROR PROC NEAR
- mov pack.state,'A' ; Set the state to abort.
- call erpos ; Position the cursor.
- jmp error2
- error1: mov ah,prstr
- mov dx,offset crlf
- int dos
- error2: mov bx,pack.argbk1 ; Get the length of the data.
- add bx,offset data ; Get to the end of the string.
- mov ah,'$' ; Put a dollar sign at the end.
- mov [bx],ah
- mov ah,prstr ; Print the error message.
- mov dx,offset data
- int dos
- ret
- ERROR ENDP
-
- ; Set the maximum data packet size. [21b]
-
- PACKLEN PROC NEAR
- mov ah,trans.spsiz ; Maximum send packet size.
- sub ah,4 ; Size minus control info.
- sub ah,trans.chklen ; And minus checksum chars.
- sub ah,2 ; Leave room at end: 2 for possible #X.
- cmp trans.ebquot,'N' ; Doing 8-bit quoting?
- je pack0 ; Nope so we've got our size.
- cmp trans.ebquot,'Y'
- je pack0 ; Not doing it in this case either.
- sub ah,1 ; Another 1 for 8th-bit quoting.
- pack0: cmp rptq,0 ; Doing repeat character quoting?
- je pack1 ; Nope, so that's all for now.
- sub ah,2 ; Another 2 for repeat prefix.
- pack1: mov trans.maxdat,ah ; Save max length for data field.
- ret
- PACKLEN ENDP
-
- ; Print the number in AX on the screen in decimal rather that hex. [19a]
-
- NOUT PROC NEAR
- cmp flags.xflg,1 ; Writing to screen? [21c]
- je nout1 ; Yes, just leave. [21c]
- push ax
- push dx
- mov temp,10 ; Divide quotient by 10.
- ; cwd ; Convert word to doubleword.
- mov dx,0 ; High order word should be zero.
- div temp ; AX <-- Quo, DX <-- Rem.
- cmp ax,0 ; Are we done?
- jz nout0 ; Yes.
- call nout ; If not, then recurse.
- nout0: add dl,'0' ; Make it printable.
- mov temp,ax
- mov ah,conout
- int dos
- mov ax,temp
- pop dx
- pop ax
- nout1: ret ; We're done. [21c]
- NOUT 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