home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c / flex.asm < prev    next >
Assembly Source File  |  2020-01-01  |  81KB  |  2,103 lines

  1. *kermit for flex 9 system
  2. *
  3. * by d j rowland
  4. *Brighton Polytechnic Computer centre
  5. *Watts building
  6. *Lewes rd.
  7. * Brighton
  8. *Sussex
  9. * England
  10.  
  11. *From: <BENDALL%DHDEMBL5.BITNET@wiscvm.wisc.edu>
  12. *Organisation:   European Molecular Biology Laboratory
  13. *Postal-Address: Meyerhofstrasse 1, 6900 Heidelberg, W. Germany
  14. *Phone:          (6221)387-0 [switchboard]
  15. *Subject:        6809 flex kermit source code
  16.  
  17. *tel. +44 273 693655 x2163
  18.  
  19. *This program is a very basic kermit , the basic code is based
  20. *on the apple version of kermit and modified to run on the
  21. *6809 cpu.
  22. *I dont guarantee its operation! its a bit crude but it does work!
  23. *It has be run with the DEC VAX kermit server and the DEC pro
  24. *kermit server
  25.  
  26. *It will get a file , send a file , and close down the server
  27. *It operates with text files only and does not have 8 bit quoting
  28.  
  29. * This software can be copied , modified etc. as required but
  30. * subject to the kermit CUCCA conditions.
  31.  
  32. * there are no set and show commands
  33. *to change the values modify the source!
  34. *there is a receive data timer (for packet rcv)
  35. *this can be modified or deleted!
  36. *its a simple timing loop round the rcv data subr.
  37.  
  38. *sytem equates
  39. cons equ $F7E8 console i/f
  40. line equ $F7EA line i/f
  41.  
  42. fms equ $d406
  43. fmscls equ $d403
  44. getfil equ $cd2d
  45. setext equ $cd33
  46. rpterr equ $cd3f
  47.  
  48. eom equ 4
  49. xlev equ 200
  50. xon equ $11
  51. xoff equ $13
  52. ctrlc equ $03
  53. ctrly equ $19
  54. max equ 255
  55. xlo equ 20
  56. suspec equ $04
  57.  
  58. *ram save locations
  59.  org $2000
  60. inp rmb 2
  61. outp rmb 2
  62. startq rmb 256
  63. end rmb 2
  64. count rmb 1
  65. fcs rmb 1
  66. lastf rmb 1
  67. suspend rmb 1 break out character
  68. nolock rmb 1
  69. tmode rmb 1
  70. scount rmb 1
  71. linbuf rmb 4
  72. point rmb 2
  73.  rmb 64
  74. stack rmb 1
  75. monito rmb 1 diagnostic mode flag
  76. linlen rmb 1
  77. lfnext rmb 1
  78.  
  79. ram equ *
  80.  
  81.  org $0000
  82. begin jmp start
  83.  
  84. mdone fcc 'done'
  85.  fcb 4
  86. prompt fcb $0d,$0a,4
  87. menu1 fcc 'Please select option :- '
  88.  fcb $0d,$0a
  89.  fcc '0. Terminal to line'
  90.  fcb $0d,$0a
  91.  fcc '1. Return to flex'
  92.  
  93.  fcb $0d,$0a
  94.  fcc '2. File send from Flex'
  95.  fcb $0d,$0a
  96.  fcc '3. File receive to Flex'
  97.  fcb $0d,$0a
  98.  fcc '4. Close server'
  99.  fcb $0d,$0a
  100.  fcc '5. Monitor on'
  101.  fcb $0d,$0a
  102.  fcc '6. Monitor off'
  103.  fcb $0d,$0a
  104.  fcc ' ? '
  105.  fcb 4
  106.  
  107. escstr fcc 'Type  <CTRL D> to exit'
  108.  fcb $0d,$0a,4
  109. filena fcc 'Flex Filename? '
  110.  fcb 4
  111. filenr fcc 'Remote filename? '
  112.  fcb 4
  113. query fcc ' ? '
  114.  fcb 4
  115.  
  116. start ldx #int
  117.  STX $f3c8
  118.  lda #3
  119.  sta line
  120.  lda #%00010101
  121.  lda #%10010101
  122.  sta line polled tx int rx
  123.  lda #suspec suspend character
  124.  sta suspend
  125.  ldx #startq
  126.  stx inp
  127.  stx outp set up line que
  128.  clr count
  129.  clr fcs
  130.  lda #xon
  131.  sta lastf
  132.  clr monito
  133.  clr tmode
  134.  clr pnum
  135.  clr pdlen
  136.  clr ptype
  137.  clr size
  138.  clr chksum
  139.  clr fld
  140.  clr rstat
  141.  clr ebqmod
  142.  clr datind
  143.  clr chebo
  144.  clr kerchr
  145.  clr delay
  146.  lda #dmaxtr
  147.  sta maxtry
  148.  lda #debq
  149.  sta rebq
  150.  sta sebq
  151.  lda #dpadln
  152.  sta rpad
  153.  sta spad
  154.  lda #dpadch
  155.  sta rpadch
  156.  sta spadch
  157.  lda #deol
  158.  sta reol
  159.  sta seol
  160.  lda #dpakln
  161.  sta rpsiz
  162.  sta spsiz
  163.  lda #dtime
  164.  sta rtime
  165.  sta stime
  166.  lda #dquote
  167.  sta rquote
  168.  sta squote
  169.  cli
  170.  jmp main
  171.  
  172.  FCB $74,$35,$7A,$29,$6C,$8B,$77,$32,$68,$8C,$79,$36,$70,$30,$71,$8D
  173. main equ * main loop and despatcher
  174.  ldy #$3000
  175.  sty point
  176.  ldx #prompt
  177.  jsr pstr issue welcome prompt
  178.  ldx #menu1
  179.  jsr pstr find out what user wants to do
  180.  lda cons+1
  181.  lda cons+1 clean i/f
  182.  jsr cinput
  183.  jsr coutch echo reply
  184.  cmpa #'0
  185.  lbeq term term emulation to line
  186.  cmpa #'2
  187.  lbeq send file transfer (kermit)
  188.  cmpa #'1
  189.  lbeq flexex return to flex
  190.  cmpa #'3
  191.  lbeq receve receive a file (kermit)
  192.  cmpa #'4
  193.  lbeq close
  194.  cmpa #'5
  195.  beq monon
  196.  cmpa #'6
  197.  beq monoff
  198.  bra main
  199.  
  200. monon sta monito
  201. mmsg ldx #mdone
  202.  jsr pstr
  203.  bra main
  204.  
  205. monoff clr monito
  206.  bra mmsg
  207.  
  208. *************************************************
  209. *terminal emulation******************************
  210.  
  211. term equ *
  212.  ldx #escstr tell user how tp break out
  213.  jsr pstr
  214. terml jsr cinchk any console i/p
  215.  beq lhand no
  216.  bit b #$10 test for <break>
  217.  bne berr yes
  218.  jsr cinput read data
  219.  cmpa suspend
  220.  lbeq main    exit at user request
  221.  
  222. sendl jsr loutch send it to line
  223.  bra lhand
  224.  
  225. berr lda cons+1 set line i/f to space
  226.  sei
  227.  lda #%11110101
  228.  sta line
  229.  ldx #$ffff
  230. wait dex
  231.  bne wait
  232.  lda #%10110101 restore i/f
  233.  sta line
  234.  cli
  235.  
  236. lhand equ *
  237.  jsr coutck ok to tx?
  238.  beq terml no
  239.  tst count que empty?
  240.  beq terml yes
  241.  jsr unque
  242.  jsr coutch send it
  243.  bra terml
  244.  
  245. ************************************
  246. flexex lda #$03   return to flex
  247.  sta line reset i/f causing ints
  248.  jmp $cd03 and warmstart to flex
  249. *********************************
  250.  
  251. ************************************
  252. *line handler and other subrs.
  253.  
  254. qures equ *
  255.  sei
  256.  pshs x
  257.  ldx #startq
  258.  stx inp
  259.  stx outp
  260.  clr count
  261.  puls x
  262.  cli
  263.  rts
  264.  
  265. cinchk equ *
  266.  pshs a see if data from console
  267.  ldb cons
  268.  bitb #1
  269.  puls a,pc
  270.  
  271. cinput bsr cinchk
  272.  beq cinput no rxd
  273.  lda cons+1
  274.  anda #$7f
  275.  rts
  276.  
  277. loutck pshs a see if line ok to tx
  278.  lda line
  279.  bit a #2
  280.  puls a,pc
  281.  
  282. telppc equ *
  283. loutch bsr loutck
  284.  beq loutch o/p to line
  285.  sta line+1
  286.  rts
  287.  
  288. pstr lda #$0d
  289.  jsr couts
  290.  lda #$0a
  291.  jsr couts
  292. pstrs lda 0,x+ send string to console
  293.  cmpa #eom
  294.  beq pstre end of message
  295.  jsr couts send char
  296.  bra pstrs
  297. pstre rts
  298.  
  299. getplc equ *
  300.  ldy #$ffff abort i/p timeout timer
  301. getplt cmpy #$0000
  302.  beq toexit timeout occured
  303.  leay -1,y keep timing
  304.  tst count
  305.  bne unque got data
  306.  jsr cinchk
  307.  beq getplt no console rx
  308.  jsr cinput get data
  309.  cmpa suspend
  310.  bne getplt not abort
  311. toexit leas 2,s equiv to an rts
  312.  jmp rpkfls handle console abort back in kermit
  313. unque equ * count must be checked as non 0 before entry
  314.  sei
  315.  pshs b,x
  316.  ldx outp
  317.  lda 0,x+ read char from line buffer
  318.  cmpx #end
  319.  bne un1
  320.  ldx #startq
  321. un1 stx outp
  322.  dec count
  323.  ldb count
  324.  cli
  325.  cmpb #xlo
  326.  bne unx
  327.  ldb #xon  send xon if reqd
  328.  cmpb lastf last code sent?
  329.  beq unx was an xon !
  330.  stb lastf
  331.  stb fcs set up for tx of an xon
  332.  ldb #%10110101
  333.  stb line set tx int on
  334. unx puls b,x,pc
  335.  
  336. couts jsr coutck
  337.  beq couts
  338.  bra coutch
  339.  
  340. coutch equ *
  341.  sta cons+1 send data to console
  342. cexit rts
  343.  
  344. coutcr jsr coutck
  345.  beq coutcr
  346.  bsr coutch o/p data
  347.  cmpa #cr
  348.  bne cexit
  349.  pshs a
  350.  lda #lf if cr then crlf
  351. coutlf jsr coutck
  352.  beq coutlf
  353.  jsr coutch
  354.  puls a get back cr !
  355.  rts
  356.  
  357.  
  358. coutck equ * see if can send to console
  359.  pshs a
  360.  lda cons
  361.  bita #2
  362.  puls a,pc
  363.  
  364. inline equ * read filename into fcb
  365.  clr b
  366. inloop pshs b
  367.  jsr cinput get data
  368.  puls b
  369.  anda #$7f
  370.  cmpa #del
  371.  beq backc
  372.  cmpa #bs
  373.  beq backc
  374.  cmpa #ctrlx
  375.  beq dellin
  376.  cmpa #cr
  377.  beq endc fini
  378.  jsr couts echo char
  379.  sta 0,x save in buffer
  380.  inx
  381.  inc b
  382.  cmp b #$1e end of buffer?
  383.  beq endc yes force finish
  384.  bra inloop
  385.  
  386. dellin ldx #query
  387.  jsr pstr
  388.  bra inline start again
  389.  
  390. backc cmp b #0
  391.  beq inloop already at start of buffer
  392.  dex
  393.  decb back up 1 locn
  394.  lda #bs
  395.  jsr couts back up console
  396.  bra inloop and continue
  397.  
  398. endc clr a
  399.  sta 0,x
  400.  rts set terminator and exit
  401.  
  402. ******************************************
  403. * line int handler*****************
  404. ******************************************
  405. int equ * interrupt
  406.  lda line
  407.  bita #1
  408.  beq ret1 not rxd
  409.  lda line+1 rxd int
  410.  ldb count
  411.  cmpb #max
  412.  beq ret que is totally full !
  413.  ldx inp
  414.  sta 0,x+ save char in buffer que
  415.  cpx #end
  416.  bne int1
  417.  ldx #startq
  418. int1 stx inp
  419.  inc b
  420.  stb count
  421.  cmpb #xlev
  422.  bne ret
  423.  lda #xoff xoff level
  424.  cmpa lastf already sent?
  425.  beq ret yesd
  426.  sta lastf
  427.  sta fcs send an xoff
  428.  lda #%10110101 turn on line tx
  429.  sta line
  430. ret rti
  431.  
  432. ret1 bit a #$80
  433.  beq ret2 not line tx
  434.  tst fcs
  435.  beq txs nothing to send
  436.  lda lastf
  437.  sta line+1 send flow code
  438. txs lda #%10010101
  439.  sta line stop tx int
  440. ret2 rti
  441.  
  442.  
  443.  
  444. *DESPATCH ROUTINE HERE FOR RECEVE AND SEND
  445. kermit EQU * RETURN FROM KERMIT DRIVERS
  446. *any error handling and status report
  447.  ldx #noerr
  448.  cmpa #true
  449.  beq kdone kermit ended succesfully
  450.  jsr fmscls close files on flex
  451.  lda errcod get error code
  452.  lsl a
  453.  ldx #errtab look up error message
  454.  ldx a,x
  455. kdone jsr pstr error message/complete message
  456.  jmp main
  457.  
  458. errtab equ * lookup error message
  459.  fdb err0
  460.  fdb err1
  461.  fdb err2
  462.  fdb err3
  463.  fdb err4
  464.  fdb err5
  465.  fdb err6
  466.  fdb err7
  467.  
  468. err0 fcc 'error 0'
  469.  fcb 4
  470. err1 fcc 'cannot receive init'
  471.  fcb 4
  472. err2 fcc 'cannot receive file header'
  473.  fcb 4
  474. err3 fcc 'cannot receive data'
  475.  fcb 4
  476. err4 fcc 'maximum retry exceeded'
  477.  fcb 4
  478. err5 fcc 'bad checksum'
  479.  fcb 4
  480. err6 fcc 'checksum incorrect, resending packet'
  481.  fcb $0d,$0a
  482.  fcb 4
  483. err7 fcc 'program error'
  484.  fcb 4
  485. noerr fcc 'transfer completed succesfully'
  486.  fcb 4
  487.  ttl       KL10 Error-free Reciprocol Micro-interface Transfer
  488.  STTL  Character and string definitions
  489.  
  490. prom equ *
  491. nul     EQU       $00             * <null>
  492. soh     EQU       $01             * <soh>
  493. bs      EQU       $08             * <bs>
  494. tab     EQU       $09             * <tab> (ctrl/I)
  495. lf      EQU       $0a             * <lf>
  496. ffd     EQU       $0c             * Form feed
  497. cr      EQU       $0d             * <cr>
  498. ctrlu   EQU       $15             * <ctrl/U>
  499. ctrlx   EQU       $18             *[0] <ctrl/X>
  500. esc     EQU       $1b             * <esc>
  501. sp      EQU       $20             * <space>
  502. del     EQU       $7f             * <del>
  503.  
  504.  STTL  Kermit defaults for operational parameters
  505.  
  506. *
  507. *       The following are the defaults which this Kermit uses for
  508. *       the protocol
  509. *
  510.  
  511. dquote  EQU       '#              * The quote character
  512. dpakln  EQU       $5f             * The packet length
  513. dpadch  EQU       nul             * The padding character
  514. dpadln  EQU       0               * The padding length
  515. dmaxtr  EQU       6             * The maximum number of tries
  516. debq    EQU       '&              * The eight-bit-quote character
  517. deol    EQU       cr              * The end-of-line character
  518. dtime equ 5 *timeout interval
  519.  
  520.  
  521.  STTL  Kermit data
  522.  
  523. *
  524. *       The following is data storage used by Kermit
  525. *
  526.  
  527. mxpack  EQU       dpakln          * Maximum packet size
  528. eof     EQU       $01             * This is the value for End-of-file
  529. buflen  EQU       $ff             * Buffer length for received data
  530. true    EQU       $01             * Symbol for true return code
  531. false   EQU       $00             * Symbol for false return code
  532. on      EQU       $01             * Symbol for value of 'on' keyword
  533. off     EQU       $00             * Symbol for value of 'off' keyword
  534. yes     EQU       $01             * Symbol for value of 'yes' keyword
  535. no      EQU       $00             * Symbol for value of 'no' keyword
  536. fbsbit  EQU       $01             * Value for SEVEN-BIT FILE-BYTE-SIZE
  537. fbebit  EQU       $00             * Value for EIGHT-BIT FILE-BYTE-SIZE
  538. errcri  EQU       $01             * Error code - cannot receive init
  539. errcrf  EQU       $02             * Error code - cannot receive file-header
  540. errcrd  EQU       $03             * Error code - cannot receive data
  541. errmrc  EQU       $04             * Error code - maximum retry count exceeded
  542. errbch  EQU       $05             * Error code - bad checksum
  543.  
  544.  org ram
  545. kerbf1 rmb 2
  546. fcb1 rmb 20
  547. fcb rmb 400 file spec
  548. fcb2 rmb 20 remote file spec
  549. pdbuf  RMB   mxpack+20       * Packet buffer JUST TO MAKE SURE ENOUGH ROOM
  550. pdlen  RMB 1                   * Common area to place data length
  551. ptype  RMB 1                   * Common area to place current packet type
  552. pnum   RMB 1                   * Common area to put packet number received
  553. rstat  RMB 1                   * Return status
  554. delay  RMB 1                   * Amount of delay before first send
  555. ebqmod RMB 1                   * Eight-bit-quoting mode
  556. datind RMB 1                   * Data index into packet buffer
  557. chebo  RMB 1                   * Switch to tell if 8th-bit was on
  558. kerchr RMB 1                   * Current character read off port
  559. fld    RMB 1                   * State of receive in rpak routine
  560. n      RMB 1                   * Message #
  561. numtry RMB 1                   * Number of tries for this packet
  562. oldtry RMB 1                   * Number of tries for previous packet
  563. maxtry RMB 1                   * Maximum tries allowed for a packet
  564. state  RMB 1                   * Current state of system
  565. size   RMB 1                   * Size of present data
  566. chksum RMB 1                   * Checksum for packet
  567. rtot   RMB 2                   * Total number of characters received
  568. stot   RMB 2                   * Total number of characters sent
  569. rchr   RMB 2                   * Number characters received, current file
  570. schr   RMB 2                   * Number of characters sent, current file
  571. eofinp RMB 1                   * End-of-file on input indicator
  572. errcod RMB 1                   * Error indicator
  573. filend rmb 1 *end of file code rcvd
  574.  
  575. saddr rmb 2
  576. *
  577. *       These fields are set parameters and should be kept in this
  578. *       order to insure integrity when setting and showing values
  579. *
  580.  
  581. srind  RMB 1                   * Switch to indicate which parm to print
  582. ebq    RMB 1   debq            * Eight-bit quote character (rec. and send)
  583.         RMB 1   debq            *               ...
  584. pad    RMB 1   dpadln          * Number of padding characters (rec. and send)
  585.         RMB 1   dpadln          *               ...
  586. padch  RMB 1   dpadch          * Padding character (receive and send)
  587.         RMB 1   dpaddh          *               ...
  588. eol    RMB 1   deol            * End-of-line character (recevie and send)
  589.         RMB 1   deol            *               ...
  590. psiz   RMB 1   dpakln          * Packet size (receive and send)
  591.         RMB 1   dpakln          *               ...
  592. time   RMB 2   $0000           * Time out interval (receive and send)
  593. quote  RMB 1   dquote          * Quote character (receive and send)
  594.         RMB 1   dquote          *               ...
  595.  
  596. *
  597. *       Some definitions to make life easier when referencing the above
  598. *       fields
  599. *
  600.  
  601. rebq    EQU       ebq             * Receive eight-bit-quote char
  602. sebq    EQU       ebq+1           * Send eight-bit-quote char
  603. rpad    EQU       pad             * Receive padding amount
  604. spad    EQU       pad+1           * Send padding amount
  605. rpadch  EQU       padch           * Receive padding character
  606. spadch  EQU       padch+1         * Send padding character
  607. reol    EQU       eol             * Receive end-of-line character
  608. seol    EQU       eol+1           * Send end-of-line character
  609. rpsiz   EQU       psiz            * Receive packet length
  610. spsiz   EQU       psiz+1          * Send packet length
  611. rtime   EQU       time            * Receive time out interval
  612. stime   EQU       time+1          * Send time out interval
  613. rquote  EQU       quote           * Receive quote character
  614. squote  EQU       quote+1         * Send quote character
  615.  
  616.  
  617.  org prom
  618.  
  619.  
  620. *************************
  621. close equ * close down server
  622.  lda #$00
  623.  sta numtry
  624. closen lda numtry
  625.  inc numtry
  626.  cmpa maxtry
  627.  bne closec
  628.  lda #errmrc to many tries
  629.  sta errcod
  630.  lda #false exit to menu with error
  631.  jmp kermit
  632.  
  633. closec lda #'G
  634.  sta ptype set up close packet
  635.  ldx #pdbuf
  636.  stx kerbf1
  637.  lda #'F
  638.  sta 0,x
  639.  lda #1
  640.  sta pdlen
  641.  clr a
  642.  sta n packet #0 for closing
  643.  sta pnum
  644.  jsr spak send it
  645.  jsr rpak get back an ack?
  646.  lda ptype
  647.  cmpa #'Y
  648.  bne closen no
  649.  lda n
  650.  cmpa pnum right one?
  651.  bne closen no
  652.  lda #true
  653.  jmp term
  654.  
  655.  
  656.  STTL  Receve routine
  657.  
  658. *
  659. *       This routine receives a file from the remote kermit and
  660. *       writes it to a disk file
  661. *
  662. *               Input  Filename returned from comnd, if any
  663. *
  664. *               Output If file transfer is good, file is output to disk
  665. *
  666. *               Registers destroyed    A,X,Y
  667. *
  668.  
  669. receve equ *
  670. *get filename
  671.  ldx #filena
  672.  jsr pstr
  673.  ldx #fcb1
  674.  jsr inline
  675.  ldx #filenr
  676.  jsr pstr
  677.  ldx #fcb2
  678.  jsr inline
  679.         jsr     rswt            * Perform send-switch routine
  680.         jmp     kermit          * Go back to main routine
  681.  
  682. rswt   lda     #'R             * The state is receive-init
  683.         sta     state           * Set that up
  684.         lda     #$00            * Zero the packet sequence number
  685.         sta     n               *               ..
  686.         sta     numtry          *       Number of tries
  687.         sta     oldtry          *       Old number of tries
  688.         sta     eofinp          *       End of input flag
  689.         sta     errcod          *       Error indicator
  690.         sta     rtot            *       Total received characters
  691.         sta     rtot+1          *               ..
  692.         sta     stot            *       Total Sent characters
  693.         sta     stot+1          *               ..
  694.         sta     rchr            *       Received characters, current file
  695.         sta     rchr+1          *               ..
  696.         sta     schr            *       and Sent characters, current file
  697.         sta     schr+1          *               ..
  698.  jsr qures
  699. rswt1  lda     state           * Fetch the current system state
  700.         cmp a     #'D             * Are we trying to receive data?
  701.         bne     rswt2           * If not, try the next one
  702.         jsr     rdat            * Go try for the data packet
  703.         jmp     rswt1           * Go back to the top of the loop
  704. rswt2  cmp a     #'F             * Do we need a file header packet?
  705.         bne     rswt3           * If not, continue checking
  706.         jsr     rfil            * Go get the file-header
  707.         jmp     rswt1           * Return to top of loop
  708. rswt3  cmp a     #'R             * Do we need the init?
  709.         bne     rswt41           * No, try next state
  710.         jsr     rini            * Yes, go get it
  711.         jmp     rswt1           * Go back to top
  712. rswt41 cmpa #'B
  713.  bne rswt4
  714.  jsr rrbrk1
  715.  jmp rswt1
  716. rswt4  cmp a     #'C             * Have we completed the transfer?
  717.         bne     rswt5           * No, we are out of states, fail
  718.         lda     #true           * Load AC for true return
  719.         rts                     * Return
  720. rswt5  lda     #false          * Set up AC for false return
  721.         rts                     * Return
  722.  
  723. rini   ldx     #pdbuf         * Point kerbf1 at the packet data buffer
  724.         stx     kerbf1          *               ..
  725.         lda     numtry          * Get current number of tries
  726.         inc     numtry          * Increment it for next time
  727.         cmp a     maxtry          * Have we tried this one enought times
  728.         bne     rini1           * Not yet, go on
  729.         bra     rini1a          * Yup, go abort this transfer
  730. rini1  jmp     rini2           * Continue
  731. rini1a lda     #'A             * Change state to 'abort'
  732.         sta     state           *               ..
  733.         lda     #errcri         * Fetch the error index
  734.         sta     errcod          *       and store it as the error code
  735.         lda     #false          * Load AC with false status
  736.         rts                     *       and return
  737. rini2 equ *
  738. *send r packet to request file
  739.  clr b
  740. rinif2 ldy #fcb2
  741.  lda b,y
  742.  cmpa #$00 move file header to packet
  743.  beq rinif1 fini
  744.  ldy #pdbuf
  745.  sta b,y
  746.  inc b
  747.  bra rinif2
  748. rinif1 stb pdlen
  749.  lda #'R
  750.  sta ptype
  751.  lda n
  752.  sta pnum
  753.  jsr spak send it
  754.   jsr     rpak            * Go try to receive a packet
  755.         sta     rstat           * Store the return status for later
  756.         lda     ptype           * Fetch the packet type we got
  757.         cmp a     #'S             * Was it an 'Init'?
  758.         bne     rini2a          * No, check the return status
  759.         jmp     rinici          * Go handle the init case
  760. rini2a lda     rstat           * Fetch the saved return status
  761.         cmp a     #false          * Is it false?
  762.         beq     rini2b          * Yes, just return with same state
  763.         lda     #'A             * No, abort this transfer
  764.         sta     state           * State is now 'abort'
  765.         lda     #errcri         * Fetch the error index
  766.         sta     errcod          *       and store it as the error code
  767.         lda     #false          * Set return status to 'false'
  768.         rts                     * Return
  769. rini2b lda     n               * Get packet sequence number expected
  770.         sta     pnum            * Stuff that parameter at the Nakit routine
  771.         jsr     nakit           * Go send the Nak
  772.         lda     #false          * Set up failure return status
  773.         rts                     *       and go back
  774.  
  775. rinici lda     pnum            * Get the packet number we received
  776.         sta     n               * Synchronize our packet numbers with this
  777.         jsr     rpar            * Load in the init stuff from packet buffer
  778.         jsr     spar            * Stuff our init info into the packet buffer
  779.         lda     #'Y             * Store the 'Ack' code into the packet type
  780.         sta     ptype           *               ..
  781.         lda     n               * Get sequence number
  782.         sta     pnum            * Stuff that parameter
  783.         lda     #off            * No, punt 8-bit quoting
  784.         sta     ebqmod          *               ..
  785.         lda     #$06            * BTW, the data length is now only 6
  786. rinic1 sta     pdlen           * Store packet data length
  787.         jsr     spak            * Send that packet
  788.         lda     numtry          * Move the number of tries for this packet
  789.         sta     oldtry          *       to prev packet try count
  790.         lda     #$00            * Zero
  791.         sta     numtry          *       the number of tries for current packet
  792.         jsr     incn            * Increment the packet number once
  793.         lda     #'F             * Advance to 'File-header' state
  794.         sta     state           *               ..
  795.         lda     #true           * Set up return code
  796.         rts                     * Return
  797.  
  798. rfil   lda     numtry          * Get number of tries for this packet
  799.         inc     numtry          * Increment it for next time around
  800.         cmp a     maxtry          * Have we tried too many times?
  801.         bne     rfil1           * Not yet
  802.         bra     rfil1a          * Yes, go abort the transfer
  803. rfil1  jmp     rfil2           * Continue transfer
  804. rfil1a bra rfilla
  805. rfil2 jsr rpak *try to receive a packet
  806.         sta     rstat           * Save the return status
  807.         lda     ptype           * Get the packet type we found
  808.         cmp a     #'S             * Was it an 'init' packet?
  809.         bne     rfil2a          * Nope, try next one
  810.         jmp     rfilci          * Handle the init case
  811. rfil2a cmp a     #'Z             * Is it an 'eof' packet??
  812.         bne     rfil2b          * No, try again
  813.         jmp     rfilce          * Yes, handle that case
  814. rfil2b cmp a     #'F             * Is it a 'file-header' packet???
  815.         bne     rfil2c          * Nope
  816.         jmp     rfilcf          * Handle file-header case
  817. rfil2c cmp a     #'B             * Break packet????
  818.         bne     rfil2x          * Wrong, go get the return status
  819.         jmp     rfilcb          * Handle a break packet
  820. rfil2x cmpa #'E
  821.  bne rfil2d
  822.  jsr pemsg send error packet info to console
  823.  jmp rfilla and abort
  824. rfil2d lda     rstat           * Fetch the return status from Rpak
  825.         cmp a     #false          * Was it a false return?
  826.         beq     rfil2e          * Yes, Nak it and return
  827. rfilla        lda     #'A             * No, abort this transfer, we don't know w
  828. hat
  829.         sta     state           *       this is
  830.         lda     #errcrf         * Fetch the error index
  831.         sta     errcod          *       and store it as the error code
  832.         lda     #false          * Set up failure return code
  833.         rts                     *       and return
  834. rfil2e lda     n               * Move the expected packet number
  835.         sta     pnum            *       into the spot for the parameter
  836.         jsr     nakit           * Nak the packet
  837.         lda     #false          * Do a false return but don't change state
  838.         rts                     * Return
  839. rfilci lda     oldtry          * Get number of tries for prev packet
  840.         inc     oldtry          * Increment it
  841.         cmp a     maxtry          * Have we tried this one too much?
  842.         bne     rfili1          * Not quite yet
  843.         bra     rfili2          * Yes, go abort this transfer
  844. rfili1 jmp     rfili3          * Continue
  845. rfili2
  846. rfili5 lda     #'A             * Move abort code
  847.         sta     state           *       to system state
  848.         lda     #errcrf         * Fetch the error index
  849.         sta     errcod          *       and store it as the error code
  850.         lda     #false          * Prepare failure return
  851.         rts                     *       and go back
  852. rfili3 lda     pnum            * See if pnum=n-1
  853.         clc                     *               ..
  854.         add a     #$01            *               ..
  855.         cmp a     n               *               ..
  856.         beq     rfili4          * If it does, than we are ok
  857.         jmp     rfili5          * Otherwise, abort
  858. rfili4 jsr     spar            * Set up the init parms in the packet buffer
  859.         lda     #'Y             * Set up the code for Ack
  860.         sta     ptype           * Stuff that parm
  861.         lda     #$06            * Packet length for init
  862.         sta     pdlen           * Stuff that also
  863.         jsr     spak            * Send the ack
  864.         lda     #$00            * Clear out
  865.         sta     numtry          *       the number of tries for current packet
  866.         lda     #true           * This is ok, return true with current state
  867.         rts                     * Return
  868. rfilce lda     oldtry          * Get number of tries for previous packet
  869.         inc     oldtry          * Up it for next time we have to do this
  870.         cmp a     maxtry          * Too many times for this packet?
  871.         bne     rfile1          * Not yet, continue
  872.         bra     rfile2          * Yes, go abort it
  873. rfile1 jmp     rfile3          *               ..
  874. rfile2
  875. rfile5 lda     #'A             * Load abort code
  876.         sta     state           *       into current system state
  877.         lda     #errcrf         * Fetch the error index
  878.         sta     errcod          *       and store it as the error code
  879.         lda     #false          * Prepare failure return
  880.         rts                     *       and return
  881. rfile3 lda     pnum            * First, see if pnum=n-1
  882.         clc                     *               ..
  883.         add a     #$01            *               ..
  884.         cmp a     n               *               ..
  885.         beq     rfile4          * If so, continue
  886.         jmp     rfile5          * Else, abort it
  887. rfile4 lda     #'Y             * Load 'ack' code
  888.         sta     ptype           * Stuff that in the packet type
  889.         lda     #$00            * This packet will have a packet data length
  890.         sta     pdlen           *       of zero
  891.         jsr     spak            * Send the packet out
  892.         lda     #$00            * Zero number of tries for current packet
  893.         sta     numtry          *               ..
  894.         lda     #true           * Set up successful return code
  895.         rts                     *       and return
  896. rfilcf lda     pnum            * Does pnum=n?
  897.         cmp a     n               *               ..
  898.         bne     rfilf1          * If not, abort
  899.         jmp     rfilf2          * Else, we can continue
  900. rfilf1 lda     #'A             * Load the abort code
  901.         sta     state           *       and stuff it as current system state
  902.         lda     #errcrf         * Fetch the error index
  903.         sta     errcod          *       and store it as the error code
  904.         lda     #false          * Prepare failure return
  905.         rts                     *       and go back
  906. rfilf2 equ *
  907. * open file for write (harris)
  908.  ldx #fcb1
  909. rfnc lda 0,x+
  910.  cmpa #$00
  911.  bne rfnc
  912.  lda #$20 change terminator to space
  913.  leax -1,x
  914.  sta 0,x
  915.  ldx #fcb1 setup i/p point
  916.  stx $cc14 to line i/p buff
  917.  ldx #fcb
  918.  jsr getfil parse file spec
  919.  bcs fer1 error in file name
  920.  lda #2 open for write
  921.  sta 0,x set to txt
  922.  jsr setext set to text
  923.  jsr fms open file for write
  924.  bne fer1 file open error
  925.         lda     #'Y             * Stuff code for 'ack'
  926.         sta     ptype           * Into packet type parm
  927.         lda     #$00            * Stuff a zero in as the packet data length
  928.         sta     pdlen           *               ..
  929.         jsr     spak            * Ack the packet
  930.         lda     numtry          * Move current tries to previous tries
  931.         sta     oldtry          *               ..
  932.         lda     #$00            * Clear the
  933.         sta     numtry          * Number of tries for current packet
  934.         jsr     incn            * Increment the packet sequence number once
  935.         lda     #'D             * Advance the system state to 'receive-data'
  936.         sta     state           *               ..
  937.         lda     #true           * Set up success return
  938.         rts                     *       and go back
  939.  
  940. fer1 jsr rpterr tell userof error
  941.  jsr fmscls
  942.  jmp main
  943.  
  944. rfilcb lda     pnum            * Does pnum=n?
  945.         cmp a     n               *               ..
  946.         bne     rfilb1          * If not, abort the transfer process
  947.         jmp     rfilb2          * Otherwise, we can continue
  948. rfilb1 lda     #'A             * Code for abort
  949.         sta     state           * Stuff that into system state
  950.         lda     #errcrf         * Fetch the error index
  951.         sta     errcod          *       and store it as the error code
  952.         lda     #false          * Load failure return status
  953.         rts                     *       and return
  954. rfilb2 lda     #'Y             * Set up 'ack' packet type
  955.         sta     ptype           *               ..
  956.         lda     #$00            * Zero out
  957.         sta     pdlen           *       the packet data length
  958.         jsr     spak            * Send out this packet
  959.         lda     #'C             * Advance state to 'complete'
  960.         sta     state           *       since we are now done with the transfer
  961.         lda     #true           * Return a true
  962.         rts                     *               ..
  963.  
  964. rdat   lda     numtry          * Get number of tries for current packet
  965.         inc     numtry          * Increment it for next time around
  966.         cmp a     maxtry          * Have we gone beyond number of tries allowed?
  967.         bne     rdat1           * Not yet, so continue
  968.         bra     rdat1a          * Yes, we have, so abort
  969. rdat1  jmp     rdat2           *               ..
  970. rdat1a lda     #'A             * Code for 'abort' state
  971.         sta     state           * Stuff that in system state
  972.         lda     #errcrd         * Fetch the error index
  973.         sta     errcod          *       and store it as the error code
  974.  jsr closef
  975.         lda     #false          * Set up failure return code
  976.         rts                     *       and go back
  977. rdat2  jsr     rpak            * Go try to receive a packet
  978.         sta     rstat           * Save the return status for later
  979.         lda     ptype           * Get the type of packet we just picked up
  980.         cmp a     #'D             * Was it a data packet?
  981.         bne     rdat2a          * If not, try next type
  982.         jmp     rdatcd          * Handle a data packet
  983. rdat2a cmp a     #'F             * Is it a file-header packet?
  984.         bne     rdat2b          * Nope, try again
  985.         jmp     rdatcf          * Go handle a file-header packet
  986. rdat2b cmp a     #'Z             * Is it an eof packet???
  987.         bne     rdat2x          * If not, go check the return status from rpak
  988.         jmp     rdatce          * It is, go handle eof processing
  989. rdat2x cmpa #'E
  990.  bne rdat2c
  991.  jsr pemsg
  992.  bra rdater
  993. rdat2c lda     rstat           * Fetch the return status
  994.         cmp a     #false          * Was it a failure return?
  995.         beq     rdat2d          * If it was, Nak it
  996. rdater        lda     #'A             * Otherwise, we give up the whole transfer
  997.         sta     state           * Set system state to 'false'
  998.         lda     #errcrd         * Fetch the error index
  999.         sta     errcod          *       and store it as the error code
  1000.  jsr closef
  1001.         lda     #false          * Set up a failure return
  1002.         rts                     *       and go back
  1003. rdat2d lda     n               * Get the expected packet number
  1004.         sta     pnum            * Stuff that parameter for Nak routine
  1005.         jsr     nakit           * Send a Nak packet
  1006.         lda     #false          * Give failure return
  1007.         rts                     * Go back
  1008.  
  1009. rdatcd lda     pnum            * Is pnum the right sequence number?
  1010.         cmp a     n               *               ..
  1011.         bne     rdatd1          * If not, try another approach
  1012.         jmp     rdatd7          * Otherwise, everything is fine
  1013. rdatd1 lda     oldtry          * Get number of tries for previous packet
  1014.         inc     oldtry          * Increment it for next time we need it
  1015.         cmp a     maxtry          * Have we exceeded that limit?
  1016.         bne     rdatd2          * Not just yet, continue
  1017.         bra     rdatd3          * Yes, go abort the whole thing
  1018. rdatd2 jmp     rdatd4          * Just continue working on the thing
  1019. rdatd3
  1020. rdatd6 lda     #'A             * Load 'abort' code into the
  1021.         sta     state           *       current system state
  1022.         lda     #errcrd         * Fetch the error index
  1023.         sta     errcod          *       and store it as the error code
  1024.  jsr closef
  1025.         lda     #false          * Make this a failure return
  1026.         rts                     * Return
  1027. rdatd4 lda     pnum            * Is pnum=n-1.. Is the received packet
  1028.         clc                     *       the one previous to the currently
  1029.         add a     #$01            *       expected packet?
  1030.         cmp a     n               *               ..
  1031.         beq     rdatd5          * Yes, continue transfer
  1032.         jmp     rdatd6          * Nope, abort the whole thing
  1033. rdatd5 jsr     spar            * Go set up init data
  1034.         lda     #'Y             * ***************** an ack to **********t
  1035.         sta     ptype           *               ..
  1036.         lda     #$00            *               ..
  1037.         sta     pdlen           *               ..
  1038.         jsr     spak            * Go send the ack
  1039.         lda     #$00            * Clear the
  1040.         sta     numtry          *       number of tries for current packet
  1041.         lda     #true           *               ..
  1042.         rts                     * Return (successful!)
  1043. rdatd7 jsr     bufemp          * Go empty the packet buffer
  1044.         lda     #'Y             * Set up an ack packet
  1045.         sta     ptype           *               ..
  1046.         lda     n               *               ..
  1047.         sta     pnum            *               ..
  1048.         lda     #$00            * Don't forget, there is no data
  1049.         sta     pdlen           *               ..
  1050.         jsr     spak            * Send it!
  1051.         lda     numtry          * Move tries for current packet count to
  1052.         sta     oldtry          *       tries for previous packet count
  1053.         lda     #$00            * Zero the
  1054.         sta     numtry          *       number of tries for current packet
  1055.         jsr     incn            * Increment the packet sequence number once
  1056.         lda     #'D             * Advance the system state to 'receive-data'
  1057.         sta     state           *               ..
  1058.         lda     #true           *               ..
  1059.         rts                     * Return (successful)
  1060.  
  1061. rdatcf lda     oldtry          * Fetch number of tries for previous packet
  1062.         inc     oldtry          * Increment it for when we need it again
  1063.         cmp a     maxtry          * Have we exceeded maximum tries allowed?
  1064.         bne     rdatf1          * Not yet, go on
  1065.         bra     rdatf2          * Yup, we have to abort this thing
  1066. rdatf1 jmp     rdatf3          * Just continue the transfer
  1067. rdatf2
  1068. rdatf5 lda     #'A             * Move 'abort' code to current system state
  1069.         sta     state           *               ..
  1070.         lda     #errcrd         * Fetch the error index
  1071.         sta     errcod          *       and store it as the error code
  1072.  jsr closef
  1073.         lda     #false          *               ..
  1074.         rts                     *       and return false
  1075. rdatf3 lda     pnum            * Is this packet the one before the expected
  1076.         clc                     *       one?
  1077.         add a     #$01            *               ..
  1078.         cmp a     n               *               ..
  1079.         beq     rdatf4          * If so, we can still ack it
  1080.         jmp     rdatf5          * Otherwise, we should abort the transfer
  1081. rdatf4 lda     #'Y             * Load 'ack' code
  1082.         sta     ptype           * Stuff that parameter
  1083.         lda     #$00            * Use zero as the packet data length
  1084.         sta     pdlen           *               ..
  1085.         jsr     spak            * Send it!
  1086.         lda     #$00            * Zero the number of tries for current packet
  1087.         sta     numtry          *               ..
  1088.         lda     #true           *               ..
  1089.         rts                     * Return (successful)
  1090.  
  1091. rdatce lda     pnum            * Is this the packet we are expecting?
  1092.         cmp a     n               *               ..
  1093.         bne     rdatf5          * No, we should go abort
  1094.         jmp     rdate2          * Yup, go handle it
  1095. rdate1 lda     #'A             * Load 'abort' code into
  1096.         sta     state           *       current system state
  1097.         lda     #errcrd         * Fetch the error index
  1098.         sta     errcod          *       and store it as the error code
  1099.         lda     #false          *               ..
  1100.         rts                     * Return (failure)
  1101. rdate2 lda     #'Y             * Get set up for the ack
  1102.         sta     ptype           * Stuff the packet type
  1103.         lda     n               *       packet number
  1104.         sta     pnum            *               ..
  1105.         lda     #$00            *       and packet data length
  1106.         sta     pdlen           *       parameters
  1107.         jsr     spak            * Go send it!
  1108.  
  1109.  jsr closef
  1110.  lda #'B
  1111.  sta state complete
  1112.  lda numtry
  1113.  sta oldtry
  1114.  lda #$00
  1115.  sta numtry
  1116.  jsr incn
  1117.  lda #true
  1118.  rts exit
  1119.  
  1120.  
  1121. closef jmp fmscls
  1122.  
  1123. rrbrk1 lda numtry
  1124.  inc numtry
  1125.  cmpa maxtry
  1126.  bne rrbrk2 not excceded try count
  1127.  jmp rdate1 too many tries
  1128. rrbrk2 jsr rpak
  1129.  sta rstat
  1130.  lda ptype
  1131.  cmpa #'Z
  1132.  bne rrbrk3
  1133.  jmp rreof reack last
  1134. rrbrk3 cmpa #'B
  1135.  bne rrbrk4
  1136.  jmp rrbp ack the break packet
  1137. rrbrk4 lda rstat
  1138.  cmp a #false
  1139.  lbeq rdat2d nak it
  1140.  bra rdate1 wrong type ..abort
  1141.  
  1142. rreof lda oldtry
  1143.  inc oldtry
  1144.  cmpa maxtry
  1145.  lbeq rdate1 error in packet #
  1146.  lda pnum
  1147.  adda #$01 prev
  1148.  cmpa n
  1149.  beq rdate4 ack it
  1150.  lbra rdate1 error in packet #
  1151.  
  1152. rrbp lda pnum
  1153.  cmpa n
  1154.  lbne rdate1 abort wrong packet #
  1155.  lbsr rdate4 ack B.. packet.
  1156.  bra rrds
  1157.  
  1158.  
  1159. rdate4 lda #'Y
  1160.  sta ptype
  1161.  lda n
  1162.  sta pnum
  1163.  lda #$00
  1164.  sta pdlen
  1165.  jsr spak send ack
  1166.  rts
  1167.  
  1168. rrds lda #'C
  1169.  sta state
  1170.  lda #true complete
  1171.  rts
  1172.  
  1173.  STTL  Send routine
  1174.  
  1175. *
  1176. *       This routine reads a file from disk and sends packets
  1177. *       of data to the remote kermit
  1178. *
  1179. *               Input  Filename returned from Comnd routines
  1180. *
  1181. *               Output File is sent over port
  1182. *
  1183. *               Registers destroyed    A,X,Y
  1184. *
  1185.  
  1186. send equ *
  1187. *get file name
  1188.  ldx #filena
  1189.  jsr pstr
  1190.  ldx #fcb1
  1191.  jsr inline
  1192.  ldx #filenr
  1193.  jsr pstr
  1194.  ldx #fcb2
  1195.  jsr inline
  1196.  jsr sswt
  1197.         jmp     kermit          * Go back to main routine
  1198.  
  1199. sswt   lda     #'S             * Set up state variable as
  1200.         sta     state           *       Send-init
  1201.         lda     #$00            * Clear
  1202.         sta     n               *       Packet number
  1203.         sta     numtry          *       Number of tries
  1204.         sta     oldtry          *       Old number of tries
  1205.         sta     eofinp          *       End of input flag
  1206.         sta     errcod          *       Error indicator
  1207.         sta     rtot            *       Total received characters
  1208.         sta     rtot+1          *               ...
  1209.         sta     stot            *       Total Sent characters
  1210.         sta     stot+1          *               ...
  1211.         sta     rchr            *       Received characters, current file
  1212.         sta     rchr+1          *               ...
  1213.         sta     schr            *       and a Sent characters, current file
  1214.         sta     schr+1          *               ...
  1215.  sta filend reset file end flag
  1216.         ldx     #pdbuf         * Set up the address of the packet buffer
  1217.         stx     saddr           *       so that we can clear it out
  1218.         lda     #$00            * Clear AC
  1219.         ldb     #$00            * Clear Y
  1220.  ldy saddr
  1221. clpbuf sta     b,y       * Step through buffer, clearing it out
  1222.         inc b                     * Up the index
  1223.         cmpb     #mxpack       * Done?
  1224.         bne     clpbuf          * No, continue
  1225. sswt1  lda     state           * Fetch state of the system
  1226.         cmp a     #'D             * Do Send-data?
  1227.         bne     sswt2           * No, try next one
  1228.         jsr     sdat            * Yes, send a data packet
  1229.         jmp     sswt1           * Go to the top of the loop
  1230. sswt2  cmp a     #'F             * Do we want to send-file-header?
  1231.         bne     sswt3           * No, continue
  1232.         jsr     sfil            * Yes, send a file header packet
  1233.         jmp     sswt1           * Return to top of loop
  1234. sswt3  cmp a     #'Z             * Are we due for an Eof packet?
  1235.         bne     sswt4           * Nope, try next state
  1236.         jsr     seof            * Yes, do it
  1237.         jmp     sswt1           * Return to top of loop
  1238. sswt4  cmp a     #'S             * Must we send an init packet
  1239.         bne     sswt5           * No, continue
  1240.         jsr     sini            * Yes, go do it
  1241.         jmp     sswt1           * And continue
  1242. sswt5  cmp a     #'B             * Time to break the connection?
  1243.         bne     sswt6           * No, try next state
  1244.         jsr     sbrk            * Yes, go send a break packet
  1245.         jmp     sswt1           * Continue from top of loop
  1246. sswt6  cmp a     #'C             * Is the entire transfer complete?
  1247.         bne     sswt7           * No, something is wrong, go abort
  1248.         lda     #true           * Return true
  1249.         rts                     *               ...
  1250. sswt7  lda     #false          * Return false
  1251.         rts                     *               ...
  1252.  
  1253. sdat   lda     numtry          * Fetch the number for tries for current packet
  1254.         inc     numtry          * Add one to it
  1255.         cmp a     maxtry          * Is it more than the maximum allowed?
  1256.         bne     sdat1           * No, not yet
  1257.         bra     sdat1a          * If it is, go abort
  1258. sdat1  jmp     sdat1b          * Continue
  1259. sdat1a lda     #'A             * Load the 'abort' code
  1260.         sta     state           * Stuff that in as current state
  1261.  lda #errmrc
  1262.  sta errcod
  1263.         lda     #false          * Enter false return code
  1264.         rts                     *       and a return
  1265. sdat1b lda     #'D             * Packet type will be 'Send-data'
  1266.         sta     ptype           *               ...
  1267.         lda     n               * Get packet sequence number
  1268.         sta     pnum            * Store that parameter to Spak
  1269.         lda     size            * This is the size of the data in the packet
  1270.         sta     pdlen           * Store that where it belongs
  1271.         jsr     spak            * Go send the packet
  1272. sdat2  jsr     rpak            * Try to get an ack
  1273.         sta     rstat           * First, save the return status
  1274.         lda     ptype           * Now get the packet type received
  1275.         cmp a     #'N             * Was it a NAK?
  1276.         bne     sdat2a          * No, try for an ACK
  1277.         jmp     sdatcn          * Go handle the nak case
  1278. sdat2a cmp a     #'Y             * Did we get an ACK?
  1279.         bne     sdat2x          * No, try checking the return status
  1280.         jmp     sdatca          * Yes, handle the ack
  1281. sdat2x cmp a #'E
  1282.  bne sdat2b
  1283.  jsr pemsg
  1284.  bra sdat1a
  1285. sdat2b lda     rstat           * Fetch the return status
  1286.         cmp a     #false          * Failure return?
  1287.         beq     sdat2c          * Yes, just return with current state
  1288.         lda     #'A             * Stuff the abort code
  1289.         sta     state           *       as the current system state
  1290.         lda     #false          * Load failure return code
  1291. sdat2c rts                     * Go back
  1292.  
  1293. sdatcn dec  pnum            * Decrement the packet sequence number
  1294.         lda     n               * Get the expected packet sequence number
  1295.         cmp a     pnum            * If n=pnum-1 then this is like an ack
  1296.         bne     sdatn1          * No, continue handling the nak
  1297.         jmp     sdata2          * Jump to ack bypassing sequence check
  1298. sdata1
  1299. sdatn1 lda     #false          * Failure return
  1300.         rts                     *               ...
  1301. sdatca lda     n               * First check packet number
  1302.         cmp a     pnum            * Did he ack the correct packet?
  1303.         bne     sdata1          * No, go give failure return
  1304. sdata2 lda     #$00            * Zero out number of tries for current packet
  1305.         sta     numtry          *               ...
  1306.         jsr     incn            * Increment the packet sequence number
  1307.         jsr     bufill          * Go fill the packet buffer with data
  1308.         sta     size            * Save the data size returned
  1309.         lda     eofinp          * Load end-of-file indicator
  1310.         cmp a     #true           * Was this set by Bufill?
  1311.         beq     sdatrz          * If so, return state 'Z' ('Send-eof')
  1312.         jmp     sdatrd          * Otherwise, return state 'D' ('Send-data')
  1313. sdatrz lda     #'Z             * Load the Eof code
  1314.         sta     state           *       and a make it the current system state
  1315.         lda     #true           * We did succeed, so give a true return
  1316.         rts                     * Go back
  1317. sdatrd lda     #'D             * Load the Data code
  1318.         sta     state           * Set current system state to that
  1319.         lda     #true           * Set up successful return
  1320.         rts                     *       and a go back
  1321.  
  1322. sfil   lda     numtry          * Fetch the current number of tries
  1323.         inc     numtry          * Up it by one
  1324.         cmp a     maxtry          * See if we went up to too many
  1325.         bne     sfil1           * Not yet
  1326.         bra     sfil1a          * Yes, go abort
  1327. sfil1  jmp     sfil1b          * If we are still ok, take this jump
  1328. sfil1a lda     #'A             * Load code for abort
  1329.         sta     state           *       and a drop that in as the current state
  1330.  lda #errmrc
  1331.  sta errcod
  1332.         lda     #false          * Load false for a return code
  1333.         rts                     *       and a return
  1334. sfil1b ldb     #$00            * Clear B
  1335. sfil1c ldy #fcb2
  1336.  lda     b,y          * Get a byte from the filename
  1337.         cmp a     #$00            * Is it a null?
  1338.         beq     sfil1d          * No, continue
  1339.  ldy #pdbuf
  1340.         sta     b,y         * Move the byte to this buffer
  1341.         incb                     * Up the index once
  1342.         jmp     sfil1c          * Loop and a do it again
  1343. sfil1d        stb     pdlen           * This is the length of the filename
  1344.         lda     #'F             * Load type ('Send-file')
  1345.         sta     ptype           * Stuff that in as the packet type
  1346.         lda     n               * Get packet number
  1347.         sta     pnum            * Store that in its common area
  1348.         jsr     spak            * Go send the packet
  1349. sfil2  jsr     rpak            * Go try to receive an ack
  1350.         sta     rstat           * Save the return status
  1351.         lda     ptype           * Get the returned packet type
  1352.         cmp a     #'N             * Is it a NAK?
  1353.         bne     sfil2a          * No, try the next packet type
  1354.         jmp     sfilcn          * Handle the case of a nak
  1355. sfil2a cmp a     #'Y             * Is it, perhaps, an ACK?
  1356.         bne     sfil2x          * If not, go to next test
  1357.         jmp     sfilca          * Go and a handle the ack case
  1358. sfil2x cmpa #'E
  1359.  bne sfil2b
  1360.  jsr pemsg
  1361.  bra sfil1a abort
  1362. sfil2b lda     rstat           * Get the return status
  1363.         cmp a     #false          * Is it a failure return?
  1364.         bne     sfil2c          * No, just go abort the send
  1365.         rts                     * Return failure with current state
  1366. sfil2c bra sfil1a
  1367. sfilcn dec     pnum            * Decrement the receive packet number once
  1368.         lda     pnum            * Load it into the AC
  1369.         cmp a     n               * Compare that with what we are looking for
  1370.         bne     sfiln1          * If n=pnum-1 then this is like an ack, do it
  1371.         jmp     sfila2          * This is like an ack
  1372. sfila1
  1373. sfiln1 lda     #false          * Load failure return code
  1374.         rts                     *       and a return
  1375. sfilca lda     n               * Get the packet number
  1376.         cmp a     pnum            * Is that the one that was acked?
  1377.         bne     sfila1          * They are not equal
  1378. sfila2 lda     #$00            * Clear AC
  1379.         sta     numtry          * Zero the number of tries for current packet
  1380.         jsr     incn            * Up the packet sequence number
  1381.         ldx     #fcb1          * Load the fcb address into the pointer
  1382. * open the file (harris)
  1383.  ldx #fcb1
  1384. sfcn lda 0,x+
  1385.  cmpa #$00
  1386.  bne sfcn
  1387.  lda #$20
  1388.  leax -1,x
  1389.  sta 0,x
  1390.  ldx #fcb1
  1391.  stx $cc14
  1392.  ldx #fcb
  1393.  jsr getfil
  1394.  bcs sfer1
  1395.  lda #1
  1396.  sta 0,x open for read
  1397.  jsr setext
  1398.  jsr fms open file
  1399.  bne sfer1
  1400.  
  1401.  clr linlen
  1402.  clr lfnext
  1403.         jsr     bufill          * Go get characters from the file
  1404.         sta     size            * Save the returned buffer size
  1405.         lda     #'D             * Set state to 'Send-data'
  1406.         sta     state           *               ...
  1407.         lda     #true           * Set up true return code
  1408.         rts                     *       and a return
  1409.  
  1410. sfer1 jsr rpterr tell user
  1411.  jsr fmscls
  1412.  jmp main
  1413.  
  1414. seof   lda     numtry          * Get the number of attempts for this packet
  1415.         inc     numtry          * Now up it once for next time around
  1416.         cmp a     maxtry          * Are we over the allowed max?
  1417.         bne     seof1           * Not quite yet
  1418.         bra     seof1a          * Yes, go abort
  1419. seof1  jmp     seof1b          * Continue sending packet
  1420. seof1a lda     #'A             * Load 'abort' code
  1421.         sta     state           * Make that the state of the system
  1422.         lda     #errmrc         * Fetch the error index
  1423.         sta     errcod          *       and a store it as the error code
  1424.         lda     #false          * Return false
  1425.         rts                     *               ...
  1426. seof1b lda     #'Z             * Load the packet type 'Z' ('Send-eof')
  1427.         sta     ptype           * Save that as a parm to Spak
  1428.         lda     n               * Get the packet sequence number
  1429.         sta     pnum            * Copy in that parm
  1430.         lda     #$00            * This is our packet data length (0 for EOF)
  1431.         sta     pdlen           * Copy it
  1432.         jsr     spak            * Go send out the Eof
  1433. seof2  jsr     rpak            * Try to receive an ack for it
  1434.         sta     rstat           * Save the return status
  1435.         lda     ptype           * Get the received packet type
  1436.         cmp a     #'N             * Was it a nak?
  1437.         bne     seof2a          * If not, try the next packet type
  1438.         jmp     seofcn          * Go take care of case nak
  1439. seof2a cmp a     #'Y             * Was it an ack
  1440.         bne     seof2x          * If it wasn't that, try return status
  1441.         jmp     seofca          * Take care of the ack
  1442. seof2x cmpa #'E
  1443.  bne seof2b
  1444.  jsr pemsg
  1445.  bra seof1a
  1446. seof2b lda     rstat           * Fetch the return status
  1447.         cmp a     #false          * Was it a failure?
  1448.         beq     seof2c          * Yes, just fail return with current state
  1449.  bra seof1a
  1450. seof2c rts                     * Return
  1451. seofcn dec     pnum            * Decrement the received packet sequence number
  1452.         lda     n               * Get the expected sequence number
  1453.         cmp a     pnum            * If it's the same as pnum-1, it is like an ac
  1454. k
  1455.         bne     seofn1          * It isn't, continue handling the nak
  1456.         jmp     seofa2          * Switch to an ack but bypass sequence check
  1457. seofa1
  1458. seofn1 lda     #false          * Load failure return status
  1459.         rts                     *       and a return
  1460. seofca lda     n               * Check sequence number expected against
  1461.         cmp a     pnum            *       the number we got.
  1462.         bne     seofa1          * If not identical, fail and a return curr. stat
  1463. e
  1464. seofa2 lda     #$00            * Clear the number of tries for current packet
  1465.         sta     numtry          *               ...
  1466.         jsr     incn            * Up the packet sequence number
  1467. seofrb lda     #'B             * Load Eot state code
  1468.         sta     state           * Store that as the current state
  1469.         lda     #true           * Give a success on the return
  1470.         rts                     *               ...
  1471.  
  1472. sini   ldy     #pdbuf         * Load the pointer to the
  1473.         sty     kerbf1          *       packet buffer into its
  1474.         jsr     spar            * Go fill in the send init parms
  1475.         lda     numtry          * If numtry > maxtry
  1476.         cmp a     maxtry          *               ...
  1477.         bne     sini1           *               ...
  1478.         bra     sini1a          *       then we are in bad shape, go fail
  1479. sini1  jmp     sini1b          * Otherwise, we just continue
  1480. sini1a lda     #'A             * Set state to 'abort'
  1481.         sta     state           *               ...
  1482.         lda     #errmrc         * Fetch the error index
  1483.         sta     errcod          *       and a store it as the error code
  1484.         lda     #$00            * Set return status (AC) to fail
  1485.         rts                     * Return
  1486. sini1b inc     numtry          * Increment the number of tries for this packet
  1487.         lda     #'S             * Packet type is 'Send-init'
  1488.         sta     ptype           * Store that
  1489.         lda     #$06            * Else it is 6
  1490. sini1d sta     pdlen           * Store that parameter
  1491.         lda     n               * Get the packet number
  1492.         sta     pnum            * Store that in its common area
  1493.         jsr     spak            * Call the routine to ship the packet out
  1494.         jsr     rpak            * Now go try to receive a packet
  1495.         sta     rstat           * Hold the return status from that last routine
  1496. sinics lda     ptype           * Case statement, get the packet type
  1497.         cmp a     #'Y             * Was it an ACK?
  1498.         bne     sinic1          * If not, try next type
  1499.         jmp     sinicy          * Go handle the ack
  1500. sinic1 cmp a     #'N             * Was it a NAK?
  1501.         bne     sinicx          * If not, try next condition
  1502.         jmp     sinicn          * Handle a nak
  1503. sinicx cmpa #'E
  1504.  bne sinic2
  1505.  jsr pemsg
  1506.  bra sini1a
  1507. sinic2 lda     rstat           * Fetch the return status
  1508.         cmp a     #false          * Was this, perhaps false?
  1509.         bne     sinic3          * Nope, do the 'otherwise' stuff
  1510.         jmp     sinicf          * Just go and a return
  1511. sinic3 bra sini1a
  1512. sinicn
  1513. sinicf rts                     * Return
  1514.  
  1515. sinicy ldb     #$00            * Clear B
  1516.         lda     n               * Get packet number
  1517.         cmp a     pnum            * Was the ack for that packet number?
  1518.         beq     siniy1          * Yes, continue
  1519.         lda     #false          * No, set false return status
  1520.         rts                     *       and a go back
  1521. siniy1 jsr     rpar            * Get parms from the ack packet
  1522. siniy3 lda     #'F             * Load code for 'Send-file' into AC
  1523.         sta     state           * Make that the new state
  1524.         lda     #$00            * Clear AC
  1525.         sta     numtry          * Reset numtry to 0 for next send
  1526.         jsr     incn            * Up the packet sequence number
  1527.         lda     #true           * Return true
  1528.         rts
  1529.  
  1530. sbrk   lda     numtry          * Get the number of tries for this packet
  1531.         inc     numtry          * Incrment it for next time
  1532.         cmp a     maxtry          * Have we exceeded the maximum
  1533.         bne     sbrk1           * Not yet
  1534.         bra     sbrk1a          * Yes, go abort the whole thing
  1535. sbrk1  jmp     sbrk1b          * Continue send
  1536. sbrk1a lda     #'A             * Load 'abort' code
  1537.         sta     state           * Make that the system state
  1538.         lda     #errmrc         * Fetch the error index
  1539.         sta     errcod          *       and a store it as the error code
  1540.         lda     #false          * Load the failure return status
  1541.         rts                     *       and a return
  1542. sbrk1b lda     #'B             * We are sending an Eot packet
  1543.         sta     ptype           * Store that as the packet type
  1544.         lda     n               * Get the current sequence number
  1545.         sta     pnum            * Copy in that parameter
  1546.         lda     #$00            * The packet data length will be 0
  1547.         sta     pdlen           * Copy that in
  1548.         jsr     spak            * Go send the packet
  1549. sbrk2  jsr     rpak            * Try to get an ack
  1550.         sta     rstat           * First, save the return status
  1551.         lda     ptype           * Get the packet type received
  1552.         cmp a     #'N             * Was it a NAK?
  1553.         bne     sbrk2a          * If not, try for the ack
  1554.         jmp     sbrkcn          * Go handle the nak case
  1555. sbrk2a cmp a     #'Y             * An ACK?
  1556.         bne     sbrk2b          * If not, look at the return status
  1557.         jmp     sbrkca          * Go handle the case of an ack
  1558. sbrk2b lda     rstat           * Fetch the return status from Rpak
  1559.         cmp a     #false          * Was it a failure?
  1560.         beq     sbrk2c          * Yes, just return with current state
  1561.  bra sbrk1a
  1562. sbrk2c rts                     *       and a return
  1563. sbrkcn dec     pnum            * Decrement the received packet number once
  1564.         lda     n               * Get the expected sequence number
  1565.         cmp a     pnum            * If =pnum-1 then this nak is like an ack
  1566.         bne     sbrkn1          * No, this was no the case
  1567.         jmp     sbrka2          * Yes! Go do the ack, but skip sequence check
  1568. sbrka1
  1569. sbrkn1 lda     #false          * Load failure return code
  1570.         rts                     *       and a go back
  1571. sbrkca lda     n               * Get the expected packet sequence number
  1572.         cmp a     pnum            * Did we get what we expected?
  1573.         bne     sbrka1          * No, return failure with current state
  1574. sbrka2 lda     #$00            * Yes, clear number of tries for this packet
  1575.         sta     numtry          *               ...
  1576.         jsr     incn            * Up the packet sequence number
  1577.         lda     #'C             * The transfer is now complete, reflect this
  1578.         sta     state           *       in the system state
  1579.         lda     #true           * Return success!
  1580.         rts                     *               ...
  1581.  
  1582.  
  1583.  
  1584.  
  1585.  STTL  Packet routines - SPAK - send packet
  1586.  
  1587. *
  1588. *       This routine forms and a sends out a complete packet in the
  1589. *       following format
  1590. *
  1591. *       <SOH><char(pdlen)><char(pnum)><ptype><data><char(chksum)><eol>
  1592. *
  1593. *               Input  kerbf1- Pointer to packet buffer
  1594. *                       pdlen-  Length of data
  1595. *                       pnum-   Packet number
  1596. *                       ptype-  Packet type
  1597. *
  1598. *               Output A-      True or False return code
  1599. *
  1600.  
  1601. spak equ *
  1602.  lda #'s
  1603.  jsr couts tell console we are sending packet
  1604.  jsr qures flush que
  1605. * PRINT PACKET NUMBER TO CONSOLE
  1606. spaknd lda     spadch          * Get the padding character
  1607.         ldb     #$00            * Init counter
  1608. spakpd cmpb     spad            * Are we done padding?
  1609.         beq     spakst          * Yes, start sending packet
  1610.         inc b                     * No, up the index and a count by one
  1611.         jsr     telppc          * Output a padding character
  1612.         jmp     spakpd          * Go around again
  1613. spakst lda     #soh            * Get the start-of-header char into AC
  1614.         jsr     telppc          * Send it
  1615.         lda     pdlen           * Get the data length
  1616.         add a     #$03            * Adjust it
  1617.         pshs a                     * Save this to be added into stot
  1618.         add a     #sp             * Make the thing a character
  1619.         sta     chksum          * First item,  start off chksum with it
  1620.         jsr     telppc          * Send the character
  1621.         puls a                     * Fetch the pdlen and a add it into the
  1622.         add a     stot            *               ...
  1623.         sta     stot            *               ...
  1624.         lda     stot+1          *               ...
  1625.         add a     #$00            *               ...
  1626.         sta     stot+1          *               ...
  1627.         lda     pnum            * Get the packet number
  1628.         clc                     *               ...
  1629.         add a     #sp             * Char it
  1630.         pshs a                     * Save it in this condition
  1631.         add a     chksum          * Add this to the checksum
  1632.         sta     chksum          *               ...
  1633.         puls a                     * Restore character
  1634.         jsr     telppc          * Send it
  1635.         lda     ptype           * Fetch the packet type
  1636.         and a     #$7f            * Make sure H.O. bit is off for chksum
  1637.         pshs a                     * Save it on stack
  1638.         add a     chksum          *               ...
  1639.         sta     chksum          *               ...
  1640.         puls a                     * Get the original character off stack
  1641.         jsr    !telppc          * Send packet type
  1642.         ldb     #$00            * Initialize data count
  1643.         stb     datind          * Hold it here
  1644. spaklp ldb     datind          * Get the current index into the data
  1645.         cmpb     pdlen  0$       * Check against packet data length, done?
  1646.         blo     spakdc          * Not yet, process another character
  1647.         jmp     spakch          * Go do chksum calculations
  1648. spakdg ldy kerbf1
  1649.  lda b,y
  1650.         add a     chksum          *               ...
  1651.         sta     chksum          *               ...
  1652.         lda     b,y      * Refetch data from packet buffer
  1653.         jsr     telppc          * Send it
  1654.         inc     datind          * Up the counter and a index
  1655.         jmp     spaklp          * Loop to do next character
  1656. spakch lda     chksum          * Now, adjust the chksum to fit in 6 bits
  1657.         and a     #$c0            * First, take bits 6 and 7
  1658.         lsr     a               *       and a shift them to the extreme right
  1659.         lsr     a               *       side of the AC
  1660.         lsr     a               *               ...
  1661.         lsr     a               *               ...
  1662.         lsr     a               *               ...
  1663.         lsr     a               *               ...
  1664.         add a     chksum          *               ...
  1665.         and a     #$3f            * All this should be mod decimal 64
  1666.         add a     #sp             * Put it in printable range
  1667.         jsr     telppc          *       and a send it
  1668.         lda     seol            * Fetch the eol character
  1669.         jsr     telppc          * Send that as the last byte of the packet
  1670. spakcr rts                     *       and a return
  1671.  
  1672.  
  1673.  STTL  Packet routines - RPAK - receive a packet
  1674.  
  1675. *
  1676. *       This routine receives a standard Kermit packet and a then breaks
  1677. *       it apart returning the individuals components in their respective
  1678. *       memory locations.
  1679. *
  1680. *               Input
  1681. *
  1682. *               Output kerbf1- Pointer to data from packet
  1683. *                       pdlen-  Length of data
  1684. *                       pnum-   Packet number
  1685. *                       ptype-  Packet type
  1686. *
  1687.  
  1688. rpak equ *
  1689. * update user console with packet number
  1690.  lda #'r
  1691.  jsr couts tell console we are receiving packet
  1692. rpaknd lda     #$00            * Clear the
  1693.         sta     chksum          *       chksum
  1694.         sta     datind          *       index into packet buffer
  1695.         sta     kerchr          *       and the current character input
  1696. rpakfs jsr     getplc          * Get a char, find SOH
  1697.         sta     kerchr          * Save it
  1698.         cmp a     #soh            * Is it an SOH character?
  1699.         bne     rpakfs          * Nope, try again
  1700.         lda     #$01            * Set up the switch for receive packet
  1701.         sta     fld             *               ...
  1702. rpklp1 lda     fld             * Get switch
  1703.         cmp a     #$06            * Compare for <= 5
  1704.         blo     rpklp2          * If it still is, continue
  1705.         jmp     rpkchk          * Otherwise, do the chksum calcs
  1706. rpklp2 cmp a     #$05            * Check fld
  1707.         bne     rpkif1          * If it is not 5, go check for SOH
  1708.         lda     datind          * Fetch the data index
  1709.         cmp a     #$00            * If the data index is not null
  1710.         bne     rpkif1          *       do the same thing
  1711.         jmp     rpkif2          * Go process the character
  1712. rpkif1 jsr     getplc          * Get a char, find SOH
  1713.         sta     kerchr          * Save that here
  1714.         cmp a     #soh            * Was it another SOH?
  1715.         bne     rpkif2          * If not, we don't have to resynch
  1716.         lda     #$00            * Yes, resynch
  1717.         sta     fld             * Reset the switch
  1718. rpkif2 lda     fld             * Get the field switch
  1719.         cmp a     #$04            * Is it <= 3?
  1720.         bhs     rpkswt          * No, go check the different cases now
  1721.         lda     kerchr          * Yes, it was, get the character
  1722.         add a     chksum          *               ...
  1723.         sta     chksum          *               ...
  1724. rpkswt lda     fld             * Now check the different cases of fld
  1725.         cmp a     #$00            * Case 0?
  1726.         bne     rpkc1           * Nope, try next one
  1727.         lda     #$00            * Yes, zero the chksum
  1728.         sta     chksum          *               ...
  1729.         jmp     rpkef           *       and restart the loop
  1730. rpkc1  cmp a     #$01            * Is it case 1?
  1731.         bne     rpkc2           * No, continue checking
  1732.         lda     kerchr          * Yes, get the length of packet
  1733.         sec                     *               ...
  1734.         sub a     #sp             * Unchar it
  1735.         sec                     *               ...
  1736.         sub a     #$03            * Adjust it down to data length
  1737.         sta     pdlen           * That is the packet data length, put it there
  1738.         jmp     rpkef           * Continue on to next item
  1739. rpkc2  cmp a     #$02            * Case 2 (packet number)?
  1740.         bne     rpkc3           * If not, try case 3
  1741.         lda     kerchr          * Fetch the character
  1742.         sec                     *               ...
  1743.         sub a     #sp             * Take it down to what it really is
  1744.         sta     pnum            * That is the packet number, save it
  1745.         jmp     rpkef           * On to the next packet item
  1746. rpkc3  cmp a     #$03            * Is it case 3 (packet type)?
  1747.         bne     rpkc4           * If not, try next one
  1748.         lda     kerchr          * Get the character and
  1749.         sta     ptype           *       stuff it as is into the packet type
  1750.         jmp     rpkef           * Go on to next item
  1751. rpkc4  cmp a     #$04            * Is it case 4???
  1752.         bne     rpkc5           * No, try last case
  1753.         ldb     #$00            * Set up the data index
  1754.         stb     datind          *               ...
  1755. rpkchl ldb     datind          * Make sure datind is in Y
  1756.         cmpb     pdlen           * Compare to the packet data length, done?
  1757.         blo     rpkif3          * Not yet, process the character as data
  1758.         jmp     rpkef           * Yes, go on to last field (chksum)
  1759. rpkif3 cmpb     #$00            * Is this the first time through the data loop?
  1760.         beq     rpkacc          * If so, SOH has been checked, skip it
  1761.         jsr     getplc          * Get a char, find SOH
  1762.         sta     kerchr          * Store it here
  1763.         cmp a     #soh            * Is it an SOH again?
  1764.         bne     rpkacc          * No, go accumulate chksum
  1765.         lda     #$ff            * Yup, SOH, go resynch packet input once again
  1766.         sta     fld             *               ...
  1767.         jmp     rpkef           *               ...
  1768. rpkacc lda     kerchr          * Get the character
  1769.         clc                     *               ...
  1770.         add a     chksum          * Add it to the chksum
  1771.         sta     chksum          *       and save new chksum
  1772.         lda     kerchr          * Get the character again
  1773.  ldy kerbf1
  1774.         ldb     datind          * Get our current data index
  1775.         sta     b,y      * Stuff the current character into the buffer
  1776.         inc     datind          * Up the index once
  1777.         jmp     rpkchl          * Go back and check if we have to do this again
  1778. rpkc5  cmp a     #$05            * Last chance, is it case 5?
  1779.         beq     rpkc51          * Ok, continue
  1780.         jmp     rpkpe           * Warn user about program error
  1781. rpkc51 lda     chksum          * Do chksum calculations
  1782.         and a     #$c0            * Grab bits 6 and 7
  1783.         lsr     a               * Shift them to the right (6 times)
  1784.         lsr     a               *               ...
  1785.         lsr     a               *               ...
  1786.         lsr     a               *               ...
  1787.         lsr     a               *               ...
  1788.         lsr     a               *               ...
  1789.         clc                     * Clear carry for addition
  1790.         add a     chksum          * Add this into original chksum
  1791.         and a     #$3f            * Make all of this mod decimal 64
  1792.         sta     chksum          *       and resave it
  1793. rpkef  inc     fld             * Now increment the field switch
  1794.         jmp     rpklp1          * And go check the next item
  1795. rpkchk lda     kerchr          * Get chksum from packet
  1796.         sub a     #sp             * Unchar it
  1797.         cmp a     chksum          * Compare it to the one this Kermit generated
  1798.         beq     rpkret          * We were successful, tell the caller that
  1799.         lda     #$06            * Store the error code
  1800.         sta     errcod          *               ...
  1801. *print to console the
  1802. * error message,packet checksum,expected checksum,crlf
  1803.  
  1804.  ldx #err6
  1805.  jsr pstr
  1806. rpkfls equ *
  1807.         sta     rtot            *               ...
  1808.         lda     rtot+1          *               ...
  1809.         add a     #$00            *               ...
  1810.         sta     rtot+1          *               ...
  1811.  lda #'T
  1812.  sta ptype error packet type
  1813.         lda     #false          * Set up failure return
  1814.         rts                     *       and go back
  1815. rpkret equ *
  1816. rpkrnd lda     pdlen           * Get the packet data length
  1817.         add a     rtot            *       'total characters received' counter
  1818.         sta     rtot            *               ...
  1819.         lda     rtot+1          *               ...
  1820.         add a     #$00            *               ...
  1821.         sta     rtot+1          *               ...
  1822.         lda     #true           * Show a successful return
  1823.         rts                     *       and return
  1824. rpkpe equ *
  1825. * send error message to console
  1826.         lda     #$07            * Load error code and store in errcod
  1827.         sta     errcod          *               ...
  1828.         jmp     rpkfls          * Go give a false return
  1829.  
  1830.  
  1831.  
  1832.  
  1833. *
  1834. *       Bufill - takes characters from the file, does any neccesary quoting,
  1835. *       and then puts them in the packet data buffer. It returns the size
  1836. *       of the data in the AC. If the size is zero and it hit end-of-file,
  1837. *       it turns on eofinp.
  1838. *
  1839.  
  1840. bufill lda     #$00            * Zero
  1841.         sta     datind          *       the buffer index
  1842.  tst filend
  1843.  bne bendit
  1844. bufil1
  1845.  tst lfnext
  1846.  bne flfs
  1847.  ldx #fcb
  1848.  jsr fms read char from file
  1849.  bne frder
  1850. fcrchk cmpa #cr cr from file ?
  1851.  bne nchck
  1852.  clr linlen
  1853.  sta lfnext
  1854. nchck bra notend
  1855. bendit jmp bffchk eof detect
  1856.  
  1857. crsubs
  1858.  lda #cr
  1859.  bra fcrchk
  1860.  
  1861. flfs clr lfnext
  1862.  lda #lf
  1863.  bra notend and send it
  1864.  
  1865. frder lda 1,x get error state
  1866.  cmpa #8
  1867.  bne frder1 error
  1868.  bra bffchk eof
  1869. frder1 jsr rpterr
  1870.  jsr fmscls
  1871.  jmp main
  1872.  
  1873. notend tst monito
  1874.  beq notenm
  1875.  jsr couts data to console
  1876. notenm        sta     kerchr          * Got a character, save it
  1877. bffqc0 cmp a     #sp             * Is the character less than a space?
  1878.         bhs     bffqc1          * If not, try next possibility
  1879.         jmp     bffctl          * This has to be controlified
  1880. bffqc1 cmp a     #del            * Is the character a del?
  1881.         bne     bffqc2          * If not, try something else
  1882.         jmp     bffctl          * Controlify it
  1883. bffqc2 cmp a     squote          * Is it the quote character?
  1884.         bne     bffqc3          * If not, continue trying
  1885.         jmp     bffstq          * It was, go stuff a quote in buffer
  1886. bffqc3
  1887.         bra     bffstf          * Nope, just stuff the character itself
  1888. bffctl lda     kerchr          *[2] Get original character back
  1889.         eor a     #$40            * Ctl(AC)
  1890.         sta     kerchr          * Save the character again
  1891. bffstq lda     squote          * Get the quote character
  1892.  ldy kerbf1
  1893.         ldb     datind          *       and the index into the buffer
  1894.         sta     b,y      * Store it in the next location
  1895.         inc b                     * Up the data index once
  1896.         stb     datind          * Save the index again
  1897. bffstf inc     schr            * Increment the data character count
  1898.         bne     bffsdc          *               ...
  1899.         inc     schr+1          *               ...
  1900. bffsdc ldy     kerbf1          * Get the saved character
  1901.  lda kerchr
  1902.         ldb     datind          *       and the data index
  1903.         sta    b,y     * This is the actual char we must store
  1904.         incb                     * Increment the index
  1905.         stb     datind          * And resave it
  1906.         pshs b                  * Take this index, put it in AC
  1907.         puls a
  1908.         add a     #$06            * Adjust it so we can see if it
  1909.         cmp a     spsiz           *       is >= spsiz-6
  1910.         bhs     bffret          * If it is, go return
  1911.         jmp     bufil1          * Otherwise, go get more characters
  1912. bffret lda     datind          * Get the index, that will be the size
  1913.         rts                     * Return with the buffer size in AC
  1914. bffchk lda     datind          * Get the data index
  1915.         cmp a     #$00            * Is it zero?
  1916.         bne     bffnes          * Nope, just return
  1917.         pshs a                  * Yes, this means the entire file has
  1918.         lda     #true           *       been transmitted so turn on
  1919.         sta     eofinp          *       the eofinp flag
  1920.         puls a
  1921. bffnes sta filend
  1922. bffne  rts                     * Return
  1923.  
  1924. *
  1925. *       Bufemp - takes a full data buffer, handles all quoting transforms
  1926. *       and writes the reconstructed data out to the file using calls to
  1927. *       FPUTC.
  1928. *
  1929.  
  1930. bufemp lda     #$00            * Zero
  1931.         sta     datind          *       the data index
  1932. bfetol lda     datind          * Get the data index
  1933.         cmp a     pdlen           * Is it >= the packet data length?
  1934.         blo     bfemor          * No, there is more to come
  1935.         rts                     * Yes, we emptied the buffer, return
  1936. bfemor ldy kerbf1
  1937.         ldb     datind          * Get the current buffer index
  1938.         lda     b,y      * Fetch the character in that position
  1939.         sta     kerchr          * Save it for the moment
  1940. bfeqc  cmp a     rquote          * Is it the normal quote character
  1941.         bne     bfeout          * No, pass this stuff up
  1942.         inc     datind          * Increment the data index
  1943.         ldb     datind          *       and fetch it in the Y-reg
  1944.         lda     b,y      * Get the next character from buffer
  1945.         sta     kerchr          * Save it
  1946.         cmp a     rquote          * Were we quoting a quote?
  1947.         beq     bfeout          * Yes, nothing has to be done
  1948.         lda     kerchr          *[2] Fetch back the original character
  1949.         eor a     #$40            * No, so controlify this again
  1950.         sta     kerchr          * Resave it
  1951. bfeout lda     kerchr          * Get the character
  1952.  tst monito
  1953.  beq bfeoum
  1954.  jsr couts in monitor send to screen
  1955. bfeoum
  1956.  ldx #fcb
  1957.  jsr fms write char
  1958.  bne wder1
  1959.         inc     rchr            * Increment the 'data characters receive' count
  1960.         bne     bfeou1          *               ...
  1961.         inc     rchr+1          *               ...
  1962. bfeou1 inc     datind          * Up the buffer index once
  1963.         jmp     bfetol          * Return to the top of the loop
  1964.  
  1965. wder1 jsr rpterr
  1966.  jsr fmscls
  1967.  jmp main
  1968.  
  1969.  
  1970. pemsg equ * write packet contents to screen
  1971.  ldx kerbf1
  1972.  lda #eom
  1973.  ldb pdlen
  1974.  sta b,x set eof
  1975.  jsr pstr string to console
  1976.  rts
  1977. *       Incn - increment the packet sequence number expected by this
  1978. *       Kermit. Then take that number Mod $3f.
  1979. *
  1980.  
  1981. incn   psh a                     * Save AC
  1982.         lda     n               * Get the packet number
  1983.         add a     #$01            * Up the number by one
  1984.         and a     #$3f            * Do this Mod $3f!
  1985.         sta     n               * Stuff the number where it belongs
  1986.         puls a                     * Restore the AC
  1987.         rts                     *       and return
  1988.  
  1989.  
  1990. *
  1991. *       Spar - This routine loads the data buffer with the init parameters
  1992. *       requested for this Kermit.
  1993. *
  1994. *               Input  NONE
  1995. *
  1996. *               Output @Kerbf1 - Operational parameters
  1997. *
  1998. *               Registers destroyed    A,Y
  1999. *
  2000.  
  2001. spar   clr b                 * Clear B
  2002.  ldy kerbf1
  2003.  stb datind *clear datind
  2004.         lda     rpsiz           * Fetch receive packet size
  2005.         add a     #$20            * Characterize it
  2006.         sta     b,y      * Stuff it in the packet buffer
  2007.         inc b                     * Increment the buffer index
  2008.  lda rtime * get the timeout interval
  2009.         add a     #$20            * Make that a printable character
  2010.         sta     b,y      *       and stuff it in the buffer
  2011.         inc b                    * Advance the index
  2012.         lda     rpad            * Get the amount of padding required
  2013.         add a     #$20            * Make that printable
  2014.         sta     b,y      * Put it in the buffer
  2015.         inc b                    * Advance index
  2016.         lda     rpadch          * Get the padding character expected
  2017.         eor  a     #$40            * Controlify it
  2018.         sta     b,y      * And stuff it
  2019.         inc b                    * Up the packet buffer index
  2020.         lda     reol            * Get the end-of-line expected
  2021.         add a     #$20            * Characterize it
  2022.         sta     b,y      * Place that next in the buffer
  2023.         inc b                    * Advance the index
  2024.         lda     rquote          * Get the quote character expected
  2025.         sta     b,y      * Store it as-is last in the buffer
  2026.         inc b                    * Advance index
  2027.         lda     rebq            * Get eight-bit-quote character
  2028.         sta     b,y      * Stuff it into the data area
  2029.         rts
  2030.  
  2031. *
  2032. *       Rpar - This routine sets operational parameters for the other kermit
  2033. *       from the init packet data buffer.
  2034. *
  2035. *               Input  @Kerbf1 - Operational parameters
  2036. *
  2037. *               Output Operational parameters set
  2038. *
  2039. *               Registers destroyed    A,Y
  2040. *
  2041.  
  2042. rpar   ldy     kerbf1            * Start the data index at 0!
  2043.  clr b
  2044.         lda     b,y      * Start grabbing data from packet buffer
  2045.         sub a     #$20            *               ...
  2046.         sta     spsiz           * That must be the packet size of other Kermit
  2047.         inc b                    * Increment the buffer index
  2048.         lda     b,y      * Get the next item
  2049.         sub a     #$20            * Uncharacterize that
  2050.         sta     stime           * Other Kermit's timeout interval
  2051.         inc b                    * Up the index once again
  2052.         lda     b,y      * Get next char
  2053.         sub a     #$20            * Restore to original value
  2054.         sta     spad            * This is the amount of padding he wants
  2055.         inc b                    * Advnace index
  2056.         lda     b,y      * Next item
  2057.         eor a     #$40            * Uncontrolify this one
  2058.         sta     spadch          * That is padding character for other Kermit
  2059.         inc b                    * Advance index
  2060.         lda     b,y      * Get next item of data
  2061.         cmp a     #$00            * If it is equal to zero
  2062.         beq     rpar2           * Use <cr> as a default
  2063.         jmp     rpar3           *               ...
  2064. rpar2  lda     #cr             * Get value of <cr>
  2065.         sta     seol            * That will be the eol character
  2066.         jmp     rpar4           * Continue
  2067. rpar3  sec                     *               ...
  2068.         sub a     #$20            * unchar the character
  2069.         sta     seol            * That is the eol character other Kermit wants
  2070. rpar4  inc b                    * Advance the buffer index
  2071.         lda     b,y      * Get quoting character
  2072.         cmp a     #$00            * If that is zero
  2073.         beq     rpar5           * Use # sign as the qoute character
  2074.         jmp     rpar6           * Otherwise, give him what he wants
  2075. rpar5  lda     #'#             * Load # sign
  2076. rpar6  sta     squote          * Make that the other Kermit's quote character
  2077.         inc b                    * Advance the index
  2078.         lda     b,y      * Get 8-bit-quoting character
  2079.         sta     sebq            * Store it - a higher level routine will work
  2080. *       out how to use it
  2081.         rts                     * Return
  2082.  
  2083. *
  2084. *       Nakit - sends a standard NAK packet out to the other Kermit.
  2085. *
  2086. *               Input  NONE
  2087. *
  2088. *               Output NONE
  2089. *
  2090.  
  2091. nakit  lda     #$00            * Zero the packet data length
  2092.         sta     pdlen           *               ...
  2093.         lda     #'N             * Set up a nak packet type
  2094.         sta     ptype           *               ...
  2095.         jsr     spak            * Now, send it
  2096.         rts                     * Return
  2097.  
  2098.  
  2099.  
  2100.  STTL  End of Kermit-65 Source
  2101.  
  2102.         end  start
  2103.