home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msk230s1.zip / MSSRCV.ASM < prev    next >
Assembly Source File  |  1988-02-12  |  33KB  |  651 lines

  1.         NAME    mssrcv
  2. ; File MSSRCV.ASM
  3. ; Edit history
  4. ; Last edit: 7 Jan 1988
  5. ; 7 Jan 1988 Check for Control-E condition before sending a NAK. [jrd]
  6. ; 1 Jan 1988 version 2.30
  7. ; 26 Dec 1987 Clean out unused pack.oldtry, etc., clean up. [jrd]
  8. ; 6 Dec 1987 Flush last disk buffer when aborting a transfer. [jrd]
  9. ; 8 Oct 1987 Ensure error pkts use 1 byte chksum at init stage. [jrd]
  10. ; 27 Aug 1987 Add tests for receiving to screen for error reports [jrd]
  11. ; 23 July 1987 Add buffer clear after opening new output file. [jrd]
  12. ; 7 June 1987 Add DOS errlev return of 2 for failure to receive. [jrd]
  13. ; 7 May 1987 Correct placement of begtim and endtim statistics calls. [jrd]
  14. ; 19 Oct 1986 Fix Rinit to use 1 byte checksums on Naks to S packets.
  15. ; 1 Oct 1986 Version 2.29a
  16. ; 17 Sept 1986 Fix file not being deleted when transfer fails. [jrd]
  17. ; 14 August 1986 Allow changing EOL characters.
  18. ; 9 August 1986 Allow Control-X/Z exit while getting 'S' packet. [jrd]
  19. ; 27 July 1986 Clear file opened flag to prevent unwanted closing of stdin.
  20. ; 16 June 1986 Add clearing of "flags.getflg" under read0: to prevent missing
  21. ;  initial packet read for REC commands. [jrd]
  22. ; 26 May 1986 Revise code to permit serial display. [jrd]
  23. ; [2.29] code frozen on 6 May 1986 [jrd]
  24.  
  25.         public  read12, read2, rin21, rfile3, read, updrtr, nak, rrinit
  26.         include mssdef.h
  27.  
  28. datas   segment public 'datas'
  29.         extrn   data:byte, bufpnt:word, chrcnt:word, curchk:byte
  30.         extrn   comand:byte, flags:byte, pack:byte, trans:byte, dtrans:byte
  31.         extrn   diskio:byte, locfil:byte, maxtry:byte, imxtry:byte
  32.         extrn   fsta:word, errlev:byte
  33.  
  34. ermes7  db      '?Unable to receive initiate-packet$'
  35. ermes8  db      '?Unable to receive file name$'
  36. ermes9  db      '?Unable to receive end of file$'
  37. erms10  db      '?Unable to receive data$'
  38. infms1  db      cr,'           Receiving: In progress',cr,lf,'$'
  39. infms3  db      'Completed',cr,lf,'$'
  40. infms4  db      'Failed',cr,lf,'$'
  41. infms6  db      'Interrupted',cr,lf,'$'
  42. filhlp2 db      ' Local path or filename or carriage return$'
  43. ender   db      bell,bell,'$'
  44. crlf    db      cr,lf,'$'
  45. temp    dw      0
  46. filopn  db      0               ; Says if disk file is open.
  47. datas   ends
  48.  
  49. code    segment public 'code'
  50.         extrn   gofil:near, outbuf:near, comnd:near
  51.         extrn   spack:near, rpack:near, serini:near, serrst:near
  52.         extrn   spar:near, rpar:near, init:near, cxmsg:near
  53.         extrn   error:near, ptchr:near, erpos:near, rtpos:near
  54.         extrn   stpos:near, rprpos:near, nppos:near, nout:near
  55.         extrn   dodec:near, doenc:near, errpack:near, intmsg:near
  56.         extrn   send11:near, clrmod:near, ihostr:near
  57.         extrn   begtim:near, endtim:near, pktsize:near
  58.         assume  cs:code, ds:datas
  59.  
  60.  
  61. ; Update retry count and fall through to send a NAK.
  62.  
  63. NAK0:   call    updrtr                  ; Update retry count.
  64. nak1:   cmp     flags.cxzflg,'E'        ; Protocol abort sign?
  65.         jne     nak                     ; ne = no
  66.         ret                             ; return to do current ('A') state
  67.  
  68. NAK:    mov     ax,pack.pktnum       ; Get the packet number we're waiting for
  69.         mov     pack.argblk,ax
  70.         mov     pack.argbk1,0
  71.         add     fsta.nakscnt,1          ; count NAKs sent
  72. ;;;     mov     cx,0                    ; No data, but this may change.
  73. ;;;     call    doenc                   ; So call encode.
  74.         mov     ah,'N'                  ; NAK that packet.
  75.         call    spack
  76.          jmp    abort
  77.          nop                            ; So 'jmp rskp' in SPACK comes here
  78.         ret                             ; Go around again.
  79.  
  80. updrtr: cmp     pack.state,'A'          ; Supposed to abort?
  81.         je      upd0                    ; Yes, don't bother with retry count.
  82.         inc     pack.numrtr             ; Increment the number of retries.
  83.         cmp     flags.xflg,1            ; Writing to screen?
  84.         je      upd0                    ; e = yes, skip this
  85.         cmp     pack.numrtr,0           ; non-zero item to display?
  86.         je      upd0                    ; nothing to display
  87.         call    rtpos                   ; Position cursor.
  88.         mov     ax,pack.numrtr
  89.         call    nout                    ; Write the number of retries.
  90. upd0:   ret
  91.  
  92. ;       Abort
  93. ABORT   PROC    NEAR
  94.         cmp     filopn,0                ; Disk file open?
  95.         je      abort0                  ; e = no so don't close.
  96.         cmp     flags.xflg,1            ; Writing to the screen?
  97.         je      abort0                  ; Yes, don't close "file".
  98.         call    outbuf          ; flush last buffer to disk, ignore errors.
  99.          nop
  100.          nop
  101.          nop
  102.         mov     ah,close2               ; DOS 2.0 file close
  103.         push    bx
  104.         mov     bx,diskio.handle        ; file handle
  105.         int     dos
  106.         pop     bx
  107.         mov     filopn,0                ; say file is no longer open
  108.         cmp     flags.abfflg,0          ; save file after closing?
  109.         je      abort0                  ; e = yes
  110.         push    dx
  111.         mov     dx,offset diskio.string ; get back file name
  112.         mov     ah,del2                 ; delete the file
  113.         int     dos
  114.         pop     dx
  115. abort0: mov     pack.state,'A'          ; Otherwise abort.
  116.         mov     byte ptr locfil,0       ; clear local filename
  117.         or      errlev,2                ; set DOS error level
  118.         ret
  119. ABORT   ENDP
  120.  
  121. ; init variables for read...
  122. rrinit  proc    near
  123.         mov     pack.numpkt,0           ; Set the number of packets to zero.
  124.         mov     pack.numrtr,0           ; Set the number of retries to zero.
  125.         mov     pack.pktnum,0           ; Set the packet number to zero.
  126.         mov     pack.numtry,0           ; Set the number of tries to zero.
  127.         mov     filopn,0                ; say no file opened yet
  128.         ret
  129. rrinit  endp
  130.  
  131. ;       RECEIVE command  --  Some code moved to the GET routine
  132.  
  133. READ    PROC    NEAR
  134.         mov     flags.nmoflg,0          ; Override file name from other host?
  135.         mov     bx,offset filhlp2       ; Text of help message.
  136.         mov     dx,offset locfil        ; local file name string
  137.         mov     byte ptr locfil,0       ; clear it first
  138.         mov     ah,cmfile               ; allow path names
  139.         call    comnd
  140.          jmp    r
  141.         cmp     ah,0                    ; was an override filename given?
  142.         je      read0                   ; e = no
  143.         mov     flags.nmoflg,1          ; yes, set flag = use this filename.
  144. read0:  mov     comand.cmrflg,0         ; Reset flag.
  145.         mov     comand.cmcr,0
  146.         mov     ah,cmcfm                ; Get a confirm.
  147.         call    comnd
  148.          jmp    r
  149.         mov     pack.state,'R'  ; Set the state to receive initiate
  150.         mov     flags.getflg,0          ; Reset flag (not a Get command)
  151.         mov     flags.xflg,0
  152.         call    rrinit                  ; init variables for read
  153.         call    init                    ; setup display form
  154.         call    serini                  ; Initialize serial port
  155.         call    ihostr                  ; initialize the host
  156.         mov     ax,0            ; tell statistics this was a receive operation
  157.         call    endtim                  ; get tod of end of file transfer
  158.         call    begtim                  ; start next statistics group
  159.  
  160. READ12:                                 ; Called by GET & SRVSND, display ok
  161.         mov     flags.cxzflg,0          ; Reset ^X/^Z flag.
  162.         mov     ah,trans.chklen         ; get desired checksum length
  163.         mov     curchk,ah               ; and remember it here
  164.         test    flags.remflg,dquiet     ; quiet display mode?
  165.         jnz     read2                   ; nz = yes, no printing
  166.         cmp     flags.destflg,2         ; Receiving to the screen?
  167.         je      read21                  ; e = yes, no formatted display
  168.         call    stpos
  169.         mov     ah,prstr                ; Be informative.
  170.         mov     dx,offset infms1
  171.         int     dos
  172.         test    flags.remflg,dserial    ; serial display mode?
  173.         jnz     read2                   ; nz = yes, skip initial retry display
  174.         call    rtpos                   ; Position cursor.
  175.         mov     ax,pack.numrtr
  176.         call    nout                    ; Write the number of retries.
  177.  
  178. READ2:                          ; Called by GENERIC server command dispatcher
  179.         cmp     flags.xflg,1            ; Are we receiving to the screen?
  180.         je      read21                  ; e = skip the screen stuff.
  181.         call    nppos            ; Position cursor for number of packets msg.
  182.         mov     ax,pack.numpkt
  183.         call    nout                    ; Write the number of packets.
  184. read21: mov     ah,pack.state           ; Get the state.
  185.         cmp     ah,'D'                  ; Data receive state?
  186.         jne     read3
  187.         call    rdata                   ; yes, get data packets
  188.         jmp     read2
  189. read3:  cmp     ah,'F'                  ; File receive state?
  190.         jne     read4
  191.         call    rfile                   ; Call receive file.
  192.         jmp     read2
  193. read4:  cmp     ah,'R'                  ; Receive initiate state?
  194.         jne     read5
  195.         call    rinit
  196.         jmp     read2
  197.                                         ; Receive Complete state processor
  198. read5:  push    ax                      ; save status in ah
  199.         xor     ax,ax           ; tell statistics this is a receive operation
  200.         call    endtim                  ; stop file timer
  201.         call    serrst                  ; Reset serial port.
  202.         mov     ah,curchk               ; get working checksum
  203.         mov     trans.chklen,ah         ; and restore for next file
  204.         mov     byte ptr locfil,0       ; clear local filename
  205.         pop     ax
  206.         mov     dx,offset infms3        ; Completed message
  207.         cmp     ah,'C'                  ; Receive complete state?
  208.         je      read6                   ; e = yes, else receive failed.
  209.         mov     dx,offset infms4        ; Failed message
  210.         or      errlev,2                ; set DOS error level
  211.         cmp     filopn,2                ; file still open?
  212.         jne     read6                   ; ne = no.
  213.         push    dx
  214.         call    abort                   ; close file & maybe delete
  215.         pop     dx
  216. read6:  cmp     flags.xflg,0            ; Did we write to the screen?
  217.         je      read6a                  ; e = no, so print status.
  218.         cmp     flags.destflg,2         ; Receiving to screen?
  219.         je      read6d                  ; Yes don't reset.
  220.         mov     flags.xflg,0            ; Reset it.
  221.         jmp     read6d                  ; Yes, so just return.
  222. read6a: test    flags.remflg,dquiet     ; quiet display mode?
  223.         jnz     read6d                  ; nz = yes, keep going
  224.         cmp     flags.destflg,2         ; Receiving to the screen?
  225.         je      read6d                  ; e = yes, no formatted display
  226.         push    dx                      ; save message pointer
  227.         call    stpos                   ; Position cursor.
  228.         pop     dx
  229.         mov     ah,prstr
  230.         cmp     flags.cxzflg,0          ; Completed or interrupted?
  231.         je      read6b                  ; Ended normally.
  232.         or      errlev,2                ; set DOS error level
  233.         mov     dx,offset infms6        ; Say was interrupted.
  234. read6b: int     dos
  235.         cmp     flags.belflg,0          ; Bell desired?
  236.         je      read6c                  ; No.
  237.         mov     dx,offset ender         ; Ring them bells.
  238.         int     dos
  239. read6c: test    flags.remflg,dserial    ; serial display?
  240.         jnz     read6d                  ; nz = yes
  241.         call    clrmod                  ; clear Mode Line
  242.         call    rprpos                  ; Put prompt here.
  243. read6d: jmp     rskp
  244. READ    ENDP
  245.  
  246.  
  247. ;       Receive routines
  248.  
  249. ;       Receive init
  250.  
  251. RINIT   PROC    NEAR
  252.         mov     ah,pack.numtry          ; Get the number of tries.
  253.         cmp     ah,imxtry               ; Reached the maximum number of tries?
  254.         jl      rinit2
  255.         mov     dx,offset ermes7
  256.         test    flags.remflg,dquiet     ; quiet display mode?
  257.         jnz     rinit1                  ; nz = yes. Don't write to screen.
  258.         cmp     flags.destflg,2         ; Receiving to the screen?
  259.         je      rinit1                  ; e = yes, no formatted display
  260.         call    erpos                   ; Position cursor.
  261.         mov     ah,prstr
  262.         int     dos                     ; Print an error message.
  263. rinit1: mov     bx,dx
  264.         mov     ah,trans.chklen
  265.         mov     curchk,ah               ; Store checksum length we want to use.
  266.         mov     trans.chklen,1          ; Send init checksum is always 1 char.
  267.         call    errpack                 ; Send error packet just in case.
  268.         mov     ah,curchk
  269.         mov     trans.chklen,ah         ; Reset to desired value.
  270.         jmp     abort                   ; Change the state to abort.
  271. rinit2: inc     ah                      ; Increment it.
  272.         mov     pack.numtry,ah          ; Save the updated number of tries.
  273.         mov     ax,pack.argbk2          ; get packet type if here from get
  274.         cmp     flags.getflg,1          ; Have we already read in the packet?
  275.         je      rin21a                  ; Yes, so don't call RPACK.
  276.         mov     ah,dtrans.seol          ; restore default end-of-line char
  277.         mov     trans.seol,ah
  278.         mov     ah,trans.chklen
  279.         mov     curchk,ah               ; Save checksum length we want to use.
  280.         mov     trans.chklen,1          ; Use 1 char for init packet.
  281.         call    rpack                   ; Get a packet.
  282.          jmp    rin22                   ; Trashed packet: nak, retry.
  283.         call    pktsize                 ; report packet size
  284.         push    ax
  285.         mov     ah,curchk
  286.         mov     trans.chklen,ah         ; Reset to desired value.
  287.         pop     ax
  288.         cmp     flags.cxzflg,0          ; does the user want out now?
  289.         jne     rinit4                  ; ne = yes, quit
  290. rin21a: cmp     ah,'S'                  ; Is it a send initiate packet?
  291.         jne     rinit3                  ; If not see if its an error.
  292. rin21:  mov     flags.getflg,0          ; Reset flag.
  293.         mov     pack.numtry,0           ; Reset the number of tries.
  294.         mov     ax,pack.argblk  ; Returned packet number. (Synchronize them.)
  295.         inc     ax                      ; Increment it.
  296.         and     ax,3FH                  ; Turn off the two high order bits.
  297.         mov     pack.pktnum,ax          ; Save modulo 64 of the number.
  298.         inc     pack.numpkt             ; Increment the number of packets.
  299.         mov     ax,pack.argbk1          ; Get the number of arguments received
  300.         mov     bx,offset data          ; Get a pointer to the data
  301.         call    spar                    ; Get data into the proper variables
  302.         mov     bx,offset data          ; Get a pointer to our data block
  303.         call    rpar                    ; Set up the receive parameters
  304.         xchg    ah,al
  305.         mov     ah,0
  306.         mov     pack.argbk1,ax          ; Store returned number of arguments
  307.         mov     ah,trans.chklen         ; Checksum length we'll use.
  308.         mov     curchk,ah               ; Save it.
  309.         mov     trans.chklen,1          ; Use 1 char for init packet.
  310.         mov     ah,'Y'                  ; Acknowledge packet.
  311.         call    spack                   ; Send the packet.
  312.          jmp    abort
  313.         mov     ah,curchk               ; Checksum length we'll use.
  314.         mov     trans.chklen,ah         ; Reset to desired value.
  315.         mov     pack.state,'F'          ; Set the state to file send.
  316.         ret
  317. rin22:  call    nak0                    ; nak the packet
  318.         mov     ah,curchk               ; and only now change checksum from 1
  319.         mov     trans.chklen,ah         ; Reset to desired value.
  320.         ret                             ; try again
  321.  
  322. rinit3: cmp     ah,'E'                  ; Is it an error packet?
  323.         jne     rinit4                  ; ne = no
  324.         call    error                   ; yes
  325. rinit4: jmp     abort
  326. RINIT   ENDP
  327.  
  328.  
  329. ;       Receive file
  330.  
  331. RFILE   PROC    NEAR
  332.         mov     dl,maxtry
  333.         cmp     pack.numtry,dl  ; Have we reached the maximum number of tries?
  334.         jl      rfile1
  335.         mov     dx,offset ermes8
  336.         jmp     rcverr                  ; do error exit
  337. rfile1: inc     pack.numtry             ; Save the updated number of tries.
  338.         call    rpack                   ; Get a packet.
  339.          jmp    nak0                    ;  Trashed packet: nak, retry.
  340.         call    pktsize                 ; report packet size
  341.         cmp     ah,'S'                  ; Is it a send initiate packet?
  342.         je      rfil10
  343.         cmp     ah,'I'                  ; An Initialization packet?
  344.         je      rfil10                  ; e = yes, don't decode it
  345. rfil09: call    dodec                   ; Decode all other incoming packets.
  346.         jmp     rfile2                  ;  No, try next type.
  347. rfil10: mov     dl,imxtry               ; S and I packets
  348.         cmp     pack.numtry,dl          ; Reached the maximum number of tries?
  349.         jl      rfil12                  ; If not proceed.
  350.         mov     dx,offset ermes7
  351.         jmp     rcverr                  ; do error exit
  352. rfil12: mov     ax,pack.pktnum          ; Get the present packet number.
  353.         cmp     ax,0                    ; Had we wrapped around?
  354.         jne     rfilx
  355.         mov     ax,64
  356. rfilx:  dec     ax                      ; Decrement.
  357.         cmp     ax,pack.argblk  ; Is the packet's number one less than now?
  358.         je      rfil13
  359.         jmp     nak0                    ; No, NAK and try again.
  360. rfil13: mov     pack.numtry,0           ; Reset the number of tries.
  361.         mov     bx,offset data          ; Get a pointer to our data block.
  362.         call    rpar                    ; Set up the parameter information.
  363.         xchg    ah,al
  364.         mov     ah,0
  365.         mov     pack.argbk1,ax          ; Save the number of arguments.
  366.         mov     ah,'Y'                  ; Acknowledge packet.
  367.         call    spack                   ; Send the packet.
  368.          jmp    abort
  369.         ret
  370. rfile2: cmp     ah,'Z'                  ; Is it an EOF packet?
  371.         jne     rfile3                  ;  No, try next type.
  372.         mov     dl,maxtry               ; Z packets
  373.         cmp     pack.numtry,dl  ; Have we reached the maximum number of tries?
  374.         jl      rfil21                  ; If not proceed.
  375.         mov     dx,offset ermes9
  376.         jmp     rcverr                  ; do error exit
  377. rfil21: mov     ax,pack.pktnum          ; Get the present packet number.
  378.         cmp     ax,0                    ; Had we wrapped around?
  379.         jne     rfily
  380.         mov     ax,64
  381. rfily:  dec     ax                      ; Decrement.
  382.         cmp     ax,pack.argblk  ; Is the packet's number one less than now?
  383.         je      rfil24
  384.         jmp     nak0                    ; No, NAK and try again.
  385. rfil24: mov     pack.numtry,0
  386.         mov     pack.argbk1,0   ; No data. (The packet number is in argblk.)
  387.         mov     ah,'Y'                  ; Acknowledge packet.
  388.         call    spack                   ; Send the packet.
  389.          jmp    abort
  390.         ret
  391. rfile3: cmp     ah,'F'                  ; Start of file (F or X packet)?
  392.         je      rfil31                  ; e = yes.
  393.         cmp     ah,'X'                  ; Text header packet?
  394.         jne     rfile4                  ; Neither one.
  395.         mov     flags.xflg,1            ; 'X', say receiving to the screen
  396. rfil31: mov     ax,pack.argblk          ; Get the packet number.
  397.         cmp     ax,pack.pktnum          ; Is it the right packet number?
  398.         je      rfil32
  399.         jmp     nak1                    ; No, NAK it and try again.
  400. rfil32: inc     ax                      ; Increment the packet number.
  401.         and     ax,3FH                  ; Turn off the two high order bits.
  402.         mov     pack.pktnum,ax          ; Save modulo 64 of the number.
  403.         inc     pack.numpkt             ; Increment the number of packets.
  404.         mov     filopn,0                ; assume not writing to a disk file
  405.         mov     ax,0            ; tell statistics this was a receive operation
  406.         call    endtim                  ; get tod & size of file transfer
  407.         call    gofil                   ; Get a file to write to.
  408.          jmp    abort
  409.         call    begtim                  ; start next statistics group
  410.         mov     chrcnt,maxpack          ; reset output buffer to be empty
  411.         cmp     flags.xflg,0            ; writing to a disk file?
  412.         jne     rfil32a                 ; ne = no
  413.         mov     filopn,2                ; Disk file open for writing
  414. rfil32a:
  415.         test    flags.remflg,dserial    ; serial display mode?
  416.         jz      rfil33                  ; z = no
  417.         mov     ah,prstr
  418.         mov     dx,offset crlf          ; display cr/lf
  419.         int     dos
  420. rfil33:
  421.         mov     pack.numtry,0           ; Reset the number of tries.
  422.         mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
  423.         mov     ah,'Y'                  ; Acknowledge packet.
  424.         call    spack                   ; Send the packet.
  425.          jmp    abort
  426.         mov     pack.state,'D'          ; Set the state to data receive.
  427.         ret
  428. rfile4: cmp     ah,'B'                  ; End of transmission?
  429.         jne     rfile5                  ; ne = no
  430.         mov     ax,pack.pktnum
  431.         cmp     ax,pack.argblk          ; Do we match?
  432.         je      rfil41
  433.         jmp     nak1                    ; No, NAK it and try again.
  434. rfil41: mov     pack.argbk1,0   ; No data.  (Packet number already in argblk).
  435.         mov     ah,'Y'                  ; Acknowledge packet.
  436.         call    spack                   ; Send the packet.
  437.          jmp    abort
  438.         mov     pack.state,'C'          ; Set the state to complete.
  439.         ret
  440. rfile5: cmp     ah,'E'                  ; Is it an error packet?
  441.         jne     rfile6                  ; ne = no
  442.         call    error
  443. rfile6: jmp     abort
  444. RFILE   ENDP
  445.  
  446.  
  447. ; Receive data
  448.  
  449. RDATA   PROC    NEAR
  450.         mov     dl,maxtry
  451.         cmp     pack.numtry,dl          ; Get the number of tries.
  452.         jl      rdata1
  453.         mov     dx,offset erms10
  454.         jmp     rcverr                  ; do error exit
  455. rdata1: inc     pack.numtry             ; Save the updated number of tries.
  456.         call    rpack                   ; Get a packet.
  457.          jmp    nak0                    ;  Trashed packet: nak, retry.
  458.         call    pktsize                 ; report packet size
  459.         cmp     ah,'D'                  ; Is it a data packet?
  460.         je      rdat11                  ; e = yes
  461.         call    dodec                   ; Decode data.
  462.         jmp     rdata2                  ;  No, try next type.
  463.                                         ; D packets
  464. rdat11: mov     ax,pack.pktnum          ; Get the present packet number.
  465.         cmp     ax,pack.argblk          ; Is the packet's number correct?
  466.         jz      rdat14
  467.         mov     dl,maxtry
  468.         cmp     pack.numtry,dl  ; Have we reached the maximum number of tries?
  469.         jl      rdat12                  ; If not proceed.
  470.         mov     dx,offset erms10
  471.         jmp     rcverr                  ; do error exit
  472. rdat12: mov     ax,pack.pktnum
  473.         cmp     ax,0                    ; Had we wrapped around?
  474.         jne     rdatx
  475.         mov     ax,64
  476. rdatx:  dec     ax
  477.         cmp     ax,pack.argblk  ; Is the packet's number one less than now?
  478.         je      rdat13
  479.         jmp     nak0                    ; No, NAK it and try again.
  480. rdat13: mov     pack.numtry,0           ; Reset number of tries.
  481.         mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
  482.         mov     ah,'Y'                  ; Acknowledge packet.
  483.         call    spack                   ; Send the packet.
  484.          jmp    abort
  485.         ret
  486. rdat14: inc     pack.pktnum             ; Increment the packet number
  487.         and     pack.pktnum,3fh         ; Save modulo 64 of the number
  488.         inc     pack.numpkt             ; Increment the number of packets.
  489.         mov     ax,pack.argbk1          ; Get the length of the data.
  490.         cmp     flags.cxzflg,0          ; Has the user typed a ^X or ^Z?
  491.         je      rdt14x                  ; No, write out the data.
  492.         cmp     flags.abfflg,1          ; Discard incomplete files?
  493.         je      rdat15          ; If yes don't write data out to file.
  494. rdt14x: call    ptchr                   ; decode the data and output to file
  495.          jmp    abort                   ;  Unable to write out chars; abort.
  496. rdat15: mov     pack.numtry,0           ; Reset the number of tries.
  497.         mov     pack.argbk1,0   ; No data.  (Packet number still in argblk.)
  498.         cmp     flags.cxzflg,0          ; Interrupt file transfer?
  499.         je      rdat16                  ; Nope.
  500.         mov     bx,offset data          ; Send data in ACK in case remote
  501.         mov     ah,flags.cxzflg         ;  knows about ^X/^Z.
  502.         mov     [bx],ah                 ; Put data into the packet.
  503.         mov     pack.argbk1,1           ; Set data size to 1.
  504.         mov     cx,1
  505.         call    doenc
  506. rdat16: mov     ah,'Y'                  ; Acknowledge packet.
  507.         call    spack                   ; Send the packet.
  508.          jmp    abort
  509.         ret
  510. rdata2: cmp     ah,'F'                  ; Start of file?
  511.         je      rdat20                  ; e = yes
  512.         cmp     ah,'X'                  ; Text header packet?
  513.         jne     rdata3                  ;  No, try next type.
  514. rdat20: mov     dl,maxtry               ; F or X packet
  515.         cmp     pack.numtry,dl          ; Reached the max number of tries?
  516.         jl      rdat21                  ; If not proceed.
  517.         mov     dx,offset ermes8
  518.         jmp     rcverr                  ; do error exit
  519. rdat21: mov     ax,pack.pktnum
  520.         cmp     ax,0                    ; Had we wrapped around?
  521.         jne     rdaty
  522.         mov     ax,64
  523. rdaty:  dec     ax
  524.         cmp     ax,pack.argblk  ; Is the packet's number one less than now?
  525.         je      rdat22
  526.         jmp     nak0                    ; No, NAK it and try again.
  527. rdat22: mov     pack.numtry,0           ; Reset number of tries.
  528.         mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
  529.         mov     ah,'Y'                  ; Acknowledge packet.
  530.         call    spack                   ; Send the packet.
  531.          jmp    abort
  532.         ret
  533. rdata3: cmp     ah,'Z'                  ; Is it a EOF packet?
  534.         je      rdat3x                  ; e = yes
  535.         jmp     rdata4                  ; Try and see if its an error.
  536. rdat3x: mov     ax,pack.pktnum          ; Get the present packet number.
  537.         cmp     ax,pack.argblk          ; Is the packet's number correct?
  538.         je      rdat32
  539.         jmp     nak0                    ; No, NAK it and try again.
  540. rdat32: inc     ax                      ; Increment the packet number.
  541.         and     ax,3FH                  ; Turn off the two high order bits.
  542.         mov     pack.pktnum,ax          ; Save modulo 64 of the number.
  543.         inc     pack.numpkt
  544.         cmp     flags.cxzflg,0          ; Do we want to discard the file?
  545.         jne     rdt32x                  ; Yes.
  546.         cmp     pack.argbk1,1           ; One piece of data?
  547.         jne     rdat33                  ; Nope - finish writing out file?
  548.         cmp     data,'D'                ; is the data "D" for discard?
  549.         jne     rdat33                  ; Nope - write out file.
  550. rdt32x: cmp     flags.abfflg,0          ; Keep incomplete files?
  551.         je      rdat33                  ; Yes, go write it out.
  552.         cmp     flags.xflg,1            ; Writing to the screen?
  553.         je      rdt32y                  ; Don't close "file".
  554.         cmp     flags.destflg,2         ; file destination = screen?
  555.         je      rdt32y                  ; e = yes, no file to close
  556.         push    bx
  557.         mov     ah,close2               ; DOS 2.0 file close
  558.         mov     bx,diskio.handle        ; file handle
  559.         int     dos                     ; Kill it, ignore errors.
  560.         pop     bx
  561.         mov     filopn,0                ; File closed now.
  562.         mov     dx,offset diskio.string ; get the filename
  563.         mov     ah,del2                 ; DOS 2.0 file delete
  564.         int     dos
  565. rdt32y: cmp     flags.cxzflg,'X'        ; Kill one file or all?
  566.         jne     rdat36                  ; No so leave flag alone.
  567.         call    cxmsg                   ; Clear msg about interrupt.
  568.         test    flags.remflg,dquiet     ; quiet display?
  569.         jnz     rdt32z                  ; nz = yes
  570.         cmp     flags.destflg,2         ; Receiving to the screen?
  571.         je      rdt32z                  ; e = yes, no formatted display
  572.         call    intmsg
  573. rdt32z: mov     flags.cxzflg,0          ; Reset - ^X only kills one file
  574.         jmp     rdat36
  575. rdat33: cmp     flags.eofcz,0           ; should we write a ^Z?
  576.         jz      rdat35                  ; no, keep going
  577.         cmp     flags.xflg,0            ; writing to a file?
  578.         jne     rdat35                  ; no, skip ^Z
  579. rdt33x: cmp     chrcnt,0                ; any space left in output buffer?
  580.         jg      rdat34                  ; g = yes
  581.         call    outbuf                  ; Write out buffer if no room for ^Z.
  582.          jmp    abort
  583. rdat34: mov     cl,'Z'- 40h             ; Put in a ^Z for EOF.
  584.         push    bx
  585.         mov     bx,bufpnt               ; Get the dma pointer
  586.         mov     [bx],cl                 ; Add it.
  587.         pop     bx
  588.         dec     chrcnt
  589. rdat35: call    outbuf                  ; Output the last buffer.
  590.          jmp    abort                   ; Give up if the disk is full.
  591.         cmp     flags.xflg,1            ; Writing to the screen?
  592.         je      rdat37                  ; Yes, don't close "file".
  593.         cmp     flags.destflg,2         ; file destination = screen?
  594.         je      rdat37                  ; e = yes, no file to close
  595.         mov     ah,close2               ; DOS 2.0 file close
  596.         push    bx
  597.         mov     bx,diskio.handle        ; file handle
  598.         int     dos
  599.         pop     bx
  600.         mov     filopn,0                ; File closed now.
  601. rdat36: cmp     flags.destflg,0         ; Writing to printer?
  602.         jne     rdat37                  ; ne = no, skip next part.
  603.         cmp     flags.xflg,1            ; Writing to screen?
  604.         je      rdat37                  ; Yes, skip this part.
  605.         mov     dl,ff                   ; Send a form feed.
  606.         mov     ah,lstout               ; Write out to first printer.
  607.         int     dos
  608. rdat37: mov     pack.numtry,0           ; Reset the number of tries.
  609.         mov     pack.argbk1,0   ; No data.  (The packet number is in argblk.)
  610.         mov     ah,'Y'                  ; Acknowledge packet.
  611.         call    spack                   ; Send the packet.
  612.          jmp    abort
  613.         mov     pack.state,'F'
  614.         ret
  615. rdata4: cmp     ah,'E'                  ; Is it an error packet?
  616.         jne     rdata5                  ; ne = no
  617.         call    error
  618. rdata5: jmp     abort
  619. RDATA   ENDP
  620.  
  621. ; Error exit. Enter with dx pointing to error message. [jrd]
  622. rcverr  proc    near
  623.         test    flags.remflg,dquiet; quiet display mode?
  624.         jnz     rcver1                  ; nz = yes. Don't write to screen
  625.         cmp     flags.destflg,2         ; Receiving to the screen?
  626.         je      rcver1                  ; e = yes, no formatted display
  627.         call    erpos                   ; Position cursor.
  628.         mov     ah,prstr
  629.         int     dos                     ; Print an error message.
  630. rcver1: mov     bx,dx                   ; set bx to error message
  631.         call    errpack                 ; Send error packet just in case.
  632.         jmp     abort                   ; Change the state to abort.
  633. rcverr  endp
  634.  
  635. ; Jumping to this location is like retskp.  It assumes the instruction
  636. ;   after the call is a jmp addr.
  637.  
  638. RSKP    PROC    NEAR
  639.         pop     bp
  640.         add     bp,3
  641.         push    bp
  642.         ret
  643. RSKP    ENDP
  644.  
  645. R       PROC    NEAR
  646.         ret
  647. R       ENDP
  648.  
  649. code    ends
  650.         end
  651.