; File MSSRCV.ASM
; Edit history
; [2.29] [jrd]
; [2.28 jrd]
; Defeat addition of extra ^Z to printer output at EOF; solves problem
; of repeated printing of last packet.
; Remove all DOS 1.x code
; General clean up.
; Joe R. Doupnik  4 Oct 1985
; Add tests on remote mode status to suppress screen messages if mode=remote.
; Add check for file still open after ^C, code is near read60:.
; Joe R. Doupnik 29 Dec 1985
;
        public  read12, read2, rin21, rfile3, read, updrtr, nak, rrinit
        include mssdef.h

datas   segment public 'datas'
        extrn   data:byte, bufpnt:word, chrcnt:word, curchk:byte
        extrn   comand:byte, flags:byte, pack:byte, trans:byte
        extrn   diskio:byte, locfil:byte

ermes7  db      '?Unable to receive initiate$'
ermes8  db      '?Unable to receive file name$'
ermes9  db      '?Unable to receive end of file$'
erms10  db      '?Unable to receive data$'
infms1  db      cr,'           Receiving: In progress$'
infms3  db      'Completed$'
infms4  db      'Failed$'
infms6  db      'Interrupted$'
remmsg1 db      'Kermit-MS: Invalid filename'
filhlp2 db      ' Local path or filename or carriage return$'
ender   db      bell,bell,'$'
temp    dw      0
filopn  db      0               ; Says if disk file is open.
datas   ends

code    segment public
        extrn   gofil:near, outbuf:near, comnd:near
        extrn   spack:near, rpack:near, serini:near, serrst:near
        extrn   spar:near, rpar:near, init:near, init1:near, cxmsg:near
        extrn   error:near, ptchr:near, erpos:near, rtpos:near
        extrn   stpos:near, rprpos:near, nppos:near, nout:near
        extrn   dodec:near, doenc:near, errpack:near
        extrn   send11:near, clrmod:near
        assume  cs:code, ds:datas


; Update retry count and fall through to send a NAK.
nak0:   call updrtr             ; Update retry count.

nak:    mov ax,pack.pktnum     ; Get the packet number we're waiting for.
        mov pack.argblk,ax
        mov pack.argbk1,0
        mov cx,0                ; No data, but this may change.
        call doenc              ; So call encode.
        mov ah,'N'              ; NAK that packet.
        call spack
         jmp abort
         nop                    ; So 'jmp rskp' in SPACK comes here. [19a]
        ret                     ; Go around again.

updrtr: cmp pack.state,'A'      ; Supposed to abort?
        je upd0                 ; Yes, don't bother with retry count.
        inc pack.numrtr         ; Increment the number of retries.
        cmp flags.xflg,1        ; Writing to screen?
        je upd0
        cmp flags.remflg,0      ; In Remote mode? [jrd]
        jne upd0                ; ne = yes. Don't write to screen. [jrd]
        call rtpos              ; Position cursor.
        mov ax,pack.numrtr
        call nout               ; Write the number of retries.
upd0:   ret

;       Abort
ABORT   PROC    NEAR
        cmp filopn,0            ; Disk file open?
        je abort0               ; e = no so don't close.
        cmp flags.xflg,1        ; Writing to the screen?
        je abort0               ; Yes, don't close "file".
        mov ah,close2           ; DOS 2.0 file close [jrd]
        push bx                 ; [jrd]
        mov bx,diskio.handle    ; file handle [jrd]
        int dos
        pop bx                  ; [jrd]
        mov filopn,0            ; say file is no longer open
        cmp flags.abfflg,0      ; save file after closing?
        je abort0               ; e = yes
        push dx
        mov dx,offset diskio.string     ; get back file name
        mov ah,del2             ; delete the file
        int dos
        pop dx
abort0: mov pack.state,'A'      ; Otherwise abort.
        ret
ABORT   ENDP

