; begin kermit3.asm [18]

;       Send command
 
SEND    PROC    NEAR
        mov ah,cmifi            ; Parse an input file spec.
        mov dx,offset fcb       ; Give the address for the FCB.
        call comnd
         jmp r                  ;  Give up on bad parse.
send1:  mov ah,cmcfm
        call comnd              ; Get a confirm.
         jmp r                  ;  Didn't get a confirm.
send11: mov ah,sfirst           ; Get the first file.
        mov dx,offset fcb
        int dos
        cmp al,0FFH             ; Any found?
        jne send12
	mov ah,prstr
	mov dx,offset crlf
	int dos
        mov ah,prstr
        mov dx,offset erms15
        int dos
        ret
send12: cmp 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 init               ; Clear the line and initialize the buffers.
	call serini		; Initialize serial port. [14]
        mov pktnum,0            ; Set the packet number to zero.
        mov numtry,0            ; Set the number of tries to zero.
        mov numpkt,0            ; Set the number of packets to zero.
        mov numrtr,0            ; Set the number of retries to zero.
        call rtpos              ; Position cursor.
        mov ax,0
        call nout               ; Write the number of retries.
        mov state,'S'           ; Set the state to receive initiate.
send2:  
IF ibmpc 
	mov ah,2                ; Position cursor.
	mov bh,0
	mov dx,scrst
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get print string function
	mov dx,offset scrst	; and string to move cursor
	int dos			; Print the string
ENDIF
        mov ah,prstr            ; Be informative.
        mov dx,offset infms2
        int dos
IF ibmpc
	mov ah,2
	mov dx,scrnp
	mov bh,0
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get print string function
	mov dx,offset scrnp	; and string to move cursor
	int dos			; Print the string
ENDIF
        mov ax,numpkt
        call nout               ; Write the packet number.
        cmp state,'D'           ; Are we in the data send state?
        jne send3
        call sdata
        jmp send2
send3:  cmp state,'F'           ; Are we in the file send state?
        jne send4
        call sfile              ; Call send file.
        jmp send2
send4:  cmp state,'Z'           ; Are we in the EOF state?
        jne send5
        call seof
        jmp send2
send5:  cmp state,'S'           ; Are we in the send initiate state?
        jne send6
        call sinit
        jmp send2
send6:  cmp state,'B'           ; Are we in the eot state?
        jne send7
        call seot
        jmp send2
send7:  cmp state,'C'           ; Are we in the send complete state?
        jne send8
	call serrst		; Reset serial port.  [14]
IF ibmpc
	mov ah,2                ; Position cursor.
	mov dx,scrst
	mov bh,0
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get print string function
	mov dx,offset scrst	; and string to move cursor
	int dos			; Print the string
ENDIF
        mov ah,prstr
        mov dx,offset infms3    ; Plus a little cuteness.
        int dos
	cmp belflg,0		; Bell desired? [17a]
	je sendnb		; [17a]
	mov dx,offset ender	; Ring them bells.   [4]
	int dos			;  [4]
sendnb:				; [17a -- new label] 
IF ibmpc
	mov ah,2
	mov dx,scrrpr
	mov bh,0
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get print string function
	mov dx,offset scrrpr	; and string to move cursor
	int dos			; Print the string
ENDIF
        jmp rskp
send8: 	call serrst		; Reset serial port.  [14]
IF ibmpc
	mov ah,2                ; Position cursor.
	mov dx,scrst
	mov bh,0
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get print string function
	mov dx,offset scrst	; and string to move cursor
	int dos			; Print the string
ENDIF
        mov ah,prstr
        mov dx,offset infms4    ; Plus a little cuteness.
        int dos
	mov dx,offset ender	; Ring them bells.   [4]
	int dos			;  [4]
IF ibmpc
	mov ah,2
	mov dx,scrrpr
	mov bh,0
	int bios
ENDIF
IF Z100
	mov ah,prstr		; Get print string function
	mov dx,offset scrrpr	; and string to move cursor
	int dos			; Print the string
ENDIF
        jmp rskp
SEND    ENDP
 
 
;       Send routines
 
;       Send initiate
 

SINIT   PROC    NEAR
        cmp 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.
        jmp abort               ; Change the state to abort.
