STTL  Receve routine

*
*       This routine receives a file from the remote kermit and
*       writes it to a disk file
*
*               Input  Filename returned from comnd, if any
*
*               Output If file transfer is good, file is output to disk
*
*               Registers destroyed    A,X,Y
*

receve equ *
*get filename
 ldx #filena
 jsr pstr
 ldx #fcb1
 jsr inline
 ldx #filenr
 jsr pstr
 ldx #fcb2
 jsr inline
        jsr     rswt            * Perform send-switch routine
        jmp     kermit          * Go back to main routine

rswt   lda     #'R             * The state is receive-init
        sta     state           * Set that up
        lda     #$00            * Zero the packet sequence number
        sta     n               *               ..
        sta     numtry          *       Number of tries
        sta     oldtry          *       Old number of tries
        sta     eofinp          *       End of input flag
        sta     errcod          *       Error indicator
        sta     rtot            *       Total received characters
        sta     rtot+1          *               ..
        sta     stot            *       Total Sent characters
        sta     stot+1          *               ..
        sta     rchr            *       Received characters, current file
        sta     rchr+1          *               ..
        sta     schr            *       and Sent characters, current file
        sta     schr+1          *               ..
 jsr qures
rswt1  lda     state           * Fetch the current system state
        cmp a     #'D             * Are we trying to receive data?
        bne     rswt2           * If not, try the next one
        jsr     rdat            * Go try for the data packet
        jmp     rswt1           * Go back to the top of the loop
rswt2  cmp a     #'F             * Do we need a file header packet?
        bne     rswt3           * If not, continue checking
        jsr     rfil            * Go get the file-header
        jmp     rswt1           * Return to top of loop
rswt3  cmp a     #'R             * Do we need the init?
        bne     rswt41           * No, try next state
        jsr     rini            * Yes, go get it
        jmp     rswt1           * Go back to top
rswt41 cmpa #'B
 bne rswt4
 jsr rrbrk1
 jmp rswt1
rswt4  cmp a     #'C             * Have we completed the transfer?
        bne     rswt5           * No, we are out of states, fail
        lda     #true           * Load AC for true return
        rts                     * Return
rswt5  lda     #false          * Set up AC for false return
        rts                     * Return

rini   ldx     #pdbuf         * Point kerbf1 at the packet data buffer
        stx     kerbf1          *               ..
        lda     numtry          * Get current number of tries
        inc     numtry          * Increment it for next time
        cmp a     maxtry          * Have we tried this one enought times
        bne     rini1           * Not yet, go on
        bra     rini1a          * Yup, go abort this transfer
rini1  jmp     rini2           * Continue
rini1a lda     #'A             * Change state to 'abort'
        sta     state           *               ..
        lda     #errcri         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Load AC with false status
        rts                     *       and return
rini2 equ *
*send r packet to request file
 clr b
rinif2 ldy #fcb2
 lda b,y
 cmpa #$00 move file header to packet
 beq rinif1 fini
 ldy #pdbuf
 sta b,y
 inc b
 bra rinif2
rinif1 stb pdlen
 lda #'R
 sta ptype
 lda n
 sta pnum
 jsr spak send it
  jsr     rpak            * Go try to receive a packet
        sta     rstat           * Store the return status for later
        lda     ptype           * Fetch the packet type we got
        cmp a     #'S             * Was it an 'Init'?
        bne     rini2a          * No, check the return status
        jmp     rinici          * Go handle the init case
rini2a lda     rstat           * Fetch the saved return status
        cmp a     #false          * Is it false?
        beq     rini2b          * Yes, just return with same state
        lda     #'A             * No, abort this transfer
        sta     state           * State is now 'abort'
        lda     #errcri         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Set return status to 'false'
        rts                     * Return
rini2b lda     n               * Get packet sequence number expected
        sta     pnum            * Stuff that parameter at the Nakit routine
        jsr     nakit           * Go send the Nak
        lda     #false          * Set up failure return status
        rts                     *       and go back

rinici lda     pnum            * Get the packet number we received
        sta     n               * Synchronize our packet numbers with this
        jsr     rpar            * Load in the init stuff from packet buffer
        jsr     spar            * Stuff our init info into the packet buffer
        lda     #'Y             * Store the 'Ack' code into the packet type
        sta     ptype           *               ..
        lda     n               * Get sequence number
        sta     pnum            * Stuff that parameter
        lda     #off            * No, punt 8-bit quoting
        sta     ebqmod          *               ..
        lda     #$06            * BTW, the data length is now only 6
