home *** CD-ROM | disk | FTP | other *** search
- public bufpnt, buff, fcb, cpfcb, chrcnt, fixfcb, init, init1,
- public gofil, outbuf, ptchr, gtchr, gtnfil, getfil, filbuf,
- public encode, decode, nulref, nulr, decbuf, errpack, rptq,
- public origr, rptct, rptval, clrfln, cxmsg, biterr, intmsg,
- public rtpos, erpos,rppos, stpos,nppos,rprpos,nrtpos,sppos,
- public kbpos,perpos,frpos, prtscr
- include msdefs.h
-
- rptmin equ 3 ; At least 3 of same char in a row.
-
- ; equates for screen positioning
- scrfln equ 0316H ; Place for file name.
- scrkb equ 0416H ; Place for percent transferred.
- scrper equ 0516H ; Place for Kbytes transferred.
- scrst equ 0616H ; Place for status.
- scrnp equ 0816H ; Place for number of packets.
- scrnrt equ 0916H ; Place for number of retries.
- screrr equ 0A16H ; Place for error msgs.
- scrhi equ 0B16H ; Err when 8th bit is on.
- scrfr equ 0B16H ; Rename file.
- scrint equ 0B16H ; Acknowledge interrupt. [20b]
- scrsp equ 0C00H ; Place for send packet.
- scrrp equ 0E00H ; Place for receive packet.
- scrrpr equ 1100H ; Prompt when Kermit ends.
-
-
-
- datas segment public 'datas'
- extrn data:byte, flags:byte, trans:byte, pack:byte, hierr:byte
- extrn dosnum:byte
-
- outlin db cr,lf,cr,lf
- db cr,lf,' File name:'
- db cr,lf,' KBytes transferred:'
- db cr,lf
- db cr,lf
- db cr,lf
- db cr,lf,' Number of packets:'
- db cr,lf,' Number of retries:'
- db cr,lf,' Last error: None'
- db cr,lf,' Last warning: None'
- db '$'
-
- ermes4 db 'Unable to rename file$'
- erms10 db '?Unable to receive data$'
- erms11 db '?Disk full$'
- erms12 db '?Unable to create file$'
- erms17 db 'Record length exceeds size of buffer$'
- infms5 db 'Renaming file to $'
- infms7 db 'File interrupt$'
- infms8 db 'File group interrupt$'
- hibit db 'Warning - Non Ascii char$'
- crlf db cr,lf,'$'
- printer db 0,'LPT1 '
- spchar db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
- spclen equ $-spchar ; Number of special chars.
- spchar2 db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 7BH,7DH,5FH,5EH,7EH,60H
- spc2len equ $-spchar2
- next db 0FFH ; No next character just yet.
- rptval db 0 ; Repeated character.
- rptct db 1 ; Number of times it's repeated.
- rptq db drpt ; Repeat prefix.
- origr db drpt ; Original repeat prefix.
- temp1 dw ? ; Temporary storage.
- temp2 dw ?
- oloc dw 0 ; Original buffer location. [21c]
- osiz dw 0 ; Original buffer size. [21c]
- chrcnt dw ? ; Number of chars in the file buffer.
- outpnt dw ? ; Position in packet.
- bufpnt dw ? ; Position in file buffer.
- fdtpnt dw ? ; Pointer to within our file.
- fcbptr dw ? ; Position in FCB.
- cbfptr dw ? ; Position in character buffer.
- filsiz dw 0 ; Double word for filesize (in bytes.)
- dw 0
- ofilsz dw 0 ; Original file size percent adjusted (/100).
- tfilsz dw 0 ; Bytes transferred.
- dw 0
- oldper dw ? ; old percentage
- oldkbt dw ? ; old KB transferred.
- wrpmsg db ? ; non-zero if we wrote percent message
- percnt dw 100 ; Number to divide by for a percent.
- bufhex dw 80H
- permsg db cr,' Percent transferred:$'
- cxzhlp db '^X cancels file, ^Z cancels batch'
- db ', ^E aborts protocol'
- db ', ^C aborts at once'
- db '$'
- asmsg db ' AS '
- asmln equ $-asmsg
- filbuf db 60H DUP(?) ; Character buffer.
- buff db dmasiz DUP(?) ; Use as our DTA.
- fcb db fcbsiz DUP(?) ; Use as our FCB.
- cpfcb db fcbsiz DUP(?) ; Save FCB in case of "*". [7]
- decbuf db dmasiz DUP(?) ; For decoding incoming data.
- datas ends
-
- code segment public
- extrn spack:near, cmblnk:near, locate:near, nout:near
- extrn putmod:near, poscur:near, clearl:near, fcbcpy:near
- assume cs:code,ds:datas
-
- ; Position cursor for an error message.
-
- ERPOS PROC NEAR
- cmp flags.xflg,1 ; Packet header seen? [21c start]
- jne erp0 ; No, do as normal.
- mov dx,offset crlf
- mov ah,prstr
- int dos
- ret
- erp0: mov dx,screrr
- jmp poscur
- ERPOS ENDP
-
- ; Position cursor for number of retries message.
-
- RTPOS PROC NEAR
- cmp flags.xflg,1 ; Packet header seen? [21c]
- jne rtp0 ; No, do as normal.
- ret
- rtp0: mov dx,scrnrt
- jmp poscur
- RTPOS ENDP
-
- ; Reassure user that we acknowledge his ^X/^Z.
-
- INTMSG PROC NEAR
- cmp flags.xflg,0 ; Writing to screen?
- jne int1 ; Yes. Don't do anything.
- mov dx,scrint
- call poscur
- call clearl
- mov dx,offset infms7 ; File interrupted?
- cmp flags.cxzflg,'X' ; Yes.
- je int0
- mov dx,offset infms8 ; File group interrupted.
- int0: mov ah,prstr
- int dos
- int1: ret
- INTMSG ENDP
-
- ; Print err message that found a non-standard-Ascii char in the file.
-
- BITERR PROC NEAR
- cmp flags.remflg,0 ; remote mode?
- jne biter1 ; yes, no printing.
- push bx
- mov dx,scrhi
- call poscur
- call clearl
- mov ah,prstr
- mov dx,offset hibit
- int dos
- pop bx
- biter1: ret
- BITERR ENDP
-
- ; Clear out message about interrupted file.
-
- CXMSG PROC NEAR
- cmp flags.xflg,0 ; Writing to screen?
- jne cxm0 ; Yes. Don't do anything.
- mov dx,scrint
- call poscur
- call clearl
- cxm0: ret
- CXMSG ENDP
-
- ; Clear out the old filename on the screen.
-
- CLRFLN PROC NEAR
- mov dx,scrfln
- call poscur
- call clearl ; Clear to end of line. [19a]
- ret
- CLRFLN ENDP
-
- ; some random screen positioning functions
- kbpos: mov dx,scrkb ; KBytes transferred.
- jmp poscur
- perpos: mov dx,scrper ; Percent transferred.
- call poscur
- jmp clearl
- frpos: mov dx,scrfr ; Say renamed file.
- call poscur
- jmp clearl
- stpos: mov dx,scrst ; Print status of file transfer.
- call poscur
- jmp clearl
- nppos: mov dx,scrnp ; Number of packets sent.
- jmp poscur
- rprpos: mov dx,scrrpr ; Reprompt position.
- jmp poscur
- nrtpos: mov dx,scrnrt ; Number of retries.
- jmp poscur
- sppos: mov dx,scrsp ; Send packet location.
- jmp poscur
- rppos: mov dx,scrrp ; Receive packet location.
- jmp poscur
-
-
-
- ; Initialize buffers and clear line.
-
- INIT PROC NEAR
- call cmblnk
- call locate
- mov ah,prstr ; Put statistics headers on the screen.
- mov dx,offset outlin
- int dos
- mov dx,offset cxzhlp
- call putmod ; write mode line
- mov wrpmsg,0 ; haven't printed the messsage yet.
- call init1
- ret
- INIT ENDP
-
- INIT1 PROC NEAR
- mov chrcnt,dmasiz ; Number of chars left.
- mov bufpnt,offset buff ; Addr for beginning.
- mov hierr,0
- ret
- INIT1 ENDP
-
- ; Output the chars in a packet.
-
- ; Called with AX = size of the data, BX = address of source.
-
- FILEIO PROC NEAR
- ptchr: mov cx,ax
- lea ax,outbufl ; Where to put data when buffer gets full.
- jmp decode
-
- ; CX = Size of data, BX = Address of data, AX = Routine to call to
- ; dump data.
-
- decode: push si
- push di
- push es
- push dx
- push ax
- mov ax,ds
- mov es,ax
- pop ax
- mov si,bx ; Source of data.
- mov bx,ax ; Coroutine to call.
- mov di,bufpnt ; Destination of data.
- mov dh,0 ; assume no quote char
- cmp trans.ebquot,'N' ; no quoting?
- je decod1 ; yes, keep going
- cmp trans.ebquot,'Y' ; or not doing it?
- je decod1 ; yes, keep going
- mov dh,trans.ebquot ; otherwise use quote char
-
- decod1: mov rptct,0 ; Reset.
- mov rptval,0 ; Ditto.
- dec cx
- jge dcod11 ; More data.
- jmp decod6 ; Else, we're through.
- dcod11: dec chrcnt ; Decrement number of chars in dta.
- jns decod2 ; Continue if space left.
- push cx
- push dx
- push bx
- call bx ; Output it if full.
- jmp decod5 ; Error return if disk is full.
- nop
- pop bx
- pop dx
- pop cx
- mov di,bufpnt
- decod2: cmp rptct,0 ; Doing a repeat?
- je dcod20 ; No, so go get a character.
- mov ah,0
- mov al,rptval ; Get the character we're repeating.
- jmp decod4 ; And write it out to the file.
- dcod20: lodsb ; Pick up a char.
- cmp rptq,0 ; Doing repeat quoting?
- je dcod21 ; Nope, skip this part.
- cmp al,rptq ; Did we pick up the repeat quote char?
- jne dcod21 ; No, continue processing it.
- lodsb ; Get the size.
- dec cx ; Modify buffer count.
- sub al,20H ; Was made printable.
- mov rptct,al ; Remember how many repetitions.
- lodsb ; Get the char to repeat.
- dec cx ; Modify buffer count.
- dcod21: mov ah,00H ; Assume no 8-bit quote char. [21b start]
- cmp al,dh ; This the 8-bit quot char?
- jne decod3
- lodsb ; Get the real character.
- dec cx ; Decrement # chars in packet
- mov ah,80H ; Turn on 8-bit quot char flag. [21b end]
- decod3: cmp al,trans.squote ; Is it the quote char? [21b] [21c]
- jne decod4 ; If not proceed.
- lodsb ; Get the quoted character
- dec cx ; Decrement # of chars in packet.
- or ah,al ; save parity (combine with prefix)
- and ah,80h ; only parity
- and al,7FH ; Turn off the parity bit.
- cmp al,trans.squote ; Is it the quote char? [21c]
- je decod4 ; If so just go write it out.
- cmp al,dh ; This the 8-bit quot char?
- je decod4 ; If so, just go write it out
- cmp al,rptq ; Is is the repeat quote character?
- je decod4 ; If so, just write it out.
- add al,40H ; Make it a control char again.
- and al,7FH ; Modulo 128.
- decod4: or al,ah ; or in parity
- stosb ; store the character
- dec rptct ; Repeat counter.
- cmp rptct,0 ; Write out char again?
- jg dcod41
- jmp decod1 ; No, get next char.
- dcod41: mov rptval,al ; Save the char.
- jmp dcod11 ; and loop to next char.
- decod5: pop bx
- pop dx ; dx is pushed twice (really)
- pop cx
- pop dx
- pop es
- pop di
- pop si
- ret
- decod6: mov bufpnt,di
- pop dx
- pop es
- pop di
- pop si
- jmp rskp ; Return successfully if done.
-
-
-
- ; output the buffer, reset bufpnt and chrcnt
-
- outbufl label word
- outbuf: cmp flags.xflg,1 ; Writing to screen? [21c]
- je outbf2 ; Yes, handle specially. [21c]
- push bx
- mov ah,writef ; The write code.
- mov dx,offset fcb
- int dos ; Write the record.
- pop bx
- cmp al,0 ; Successful.
- jz outbf1
- push ax ; Remember the return code. [20d]
- call abfil ; Fix things up before aborting. [20d]
- pop ax ; Retrive return code. [20d]
- cmp al,01
- jz outbf0
- call erpos
- mov ah,prstr
- mov dx,offset erms17 ; Record length exceeds dta.
- int dos
- ret
- outbf0: call erpos
- mov ah,prstr ; Tell about it.
- mov dx,offset erms11 ; Disk full error.
- int dos
- ret
- outbf1: add tfilsz+2,80H ; Say 128 more characters received.
- adc tfilsz,0
- call kbpr ; Print the kilobytes received.
- call perpr ; Print the percent ('?' for now).
- outb11: mov bufpnt,offset buff ; Addr for beginning.
- mov chrcnt,dmasiz-1 ; Buffer size.
- jmp rskp
- outbf2: mov cx,dmasiz-1 ; Number of chars to write. [21c]
- sub cx,chrcnt ; minus # of unused in buffer
- mov di,offset buff ; Where they are. [21c]
- call prtscr ; Output buffer to screen. [21c]
- jmp outb11 ; Reset counter & pointer. [21c]
-
- ; Tidy up before aborting. [20d]
- ABFIL PROC NEAR
- mov ah,closf ; Close the file.
- mov dx,offset fcb
- int dos
- cmp flags.abfflg,1 ; Delete what got across or keep it?
- jne abfil0 ; Nope, keep it.
- mov ah,delf ; Delete it.
- mov dx,offset fcb
- int dos
- abfil0: mov bx,offset erms10 ; Text of message to send.
- call errpack ; Send an error packet.
- ret
- ABFIL ENDP
-
- ; General routine for sending an error packet. Register BX should
- ; point to the text of the message being sent in the packet. [20f]
-
- ERRPACK PROC NEAR
- mov di,offset data ; Where to put the message.
- mov al,0
- errp1: mov ah,[bx]
- cmp ah,'$' ; At end of message?
- je errp2
- inc al ; Remember number of chars in msg.
- mov [di],ah
- inc bx
- inc di
- jmp errp1
- errp2: mov ah,0
- mov pack.argbk1,ax
- mov ah,'E' ; And send an error packet.
- call spack
- ret ; Return if succeed or fail.
- nop
- nop
- ret
- ERRPACK ENDP
-
- ; Get the chars from the file.
-
- gtchr: cmp flags.filflg,0 ; Is there anything in the DMA?
- jz gtchr0 ; Yup, proceed.
- 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 inbuf
- jmp gtchr1 ; No more chars, go return EOF.
- nop ; Make three bytes long.
- gtchr0: lea bx,inbufl
- jmp encode
- gtchr1: mov ax,0ffffh
- ret
-
- ; encode - writes data portion of kermit packet into filbuf.
- ; expects BX to contain the address of a routine to refill the buffer,
- ; chrcnt to be the # of chars in the buffer, trans.maxdat to contain
- ; the maximum size of the data packet, bufpnt to contain a pointer to
- ; the source of the characters.
- ; Returns: AX/ the number of characters actually written to the buffer.
-
- encode: mov cl,trans.maxdat ; Maximum packet size. [21b]
- mov ch,0
- mov di,offset filbuf ; Where to put the data.
- mov si,bufpnt ; pointer into source buffer
- mov dl,trans.rquote ; send quote char
- mov dh,0 ; assume no 8-bit quoting
- cmp trans.ebquot,'N' ; not doing 8-bit quoting
- je encod1
- cmp trans.ebquot,'Y' ; or can but won't?
- je encod1
- mov dh,0ffh ; remember we have to do it
- encod1: dec cx ; Decrement output buffer counter.
- jge encod2 ; Go on if there is more than one left.
- sub di,offset filbuf
- mov ax,di
- mov bufpnt,si ; update pointer into DMA.
- jmp rskp
- encod2: dec chrcnt ; any data in buffer?
- jge encod3 ; yes, skip over buffer refill.
- call bx ; Get another buffer full.
- jmp encod8
- mov si,bufpnt ; update position in DMA.
- cmp chrcnt,0 ; no characters returned?
- jne encod3 ; Got some, keep going.
- jmp encod8 ; none, assume eof.
- encod3: lodsb
- cmp rptq,0 ; Are we doing repeat prefixing?
- je encd3x ; Nope, skip next part.
- cmp chrcnt,0 ; Are we on the last character?
- jle encd31 ; Yes, so there's no next character.
- cmp rptct,94 ; Max number that we can put in a byte.
- je encd31 ; Then that's it.
- mov ah,[si] ; Get the next character.
- cmp al,ah ; Is current char == next char?
- jne encd31
- inc rptct ; Number of times char appears.
- mov rptval,al ; Remember the character.
- inc cx ; Repeats don't take up so much buffer space.
- jmp encod1 ; Keep checking for more.
- encd31: cmp rptct,1 ; Were previous characters repeats?
- je encd3x ; No, so just add this char.
- cmp rptct,rptmin ; Are we within bounds for repeat prefixing?
- jge encd32 ; Yes, use repeat prefixing.
- mov al,rptct
- mov ah,0
- sub si,ax ; Not enough characters to warrant it.
- mov rptval,0 ; Clear out this value.
- inc cx ; Adjust output buffer pointer.
- mov al,rptq
- mov origr,al ; Save original repeat prefix.
- mov rptq,0 ; Pretend we're not doing the prefixing.
- mov al,rptct
- mov ah,0
- add chrcnt,ax ; Adjust input buffer pointer.
- jmp encod1 ; Reprocess those characters.
- encd32: push ax ; Do repeat prefixing - save data.
- mov al,rptq ; Add repeat prefix char.
- stosb
- dec cx ; Account for it in buffer size.
- mov al,rptct ; Get the repeat count.
- add al,20H ; Make it printable.
- stosb ; Add to buffer.
- dec cx
- pop ax ; Get back the actual character.
- mov rptct,1 ; Reset repeat count.
- mov rptval,0 ; And this.
- encd3x: cmp dh,0 ; are we doing 8-bit quoting?
- je encod4 ; no, forget this.
- test al,80h ; parity on?
- je encod4 ; no, don't bother with this
- and al,7fh ; turn off parity
- push ax ; save original char for a bit
- dec cx ; decrement # of chars left
- mov al,trans.ebquot ; get quote char
- stosb ; save in buffer
- pop ax ; restore character
- encod4: mov ah,al ; save character
- and ah,80h ; only parity
- and al,7fh ; turn off parity in character
- cmp al,' ' ; Compare to a space.
- jl encod5 ; If less then its a control char.
- cmp al,del ; Is the char a delete?
- jz encod5 ; Go quote it.
- cmp al,dl ; Is it the quote char?
- je encod6 ; Yes - go add it. [21b start]
- cmp dh,0 ; are we doing 8-bit quoting?
- je encd41 ; no, don't translate it
- cmp al,trans.ebquot ; Is it the 8-bit quote char?
- je encod6 ; Yes, just output with quote
- encd41: cmp origr,0 ; Doing repeat prefixing?
- je encod7 ; No, don't check for quote char.
- cmp al,origr ; Is this the repeat quote character.
- je encod6 ; Yes, then quote it.
- jmp short encod7 ; else don't quote it.
- encod5: add al,40h ; control char, uncontrollify
- and al,7fh
- encod6: push ax ; save the char
- dec cx
- mov al,dl
- stosb
- pop ax
- encod7: or al,ah ; put parity back
- stosb
- cmp rptct,1 ; One occurence of this char?
- jne encd7x
- mov al,origr
- mov rptq,al ; Restore repeat quote char.
- jmp encod1 ; Yes, so loop around for some more.
- encd7x: dec rptct ; Add another entry of this char.
- jmp encod1 ; With quoting and all.
-
- encod8: sub di,offset filbuf
- or di,di
- je encod9 ; Nope.
- mov ax,di
- jmp rskp
- encod9: mov ax,0FFFFH ; Get a minus one.
- ret
-
-
- inbufl label word
- inbuf: mov ah,flags.eoflag ; Have we reached the end?
- cmp ah,0
- jz inbuf0
- ret ; Return if set.
- inbuf0: push si
- push di
- push dx
- push bx
- push cx
- mov bx,offset buff ; Set the r/w buffer pointer.
- mov bufpnt,bx
- mov ah,readf ; Read a record.
- mov dx,offset fcb
- int dos
- mov cx,filsiz
- cmp cx,0 ; Check for 128 chars or less left.
- jne inbuf1 ; Still have data left.
- mov ax,ds
- mov es,ax
- mov si,offset filsiz+2
- mov di,offset bufhex
- cmps filsiz+2,es:bufhex
- ja inbuf1 ; More than 128 chars.
- mov flags.eoflag,0FFH ; Set End-of-file.
- mov cx,filsiz+2
- cmp flags.filflg,0 ; Ever used DMA? [25]
- jnz inbf01
- dec cx ; Account for DEC in caller routine.
- inbf01: mov chrcnt,cx ; Return proper number of chars.
- mov flags.filflg,0 ; Buffer not empty.
- pop cx
- pop bx
- pop dx
- pop di
- pop si
- jmp rskp
- inbuf1: sub filsiz+2,80H ; Sent another 128 chars.
- sbb filsiz,0 ; Account for the doubleword.
- add tfilsz+2,80H ; Book keeping for the same.
- adc tfilsz,0
- push ax
- call kbpr ; Print the kilobytes sent.
- call perpr ; Print the percent sent.
- pop ax
- mov al,80H ; Use as counter for number of chars read.
- pop cx
- pop bx
- pop dx
- pop di
- pop si
- cmp flags.filflg,0 ; Ever used DMA?
- jnz inbf21 ; Nope, then don't change count.
- dec al ; Fix boundary error.
- inbf21: mov ah,0 ; Zero the flag (buffer not empty).
- mov chrcnt,ax ; Number of chars read from file.
- mov flags.filflg,0 ; Buffer not empty.
- jmp rskp
-
- nulref: mov chrcnt,0 ; No data to return.
- jmp rskp
-
- nulr: ret
-
- ; Print the number of Kilobytes transferred.
-
- kbpr: cmp flags.remflg,0 ; remote mode?
- jne kbpr1 ; yes, no printing.
- mov ax,tfilsz+2
- mov bx,tfilsz
- mov cl,10
- shr ax,cl ; divide by 1024
- mov cl,6 ; high order moves 16-10 = 6 bits
- shl bx,cl
- or ax,bx
- cmp ax,oldkbt ; is it the same?
- je kbpr1 ; yes, skip printing
- mov oldkbt,ax ; save new # of kb
- push ax
- call kbpos ; Postion the cursor.
- pop ax
- call nout ; Print the number of KBytes transferred.
- kbpr1: ret
-
- ; Print the percent transferred.
-
- perpr: cmp flags.remflg,0 ; remote mode?
- jne perpr5 ; yes, no printing.
- mov ax,tfilsz
- or ax,tfilsz+2
- cmp ax,oldper ; same as it was before?
- je perpr5 ; yes, don't bother printing.
- mov oldper,ax ; remember this for next time
- cmp ofilsz,0 ; No divide by zeroes.
- je perpr5 ; If not proceed.
- cmp wrpmsg,0 ; did we write the percentage message?
- jne perpr1 ; yes, skip this part
- call perpos ; position cursor
- mov dx,offset permsg
- mov ah,prstr
- int dos ; write out message
- mov wrpmsg,1 ; init flag so we don't do it again
- perpr1: call perpos ; Position the cursor.
- perpr2: mov dx,tfilsz ; Get the high order word.
- mov ax,tfilsz+2 ; Get the low order word.
- div ofilsz ; Div by percent adjusted original file size.
- cmp ax,100 ; > 100% ?
- jle perpr3 ; no, accept it
- mov ax,100 ; else just use 100
- perpr3: call nout
- mov dl,'%' ; Load a percent sign.
- perpr4: mov ah,conout ; Print the character.
- int dos
- perpr5: ret
-
- getfil: mov ah,0FFH
- mov flags.filflg,ah ; Nothing in the DMA.
- mov ax,0
- mov flags.eoflag,ah ; Not the end of file.
- mov bx,offset fcb+0CH
- mov [bx],ax ; Zero the current block number.
- mov bx,offset fcb+0EH
- mov [bx],ax ; Ditto for Lrecl.
- mov bx,offset fcb+20H
- mov [bx],ah ; Zero the current record (of block).
- inc bx
- mov [bx],ax ; Same for record (of file).
- mov bx,offset fcb+23H
- mov [bx],ax
- mov ah,openf ; Open the file.
- mov dx,offset fcb
- int dos
- mov dx,word ptr fcb+18 ; get file size (hi order word)
- mov filsiz,dx
- mov ax,word ptr fcb+16 ; lo order word
- mov filsiz+2,ax
- div percnt ; Divide by 100.
- mov ofilsz,ax
- mov tfilsz,0 ; Set bytes sent to zero.
- mov tfilsz+2,0
- mov oldkbt,-1
- mov oldper,-1
- cmp filsiz,0 ; Null file?
- jne getfl0 ; Nope.
- cmp filsiz+2,0 ; Null file?
- jne getfl0 ; Nope.
- mov flags.eoflag,0FFH ; Set EOF.
- getfl0: jmp rskp
-
-
- gtnfil: cmp flags.cxzflg,'Z' ; Did we have a ^Z? [20b]
- je gtn5 ; If yes, we're done sending files. [20b]
- cmp flags.wldflg,0 ; Was there a "*"? [7 start]
- je gtn5 ; Nope.
- mov bx,offset cpfcb ; Get FCB from last check for file.
- mov di,offset fcb ; Copy to FCB.
- mov cl,37 ; Size of FCB.
- call fcbcpy
- gtn2: mov ah,snext
- mov dx,offset fcb ; More files?
- int dos
- cmp al,0FFH
- je gtn5
- mov bx,offset fcb
- mov di,offset cpfcb
- mov cl,37
- call fcbcpy ; Copy from FCB.
- mov di,offset fcb+1 ; Get name of next file to send.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy
- call getfil ; Initialize
- jmp r
- jmp rskp
- gtn5: mov flags.wldflg,0 ; Reset wild card flag.
- ret ; [7 end]
-
-
- ; Get the file name (including host to micro translation)
-
- gofil: cmp flags.xflg,1 ; Remote command? [21c]
- jne goflx ; No.... [21c]
- jmp gofla ; Yes so skip this stuff. [21c]
- goflx: cmp flags.nmoflg,1 ; Overriding name from other side? [21a]
- jne gofil0 ; No - get the filename. [21a]
- jmp gofil7 ; Yes, so ignore packet contents. [21a]
- gofil0: mov bx,offset data ; Get the address of the file name. [21a]
- mov fdtpnt,bx ; Store the address.
- mov bx,offset fcb+1 ; Address of the FCB.
- mov fcbptr,bx ; Save it.
- mov ax,0
- mov temp1,ax ; Initialize the char count.
- mov temp2,ax
- cmp flags.droflg,1 ; Default drive? [21a]
- je gofil1 ; No - don't blank out value in FCB. [21a]
- mov si,offset fcb
- mov [si],ah ; Set the drive to default to current.
- gofil1: mov ch,' ' ; Moved the label. [21a]
- mov [bx],ch ; Blank the FCB.
- inc bx
- inc ah
- cmp ah,0BH ; Twelve?
- jl gofil1
- gofil2: mov bx,fdtpnt ; Get the NAME field.
- mov ah,[bx]
- inc bx
- mov fdtpnt,bx
- cmp ah,'.' ; Seperator?
- jne gofil3
- mov bx,offset fcb+9H
- mov fcbptr,bx
- mov ax,temp1
- mov temp2,ax
- mov temp1,9H
- jmp gofil6
- gofil3: cmp ah,0 ; Trailing null?
- jz gofil7 ; Then we're done.
- call verlet ; Verify that the char is legal.
- mov bx,fcbptr
- mov [bx],ah
- inc bx
- mov fcbptr,bx
- mov ax,temp1 ; Get the char count.
- inc ax
- mov temp1,ax
- cmp ax,8H ; Are we finished with this field?
- jl gofil2
- gofil4: mov temp2,ax
- mov bx,fdtpnt
- mov ah,[bx]
- inc bx
- mov fdtpnt,bx
- cmp ah,0
- jz gofil7
- cmp ah,'.' ; Is this the terminator?
- jne gofil4 ; Go until we find it.
- gofil6: mov bx,fdtpnt ; Get the TYPE field.
- mov ah,[bx]
- inc bx
- mov fdtpnt,bx
- cmp ah,0 ; Trailing null?
- jz gofil7 ; Then we're done.
- call verlet ; Verify that the char is legal.
- mov bx,fcbptr
- mov [bx],ah
- inc bx
- mov fcbptr,bx
- inc temp1 ; Increment char count.
- cmp temp1,0CH ; Are we finished with this field?
- jl gofil6
- gofil7: cmp flags.remflg,0 ; remote mode?
- jne gofil7a ; yes, don't print it.
- call prtfn ; Print the file name. [21a]
- gofil7a:cmp flags.destflg,0 ; Writing to the printer?
- jne gf7y
- push es
- mov ax,ds
- mov es,ax ; Set this up.
- mov cx,11
- mov si,offset printer
- mov di,offset fcb
- repne movsb ; Change name in FCB to be printer.
- pop es
- jmp gofil9
- gf7y: mov ah,flags.flwflg ; Is file warning on?
- cmp ah,0
- jnz gf7x
- jmp gofil9 ; If not, just proceed.
- gf7x: mov ah,openf ; See if the file exists.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Does it exist?
- jnz gf8x
- jmp gofil9 ; If not create it.
- gf8x: cmp flags.remflg,0 ; remote mode?
- jne gf8xa ; yes, skip printing
- call frpos ; Position cursor.
- mov ah,prstr ; Inform the user we are renaming the file.
- mov dx,offset infms5
- int dos
- gf8xa: mov ax,temp2 ; Get the number of chars in the file name.
- cmp ax,0
- jne gofil8
- mov ax,temp1
- mov temp2,ax
- gofil8: mov ch,0
- mov cl,al
- mov al,0 ; Says if first field is full.
- cmp cl,9H ; Is the first field full?
- jne gofl81
- mov al,0FFH ; Set a flag saying so.
- dec cl
- gofl81: mov bx,offset fcb ; Get the FCB.
- add bx,cx ; Add in the character number.
- mov ah,'&'
- mov [bx],ah ; Replace the char with an ampersand.
- push ax
- push bx
- mov ah,openf ; See if the file exists.
- mov dx,offset fcb
- int dos
- pop bx
- cmp al,0FFH ; Does it exist?
- pop ax
- jz gofl89 ; If not create it.
- cmp al,0 ; Get the flag.
- jz gofl83
- dec cl ; Decrement the number of chars.
- cmp cl,0
- jz gofl88 ; If no more, die.
- jmp gofl81
- gofl83: inc cl ; Increment the number of chars.
- cmp cl,9H ; Are we to the end?
- jl gofl81 ; If not try again ; else fail.
-
- gofl88: cmp flags.remflg,0 ; remote mode?
- jne gofl88a ; yes, no printing
- call erpos ; Position cursor.
- mov ah,prstr ; Tell the user that we can't rename it.
- mov dx,offset ermes4
- int dos
- gofl88a:mov bx,dx ; Tell host can't rename. [20f]
- call errpack ; Send error packet before abort. [20f]
- ret
-
- gofl89: cmp flags.remflg,0 ; remote mode
- jne gofil9 ; yes, don't have to print it
- mov bx,offset fcb+0CH ; Point past the end of the file name.
- mov dh,[bx] ; Save the present contents.
- mov ah,'$'
- mov [bx],ah ; Put in a dollar sign.
- push dx
- mov ah,prstr ; Print the file name.
- mov dx,offset fcb+1
- int dos
- pop dx
- mov bx,offset fcb+0CH ; Restore over the dollar sign.
- mov [bx],dh
- gofil9: mov ah,delf ; Delete the file if it exists.
- mov dx,offset fcb
- int dos
- mov ax,0
- mov si,offset fcb+0CH
- mov [si],ax ; Zero current block.
- mov si,offset fcb+0EH
- mov [si],ax ; Same for Lrecl.
- mov si,offset fcb+20H
- mov [si],ah ; Zero the current record (within block).
- inc si
- mov [si],ax ; Zero record (within file).
- mov si,offset fcb+23H
- mov [si],ax
- mov ofilsz,0 ; File size unknown.
- mov tfilsz,0 ; Set bytes received to zero.
- mov tfilsz+2,0
- mov oldkbt,-1
- mov oldper,-1
- mov ah,makef ; Now create it.
- mov dx,offset fcb
- int dos
- cmp al,0FFH ; Is the disk full?
- je gf9x
- jmp rskp
- gf9x: cmp flags.remflg,0 ; remote mode?
- jne gf9xa ; yes, don't try printing
- call erpos ; Position cursor.
- mov ah,prstr ; If so tell the user.
- mov dx,offset erms12
- int dos
- mov bx,dx
- gf9xa: call errpack ; Send an error packet.
- ret
- gofla: cmp pack.argbk1,0 ; Any data in "X" packet? [21c start]
- je gofla1 ; Nothing to print.
- mov ah,prstr
- mov dx,offset crlf
- int dos
- mov di,offset data ; Where data is.
- mov cx,pack.argbk1 ; How much data we have.
- call prtscr ; Print it on the screen.
- gofla1: mov ah,prstr
- mov dx,offset crlf
- int dos
- jmp rskp ; And done. [21c end]
- FILEIO ENDP
-
- ; Passed char of incoming filename in AH. Verify that it is legal
- ; and if not change it to an "X".
- verlet: cmp ah,'0'
- jl ver2 ; See if it's a legal weird char.
- cmp ah,'z'+1
- jns ver2
- cmp ah,'9'
- jle ver1 ; It's between 0-9 so it's OK.
- cmp ah,'A'
- jl ver2 ; Coud be a weird char.
- cmp ah,'Z'
- jle ver1 ; It's A-Z so it's OK.
- cmp ah,'a'
- jl ver2
- and ah,137O ; It's a-z, capitalize.
- ver1: ret
-
- ver2: push es
- mov cx,ds
- mov es,cx ; Scan uses ES register.
- mov di,offset spchar ; Special chars.
- mov cx,spclen ; How many of them.
- cmp dosnum,0 ; Under version 2.0
- je ver3
- mov di,offset spchar2
- mov cx,spc2len
- ver3: mov al,ah ; Char is in al.
- repnz scasb ; Search string for input char.
- pop es
- mov ah,al ; Return it in AH.
- cmp cx,0 ; Was it there?
- jnz ver1 ; Yes, return it.
- mov ah,'X' ; If illegal, replace with "X".
- mov flags.nmoflg,1
- ret
-
- ; Print incoming filename(s). [21a]
- PRTFN PROC NEAR
- call clrfln ; Position cursor & blank out the line.
- mov di,offset data ; Where to put the name.
- mov bx,offset fcb ; Where it is now.
- cmp flags.droflg,0 ; Drive specified?
- je prtfn1
- mov dl,[bx] ; Which one did they say?
- add dl,'@' ; Make it readable.
- mov ah,dconio ; Print the drive name.
- int dos
- mov dl,':'
- int dos
- prtfn1: inc bx ; Point to start of filename.
- cmp flags.nmoflg,0 ; Is filename in packet?
- je prtfn2 ; no, keep going
- add di,pack.argbk1 ; bump by length of remote name
- mov si,offset asmsg ; something to put after it
- mov cx,asmln ; length of it
- rep movsb ; add this to the buffer
- prtfn2: mov cx,8 ; At most 8 letters in file name.
- mov si,bx ; this is source now
- prtfn3: lodsb ; get a letter
- cmp al,' ' ; Done with name?
- je prtfn4 ; yes, continue
- stosb ; else store
- loop prtfn3 ; and loop thru rest
- prtfn4: mov si,offset fcb+9 ; Point to file type.
- cmp byte ptr [si],' ' ; is there a type?
- je prtfn5 ; Nope so we're done.
- mov al,'.' ; Add the dot.
- stosb
- mov cx,3 ; At most 3 letters in file type.
- rep movsb ; copy type (incl trailing spaces)
- prtfn5: mov byte ptr [di],'$' ; end the string
- mov ah,prstr ; Print the file name.
- mov dx,offset data
- int dos
- mov flags.droflg,0 ; Reset flag once have the full name.
- mov flags.nmoflg,0
- ret
- PRTFN ENDP
-
- ; Print data onto the screen. If text has no "$" in it, just print
- ; it. Else, do special output for the "$".
- ; Routine expects: DI = Start of buffer we are to print.
- ; CX = Number of characters to print. [21c]
-
- PRTSCR PROC NEAR
- mov al,'$' ; This is what we're looking for.
- mov oloc,di ; Remember original buffer address.
- mov osiz,cx ; And original size.
- push es
- mov bx,ds
- mov es,bx ; Have ES point to data area.
- prts0: repnz scasb ; Search for "$" in the buffer.
- cmp cx,0 ; Found one?
- je prts1 ; No, do a regular DOS call.
- mov ah,prstr
- mov dx,oloc ; Print up to the "$".
- int dos
- mov ah,dconio
- mov dl,'$'
- int dos ; Print the "$"
- mov oloc,di ; New starting location.
- mov osiz,cx ; New size.
- jmp prts0
- prts1: mov bx,oloc ; The buffer location.
- add bx,osiz ; Point past the data.
- mov [bx],al ; Add "$" for printing.
- mov ah,prstr
- mov dx,oloc
- int dos
- pop es
- ret
- PRTSCR ENDP
-
- FIXFCB PROC NEAR
- push ax ; Don't forget this. [22]
- mov bx,offset fcb+18
- mov di,offset filsiz
- mov ax,[bx]
- mov [di],ax
- mov bx,offset fcb+16
- mov ax,[bx]
- mov 2[di],ax
- pop ax ; Get number of chars in last buffer full. [22]
- sub filsiz+2,ax ; Get real file size.
- sbb filsiz,0
- mov bx,offset fcb+18
- mov di,offset filsiz
- mov ax,[di]
- mov [bx],ax
- mov bx,offset fcb+16
- mov ax,2[di]
- mov [bx],ax
- ret
- FIXFCB 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