; init variables for read...
rrinit  proc    near
        mov pack.numpkt,0       ; Set the number of packets to zero.
        mov pack.numrtr,0       ; Set the number of retries to zero.
        mov pack.pktnum,0       ; Set the packet number to zero.
        mov pack.numtry,0       ; Set the number of tries to zero.
        ret
rrinit  endp

;       RECEIVE command  --  Some code moved to the GET routine. [21a]

READ    PROC    NEAR
        mov comand.cmrflg,1     ; Say we're receiving a file. [21a start]
        mov comand.cmcr,1       ; Allow bare CR after RECEIVE.
        mov flags.nmoflg,0      ; Override file name from other host?
        mov bx,offset filhlp2   ; Text of help message.
        mov dx,offset locfil    ; local file name string [jrd]
        mov ah,cmfile           ; allow path names [jrd]
        call comnd
         jmp r
        cmp ah,0                ; was an override filename given?
        je read0                ; e = no
        mov flags.nmoflg,1      ; yes. set flag saying use this filename.
read0:  mov comand.cmrflg,0     ; Reset flag.
        mov comand.cmcr,0
        mov ah,cmcfm            ; Get a confirm.
        call comnd
         jmp r
read1:  cmp flags.remflg,0      ; remote mode?
        jne read12              ; yes, no printing
        cmp flags.destflg,2     ; Receiving to the screen? [27c]
        je read12               ; Yes no printing [27c]
        call init
                                ; Called also by GET code
read12: mov flags.cxzflg,0      ; Reset ^X/^Z flag. [20c]
        call rrinit             ; init variables for read
        call serini             ; Initialize serial port. [14]
        cmp flags.remflg,0      ; in remote mode?
        jne read12a             ; yes, no printing
        call init1              ; Clear the line and initialize the buffers.
        cmp flags.destflg,2     ; Receiving to the screen? [27c]
        je read12a              ; Yes no printing [27c]
        call stpos
        mov ah,prstr            ; Be informative.
        mov dx,offset infms1
        int dos
        call rtpos              ; Position cursor.
        mov ax,pack.numrtr
        call nout               ; Write the number of retries.

read12a:mov pack.state,'R'      ; Set the state to receive initiate.

read2:  cmp flags.xflg,1        ; Are we receiving to the screen. [21c]
        je read21               ; Skip the screen stuff. [21c]
        cmp flags.remflg,0      ; maybe remote mode?
        jne read21              ; yup, skip the screen stuff
        call nppos              ; Position cursor for number of packets msg.
        mov ax,pack.numpkt
        call nout               ; Write the number of packets.
read21: mov ah,pack.state       ; Get the state. [21c]
        cmp ah,'D'              ; Are we in the data send state?
        jne read3
        call rdata
        jmp read2
read3:  cmp ah,'F'              ; Are we in the file receive state?
        jne read4
        call rfile              ; Call receive file.
        jmp read2
read4:  cmp ah,'R'              ; Are we in the receive initiate state?
        jne read5
        call rinit
        jmp read2
read5:  cmp ah,'C'              ; Are we in the receive complete state?
        jne read6
        call serrst             ; Reset serial port. [14]
        cmp flags.xflg,0        ; Did we write to the screen? [21c]
        je read51               ; No so print status. [21c]
        cmp flags.destflg,2     ; Receiving to screen? [27c]
        je read51a              ; Yes don't reset. [27c]
        mov flags.xflg,0        ; Reset it. [21c]
        jmp rskp                ; Yes, so just return. [21c]
read51: cmp flags.remflg,0      ; remote mode?
        jne read51a             ; yes, keep going
        call stpos              ; Position cursor. [21c]
        mov ah,prstr
        mov dx,offset infms3    ; Plus a little cuteness.
        cmp flags.cxzflg,0      ; Completed or interrupted? [20c]
        je read13               ; Ended normally. [20c]
        mov dx,offset infms6    ; Say was interrupted. [20c]
read13: int dos
        cmp flags.belflg,0      ; Bell desired?  [17a]
        je readnb               ; No.  [17a]
        mov dx,offset ender     ; Ring them bells.    [4]
        int dos                 ; [4]