rinic1 sta     pdlen           * Store packet data length
        jsr     spak            * Send that packet
        lda     numtry          * Move the number of tries for this packet
        sta     oldtry          *       to prev packet try count
        lda     #$00            * Zero
        sta     numtry          *       the number of tries for current packet
        jsr     incn            * Increment the packet number once
        lda     #'F             * Advance to 'File-header' state
        sta     state           *               ..
        lda     #true           * Set up return code
        rts                     * Return

rfil   lda     numtry          * Get number of tries for this packet
        inc     numtry          * Increment it for next time around
        cmp a     maxtry          * Have we tried too many times?
        bne     rfil1           * Not yet
        bra     rfil1a          * Yes, go abort the transfer
rfil1  jmp     rfil2           * Continue transfer
rfil1a bra rfilla
rfil2 jsr rpak *try to receive a packet
        sta     rstat           * Save the return status
        lda     ptype           * Get the packet type we found
        cmp a     #'S             * Was it an 'init' packet?
        bne     rfil2a          * Nope, try next one
        jmp     rfilci          * Handle the init case
rfil2a cmp a     #'Z             * Is it an 'eof' packet??
        bne     rfil2b          * No, try again
        jmp     rfilce          * Yes, handle that case
rfil2b cmp a     #'F             * Is it a 'file-header' packet???
        bne     rfil2c          * Nope
        jmp     rfilcf          * Handle file-header case
rfil2c cmp a     #'B             * Break packet????
        bne     rfil2x          * Wrong, go get the return status
        jmp     rfilcb          * Handle a break packet
rfil2x cmpa #'E
 bne rfil2d
 jsr pemsg send error packet info to console
 jmp rfilla and abort
rfil2d lda     rstat           * Fetch the return status from Rpak
        cmp a     #false          * Was it a false return?
        beq     rfil2e          * Yes, Nak it and return
rfilla        lda     #'A             * No, abort this transfer, we don't know what
        sta     state           *       this is
        lda     #errcrf         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Set up failure return code
        rts                     *       and return
rfil2e lda     n               * Move the expected packet number
        sta     pnum            *       into the spot for the parameter
        jsr     nakit           * Nak the packet
        lda     #false          * Do a false return but don't change state
        rts                     * Return
rfilci lda     oldtry          * Get number of tries for prev packet
        inc     oldtry          * Increment it
        cmp a     maxtry          * Have we tried this one too much?
        bne     rfili1          * Not quite yet
        bra     rfili2          * Yes, go abort this transfer
rfili1 jmp     rfili3          * Continue
rfili2
rfili5 lda     #'A             * Move abort code
        sta     state           *       to system state
        lda     #errcrf         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Prepare failure return
        rts                     *       and go back
rfili3 lda     pnum            * See if pnum=n-1
        clc                     *               ..
        add a     #$01            *               ..
        cmp a     n               *               ..
        beq     rfili4          * If it does, than we are ok
        jmp     rfili5          * Otherwise, abort
rfili4 jsr     spar            * Set up the init parms in the packet buffer
        lda     #'Y             * Set up the code for Ack
        sta     ptype           * Stuff that parm
        lda     #$06            * Packet length for init
        sta     pdlen           * Stuff that also
        jsr     spak            * Send the ack
        lda     #$00            * Clear out
        sta     numtry          *       the number of tries for current packet
        lda     #true           * This is ok, return true with current state
        rts                     * Return
rfilce lda     oldtry          * Get number of tries for previous packet
        inc     oldtry          * Up it for next time we have to do this
        cmp a     maxtry          * Too many times for this packet?
        bne     rfile1          * Not yet, continue
        bra     rfile2          * Yes, go abort it
rfile1 jmp     rfile3          *               ..
rfile2
rfile5 lda     #'A             * Load abort code
        sta     state           *       into current system state
        lda     #errcrf         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Prepare failure return
        rts                     *       and return
rfile3 lda     pnum            * First, see if pnum=n-1
        clc                     *               ..
        add a     #$01            *               ..
        cmp a     n               *               ..
        beq     rfile4          * If so, continue
        jmp     rfile5          * Else, abort it
rfile4 lda     #'Y             * Load 'ack' code
        sta     ptype           * Stuff that in the packet type
        lda     #$00            * This packet will have a packet data length
        sta     pdlen           *       of zero
        jsr     spak            * Send the packet out
        lda     #$00            * Zero number of tries for current packet
        sta     numtry          *               ..
        lda     #true           * Set up successful return code
        rts                     *       and return
rfilcf lda     pnum            * Does pnum=n?
        cmp a     n               *               ..
        bne     rfilf1          * If not, abort
        jmp     rfilf2          * Else, we can continue
rfilf1 lda     #'A             * Load the abort code
        sta     state           *       and stuff it as current system state
        lda     #errcrf         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Prepare failure return
        rts                     *       and go back
rfilf2 equ *
* open file for write (harris)
 ldx #fcb1
