STTL Send routine * * This routine reads a file from disk and sends packets * of data to the remote kermit * * Input Filename returned from Comnd routines * * Output File is sent over port * * Registers destroyed A,X,Y * send equ * *get file name ldx #filena jsr pstr ldx #fcb1 jsr inline ldx #filenr jsr pstr ldx #fcb2 jsr inline jsr sswt jmp kermit * Go back to main routine sswt lda #'S * Set up state variable as sta state * Send-init lda #$00 * Clear sta n * Packet number 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 a Sent characters, current file sta schr+1 * ... sta filend reset file end flag ldx #pdbuf * Set up the address of the packet buffer stx saddr * so that we can clear it out lda #$00 * Clear AC ldb #$00 * Clear Y ldy saddr clpbuf sta b,y * Step through buffer, clearing it out inc b * Up the index cmpb #mxpack * Done? bne clpbuf * No, continue sswt1 lda state * Fetch state of the system cmp a #'D * Do Send-data? bne sswt2 * No, try next one jsr sdat * Yes, send a data packet jmp sswt1 * Go to the top of the loop sswt2 cmp a #'F * Do we want to send-file-header? bne sswt3 * No, continue jsr sfil * Yes, send a file header packet jmp sswt1 * Return to top of loop sswt3 cmp a #'Z * Are we due for an Eof packet? bne sswt4 * Nope, try next state jsr seof * Yes, do it jmp sswt1 * Return to top of loop sswt4 cmp a #'S * Must we send an init packet bne sswt5 * No, continue jsr sini * Yes, go do it jmp sswt1 * And continue sswt5 cmp a #'B * Time to break the connection? bne sswt6 * No, try next state jsr sbrk * Yes, go send a break packet jmp sswt1 * Continue from top of loop sswt6 cmp a #'C * Is the entire transfer complete? bne sswt7 * No, something is wrong, go abort lda #true * Return true rts * ... sswt7 lda #false * Return false rts * ... sdat lda numtry * Fetch the number for tries for current packet inc numtry * Add one to it cmp a maxtry * Is it more than the maximum allowed? bne sdat1 * No, not yet bra sdat1a * If it is, go abort sdat1 jmp sdat1b * Continue sdat1a lda #'A * Load the 'abort' code sta state * Stuff that in as current state lda #errmrc sta errcod lda #false * Enter false return code rts * and a return sdat1b lda #'D * Packet type will be 'Send-data' sta ptype * ... lda n * Get packet sequence number sta pnum * Store that parameter to Spak lda size * This is the size of the data in the packet sta pdlen * Store that where it belongs jsr spak * Go send the packet sdat2 jsr rpak * Try to get an ack sta rstat * First, save the return status lda ptype * Now get the packet type received cmp a #'N * Was it a NAK? bne sdat2a * No, try for an ACK jmp sdatcn * Go handle the nak case sdat2a cmp a #'Y * Did we get an ACK? bne sdat2x * No, try checking the return status jmp sdatca * Yes, handle the ack sdat2x cmp a #'E bne sdat2b jsr pemsg bra sdat1a sdat2b lda rstat * Fetch the return status cmp a #false * Failure return? beq sdat2c * Yes, just return with current state lda #'A * Stuff the abort code sta state * as the current system state lda #false * Load failure return code sdat2c rts * Go back sdatcn dec pnum * Decrement the packet sequence number lda n * Get the expected packet sequence number cmp a pnum * If n=pnum-1 then this is like an ack bne sdatn1 * No, continue handling the nak jmp sdata2 * Jump to ack bypassing sequence check sdata1 sdatn1 lda #false * Failure return rts * ... sdatca lda n * First check packet number cmp a pnum * Did he ack the correct packet? bne sdata1 * No, go give failure return sdata2 lda #$00 * Zero out number of tries for current packet sta numtry * ... jsr incn * Increment the packet sequence number jsr bufill * Go fill the packet buffer with data sta size * Save the data size returned lda eofinp * Load end-of-file indicator cmp a #true * Was this set by Bufill? beq sdatrz * If so, return state 'Z' ('Send-eof') jmp sdatrd * Otherwise, return state 'D' ('Send-data') sdatrz lda #'Z * Load the Eof code sta state * and a make it the current system state lda #true * We did succeed, so give a true return rts * Go back sdatrd lda #'D * Load the Data code sta state * Set current system state to that lda #true * Set up successful return rts * and a go back sfil lda numtry * Fetch the current number of tries inc numtry * Up it by one cmp a maxtry * See if we went up to too many bne sfil1 * Not yet bra sfil1a * Yes, go abort sfil1 jmp sfil1b * If we are still ok, take this jump sfil1a lda #'A * Load code for abort sta state * and a drop that in as the current state lda #errmrc sta errcod lda #false * Load false for a return code rts * and a return sfil1b ldb #$00 * Clear B sfil1c ldy #fcb2 lda b,y * Get a byte from the filename cmp a #$00 * Is it a null? beq sfil1d * No, continue ldy #pdbuf sta b,y * Move the byte to this buffer incb * Up the index once jmp sfil1c * Loop and a do it again sfil1d stb pdlen * This is the length of the filename lda #'F * Load type ('Send-file') sta ptype * Stuff that in as the packet type lda n * Get packet number sta pnum * Store that in its common area jsr spak * Go send the packet sfil2 jsr rpak * Go try to receive an ack sta rstat * Save the return status lda ptype * Get the returned packet type cmp a #'N * Is it a NAK? bne sfil2a * No, try the next packet type jmp sfilcn * Handle the case of a nak sfil2a cmp a #'Y * Is it, perhaps, an ACK? bne sfil2x * If not, go to next test jmp sfilca * Go and a handle the ack case sfil2x cmpa #'E bne sfil2b jsr pemsg bra sfil1a abort sfil2b lda rstat * Get the return status cmp a #false * Is it a failure return? bne sfil2c * No, just go abort the send rts * Return failure with current state sfil2c bra sfil1a sfilcn dec pnum * Decrement the receive packet number once lda pnum * Load it into the AC cmp a n * Compare that with what we are looking for bne sfiln1 * If n=pnum-1 then this is like an ack, do it jmp sfila2 * This is like an ack sfila1 sfiln1 lda #false * Load failure return code rts * and a return sfilca lda n * Get the packet number cmp a pnum * Is that the one that was acked? bne sfila1 * They are not equal sfila2 lda #$00 * Clear AC sta numtry * Zero the number of tries for current packet jsr incn * Up the packet sequence number ldx #fcb1 * Load the fcb address into the pointer * open the file (harris) ldx #fcb1 sfcn lda 0,x+ cmpa #$00 bne sfcn lda #$20 leax -1,x sta 0,x ldx #fcb1 stx $cc14 ldx #fcb jsr getfil bcs sfer1 lda #1 sta 0,x open for read jsr setext jsr fms open file bne sfer1 clr linlen clr lfnext jsr bufill * Go get characters from the file sta size * Save the returned buffer size lda #'D * Set state to 'Send-data' sta state * ... lda #true * Set up true return code rts * and a return sfer1 jsr rpterr tell user jsr fmscls jmp main seof lda numtry * Get the number of attempts for this packet inc numtry * Now up it once for next time around cmp a maxtry * Are we over the allowed max? bne seof1 * Not quite yet bra seof1a * Yes, go abort seof1 jmp seof1b * Continue sending packet seof1a lda #'A * Load 'abort' code sta state * Make that the state of the system lda #errmrc * Fetch the error index sta errcod * and a store it as the error code lda #false * Return false rts * ... seof1b lda #'Z * Load the packet type 'Z' ('Send-eof') sta ptype * Save that as a parm to Spak lda n * Get the packet sequence number sta pnum * Copy in that parm lda #$00 * This is our packet data length (0 for EOF) sta pdlen * Copy it jsr spak * Go send out the Eof seof2 jsr rpak * Try to receive an ack for it sta rstat * Save the return status lda ptype * Get the received packet type cmp a #'N * Was it a nak? bne seof2a * If not, try the next packet type jmp seofcn * Go take care of case nak seof2a cmp a #'Y * Was it an ack bne seof2x * If it wasn't that, try return status jmp seofca * Take care of the ack seof2x cmpa #'E bne seof2b jsr pemsg bra seof1a seof2b lda rstat * Fetch the return status cmp a #false * Was it a failure? beq seof2c * Yes, just fail return with current state bra seof1a seof2c rts * Return seofcn dec pnum * Decrement the received packet sequence number lda n * Get the expected sequence number cmp a pnum * If it's the same as pnum-1, it is like an ack bne seofn1 * It isn't, continue handling the nak jmp seofa2 * Switch to an ack but bypass sequence check seofa1 seofn1 lda #false * Load failure return status rts * and a return seofca lda n * Check sequence number expected against cmp a pnum * the number we got. bne seofa1 * If not identical, fail and a return curr. state seofa2 lda #$00 * Clear the number of tries for current packet sta numtry * ... jsr incn * Up the packet sequence number seofrb lda #'B * Load Eot state code sta state * Store that as the current state lda #true * Give a success on the return rts * ... sini ldy #pdbuf * Load the pointer to the sty kerbf1 * packet buffer into its jsr spar * Go fill in the send init parms lda numtry * If numtry > maxtry cmp a maxtry * ... bne sini1 * ... bra sini1a * then we are in bad shape, go fail sini1 jmp sini1b * Otherwise, we just continue sini1a lda #'A * Set state to 'abort' sta state * ... lda #errmrc * Fetch the error index sta errcod * and a store it as the error code lda #$00 * Set return status (AC) to fail rts * Return sini1b inc numtry * Increment the number of tries for this packet lda #'S * Packet type is 'Send-init' sta ptype * Store that lda #$06 * Else it is 6 sini1d sta pdlen * Store that parameter lda n * Get the packet number sta pnum * Store that in its common area jsr spak * Call the routine to ship the packet out jsr rpak * Now go try to receive a packet sta rstat * Hold the return status from that last routine sinics lda ptype * Case statement, get the packet type cmp a #'Y * Was it an ACK? bne sinic1 * If not, try next type jmp sinicy * Go handle the ack sinic1 cmp a #'N * Was it a NAK? bne sinicx * If not, try next condition jmp sinicn * Handle a nak sinicx cmpa #'E bne sinic2 jsr pemsg bra sini1a sinic2 lda rstat * Fetch the return status cmp a #false * Was this, perhaps false? bne sinic3 * Nope, do the 'otherwise' stuff jmp sinicf * Just go and a return sinic3 bra sini1a sinicn sinicf rts * Return sinicy ldb #$00 * Clear B lda n * Get packet number cmp a pnum * Was the ack for that packet number? beq siniy1 * Yes, continue lda #false * No, set false return status rts * and a go back siniy1 jsr rpar * Get parms from the ack packet siniy3 lda #'F * Load code for 'Send-file' into AC sta state * Make that the new state lda #$00 * Clear AC sta numtry * Reset numtry to 0 for next send jsr incn * Up the packet sequence number lda #true * Return true rts sbrk lda numtry * Get the number of tries for this packet inc numtry * Incrment it for next time cmp a maxtry * Have we exceeded the maximum bne sbrk1 * Not yet bra sbrk1a * Yes, go abort the whole thing sbrk1 jmp sbrk1b * Continue send sbrk1a lda #'A * Load 'abort' code sta state * Make that the system state lda #errmrc * Fetch the error index sta errcod * and a store it as the error code lda #false * Load the failure return status rts * and a return sbrk1b lda #'B * We are sending an Eot packet sta ptype * Store that as the packet type lda n * Get the current sequence number sta pnum * Copy in that parameter lda #$00 * The packet data length will be 0 sta pdlen * Copy that in jsr spak * Go send the packet sbrk2 jsr rpak * Try to get an ack sta rstat * First, save the return status lda ptype * Get the packet type received cmp a #'N * Was it a NAK? bne sbrk2a * If not, try for the ack jmp sbrkcn * Go handle the nak case sbrk2a cmp a #'Y * An ACK? bne sbrk2b * If not, look at the return status jmp sbrkca * Go handle the case of an ack sbrk2b lda rstat * Fetch the return status from Rpak cmp a #false * Was it a failure? beq sbrk2c * Yes, just return with current state bra sbrk1a sbrk2c rts * and a return sbrkcn dec pnum * Decrement the received packet number once lda n * Get the expected sequence number cmp a pnum * If =pnum-1 then this nak is like an ack bne sbrkn1 * No, this was no the case jmp sbrka2 * Yes! Go do the ack, but skip sequence check sbrka1 sbrkn1 lda #false * Load failure return code rts * and a go back sbrkca lda n * Get the expected packet sequence number cmp a pnum * Did we get what we expected? bne sbrka1 * No, return failure with current state sbrka2 lda #$00 * Yes, clear number of tries for this packet sta numtry * ... jsr incn * Up the packet sequence number lda #'C * The transfer is now complete, reflect this sta state * in the system state lda #true * Return success! rts * ...