        NAME    mssrcv
; File MSSRCV.ASM
; Edit history
; Last edit: 7 Jan 1988
; 7 Jan 1988 Check for Control-E condition before sending a NAK. [jrd]
; 1 Jan 1988 version 2.30
; 26 Dec 1987 Clean out unused pack.oldtry, etc., clean up. [jrd]
; 6 Dec 1987 Flush last disk buffer when aborting a transfer. [jrd]
; 8 Oct 1987 Ensure error pkts use 1 byte chksum at init stage. [jrd]
; 27 Aug 1987 Add tests for receiving to screen for error reports [jrd]
; 23 July 1987 Add buffer clear after opening new output file. [jrd]
; 7 June 1987 Add DOS errlev return of 2 for failure to receive. [jrd]
; 7 May 1987 Correct placement of begtim and endtim statistics calls. [jrd]
; 19 Oct 1986 Fix Rinit to use 1 byte checksums on Naks to S packets.
; 1 Oct 1986 Version 2.29a
; 17 Sept 1986 Fix file not being deleted when transfer fails. [jrd]
; 14 August 1986 Allow changing EOL characters.
; 9 August 1986 Allow Control-X/Z exit while getting 'S' packet. [jrd]
; 27 July 1986 Clear file opened flag to prevent unwanted closing of stdin.
; 16 June 1986 Add clearing of "flags.getflg" under read0: to prevent missing
;  initial packet read for REC commands. [jrd]
; 26 May 1986 Revise code to permit serial display. [jrd]
; [2.29] code frozen on 6 May 1986 [jrd]

        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, dtrans:byte
        extrn   diskio:byte, locfil:byte, maxtry:byte, imxtry:byte
        extrn   fsta:word, errlev:byte

ermes7  db      '?Unable to receive initiate-packet$'
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',cr,lf,'$'
infms3  db      'Completed',cr,lf,'$'
infms4  db      'Failed',cr,lf,'$'
infms6  db      'Interrupted',cr,lf,'$'
filhlp2 db      ' Local path or filename or carriage return$'
ender   db      bell,bell,'$'
crlf    db      cr,lf,'$'
temp    dw      0
filopn  db      0               ; Says if disk file is open.
datas   ends

code    segment public 'code'
        extrn   gofil:near, outbuf:near, comnd:near
        extrn   spack:near, rpack:near, serini:near, serrst:near
        extrn   spar:near, rpar:near, init: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, intmsg:near
        extrn   send11:near, clrmod:near, ihostr:near
        extrn   begtim:near, endtim:near, pktsize:near
        assume  cs:code, ds:datas


; Update retry count and fall through to send a NAK.

NAK0:   call    updrtr                  ; Update retry count.
nak1:   cmp     flags.cxzflg,'E'        ; Protocol abort sign?
        jne     nak                     ; ne = no
        ret                             ; return to do current ('A') state

NAK:    mov     ax,pack.pktnum       ; Get the packet number we're waiting for
        mov     pack.argblk,ax
        mov     pack.argbk1,0
        add     fsta.nakscnt,1          ; count NAKs sent
;;;     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
        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                    ; e = yes, skip this
        cmp     pack.numrtr,0           ; non-zero item to display?
        je      upd0                    ; nothing to display
        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".
        call    outbuf          ; flush last buffer to disk, ignore errors.
         nop
         nop
         nop
        mov     ah,close2               ; DOS 2.0 file close
        push    bx
        mov     bx,diskio.handle        ; file handle
        int     dos
        pop     bx
        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.
        mov     byte ptr locfil,0       ; clear local filename
        or      errlev,2                ; set DOS error level
        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.
        mov     filopn,0                ; say no file opened yet
        ret
rrinit  endp

;       RECEIVE command  --  Some code moved to the GET routine

READ    PROC    NEAR
        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
        mov     byte ptr locfil,0       ; clear it first
        mov     ah,cmfile               ; allow path names
        call    comnd
         jmp    r
        cmp     ah,0                    ; was an override filename given?
        je      read0                   ; e = no
        mov     flags.nmoflg,1          ; yes, set flag = use this filename.