rfnc lda 0,x+
 cmpa #$00
 bne rfnc
 lda #$20 change terminator to space
 leax -1,x
 sta 0,x
 ldx #fcb1 setup i/p point
 stx $cc14 to line i/p buff
 ldx #fcb
 jsr getfil parse file spec
 bcs fer1 error in file name
 lda #2 open for write
 sta 0,x set to txt
 jsr setext set to text
 jsr fms open file for write
 bne fer1 file open error
        lda     #'Y             * Stuff code for 'ack'
        sta     ptype           * Into packet type parm
        lda     #$00            * Stuff a zero in as the packet data length
        sta     pdlen           *               ..
        jsr     spak            * Ack the packet
        lda     numtry          * Move current tries to previous tries
        sta     oldtry          *               ..
        lda     #$00            * Clear the
        sta     numtry          * Number of tries for current packet
        jsr     incn            * Increment the packet sequence number once
        lda     #'D             * Advance the system state to 'receive-data'
        sta     state           *               ..
        lda     #true           * Set up success return
        rts                     *       and go back

fer1 jsr rpterr tell userof error
 jsr fmscls
 jmp main

rfilcb lda     pnum            * Does pnum=n?
        cmp a     n               *               ..
        bne     rfilb1          * If not, abort the transfer process
        jmp     rfilb2          * Otherwise, we can continue
rfilb1 lda     #'A             * Code for abort
        sta     state           * Stuff that into system state
        lda     #errcrf         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          * Load failure return status
        rts                     *       and return
rfilb2 lda     #'Y             * Set up 'ack' packet type
        sta     ptype           *               ..
        lda     #$00            * Zero out
        sta     pdlen           *       the packet data length
        jsr     spak            * Send out this packet
        lda     #'C             * Advance state to 'complete'
        sta     state           *       since we are now done with the transfer
        lda     #true           * Return a true
        rts                     *               ..

rdat   lda     numtry          * Get number of tries for current packet
        inc     numtry          * Increment it for next time around
        cmp a     maxtry          * Have we gone beyond number of tries allowed?
        bne     rdat1           * Not yet, so continue
        bra     rdat1a          * Yes, we have, so abort
rdat1  jmp     rdat2           *               ..
rdat1a lda     #'A             * Code for 'abort' state
        sta     state           * Stuff that in system state
        lda     #errcrd         * Fetch the error index
        sta     errcod          *       and store it as the error code
 jsr closef
        lda     #false          * Set up failure return code
        rts                     *       and go back
rdat2  jsr     rpak            * Go try to receive a packet
        sta     rstat           * Save the return status for later
        lda     ptype           * Get the type of packet we just picked up
        cmp a     #'D             * Was it a data packet?
        bne     rdat2a          * If not, try next type
        jmp     rdatcd          * Handle a data packet
rdat2a cmp a     #'F             * Is it a file-header packet?
        bne     rdat2b          * Nope, try again
        jmp     rdatcf          * Go handle a file-header packet
rdat2b cmp a     #'Z             * Is it an eof packet???
        bne     rdat2x          * If not, go check the return status from rpak
        jmp     rdatce          * It is, go handle eof processing
rdat2x cmpa #'E
 bne rdat2c
 jsr pemsg
 bra rdater
rdat2c lda     rstat           * Fetch the return status
        cmp a     #false          * Was it a failure return?
        beq     rdat2d          * If it was, Nak it
rdater        lda     #'A             * Otherwise, we give up the whole transfer
        sta     state           * Set system state to 'false'
        lda     #errcrd         * Fetch the error index
        sta     errcod          *       and store it as the error code
 jsr closef
        lda     #false          * Set up a failure return
        rts                     *       and go back
rdat2d lda     n               * Get the expected packet number
        sta     pnum            * Stuff that parameter for Nak routine
        jsr     nakit           * Send a Nak packet
        lda     #false          * Give failure return
        rts                     * Go back

rdatcd lda     pnum            * Is pnum the right sequence number?
        cmp a     n               *               ..
        bne     rdatd1          * If not, try another approach
        jmp     rdatd7          * Otherwise, everything is fine
rdatd1 lda     oldtry          * Get number of tries for previous packet
        inc     oldtry          * Increment it for next time we need it
        cmp a     maxtry          * Have we exceeded that limit?
        bne     rdatd2          * Not just yet, continue
        bra     rdatd3          * Yes, go abort the whole thing
rdatd2 jmp     rdatd4          * Just continue working on the thing
rdatd3
rdatd6 lda     #'A             * Load 'abort' code into the
        sta     state           *       current system state
        lda     #errcrd         * Fetch the error index
        sta     errcod          *       and store it as the error code
 jsr closef
        lda     #false          * Make this a failure return
        rts                     * Return