sinit2: inc 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 argbk1,ax           ; Save the number of arguments.
        mov ax,numpkt           ; Get the packet number.
        mov argblk,ax
        mov ah,'S'              ; Send initiate packet.
        call spack              ; Send the packet.
	 jmp abort
        call rpack              ; Get a packet.
         jmp r                  ;  Trashed packet don't change state, retry.
        cmp ah,'Y'              ; ACK?
        jne sinit3              ; If not try next.
        mov ax,pktnum           ; Get the packet number.
        cmp ax,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 pktnum,ax           ; Save modulo 64 of the number.
        inc numpkt              ; Increment the number of packets.
        mov ax,argbk1           ; Get the number of pieces of data.
        mov bx,offset data      ; Pointer to the data.
        call spar               ; Read in the data.
        mov ah,numtry           ; Get the number of tries.
        mov oldtry,ah           ; Save it.
        mov numtry,0            ; Reset the number of tries.
        mov state,'F'           ; Set the state to file send.
        call getfil             ; Open the file.
         jmp abort              ;  Something is wrong, die.
        ret
sinit3: cmp ah,'N'              ; NAK?
        jne sinit4              ; If not see if its an error.
        call rtpos              ; Position cursor.
        inc numrtr              ; Increment the number of retries
        mov ax,numrtr
        call nout               ; Write the number of retries.
        mov ax,pktnum           ; Get the present packet number.
        inc ax                  ; Increment.
        cmp ax,argblk           ; Get the packet's number.
        je sini32
        ret                     ; If not assume its for this packet, go again.
sini32: mov numtry,0            ; Reset number of tries.
        mov state,'F'           ; Set the state to file send.
        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 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.
        jmp abort               ; Change the state to abort.
sfile1: inc numtry              ; Increment it.
        mov datptr,offset data  ; Get a pointer to our data block.
	mov bx,offset fcb+1		; Pointer to file name in FCB.
	mov fcbptr,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,fcbptr
	mov ah,[bx]		; Get char of filename.
	inc bx
	mov fcbptr,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
	mov argbk1,cx		; Save number of char in filename.
	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

        mov ax,pktnum           ; Get the packet number.
        mov argblk,ax
        mov ah,'F'              ; File header packet.
        call spack              ; Send the packet.
	 jmp abort
        call rpack              ; Get a packet.
         jmp r                  ;  Trashed packet don't change state, retry.
        cmp ah,'Y'              ; ACK?
        jne sfile2              ; If not try next.
        mov ax,pktnum           ; Get the packet number.
        cmp ax,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 pktnum,ax           ; Save modulo 64 of the number.
        inc numpkt              ; Increment the number of packets.
        mov ah,numtry           ; Get the number of tries.
        mov oldtry,ah           ; Save it.
        mov 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 eoflag,ah           ; Indicate not EOF.
        mov ah,0FFH
        mov filflg,ah           ; Indicate file buffer empty.
        call gtchr
         jmp sfil16             ; Error go see if its EOF.
        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 state,ah
        ret
sfil17: mov siz,ax

        mov 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 numrtr              ; Increment the number of retries
        mov ax,numrtr
        call nout               ; Write the number of retries.
        mov ax,pktnum           ; Get the present packet number.
        inc ax                  ; Increment.
        cmp ax,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 numtry,maxtry       ; Have we reached the maximum number of tries?
        jl sdata1
	call erpos
        mov dx,offset erms14
        mov ah,prstr
        int dos                 ; Print an error message.
        jmp abort               ; Change the state to abort.
sdata1: inc numtry              ; Increment it.
        mov datptr,offset data  ; Get a pointer to our data block.
        mov cbfptr,offset filbuf ; Pointer to chars to be sent.
        mov cx,1                ; First char.
sdat11: mov bx,cbfptr
        mov ah,[bx]
        inc cbfptr
        mov bx,datptr
        mov [bx],ah             ; Put the char in the data packet.
        inc datptr              ; Save position in data packet.
        inc cx                  ; Increment the count.
        cmp cx,siz              ; Have we transfered that many?
        jle sdat11              ; If not get another.
        mov ax,siz              ; Number of char in char buffer.
        mov argbk1,ax
        mov ax,pktnum           ; Get the packet number.
        mov argblk,ax
        mov ah,'D'              ; Data packet.
        call spack              ; Send the packet.
	 jmp abort
        call rpack              ; Get a packet.
         jmp r                  ;  Trashed packet don't change state, retry.
        cmp ah,'Y'              ; ACK?
        jne sdata2              ; If not try next.
        mov ax,pktnum           ; Get the packet number.
        cmp ax,argblk           ; Is it the right packet number?
        jz sdat12
        ret                     ; If not hold out for the right one.