read0:  mov     comand.cmrflg,0         ; Reset flag.
        mov     comand.cmcr,0
        mov     ah,cmcfm                ; Get a confirm.
        call    comnd
         jmp    r
        mov     pack.state,'R'  ; Set the state to receive initiate
        mov     flags.getflg,0          ; Reset flag (not a Get command)
        mov     flags.xflg,0
        call    rrinit                  ; init variables for read
        call    init                    ; setup display form
        call    serini                  ; Initialize serial port
        call    ihostr                  ; initialize the host
        mov     ax,0            ; tell statistics this was a receive operation
        call    endtim                  ; get tod of end of file transfer
        call    begtim                  ; start next statistics group

READ12:                                 ; Called by GET & SRVSND, display ok
        mov     flags.cxzflg,0          ; Reset ^X/^Z flag.
        mov     ah,trans.chklen         ; get desired checksum length
        mov     curchk,ah               ; and remember it here
        test    flags.remflg,dquiet     ; quiet display mode?
        jnz     read2                   ; nz = yes, no printing
        cmp     flags.destflg,2         ; Receiving to the screen?
        je      read21                  ; e = yes, no formatted display
        call    stpos
        mov     ah,prstr                ; Be informative.
        mov     dx,offset infms1
        int     dos
        test    flags.remflg,dserial    ; serial display mode?
        jnz     read2                   ; nz = yes, skip initial retry display
        call    rtpos                   ; Position cursor.
        mov     ax,pack.numrtr
        call    nout                    ; Write the number of retries.

READ2:                          ; Called by GENERIC server command dispatcher
        cmp     flags.xflg,1            ; Are we receiving to the screen?
        je      read21                  ; e = 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.
        cmp     ah,'D'                  ; Data receive state?
        jne     read3
        call    rdata                   ; yes, get data packets
        jmp     read2
read3:  cmp     ah,'F'                  ; File receive state?
        jne     read4
        call    rfile                   ; Call receive file.
        jmp     read2
read4:  cmp     ah,'R'                  ; Receive initiate state?
        jne     read5
        call    rinit
        jmp     read2
                                        ; Receive Complete state processor
read5:  push    ax                      ; save status in ah
        xor     ax,ax           ; tell statistics this is a receive operation
        call    endtim                  ; stop file timer
        call    serrst                  ; Reset serial port.
        mov     ah,curchk               ; get working checksum
        mov     trans.chklen,ah         ; and restore for next file
        mov     byte ptr locfil,0       ; clear local filename
        pop     ax
        mov     dx,offset infms3        ; Completed message
        cmp     ah,'C'                  ; Receive complete state?
        je      read6                   ; e = yes, else receive failed.
        mov     dx,offset infms4        ; Failed message
        or      errlev,2                ; set DOS error level
        cmp     filopn,2                ; file still open?
        jne     read6                   ; ne = no.
        push    dx
        call    abort                   ; close file & maybe delete
        pop     dx
read6:  cmp     flags.xflg,0            ; Did we write to the screen?
        je      read6a                  ; e = no, so print status.
        cmp     flags.destflg,2         ; Receiving to screen?
        je      read6d                  ; Yes don't reset.
        mov     flags.xflg,0            ; Reset it.
        jmp     read6d                  ; Yes, so just return.
read6a: test    flags.remflg,dquiet     ; quiet display mode?
        jnz     read6d                  ; nz = yes, keep going
        cmp     flags.destflg,2         ; Receiving to the screen?
        je      read6d                  ; e = yes, no formatted display
        push    dx                      ; save message pointer
        call    stpos                   ; Position cursor.
        pop     dx
        mov     ah,prstr
        cmp     flags.cxzflg,0          ; Completed or interrupted?
        je      read6b                  ; Ended normally.
        or      errlev,2                ; set DOS error level
        mov     dx,offset infms6        ; Say was interrupted.
read6b: int     dos
        cmp     flags.belflg,0          ; Bell desired?
        je      read6c                  ; No.
        mov     dx,offset ender         ; Ring them bells.
        int     dos
read6c: test    flags.remflg,dserial    ; serial display?
        jnz     read6d                  ; nz = yes
        call    clrmod                  ; clear Mode Line
        call    rprpos                  ; Put prompt here.
read6d: jmp     rskp
READ    ENDP


;       Receive routines

;       Receive init

