home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / flex1 / flxker.txt next >
Text File  |  2020-01-01  |  81KB  |  2,112 lines

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