readnb: call clrmod             ; clear Mode Line
        call rprpos             ; Put prompt here.
read51a:jmp rskp

read6:  cmp filopn,2            ; file still open?
        jne read60              ; ne = no.
        call abort              ; close file & maybe delete. [jrd]
read60: call serrst             ; Reset serial port. [14]
        cmp flags.xflg,0        ; Did we write out to screen? [21c]
        je read61               ; No so print status. [21c]
        cmp flags.destflg,2     ; Receiving to screen? [27c]
        je read7a               ; Yes don't reset. [27c]
        mov flags.xflg,0        ; Reset it. [21c]
        jmp rskp                ; Print onto screen. [21c]
read61: cmp flags.remflg,0      ; remote mode?
        jne read7a              ; yes, no printing.
        call stpos              ; Position cursor.  [21c]
        mov ah,prstr
        mov dx,offset infms4    ; Plus a little cuteness.
        int dos
        cmp flags.belflg,0      ; Bell desired?  [17a]
        je read7                ; No.  [17a]
        mov dx,offset ender     ; Ring them bells.   [4]
        int dos                 ;  [4]
read7:  call clrmod             ; clear mode line
        call rprpos             ; Put prompt here.
read7a: jmp rskp
READ    ENDP


;       Receive routines

;       Receive init

RINIT   PROC    NEAR
        mov ah,pack.numtry      ; Get the number of tries.
        cmp ah,imxtry           ; Have we reached the maximum number of tries?
        jl rinit2
        mov dx,offset ermes7
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rinit1              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rinit1: mov bx,dx               ; [jrd]
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rinit2: inc ah                  ; Increment it.
        mov pack.numtry,ah      ; Save the updated number of tries.
        mov ax,pack.argbk2      ; get packet type if here from get
        cmp flags.getflg,1      ; Have we already read in the packet? [21a]
        je rin21a               ; Yes, so don't call RPACK. [21a]
        mov ah,trans.chklen
        mov curchk,ah           ; Save checksum length we want to use.
        mov trans.chklen,1      ; Use 1 char for init packet.
        call rpack              ; Get a packet.
         jmp rin22              ; Trashed packet: nak, retry.
        push ax
        mov ah,curchk
        mov trans.chklen,ah     ; Reset to desired value.
        pop ax
rin21a: cmp ah,'S'              ; Is it a send initiate packet?
        jne rinit3              ; If not see if its an error.
rin21:  mov flags.getflg,0      ; Reset flag. [21a]
        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 ax,pack.argblk      ; Returned packet number.  (Synchronize them.)
        inc ax                  ; Increment it.
        and ax,3FH              ; Turn off the two high order bits.
        mov pack.pktnum,ax      ; Save modulo 64 of the number.
        mov bx,pack.numpkt
        inc bx                  ; Increment the number of packets.
        mov pack.numpkt,bx
        mov ax,pack.argbk1      ; Get the number of arguments received.
        mov bx,offset data      ; Get a pointer to the data.
        call spar               ; Get the data into the proper variables.
        mov bx,offset data      ; Get a pointer to our data block.
        call rpar               ; Set up the receive parameters.
        xchg ah,al
        mov ah,0
        mov pack.argbk1,ax      ; Store the returned number of arguments.
        mov ah,trans.chklen     ; Checksum length we'll use.
        mov curchk,ah           ; Save it.
        mov trans.chklen,1      ; Use 1 char for init packet.
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        mov ah,curchk           ; Checksum length we'll use.
        mov trans.chklen,ah     ; Reset to desired value.
        mov ah,'F'              ; Set the state to file send.
        mov pack.state,ah
        ret
rin22:  mov ah,curchk
        mov trans.chklen,ah     ; Reset to desired value.
        jmp nak0                ; Try again.
rinit3: cmp ah,'E'              ; Is it an error packet?
        jne rinit4
        call error
rinit4: jmp abort
RINIT   ENDP


;       Receive file