RINIT   PROC    NEAR
        mov     ah,pack.numtry          ; Get the number of tries.
        cmp     ah,imxtry               ; Reached the maximum number of tries?
        jl      rinit2
        mov     dx,offset ermes7
        test    flags.remflg,dquiet     ; quiet display mode?
        jnz     rinit1                  ; nz = yes. Don't write to screen.
        cmp     flags.destflg,2         ; Receiving to the screen?
        je      rinit1                  ; e = yes, no formatted display
        call    erpos                   ; Position cursor.
        mov     ah,prstr
        int     dos                     ; Print an error message.
rinit1: mov     bx,dx
        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.
        call    errpack                 ; Send error packet just in case.
        mov     ah,curchk
        mov     trans.chklen,ah         ; Reset to desired value.
        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?
        je      rin21a                  ; Yes, so don't call RPACK.
        mov     ah,dtrans.seol          ; restore default end-of-line char
        mov     trans.seol,ah
        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.
        call    pktsize                 ; report packet size
        push    ax
        mov     ah,curchk
        mov     trans.chklen,ah         ; Reset to desired value.
        pop     ax
        cmp     flags.cxzflg,0          ; does the user want out now?
        jne     rinit4                  ; ne = yes, quit
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.
        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.
        inc     pack.numpkt             ; Increment the number of packets.
        mov     ax,pack.argbk1          ; Get the number of arguments received
        mov     bx,offset data          ; Get a pointer to the data
        call    spar                    ; Get 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 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     pack.state,'F'          ; Set the state to file send.
        ret
rin22:  call    nak0                    ; nak the packet
        mov     ah,curchk               ; and only now change checksum from 1
        mov     trans.chklen,ah         ; Reset to desired value.
        ret                             ; try again

rinit3: cmp     ah,'E'                  ; Is it an error packet?
        jne     rinit4                  ; ne = no
        call    error                   ; yes
rinit4: jmp     abort
RINIT   ENDP


;       Receive file

RFILE   PROC    NEAR
        mov     dl,maxtry
        cmp     pack.numtry,dl  ; Have we reached the maximum number of tries?
        jl      rfile1
        mov     dx,offset ermes8
        jmp     rcverr                  ; do error exit
rfile1: inc     pack.numtry             ; Save the updated number of tries.
        call    rpack                   ; Get a packet.
         jmp    nak0                    ;  Trashed packet: nak, retry.
        call    pktsize                 ; report packet size
        cmp     ah,'S'                  ; Is it a send initiate packet?
        je      rfil10
        cmp     ah,'I'                  ; An Initialization packet?
        je      rfil10                  ; e = yes, don't decode it
rfil09: call    dodec                   ; Decode all other incoming packets.
        jmp     rfile2                  ;  No, try next type.
rfil10: mov     dl,imxtry               ; S and I packets
        cmp     pack.numtry,dl          ; Reached the maximum number of tries?
        jl      rfil12                  ; If not proceed.
        mov     dx,offset ermes7
        jmp     rcverr                  ; do error exit
rfil12: mov     ax,pack.pktnum          ; Get the present packet number.
        cmp     ax,0                    ; Had we wrapped around?
        jne     rfilx
        mov     ax,64
rfilx:  dec     ax                      ; Decrement.
        cmp     ax,pack.argblk  ; Is the packet's number one less than now?
        je      rfil13
        jmp     nak0                    ; No, NAK and try again.
rfil13: 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.
        mov     dl,maxtry               ; Z packets
        cmp     pack.numtry,dl  ; Have we reached the maximum number of tries?
        jl      rfil21                  ; If not proceed.
        mov     dx,offset ermes9
        jmp     rcverr                  ; do error exit
rfil21: mov     ax,pack.pktnum          ; Get the present packet number.
        cmp     ax,0                    ; Had we wrapped around?
        jne     rfily
        mov     ax,64
rfily:  dec     ax                      ; Decrement.
        cmp     ax,pack.argblk  ; Is the packet's number one less than now?
        je      rfil24
        jmp     nak0                    ; No, NAK and try again.
rfil24: mov     pack.numtry,0
        mov     pack.argbk1,0   ; No data. (The packet number is in argblk.)
        mov     ah,'Y'                  ; Acknowledge packet.
        call    spack                   ; Send the packet.
         jmp    abort
        ret
rfile3: cmp     ah,'F'                  ; Start of file (F or X packet)?
        je      rfil31                  ; e = yes.
        cmp     ah,'X'                  ; Text header packet?
        jne     rfile4                  ; Neither one.
        mov     flags.xflg,1            ; 'X', say receiving to the screen