sdat12: inc ax                  ; Increment the packet number.
        and ax,3FH              ; Turn off the two high order bits.
        mov pktnum,ax           ; Save modulo 64 of the number.
        inc numpkt              ; Increment the number of packets.
        mov ah,numtry           ; Get the number of tries.
        mov oldtry,ah           ; Save it.
        mov numtry,0            ; Reset the number of tries.
        call gtchr
         jmp sdat13             ; Error go see if its EOF.
        mov siz,ax              ; Save the size of the data gotten.
        ret

sdat13: cmp ah,0FFH             ; Is it EOF?
        je sdt131
        jmp abort               ; If not give up.

sdt131: mov state,'Z'           ; Set the state to EOF.
        ret
sdata2: cmp ah,'N'              ; NAK?
        jne sdata3              ; See if is an error packet.
        call rtpos	        ; Position cursor.
        inc numrtr              ; Increment the number of retries
        mov ax,numrtr
        call nout               ; Write the number of retries.
        mov ax,pktnum           ; Get the present packet number.
        inc ax                  ; Increment.
        cmp ax,argblk           ; Is the packet's number one more than now?
        jz sdat12               ; Just as good as ACK; goto ACK code.
        ret                     ; If not go try again.
sdata3: cmp ah,'E'              ; Is it an error packet.
        jne sdata4
        call error
sdata4: jmp abort
SDATA   ENDP
 
 
;       Send EOF
 
SEOF    PROC    NEAR
        cmp 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.
        jmp abort               ; Change the state to abort.
seof1:  inc numtry              ; Increment it.
        mov ax,pktnum           ; Get the packet number.
        mov argblk,ax
        mov argbk1,0            ; No data.
        mov ah,'Z'              ; EOF packet.
        call spack              ; Send the packet.
	 jmp abort
        call rpack              ; Get a packet.
         jmp r                  ;  Trashed packet don't change state, retry.
        cmp ah,'Y'              ; ACK?
        jne seof2               ; If not try next.
        mov ax,pktnum           ; Get the packet number.
        cmp ax,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 pktnum,ax           ; Save modulo 64 of the number.
        inc numpkt              ; Increment the number of packets.
        mov ah,numtry           ; Get the number of tries.
        mov oldtry,ah           ; Save it.
        mov 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 state,'F'           ; Set the state to file send.
        ret
seof13: mov 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 numrtr              ; Increment the number of retries
        mov ax,numrtr
        call nout               ; Write the number of retries.
        mov ax,pktnum           ; Get the present packet number.
        inc ax                  ; Increment.
        cmp ax,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 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.
        jmp abort               ; Change the state to abort.
seot1:  inc numtry              ; Increment it.
        mov ax,pktnum           ; Get the packet number.
        mov argblk,ax
        mov argbk1,0            ; No data.
        mov ah,'B'              ; EOF packet.
        call spack              ; Send the packet.
	 jmp abort
        call rpack              ; Get a packet.
         jmp r                  ; Trashed packet don't change state, retry.
        cmp ah,'Y'              ; ACK?
        jne seot2               ; If not try next.
        mov ax,pktnum           ; Get the packet number.
        cmp ax,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 pktnum,ax           ; Save modulo 64 of the number.
        inc numpkt              ; Increment the number of packets.
        mov ah,numtry           ; Get the number of tries.
        mov oldtry,ah           ; Save it.
        mov numtry,0            ; Reset the number of tries.
        mov state,'C'           ; Set the state to file send.
        ret
seot2:  cmp ah,'N'              ; NAK?
        jne seot3               ; Is it error.
        call rtpos              ; Position cursor.
        inc numrtr              ; Increment the number of retries
        mov ax,numrtr
        call nout               ; Write the number of retries.
        mov ax,pktnum           ; Get the present packet number.
        inc ax                  ; Increment.
        cmp ax,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
; end kermit3.asm [18]
e reached the maximum number of tries?
        jl rdat12               ; If not proceed.
	call erpos              ; Position 