RFILE   PROC    NEAR
        cmp pack.numtry,maxtry  ; Have we reached the maximum number of tries?
        jl rfile1
        mov dx,offset ermes8
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rfile0              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rfile0: mov bx,dx               ; [jrd]
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rfile1: inc pack.numtry         ; Save the updated number of tries.
        call rpack              ; Get a packet.
         jmp nak0               ;  Trashed packet: nak, retry.
        cmp ah,'S'              ; Is it a send initiate packet?
        je rfil10
        cmp ah,'I'              ; Is it an Initialization packet? [jrd]
        je rfil10               ; e = yes, don't decode it. [jrd]
rfil09: call dodec              ; Decode all other incoming packets.
        jmp rfile2              ;  No, try next type.
rfil10: cmp pack.oldtry,imxtry  ; Have we reached the maximum number of tries?
        jl rfil12               ; If not proceed.
        mov dx,offset ermes7
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rfil1a              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rfil1a: mov bx,dx               ; [jrd]
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rfil12: inc pack.oldtry         ; Save the updated number of tries.
        mov ax,pack.pktnum      ; Get the present packet number.
        cmp ax,0                ; Had we wrapped around? [18 start]
        jne rfilx
        mov ax,64
rfilx:  dec ax                  ; Decrement.  [18 end -- new label]
        cmp ax,pack.argblk      ; Is the packet's number one less than now?
        je rfil13
        jmp nak0                ; No, NAK and try again.
rfil13: call updrtr             ; Update retry count.
        mov pack.numtry,0       ; Reset the 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 ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        ret
rfile2: cmp ah,'Z'              ; Is it an EOF packet?
        jne rfile3              ;  No, try next type.
        cmp pack.oldtry,maxtry  ; Have we reached the maximum number of tries?
        jl rfil21               ; If not proceed.
        mov dx,offset ermes9
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rfil2a              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rfil2a: mov bx,dx
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rfil21: inc pack.oldtry         ; Increment it.
        mov ax,pack.pktnum      ; Get the present packet number.
        cmp ax,0                ; Had we wrapped around? [18 start]
        jne rfily
        mov ax,64
rfily:  dec ax                  ; Decrement.  [18 end -- new label]
        cmp ax,pack.argblk      ; Is the packet's number one less than now?
        je rfil24
        jmp nak0                ; No, NAK and try again.
rfil24: call updrtr             ; Update retry count.
        mov pack.numtry,0
        mov pack.argbk1,0       ; No data.  (The packet number is in argblk.)
        mov cx,0
        call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        ret
rfile3: cmp ah,'F'              ; Start of file?
        je rfil31               ; Yes. [21c]
        cmp ah,'X'              ; Text header packet? [21c]
        jne rfile4              ; Neither one.
rfil31: mov ax,pack.argblk      ; Get the packet number. [21c]
        cmp ax,pack.pktnum      ; Is it the right packet number?
        je rfil32
        jmp nak                 ; No, NAK it and try again.
rfil32: 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.
        call gofil              ; Get a file to write to.
         jmp abort
        mov filopn,2            ; Disk file open for writing. [jrd]
        call init1              ; Initialize all the buffers.
        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.argbk1,0       ; No data.  (The packet number is in argblk.)
        mov cx,0
        call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        mov pack.state,'D'      ; Set the state to data receive.
        ret
rfile4: cmp ah,'B'              ; End of transmission.
        jne rfile5
        mov ax,pack.pktnum
        cmp ax,pack.argblk      ; Do we match?
        je rfil41
        jmp nak                 ; No, NAK it and try again.
rfil41: mov pack.argbk1,0       ; No data.  (Packet number already in argblk).
        mov cx,0
        call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        mov pack.state,'C'      ; Set the state to complete.
        ret
rfile5: cmp ah,'E'              ; Is it an error packet.
        jne rfile6
        call error
rfile6: jmp abort
RFILE   ENDP


;       Receive data