rfil31: mov     ax,pack.argblk          ; Get the packet number.
        cmp     ax,pack.pktnum          ; Is it the right packet number?
        je      rfil32
        jmp     nak1                    ; 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.
        mov     filopn,0                ; assume not writing to a disk file
        mov     ax,0            ; tell statistics this was a receive operation
        call    endtim                  ; get tod & size of file transfer
        call    gofil                   ; Get a file to write to.
         jmp    abort
        call    begtim                  ; start next statistics group
        mov     chrcnt,maxpack          ; reset output buffer to be empty
        cmp     flags.xflg,0            ; writing to a disk file?
        jne     rfil32a                 ; ne = no
        mov     filopn,2                ; Disk file open for writing
rfil32a:
        test    flags.remflg,dserial    ; serial display mode?
        jz      rfil33                  ; z = no
        mov     ah,prstr
        mov     dx,offset crlf          ; display cr/lf
        int     dos
rfil33:
        mov     pack.numtry,0           ; Reset the number of tries.
        mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
        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                  ; ne = no
        mov     ax,pack.pktnum
        cmp     ax,pack.argblk          ; Do we match?
        je      rfil41
        jmp     nak1                    ; No, NAK it and try again.
rfil41: mov     pack.argbk1,0   ; No data.  (Packet number already in argblk).
        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                  ; ne = no
        call    error
rfile6: jmp     abort
RFILE   ENDP


; Receive data

RDATA   PROC    NEAR
        mov     dl,maxtry
        cmp     pack.numtry,dl          ; Get the number of tries.
        jl      rdata1
        mov     dx,offset erms10
        jmp     rcverr                  ; do error exit
rdata1: inc     pack.numtry             ; Save the updated number of tries.
        call    rpack                   ; Get a packet.
         jmp    nak0                    ;  Trashed packet: nak, retry.
        call    pktsize                 ; report packet size
        cmp     ah,'D'                  ; Is it a data packet?
        je      rdat11                  ; e = yes
        call    dodec                   ; Decode data.
        jmp     rdata2                  ;  No, try next type.
                                        ; D packets
rdat11: mov     ax,pack.pktnum          ; Get the present packet number.
        cmp     ax,pack.argblk          ; Is the packet's number correct?
        jz      rdat14
        mov     dl,maxtry
        cmp     pack.numtry,dl  ; Have we reached the maximum number of tries?
        jl      rdat12                  ; If not proceed.
        mov     dx,offset erms10
        jmp     rcverr                  ; do error exit
rdat12: mov     ax,pack.pktnum
        cmp     ax,0                    ; Had we wrapped around?
        jne     rdatx
        mov     ax,64
rdatx:  dec     ax
        cmp     ax,pack.argblk  ; Is the packet's number one less than now?
        je      rdat13
        jmp     nak0                    ; No, NAK it and try again.
rdat13: mov     pack.numtry,0           ; Reset number of tries.
        mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
        mov     ah,'Y'                  ; Acknowledge packet.
        call    spack                   ; Send the packet.
         jmp    abort
        ret
rdat14: inc     pack.pktnum             ; Increment the packet number
        and     pack.pktnum,3fh         ; Save modulo 64 of the number
        inc     pack.numpkt             ; Increment the number of packets.
        mov     ax,pack.argbk1          ; Get the length of the data.
        cmp     flags.cxzflg,0          ; Has the user typed a ^X or ^Z?
        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.
rdt14x: call    ptchr                   ; decode the data and output to file
         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.)
        cmp     flags.cxzflg,0          ; Interrupt file transfer?
        je      rdat16                  ; Nope.
        mov     bx,offset data          ; Send data in ACK in case remote
        mov     ah,flags.cxzflg         ;  knows about ^X/^Z.
        mov     [bx],ah                 ; Put data into the packet.
        mov     pack.argbk1,1           ; Set data size to 1.
        mov     cx,1
        call    doenc
rdat16: mov     ah,'Y'                  ; Acknowledge packet.
        call    spack                   ; Send the packet.
         jmp    abort
        ret
rdata2: cmp     ah,'F'                  ; Start of file?
        je      rdat20                  ; e = yes
        cmp     ah,'X'                  ; Text header packet?
        jne     rdata3                  ;  No, try next type.