rdatd4 lda     pnum            * Is pnum=n-1.. Is the received packet
        clc                     *       the one previous to the currently
        add a     #$01            *       expected packet?
        cmp a     n               *               ..
        beq     rdatd5          * Yes, continue transfer
        jmp     rdatd6          * Nope, abort the whole thing
rdatd5 jsr     spar            * Go set up init data
        lda     #'Y             * ***************** an ack to **********t
        sta     ptype           *               ..
        lda     #$00            *               ..
        sta     pdlen           *               ..
        jsr     spak            * Go send the ack
        lda     #$00            * Clear the
        sta     numtry          *       number of tries for current packet
        lda     #true           *               ..
        rts                     * Return (successful!)
rdatd7 jsr     bufemp          * Go empty the packet buffer
        lda     #'Y             * Set up an ack packet
        sta     ptype           *               ..
        lda     n               *               ..
        sta     pnum            *               ..
        lda     #$00            * Don't forget, there is no data
        sta     pdlen           *               ..
        jsr     spak            * Send it!
        lda     numtry          * Move tries for current packet count to
        sta     oldtry          *       tries for previous packet count
        lda     #$00            * Zero the
        sta     numtry          *       number of tries for current packet
        jsr     incn            * Increment the packet sequence number once
        lda     #'D             * Advance the system state to 'receive-data'
        sta     state           *               ..
        lda     #true           *               ..
        rts                     * Return (successful)

rdatcf lda     oldtry          * Fetch number of tries for previous packet
        inc     oldtry          * Increment it for when we need it again
        cmp a     maxtry          * Have we exceeded maximum tries allowed?
        bne     rdatf1          * Not yet, go on
        bra     rdatf2          * Yup, we have to abort this thing
rdatf1 jmp     rdatf3          * Just continue the transfer
rdatf2
rdatf5 lda     #'A             * Move 'abort' code to current system state
        sta     state           *               ..
        lda     #errcrd         * Fetch the error index
        sta     errcod          *       and store it as the error code
 jsr closef
        lda     #false          *               ..
        rts                     *       and return false
rdatf3 lda     pnum            * Is this packet the one before the expected
        clc                     *       one?
        add a     #$01            *               ..
        cmp a     n               *               ..
        beq     rdatf4          * If so, we can still ack it
        jmp     rdatf5          * Otherwise, we should abort the transfer
rdatf4 lda     #'Y             * Load 'ack' code
        sta     ptype           * Stuff that parameter
        lda     #$00            * Use zero as the packet data length
        sta     pdlen           *               ..
        jsr     spak            * Send it!
        lda     #$00            * Zero the number of tries for current packet
        sta     numtry          *               ..
        lda     #true           *               ..
        rts                     * Return (successful)

rdatce lda     pnum            * Is this the packet we are expecting?
        cmp a     n               *               ..
        bne     rdatf5          * No, we should go abort
        jmp     rdate2          * Yup, go handle it
rdate1 lda     #'A             * Load 'abort' code into
        sta     state           *       current system state
        lda     #errcrd         * Fetch the error index
        sta     errcod          *       and store it as the error code
        lda     #false          *               ..
        rts                     * Return (failure)
rdate2 lda     #'Y             * Get set up for the ack
        sta     ptype           * Stuff the packet type
        lda     n               *       packet number
        sta     pnum            *               ..
        lda     #$00            *       and packet data length
        sta     pdlen           *       parameters
        jsr     spak            * Go send it!

 jsr closef
 lda #'B
 sta state complete
 lda numtry
 sta oldtry
 lda #$00
 sta numtry
 jsr incn
 lda #true
 rts exit


closef jmp fmscls

rrbrk1 lda numtry
 inc numtry
 cmpa maxtry
 bne rrbrk2 not excceded try count
 jmp rdate1 too many tries
rrbrk2 jsr rpak
 sta rstat
 lda ptype
 cmpa #'Z
 bne rrbrk3
 jmp rreof reack last
rrbrk3 cmpa #'B
 bne rrbrk4
 jmp rrbp ack the break packet
rrbrk4 lda rstat
 cmp a #false
 lbeq rdat2d nak it
 bra rdate1 wrong type ..abort

rreof lda oldtry
 inc oldtry
 cmpa maxtry
 lbeq rdate1 error in packet #
 lda pnum
 adda #$01 prev
 cmpa n
 beq rdate4 ack it
 lbra rdate1 error in packet #

rrbp lda pnum
 cmpa n
 lbne rdate1 abort wrong packet #
 lbsr rdate4 ack B.. packet.
 bra rrds


rdate4 lda #'Y
 sta ptype
 lda n
 sta pnum
 lda #$00
 sta pdlen
 jsr spak send ack
 rts

rrds lda #'C
 sta state
 lda #true complete 
 rts