RDATA   PROC    NEAR
        cmp pack.numtry,maxtry  ; Get the number of tries.
        jl rdata1
        mov dx,offset erms10
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rdata0              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rdata0: mov bx,dx               ; [jrd]
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rdata1: inc pack.numtry         ; Save the updated number of tries.
        call rpack              ; Get a packet.
         jmp nak0               ;  Trashed packet: nak, retry.
        cmp ah,'D'              ; Is it a data packet?
        je rdat11
        call dodec              ; Decode data.
        jmp rdata2              ;  No, try next type.
rdat11: mov ax,pack.pktnum      ; Get the present packet number.
        cmp ax,pack.argblk      ; Is the packet's number correct?
        jz rdat14
        cmp pack.oldtry,maxtry  ; Have we reached the maximum number of tries?
        jl rdat12               ; If not proceed.
        mov dx,offset erms10
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rdat1a              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rdat1a: mov bx,dx               ; [jrd]
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rdat12: inc pack.oldtry         ; Save the updated number of tries.
        mov ax,pack.pktnum
        cmp ax,0                ; Had we wrapped around? [18 start]
        jne rdatx
        mov ax,64
rdatx:  dec ax                  ; [14] [18 end -- new label]
        cmp ax,pack.argblk      ; Is the packet's number one less than now?
        je rdat13
        jmp nak0                ; No, NAK it and try again.
rdat13: call updrtr             ; Update retry count.
        mov pack.numtry,0       ; Reset number of tries.
        mov pack.argbk1,0       ; No data.  (The packet number is in argblk.)
        mov cx,0
        call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        ret
rdat14: 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 ax,pack.argbk1      ; Get the length of the data.
        cmp flags.cxzflg,0      ; Has the user typed a ^X or ^Z? [20c]
        je rdt14x               ; No, write out the data.
        cmp flags.abfflg,1      ; Discard incomplete files?
        je rdat15               ; If yes don't write data out to file. [20c]
rdt14x: mov bx,offset data      ; Where the data is. [25]
        call ptchr
         jmp abort              ;  Unable to write out chars; abort.
rdat15: mov pack.numtry,0       ; Reset the number of tries.
        mov pack.argbk1,0       ; No data.  (Packet number still in argblk.)
        mov cx,0
        cmp flags.cxzflg,0      ; Interrupt file transfer? [20c]
        je rdat16               ; Nope. [20c]
        mov bx,offset data      ; Send data in ACK in case remote... [20c]
        mov ah,flags.cxzflg     ; ... knows about ^X/^Z. [20c]
        mov [bx],ah             ; Put data into the packet. [20c]
        mov pack.argbk1,1       ; Set data size to 1. [20c]
        mov cx,1
rdat16: call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        ret
rdata2: cmp ah,'F'              ; Start of file?
        je rdat20               ; Yup. [21c]
        cmp ah,'X'              ; Text header packet? [21c]
        jne rdata3              ;  No, try next type.
rdat20: cmp pack.oldtry,maxtry  ; Reached the max number of tries? [21c]
        jl rdat21               ; If not proceed.
        mov dx,offset ermes8
        cmp flags.remflg,0      ; In remote mode? [jrd]
        jne rdat23              ; ne = yes. Don't write to screen. [jrd]
        call erpos              ; Position cursor.
        mov ah,prstr
        int dos                 ; Print an error message.
rdat23: mov bx,dx
        call errpack            ; Send error packet just in case.
        jmp abort               ; Change the state to abort.
rdat21: inc pack.oldtry         ; Save the updated number of tries.
        mov ax,pack.pktnum
        cmp ax,0                ; Had we wrapped around? [18 start]
        jne rdaty
        mov ax,64
rdaty:  dec ax                  ; [14 Omitted accidentally - D.T.] [18 end]
        cmp ax,pack.argblk      ; Is the packet's number one less than now?
        je rdat22
        jmp nak0                ; No, NAK it and try again.