rdat20: mov     dl,maxtry               ; F or X packet
        cmp     pack.numtry,dl          ; Reached the max number of tries?
        jl      rdat21                  ; If not proceed.
        mov     dx,offset ermes8
        jmp     rcverr                  ; do error exit
rdat21: mov     ax,pack.pktnum
        cmp     ax,0                    ; Had we wrapped around?
        jne     rdaty
        mov     ax,64
rdaty:  dec     ax
        cmp     ax,pack.argblk  ; Is the packet's number one less than now?
        je      rdat22
        jmp     nak0                    ; No, NAK it and try again.
rdat22: mov     pack.numtry,0           ; Reset number of tries.
        mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
        mov     ah,'Y'                  ; Acknowledge packet.
        call    spack                   ; Send the packet.
         jmp    abort
        ret
rdata3: cmp     ah,'Z'                  ; Is it a EOF packet?
        je      rdat3x                  ; e = yes
        jmp     rdata4                  ; Try and see if its an error.
rdat3x: mov     ax,pack.pktnum          ; Get the present packet number.
        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?
        jne     rdt32x                  ; Yes.
        cmp     pack.argbk1,1           ; One piece of data?
        jne     rdat33                  ; Nope - finish writing out file?
        cmp     data,'D'                ; is the data "D" for discard?
        jne     rdat33                  ; Nope - write out file.
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".
        cmp     flags.destflg,2         ; file destination = screen?
        je      rdt32y                  ; e = yes, no file to close
        push    bx
        mov     ah,close2               ; DOS 2.0 file close
        mov     bx,diskio.handle        ; file handle
        int     dos                     ; Kill it, ignore errors.
        pop     bx
        mov     filopn,0                ; File closed now.
        mov     dx,offset diskio.string ; get the filename
        mov     ah,del2                 ; DOS 2.0 file delete
        int     dos
rdt32y: cmp     flags.cxzflg,'X'        ; Kill one file or all?
        jne     rdat36                  ; No so leave flag alone.
        call    cxmsg                   ; Clear msg about interrupt.
        test    flags.remflg,dquiet     ; quiet display?
        jnz     rdt32z                  ; nz = yes
        cmp     flags.destflg,2         ; Receiving to the screen?
        je      rdt32z                  ; e = yes, no formatted display
        call    intmsg
rdt32z: mov     flags.cxzflg,0          ; Reset - ^X only kills one file
        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?
        jg      rdat34                  ; g = yes
        call    outbuf                  ; Write out buffer if no room for ^Z.
         jmp    abort
rdat34: mov     cl,'Z'- 40h             ; Put in a ^Z for EOF.
        push    bx
        mov     bx,bufpnt               ; Get the dma pointer
        mov     [bx],cl                 ; Add it.
        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".
        cmp     flags.destflg,2         ; file destination = screen?
        je      rdat37                  ; e = yes, no file to close
        mov     ah,close2               ; DOS 2.0 file close
        push    bx
        mov     bx,diskio.handle        ; file handle
        int     dos
        pop     bx
        mov     filopn,0                ; File closed now.
rdat36: cmp     flags.destflg,0         ; Writing to printer?
        jne     rdat37                  ; ne = no, 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     pack.numtry,0           ; Reset the number of tries.
        mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
        mov     ah,'Y'                  ; Acknowledge packet.
        call    spack                   ; Send the packet.
         jmp    abort
        mov     pack.state,'F'
        ret
rdata4: cmp     ah,'E'                  ; Is it an error packet?
        jne     rdata5                  ; ne = no
        call    error
rdata5: jmp     abort
RDATA   ENDP

; Error exit. Enter with dx pointing to error message. [jrd]
rcverr  proc    near
        test    flags.remflg,dquiet; quiet display mode?
        jnz     rcver1                  ; nz = yes. Don't write to screen
        cmp     flags.destflg,2         ; Receiving to the screen?
        je      rcver1                  ; e = yes, no formatted display
        call    erpos                   ; Position cursor.
        mov     ah,prstr
        int     dos                     ; Print an error message.
rcver1: mov     bx,dx                   ; set bx to error message
        call    errpack                 ; Send error packet just in case.
        jmp     abort                   ; Change the state to abort.
rcverr  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