rdat22: call updrtr             ; Update retry count.
        mov pack.numtry,0       ; Reset number of tries.
        mov pack.argbk1,0       ; No data.  (The packet number is in argblk.)
        mov cx,0
        call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        ret
rdata3: cmp ah,'Z'              ; Is it a EOF packet?
        je rdat3x               ; [13]
        jmp rdata4              ; Try and see if its an error. [13]
rdat3x: mov ax,pack.pktnum      ; Get the present packet number. [13]
        cmp ax,pack.argblk      ; Is the packet's number correct?
        je rdat32
        jmp nak0                ; No, NAK it and try again.
rdat32: 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
        cmp flags.cxzflg,0      ; Do we want to discard the file? [20c]
        jne rdt32x              ; Yes. [20c]
        cmp pack.argbk1,1       ; One piece of data? [20c]
        jne rdat33              ; Nope - finish writing out file? [20c]
        mov bx,offset data      ; Get data area. [20c]
        mov ah,[bx]             ; Get the data. [20c]
        cmp ah,'D'              ; "D" for discard? [20c]
        jne rdat33              ; Nope - write out file. [20c]
rdt32x: cmp flags.abfflg,0      ; Keep incomplete files?
        je rdat33               ; Yes, go write it out.
        cmp flags.xflg,1        ; Writing to the screen?
        je rdt32y               ; Don't close "file".
        push bx                 ; [jrd]
        mov ah,close2           ; DOS 2.0 file close [jrd]
        mov bx,diskio.handle    ; file handle [jrd]
        int dos                 ; Kill it, ignore errors. [20c]
        pop bx                  ; [jrd]
        mov dx,offset diskio.string ; get the filename
        mov ah,del2             ; DOS 2.0 file delete [jrd]
        int dos
rdt32y: cmp flags.cxzflg,'X'    ; Kill one file or all? [20c]
        jne rdat36              ; No so leave flag alone. [20c]
        call cxmsg              ; Clear msg about interrupt. [20c]
        mov flags.cxzflg,0      ; Reset - ^X only kills one file. [20c]
        jmp rdat36
rdat33: cmp flags.eofcz,0       ; should we write a ^Z?
        jz rdat35               ; no, keep going
        cmp flags.xflg,0        ; writing to a file?
        jne rdat35              ; no, skip ^Z
rdt33x: cmp chrcnt,0            ; any space left in output buffer? [jrd]
        jg rdat34               ; g = yes [jrd]
        call outbuf             ; Write out buffer if no room for ^Z.
         jmp abort
rdat34: mov cl,'Z'-100O         ; Put in a ^Z for EOF.
        push bx
        mov bx,bufpnt           ; Get the dma pointer. [jrd]
        mov [bx],cl             ; Add it. [21c]
        pop bx
        dec chrcnt
rdat35: call outbuf             ; Output the last buffer.
         jmp abort              ; Give up if the disk is full.
        cmp flags.xflg,1        ; Writing to the screen?
        je rdat37               ; Yes, don't close "file".
        mov ah,close2           ; DOS 2.0 file close [jrd]
        push bx                 ; [jrd]
        mov bx,diskio.handle    ; file handle [jrd]
        int dos
        pop bx                  ; [jrd]
rdat36: cmp flags.destflg,1     ; Writing to disk?
        je rdat37               ; Yes, skip next part.
        cmp flags.xflg,1        ; Writing to screen?
        je rdat37               ; Yes, skip this part.
        mov dl,ff               ; Send a form feed.
        mov ah,lstout           ; Write out to first printer.
        int dos
rdat37: 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.argbk1,0       ; No data.  (The packet number is in argblk.)
        mov cx,0
        call doenc
        mov ah,'Y'              ; Acknowledge packet.
        call spack              ; Send the packet.
         jmp abort
        mov pack.state,'F'
        mov filopn,0            ; File closed now.
        ret
rdata4: cmp ah,'E'                      ; Is it an error packet.
        jne rdata5
        call error
rdata5: jmp abort
RDATA   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

R       PROC    NEAR
        ret
R       ENDP

code    ends
        end



