home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / b / krtsen.mac < prev    next >
Text File  |  2020-01-01  |  27KB  |  816 lines

  1.     .title    KRTSEN    Send file processing
  2.     .ident    "V03.63"
  3.  
  4. ; /63/    27-Sep-97  Billy Youdelman  V03.63
  5. ;
  6. ;    sdat$$ now rewinds instead of close/reopen to get back to top of file
  7. ;    undo repeated char encoding before dispaying remote ACK packet
  8. ;    display file size and type in "sending file" messages
  9. ;    display contents of SEND FILE ACK packet, if any..
  10. ;    redo data packet at sdat$$ when resizing due to first one failing
  11. ;    so the next retry is actually done with the smaller sized packet
  12.  
  13. ; /62/    27-Jul-93  Billy Youdelman  V03.62
  14. ;
  15. ;    dump FILLOG, as PRINTM now does this
  16. ;    use log$packets for state logging
  17. ;    provide for logfile errors
  18. ;    add time to SEN.SW state logging
  19. ;    modified to wait thru bad ack packets, noise, etc..
  20. ;    recpkt buffer back to normal size, now passes same to rpack
  21.  
  22. ; /BBS/     1-Dec-91  Billy Youdelman  V03.61
  23. ;
  24. ;    increased size of recpkt buffer to $allsiz to avoid writing past
  25. ;    eob (causing trap to 4 in rpack$ which crashes the program) when
  26. ;    packets are out of sync and a long packet arrives where an ack
  27. ;    is expected, or line noise "extends" otherwise ok data..
  28. ;
  29. ;    kill debug to TT if not running as a local Kermit
  30. ;    modified to (w/KRTATR) send all attributes in a single packet
  31. ;    ensure directory search channel is closed on errors/aborts
  32. ;
  33. ;    display abort message when file skipped due to SET FILE PROTECT
  34. ;    (by an "X" or "Z" in the ACK packet) on the other Kermit
  35.  
  36. ;    13-Oct-84  14:04:37  Brian Nelson
  37. ;
  38. ;    Copyright 1983,1984 Change Software, Inc.
  39. ;
  40. ;    This software is furnished under a license and may
  41. ;    be  used  and  copied  only in accordance with the
  42. ;    terms of such license and with  the  inclusion  of
  43. ;    the  above copyright notice.  This software or any
  44. ;    other copies thereof may not be provided or other-
  45. ;    wise made available to any other person.  No title
  46. ;    to and ownership of the software is hereby  trans-
  47. ;    ferred.
  48. ;
  49. ;    The information in this  software  is  subject  to
  50. ;    change  without notice and should not be construed
  51. ;    as a commitment by the author.
  52.  
  53.  
  54.     .include "IN:KRTMAC.MAC"
  55.     .iif ndf  KRTINC  .error    <; .include for IN:KRTMAC.MAC failed>
  56.     .include "IN:KRTDEF.MAC"
  57.     .iif ndf  MSG$DA  .error    <; .include for IN:KRTDEF.MAC failed>
  58.  
  59.     .mcall    .PURGE            ; /62/ to hose dir search ch on err
  60.  
  61.  
  62.     .sbttl    Local data
  63.  
  64.     .psect    $pdata            ; /62/ consolidated this stuff here..
  65. fillst:    .word    10$    ,20$    ,30$    ; /63/
  66.  10$:    .asciz    "ASCII (7-bit)"        ; /63/
  67.  20$:    .asciz    "BINARY (8-bit)"    ; /63/
  68.  30$:    .asciz    "DEC-Multinational"    ; /63/
  69. adpmsg:    .asciz    "First data packet failed, PACKET-LENGTH reduced to "
  70. adptag:    .asciz    ". bytes"
  71. badpre:    .asciz    "Ignoring invalid "
  72. badack:    .asciz    "ACK/NAK serial number"
  73. badpak:    .asciz    "response"        ; /63/
  74. badtag:    .asciz    ", paknum: "
  75. sen.01:    .asciz    "SEN.SW"
  76. sen.02:    .asciz    "Warning: Parity found in SOH byte"
  77. sen.03:    .asciz    "Remote ACK: "        ; /63/
  78. sen.04:    .asciz    "ABORT$CURRENT-FILE"
  79. sen.05:    .asciz    "ABORT$ALL-FILES"
  80. sen.06:    .byte    eof$dis    ,0
  81. sen.07:    .asciz    "Sending file "
  82. sen.08:    .asciz    " as "            ; /63/
  83. sen.09:    .asciz    " file "
  84.     .even
  85.  
  86.     .psect    recpkt    ,rw,d,lcl,rel,con
  87. recpkt:    .blkb    maxpak+2        ; /62/ added passed length to rpack
  88.  
  89.  
  90.     .psect    $code
  91.     .sbttl    State controller for send file processing
  92.     .enabl    lsb
  93.  
  94. sensw::    movb    @r5    ,state        ; state at which caller wants to begin
  95.     clr    cccnt            ; /62/ no ^Cs typed yet
  96.     movb    #defchk    ,chktyp        ; setup the default checksum type
  97.     mov    #1    ,chksiz        ; size of default checksum
  98.     mov    $image    ,image        ; ensure correct default for mode
  99.     clr    paknum            ; packet_number := 0
  100.     clr    numtry            ; retry_count := 0
  101.     cmpb    conpar+p.chkt,#'1    ; did other system want CRC checks?
  102.     bne    10$            ; yep
  103.     cmpb    senpar+p.chkt,#'1    ; simple block checks today?
  104.     beq    20$            ; yes, assume caller's state is ok
  105. 10$:    movb    #sta.sin,state        ; no, must force a sinit exchange
  106. 20$:    clr    logini            ; /62/ force display stats header
  107.     call    inista            ; /63/ init packet count stats
  108.     clr    dpnumber        ; /43/ clear data packet count
  109.     movb    sentim    ,senpar+p.time    ; /62/ load send time-out value
  110.  
  111. 30$:    call    sendeb            ; do send debugging if enabled
  112.     call    senlog            ; /62/ update transfer stats display
  113.     cmp    incpar    ,#1        ; /62/ is it possible that parity
  114.     bne    40$            ; /62/ is messed up?
  115.     calls    printm    ,<#1,#sen.02>    ; /62/ warn, but only once
  116.     inc    incpar            ; /62/ be sure it is only once!
  117. 40$:    tst    remote            ; /43/ if remote,
  118.     bne    50$            ; /43/ ignore random noise
  119.     tst    cccnt            ; /36/ ^C abort?
  120.     beq    50$            ; /36/ no
  121.     movb    #sta.cca,state        ; /36/ ya, fake abort
  122. 50$:    scan    state    ,#70$        ; now dispatch
  123.     asl    r0            ; based on current
  124.     jsr    pc    ,@80$(r0)    ; state
  125.     movb    r1    ,state        ; set a new state
  126.     bcc    30$            ; ok
  127.  
  128.     movb    #defchk    ,chktyp        ; reset the checksum type
  129.     mov    #1    ,chksiz        ; size of the above checksum
  130.     save    <r0>            ; save the exit status code
  131.     tst    inopn            ; file open from a failure?
  132.     beq    60$            ; no
  133.     calls    close    ,<#lun.in>    ; ya, ensure that it's closed
  134.     clr    inopn            ; /BBS/ say so..
  135. 60$:
  136.     .purge    #lun.sr            ; /62/ close dir search channel
  137.     call    incsta            ; /43/ increment timer stats
  138.     unsave    <r0>            ; pop exit status code please
  139.     return
  140.  
  141.     .save
  142.     .psect    $pdata
  143. 70$:    .byte    sta.abo    ,sta.brk,sta.com,sta.dat,sta.fil,sta.atr,sta.sin
  144.     .byte    sta.eof    ,sta.cca
  145.     .byte    0
  146.     .even
  147. 80$:    .word    send.$
  148.     .word    send$$    ,sbreak    ,send.c    ,sdata    ,sfile    ,sattr    ,sinit    ; /62/
  149.     .word    seof    ,ccabort
  150.     .restore
  151.  
  152.     .dsabl    lsb
  153.  
  154.  
  155.     .sbttl    State routines for SENSW
  156.     .enabl    lsb            ; /62/
  157.  
  158. send.$:    call    bad$pak            ; /62/ report ignoring bad packet type
  159.     movb    state    ,r1        ; /62/ stay in same state
  160.     clc                ; keep sensw running
  161.     return
  162.  
  163. ccabort:spack    #msg$err,paknum        ; /36/ break up a deadlock perhaps
  164. send$$:    mov    sp    ,r0        ; flag there was an error
  165.     movb    #sta.abo,r1        ; return(abort)
  166.     br    10$
  167.  
  168. send.c:    clr    r0            ; complete
  169. 10$:    sec                ; exit sensw
  170.     return
  171.  
  172.     .dsabl    lsb            ; /62/
  173.  
  174.  
  175.     .sbttl    Received bad ACK/NAK and error handling
  176.     .enabl    lsb            ; /62/ all new..
  177.  
  178. sndx$$:    movb    state    ,r1        ; time-out, stay in current state
  179.     br    10$            ; kill re-read loop and retry packet
  180. sndx.$:    cmp    numtry    ,maxtry        ; bad data, been here too often?
  181.     blo    bad$pak            ; compare as if already bumped..
  182. s$retry:call    m$retry            ; too many retries error
  183.     br    sabort
  184. sndx.e:    calls    prerrp    ,<#recpkt>    ; print out received error packet
  185.     br    sabort
  186. s$sync:    call    m$sync            ; can't resync packets error
  187. sabort:    movb    #sta.abo,r1        ; exit please
  188. 10$:    clr    datauk            ; stop read_only loop
  189.     return
  190.  
  191. bad$pak:mov    #1    ,datauk        ; listen again, no matter what
  192.     mov    #badpak    ,r3        ; point to appropriate text
  193.     br    20$            ; common code..
  194. bad$ack:mov    #-1    ,datauk        ; listen again, but just once
  195.     mov    #badack    ,r3        ; point to appropriate text
  196. 20$:    inc    numtry            ; this is another retry
  197.     mov    #pcnt.s    ,r1        ; packet number
  198.     mov    #spare1    ,r0        ; where to write ascii output
  199.     clr    r2            ; kill leading zero and spaces
  200.     call    $cddmg            ; convert 32-bit # to ascii
  201.     clrb    @r0            ; make it .asciz
  202.     calls    printm    ,<#4,#badpre,r3,#badtag,#spare1> ; say what's up
  203.     return
  204.  
  205.     .dsabl    lsb
  206.  
  207.  
  208.     .sbttl    Send debugging and logging    ; /62/ major revision..
  209.  
  210. sendeb:    mov    trace    ,r0        ; copy of debug status word
  211.     bic    #^c<log$pa!log$de>,r0    ; need to do this?
  212.     beq    30$            ; nope
  213.     save    <r1,r2>
  214.     sub    #100.    ,sp        ; allocate a small buffer
  215.     mov    sp    ,r1        ; point to it
  216.     mov    #sen.01    ,r2        ; /62/ pointer to "SEN.SW"
  217.     call    paksta            ; get elapsed time of last packet
  218.     sub    sp    ,r1        ; get the record length
  219.     mov    sp    ,r2        ; and point back to the record
  220.     bit    #log$pa    ,trace        ; debugging for SEND.SW
  221.     beq    10$            ; if trace is on then
  222.     calls    putrec    ,<r2,r1,#lun.lo> ; dump it
  223.     tst    r0            ; did it work?
  224.     beq    10$            ; ya
  225.     call    logerr            ; no, handle the error
  226. 10$:    tst    remote            ; is there a TT to do this?
  227.     bne    20$            ; not right now..
  228.     bit    #log$de    ,trace        ; terminal debugging on?
  229.     beq    20$            ; no
  230.     wrtall    r2            ; ya, print it
  231.     .newline
  232. 20$:    add    #100.    ,sp        ; deallocate the buffer
  233.     unsave    <r2,r1>
  234. 30$:    return
  235.  
  236.  
  237.     .sbttl    Send attribute data for the current file
  238.     .enabl    lsb
  239.  
  240. ; /BBS/    Modified to (w/KRTATR.MAC) send all attributes in a single packet
  241. ; /E64/ Change this back to send multiple attributes packets if
  242. ; /E64/ more than 94 bytes of attributes.
  243.  
  244. sattr:    clr    datauk            ; /62/ init re-read only flag
  245.     inc    numtry            ; abort if it's been trying too much
  246.     cmp    numtry    ,maxtry        ; well?
  247.     blos    10$            ; no, keep it up
  248.     jmp    s$retry            ; /62/ handle the error please
  249.  
  250. 10$:    tst    doattr            ; really do this?
  251.     beq    30$            ; no
  252.     calls    w$attr    ,<#lun.in,#packet> ; build the attributes packet
  253.     tst    r0            ; any errors along the way?
  254.     bne    30$            ; yes
  255.     tst    r1            ; anything to send over?
  256.     beq    30$            ; no
  257.  
  258.     spack    #msg$atr,paknum,r1,#packet ; send file attributes to receiver
  259. 20$:    rpack    r2 ,r3    ,#recpkt,#maxpak ; /62/ get the reply please
  260.     scan    r1    ,#50$        ; and take action on the reply
  261.     asl    r0            ; dispatch based on the packet type
  262.     jsr    pc    ,@60$(r0)    ; simple
  263.     tst    datauk            ; /62/ need to re-read w/o re-sending?
  264.     bne    20$            ; /62/ ya
  265.     br    40$            ; /62/ no
  266.  
  267. 30$:    calls    buffil    ,<#0,#packet>    ; /63/ get the first buffer of data
  268.     mov    r1    ,size        ; and save it
  269.     movb    #sta.dat,r1        ; switch to data state
  270. 40$:    clc                ; /62/ keep sensw running
  271.     return
  272.  
  273.     .save
  274.     .psect    $pdata
  275. 50$:    .byte    msg$err    ,msg$nak,msg$ack,timout    ,badchk
  276.     .byte    0
  277.     .even
  278. 60$:    .word    sndx.$                    ; /62/
  279.     .word    sndx.e    ,satr.n    ,satr.y    ,sndx$$    ,sndx.$    ; /62/ badchk = noise
  280.     .restore
  281.  
  282.     .dsabl    lsb
  283.  
  284.  
  285.     .sbttl    Process response to SATTR
  286.     .enabl    lsb            ; /62/
  287.  
  288. satr$$:    jmp    sndx$$            ; /62/ common code
  289.  
  290. satr.n:    cmp    r3    ,paknum        ; /62/ is NAK for this packet?
  291.     beq    satr$$            ; /62/ ya, resend the data
  292.     dec    r3            ; NAK for next packet
  293.     bge    10$            ; is ACK for current packet
  294.     mov    #63.    ,r3        ; if --paknum<0, 63:paknum
  295. 10$:    cmp    r3    ,paknum        ; well?
  296.     beq    40$            ; /62/ it's an implicit ACK
  297.     br    20$            ; /62/ out of sync, try to fix things
  298.  
  299. satr.y:    cmp    r3    ,paknum        ; ensure ACK is for correct packet
  300.     beq    40$            ; it is
  301. 20$:    cmp    numtry    ,maxtry        ; /62/ it isn't, been here too often?
  302.     blos    30$            ; /62/ not yet
  303.     jmp    s$sync            ; /62/ ya, say so, send error packet
  304.  
  305. 30$:    tst    datauk            ; /62/ already tossed one bad ACK/NAK?
  306.     blt    satr$$            ; /62/ ya, re-send packet
  307.     jmp    bad$ack            ; /62/ listen again, but just once
  308.  
  309. 40$:    clr    datauk            ; /62/ stop read_only loop
  310.     clr    numtry            ; retrycount := 0
  311.     incm64    paknum            ; paknum := (paknum+1) mod 64
  312. 50$:    calls    buffil    ,<#0,#packet>    ; /63/ get the first buffer of data
  313.     mov    r1    ,size        ; /BBS/ and save it
  314.     movb    #sta.dat,r1        ; /BBS/ switch to data state
  315.     return
  316.  
  317.     .dsabl    lsb            ; /62/
  318.  
  319.  
  320.     .sbttl    Send a break packet
  321.     .enabl    lsb
  322.  
  323. sbreak:    clr    datauk            ; /62/ init re-read only flag
  324.     inc    numtry            ; abort if retry count is too high
  325.     cmp    numtry    ,maxtry        ; well?
  326.     blos    10$            ; ok
  327.     jmp    s$retry            ; /62/ handle the error please
  328.  
  329. 10$:    spack    #msg$bre,paknum,#0,#packet ; send a break packet
  330. 20$:    rpack    r2 ,r3    ,#recpkt,#maxpak ; /62/ read the response
  331.     scan    r1    ,#30$        ; and dispatch based on it
  332.     asl    r0            ; word indexing
  333.     jsr    pc    ,@40$(r0)
  334.     tst    datauk            ; /62/ need to re-read w/o re-sending?
  335.     bne    20$            ; /62/ ya
  336.     return                ; /62/ no, carry cleared by above tst
  337.  
  338.     .save
  339.     .psect    $pdata
  340. 30$:    .byte    msg$err    ,msg$nak,msg$ack,timout    ,badchk
  341.     .byte    0
  342.     .even
  343. 40$:    .word    sndx.$                    ; /62/
  344.     .word    sndx.e    ,sbrk.n    ,sbrk.y    ,sndx$$    ,sndx.$    ; /62/ badchk = noise
  345.     .restore
  346.  
  347.     .dsabl    lsb
  348.  
  349.  
  350.     .sbttl    Process response to SBREAK
  351.     .enabl    lsb            ; /62/
  352.  
  353. sbrk$$:    jmp    sndx$$            ; /62/ common code
  354.  
  355. sbrk.n:    cmp    r3    ,paknum        ; /62/ is NAK for this packet?
  356.     beq    sbrk$$            ; /62/ ya, resend the data
  357.     dec    r3            ; NAK for next packet
  358.     bge    10$            ; is ACK for current packet
  359.     mov    #63.    ,r3        ; if --paknum<0, 63:paknum
  360. 10$:    cmp    r3    ,paknum        ; well?
  361.     beq    40$            ; /62/ it's an implicit ACK
  362.     br    20$            ; /62/ out of sync, try to fix things
  363.  
  364. sbrk.y:    cmp    r3    ,paknum        ; ensure ACK is for correct packet
  365.     beq    40$            ; it is
  366. 20$:    cmp    numtry    ,maxtry        ; /62/ it isn't, been here too often?
  367.     blos    30$            ; /62/ not yet
  368.     jmp    s$sync            ; /62/ ya, say so, send error packet
  369.  
  370. 30$:    tst    datauk            ; /62/ already tossed one bad ACK/NAK?
  371.     blt    sbrk$$            ; /62/ ya, re-send packet
  372.     jmp    bad$ack            ; /62/ listen again, but just once
  373.  
  374. 40$:    clr    datauk            ; /62/ stop read_only loop
  375.     clr    numtry            ; ACK for this packet
  376.     incm64    paknum            ; paknum := (paknum+1) mod 64
  377.     movb    #sta.com,r1        ; return(complete)
  378.     return
  379.  
  380.     .dsabl    lsb            ; /62/
  381.  
  382.  
  383.     .sbttl    Send file init
  384.     .enabl    lsb
  385.  
  386. sinit:    movb    #msg$snd,-(sp)        ; normal sinit operation
  387.     call    .sinit            ; for sending files
  388.     return
  389.  
  390. .sinit::clr    datauk            ; /62/ init re-read only flag
  391.     inc    numtry            ; /62/ moved this test here..
  392.     cmp    numtry    ,initry        ; abort if we've been trying too much
  393.     blos    10$            ; no, keep it up
  394.     call    s$retry            ; /62/ yes, return(abort)
  395.     br    30$            ; /62/ go pop init type off the stack
  396.  
  397. 10$:    mov    chktyp    ,-(sp)        ; save checksum type (not needed)
  398.     mov    chksiz    ,-(sp)        ; and size (also not needed)
  399.     movb    #defchk    ,chktyp        ; force type one please
  400.     mov    #1    ,chksiz        ; length of it
  401.     calls    spar    ,<#packet>    ; get our send parameters
  402.     call    cantyp            ; flush pending input please
  403.     movb    6(sp)    ,r5        ; packet type to do today
  404.     spack    r5,paknum,sparsz,#packet ; send our init info now
  405. 20$:    rpack    r2 ,r3    ,#recpkt,#maxpak ; /62/ and get the other's response
  406.     scan    r1    ,#40$        ; and dispatch to the correct
  407.     asl    r0            ; routine now
  408.     jsr    pc    ,@50$(r0)
  409.     tst    datauk            ; /62/ need to re-read w/o re-sending?
  410.     bne    20$            ; /62/ ya  note above tst clears carry
  411.     mov    (sp)+    ,chksiz        ; restore checksum size
  412.     mov    (sp)+    ,chktyp        ; restore checksum type
  413. 30$:    mov    (sp)+    ,@sp        ; dump passed packet type now
  414.     return
  415.  
  416.     .save
  417.     .psect    $pdata
  418. 40$:    .byte    msg$err    ,msg$nak,msg$ack,timout    ,badchk
  419.     .byte    0
  420.     .even
  421. 50$:    .word    sndx.$                    ; /62/
  422.     .word    sini.e    ,sini.n    ,sini.y    ,sndx$$    ,sndx.$    ; /62/ badchk = noise
  423.     .restore
  424.  
  425.     .dsabl    lsb
  426.  
  427.  
  428.     .sbttl    Process response to SINIT
  429.     .enabl    lsb            ; /62/
  430.  
  431. sini.$:    jmp    sndx.$            ; /62/ common
  432. sini$$:    jmp    sndx$$            ; /62/ code
  433.  
  434. sini.e:    calls    prerrp    ,<#recpkt>    ; /62/ print error message
  435.     cmpb    r5    ,#msg$ser    ; if called from sinfo..
  436.     beq    40$            ; /62/ ..ignore errors
  437.     jmp    sabort            ; /62/ return(abort)
  438.  
  439. sini.n:    cmp    r3    ,paknum        ; /62/ is NAK for this packet?
  440.     bne    sini.$            ; /62/ no, try just listening again
  441.     cmpb    r5    ,#msg$ser    ; server NAK for "I" (sinfo) packet?
  442.     bne    10$            ; /62/ no
  443.     cmp    numtry    ,#2        ; gotten at least one NAK for "I" ?
  444.     bhis    40$            ; /62/ ya, move to file state
  445. 10$:    br    sini$$            ; /62/ no, loop another time
  446.  
  447. sini.y:    cmp    r3    ,paknum        ; got an ACK for sinit
  448.     beq    30$            ; and the ACK is for correct packet
  449.     cmp    numtry    ,initry        ; /62/ it isn't, been here too often?
  450.     blos    20$            ; /62/ not yet
  451.     jmp    s$sync            ; /62/ ya, say so, send error packet
  452.  
  453. 20$:    tst    datauk            ; /62/ already tossed one bad ACK/NAK?
  454.     blt    sini$$            ; /62/ ya, re-send packet
  455.     jmp    bad$ack            ; /62/ listen again, but just once
  456.  
  457. 30$:    calls    rpar    ,<#recpkt,r2>    ; load the other's parameters now
  458. 40$:    clr    datauk            ; /62/ stop read_only loop
  459.     clr    numtry            ; number_of_tries := 0
  460.     incm64    paknum            ; pack_number := pack_number+1 mod 64
  461.     movb    #sta.fil,r1        ; return(file)
  462.     jmp    inirepeat        ; /62/ initialize repeat processing
  463.  
  464.     .dsabl    lsb            ; /62/
  465.  
  466.  
  467.     .sbttl    Send a file
  468.     .enabl    lsb
  469.  
  470. sfile:    clr    datauk            ; /62/ init re-read only flag
  471.     inc    numtry            ; /62/ moved this test here..
  472.     cmp    numtry    ,maxtry        ; abort if we've been trying too much
  473.     blos    10$            ; no, keep it up
  474.     jmp    s$retry            ; /62/ handle the error please
  475.  
  476. 10$:    movb    conpar+p.chkt,chktyp    ; switch to new checksum type
  477.     movb    chktyp    ,chksiz        ; compute the checksum size also
  478.     sub    #'0    ,chksiz        ; simple
  479.     mov    $image    ,image        ; ensure correct default for mode
  480.     mov    #filnam    ,r3        ; and point to it please
  481.     clr    skipfl            ; the user skipped the rest of a file
  482.     call    clratr            ; ensure attribute stuff is cleared
  483.     call    inirepeat        ; must reset ptrs for repeat counts
  484.     sub    #ln$max+2,sp        ; /63/ a converted file name buffer
  485.     mov    sp    ,r4        ; and point to it please
  486.     tst    inopn            ; open files hanging around?
  487.     beq    20$            ; no
  488.     calls    close    ,<#lun.in>    ; yes, clean up please
  489.     clr    inopn            ; it's closed now
  490. 20$:    tstb    filnam            ; /38/ a REAL file today?
  491.     bne    30$            ; /38/ ya..
  492.     jmp    70$            ; /38/ no, must be an extended reply
  493. 30$:    tst    doauto            ; see if we should check for binary
  494.     beq    40$            ; no, don't do it please
  495.     tst    image            ; /56/
  496.     bne    40$            ; /56/
  497.     calls    chkext    ,<#filnam>    ; should we force binary mode?
  498.     tst    r0            ; if gt, then yes
  499.     ble    40$            ; no
  500.     mov    #binary    ,image        ; yes, force binary file operations
  501. 40$:    calls    open    ,<#filnam,#lun.in,image> ; open the file for input
  502.     tst    r0            ; did it work?
  503.     beq    50$            ; yes
  504.     calls    syserr    ,<r0,#errtxt>    ; no
  505.     calls    error    ,<#3,#errtxt,#aspace,#filnam> ; /BBS/ add space here
  506.     movb    #sta.abo,r1        ; return(abort)
  507.     br    90$            ; go dump local buffer and exit
  508.  
  509. 50$:    mov    sp    ,inopn        ; file is open
  510.     tst    xmode            ; is this a server X-tended reply?
  511.     bne    70$            ; yes, send a simple "X" packet
  512.     calls    namcvt    ,<#filnam,r4>    ; convert to simple name (strip dev:)
  513.     tstb    asname            ; /36/ check for alternate name?
  514.     beq    60$            ; /36/ no
  515.     mov    #asname    ,r4        ; /36/ yes, point to that name
  516. 60$:    movb    #'[    ,errtxt        ; /63/ a leading bracket
  517.     mov    #lun.in    ,r0        ; /63/ the LUN in use here
  518.     asl    r0            ; /63/ word indexing
  519. ; /E64/    NOTE: this doesn't handle large files!!
  520.     mov    sizof(r0),r0        ; /63/ recover the file size
  521.     mov    #errtxt+1,r1        ; /63/ start writing size here
  522.     call    L10012            ; /63/ convert size to ascii
  523.     movb    #']    ,(r1)+        ; /63/ a terminating bracket
  524.     clrb    (r1)            ; /63/ terminate the size string
  525.     mov    image    ,r1        ; /63/ recover current file-type
  526.     asl    r1            ; /63/ word indexing
  527.     mov    fillst(r1),r1        ; /63/ point to its description
  528.     calls    printm    ,<#7,#sen.07,#filnam,#errtxt,#sen.08,r1,#sen.09,r4>
  529.     strlen    r4            ; and get the file name length
  530.     spack    #msg$fil,paknum,r0,r4    ; set the file name packet over
  531.     clrb    asname            ; /36/ ensure one shot only
  532.     br    80$
  533.  
  534. 70$:    spack    #msg$tex,paknum        ; server extended reply here, send "X"
  535. 80$:    rpack    r2 ,r3    ,#recpkt,#maxpak ; /62/ get response to the file name
  536.     scan    r1    ,#100$        ; and dispatch on the response
  537.     asl    r0            ; word indexing
  538.     jsr    pc    ,@110$(r0)    ; and call the appropriate response
  539.     tst    datauk            ; /62/ need to re-read w/o re-sending?
  540.     bne    80$            ; /62/ ya
  541. 90$:    add    #ln$max+2,sp        ; /63/ dump local buff, clears carry
  542.     return
  543.  
  544.     .save
  545.     .psect    $pdata
  546. 100$:    .byte    msg$err    ,msg$nak,msg$ack,timout    ,badchk
  547.     .byte    0
  548.     .even
  549. 110$:    .word    sndx.$                    ; /62/
  550.     .word    sndx.e    ,sfil.n    ,sfil.y    ,sndx$$    ,sndx.$    ; /62/ badchk = noise
  551.     .restore
  552.  
  553.     .dsabl    lsb
  554.  
  555.  
  556.     .sbttl    Process response to SFILE
  557.     .enabl    lsb            ; /62/
  558.  
  559. sfil$$:    jmp    sndx$$            ; /62/ common code
  560.  
  561. sfil.n:    cmp    r3    ,paknum        ; /62/ is NAK for this packet?
  562.     beq    sfil$$            ; /62/ ya, resend the data
  563.     dec    r3            ; NAK for next packet
  564.     bge    10$            ; is ACK for current packet
  565.     mov    #63.    ,r3        ; if --paknum<0, 63:paknum
  566. 10$:    cmp    r3    ,paknum        ; well?
  567.     beq    40$            ; /62/ it's an implicit ACK
  568.     br    20$            ; /62/ out of sync, try to fix things
  569.  
  570. sfil.y:    cmp    r3    ,paknum        ; ensure ACK is for correct packet
  571.     beq    40$            ; it is
  572. 20$:    cmp    numtry    ,maxtry        ; /62/ it isn't, been here too often?
  573.     blos    30$            ; /62/ not yet
  574.     jmp    s$sync            ; /62/ ya, say so, send error packet
  575.  
  576. 30$:    tst    datauk            ; /62/ already tossed one bad ACK/NAK?
  577.     blt    sfil$$            ; /62/ ya, re-send packet
  578.     jmp    bad$ack            ; /62/ listen again, but just once
  579.  
  580. 40$:    tstb    recpkt            ; /63/ anything in received packet?
  581.     beq    50$            ; /63/ no
  582.     calls    bufunp    ,<#recpkt,#spare1> ; /63/ undo repeat encoding first
  583.     calls    printm    ,<#2,#sen.03,#spare1> ; /63/ ya, print the packet
  584. 50$:    clr    datauk            ; /62/ stop read_only loop
  585.     clr    numtry            ; number_of_tries := 0
  586.     incm64    paknum            ; packnumber := packnumber+1 mod 64
  587.     movb    #sta.atr,r1        ; assume return(attribute)
  588.     tst    xmode            ; /38/ is this an extended reply?
  589.     beq    60$            ; /38/ no, attributes are next
  590.     calls    buffil    ,<#0,#packet>    ; /63/ ya, get first buffer of data
  591.     mov    r1    ,size        ; /38/ and save it
  592.     movb    #sta.dat,r1        ; /38/ skip attributes, return(data)
  593. 60$:    return
  594.  
  595.     .dsabl    lsb
  596.  
  597.  
  598.     .sbttl    Send file data
  599.     .enabl    lsb
  600.  
  601. sdata:    clr    datauk            ; /62/ init re-read only flag
  602.     inc    numtry            ; abort if we've been trying too much
  603.     cmp    numtry    ,maxtry        ; well?
  604.     blos    10$            ; no, keep it up
  605.     jmp    s$retry            ; /62/ flag the error type please
  606.  
  607. 10$:    spack    #msg$dat,paknum,size,#packet ; send the next record please
  608. 20$:    rpack    r2 ,r3    ,#recpkt,#maxpak ; /62/ get the reply
  609.     scan    r1    ,#30$        ; look for type in list of responses
  610.     asl    r0            ; word indexing
  611.     jsr    pc    ,@40$(r0)    ; dispatch based on the packet type
  612.     tst    datauk            ; /62/ need to re-read w/o re-sending?
  613.     bne    20$            ; /62/ ya
  614.     return                ; /62/ no, carry cleared by above tst
  615.  
  616.     .save
  617.     .psect    $pdata
  618. 30$:    .byte    msg$err    ,msg$nak,msg$ack,timout    ,badchk
  619.     .byte    0
  620.     .even
  621. 40$:    .word    sndx.$                    ; /62/
  622.     .word    sndx.e    ,sdat.n    ,sdat.y    ,sdat$$    ,sndx.$    ; /62/ badchk = noise
  623.     .restore
  624.  
  625.     .dsabl    lsb
  626.  
  627.  
  628.     .sbttl    Process response to SDATA
  629.  
  630. sdat$$:    tst    dpnumber        ; /43/ first data packet?
  631.     bne    10$            ; /43/ no
  632.     cmp    senlng    ,#maxpak    ; /43/ long packet gotten TOO small?
  633.     blos    10$            ; /43/ ya
  634.     asr    senlng            ; /43/ no, reduce packet size
  635.     mov    senlng    ,r0        ; /BBS/ pass new length to L10012
  636.     mov    #spare1    ,r1        ; /BBS/ where to write ascii digits
  637.     call    L10012            ; /BBS/ convert r0 to decimal number
  638.     clrb    @r1            ; /BBS/ null terminate the string
  639.     calls    printm    ,<#3,#adpmsg,#spare1,#adptag> ; /BBS/ inform the user
  640. ;/E64/    This next, commented-out section closes and re-opens the
  641. ;    input file to reset our send pointer.  We are going to try
  642. ;    rewinding it, instead.
  643. ;    calls    close    ,<#lun.in>    ; /E64/ clean up please
  644. ;    clr    inopn            ; /E64/ it's closed now
  645. ;    calls    open    ,<#filnam,#lun.in,image> ; /63/ back to top of file
  646. ;    tst    r0            ; /E64/ did it work?
  647. ;    beq    50$            ; /E64/ yes
  648. ;    calls    syserr    ,<r0,#errtxt>    ; /E64/ no
  649. ;    calls    error    ,<#3,#errtxt,#aspace,#filnam> ; /E64/ add space here
  650. ;    jmp    sabort            ; /E64/ whoops!!
  651. ;
  652. ;50$:    mov    sp    ,inopn        ; file is open
  653.     calls    rewind    ,<#lun.in>    ; /E64/ rewind please
  654.     clr    fileout+0        ; /63/ no chars sent yet
  655.     clr    fileout+2        ; /63/ this too just to be sure..
  656.     call    inirepeat        ; /E64/ must reset repeat count ptrs
  657.     calls    buffil    ,<#0,#packet>    ; /63/ redo the re-sized packet
  658.     mov    r1    ,size        ; /63/ and save it's new length here
  659. 10$:    jmp    sndx$$            ; /62/ keep current state, try again
  660.  
  661.  
  662.     .enabl    lsb
  663.  
  664. sdat.n:    cmp    r3    ,paknum        ; /62/ is NAK for this packet?
  665.     beq    sdat$$            ; /62/ ya, resend the data
  666.     dec    r3            ; NAK for next packet
  667.     bge    10$            ; is ACK for current packet
  668.     mov    #63.    ,r3        ; if --paknum<0, 63:paknum
  669. 10$:    cmp    r3    ,paknum        ; well?
  670.     beq    40$            ; /62/ it's an implicit ACK
  671.     br    20$            ; /62/ out of sync, try to fix things
  672.  
  673. sdat.y:    cmp    r3    ,paknum        ; ensure ACK is for correct packet
  674.     beq    40$            ; it is
  675. 20$:    cmp    numtry    ,maxtry        ; /62/ it isn't, been here too often?
  676.     blos    30$            ; /62/ not yet
  677.     jmp    s$sync            ; /62/ ya, say so, send error packet
  678.  
  679. 30$:    tst    datauk            ; /62/ already tossed one bad ACK/NAK?
  680.     blt    sdat$$            ; /62/ ya, re-send packet
  681.     jmp    bad$ack            ; /62/ listen again, but just once
  682.  
  683. 40$:    clr    datauk            ; /62/ stop read_only loop
  684.     add    #1    ,dpnumber    ; /43/ datapacket_number++
  685.     bcc    50$            ; /43/
  686.     mov    #1    ,dpnumber    ; /43/ avoid overflow
  687. 50$:    clr    numtry            ; retry_counter = 0
  688.     incm64    paknum            ; paknum = paknum++ mod 64
  689.     tst    remote            ; is this a remote system?
  690.     bne    90$            ; yes, forget about checking
  691.     tst    cccnt            ; ^C pending?
  692.     bne    80$            ; yes, always send an error packet
  693.     call    chkabo            ; now check for ^A, ^E, ^X or ^Z
  694.     cmpb    r0    ,#'A&37        ; /56/ ^A stats?
  695.     bne    60$            ; /56/ no
  696.     call    cs$out            ; /56/ yes, dump char counts
  697.     br    90$            ; /56/ and finish up
  698. 60$:    cmpb    r0    ,#abt$err&37    ; /56/ if ^E
  699.     beq    80$            ; /56/ then send error packet
  700.     cmpb    r0    ,#abt$cur&37    ; if ^X
  701.     beq    70$            ; then abort current file
  702.     cmpb    r0    ,#abt$all&37    ; if ^Z
  703.     bne    90$            ; then abort file group
  704.     mov    #-1    ,index        ; flag that we are all done
  705. 70$:    mov    #sta.eof,r1        ; force new state to EOF
  706.     mov    sp    ,skipfl        ; get seof to set discard
  707.     return
  708. 80$:    spack    #msg$err,paknum        ; send an error packet
  709.     clr    cccnt            ; /36/ clear ^C flag
  710.     jmp    sabort            ; /62/ force state to abort
  711.  
  712. 90$:    cmpb    recpkt    ,#abt$cur    ; ACK contain a "X" for skipfile?
  713.     bne    100$            ; /BBS/ no
  714.     calls    printm    ,<#2,#sen.03,#sen.04> ; /63/ ya, say so if not remote
  715.     br    110$            ; /BBS/ then fake EOF
  716. 100$:    cmpb    recpkt    ,#abt$all    ; ACK contain a "Z" for skip all?
  717.     bne    120$            ; no
  718.     calls    printm    ,<#2,#sen.03,#sen.05> ; /63/ ya, say so if not remote
  719.      mov    #-1    ,index        ; flag a fake no more files and
  720. 110$:     movb    #sta.eof,r1        ; fake EOF for either "X" or "Z" ACK
  721.      return
  722.  
  723. 120$:    add    size    ,charout+2    ; /43/ keep track of counts
  724.     adc    charout+0        ; /43/ 32. bits please
  725.     calls    buffil    ,<#0,#packet>    ; /63/ get next buffer of data to send
  726.     mov    r1    ,size        ; and save the size please
  727.     bne    130$            ; something was there
  728.      movb    #sta.eof,r1        ; set state to EOF
  729.      return
  730. 130$:    movb    #sta.dat,r1        ; not EOF, stay in data state
  731.     return
  732.  
  733.     .dsabl    lsb
  734.  
  735.  
  736.     .sbttl    Send end of file packet
  737.     .enabl    lsb
  738.  
  739. seof:    clr    datauk            ; /62/ init re-read only flag
  740.     inc    numtry            ; abort if we've been trying too much
  741.     cmp    numtry    ,maxtry        ; well?
  742.     blos    10$            ; no, keep it up
  743.     jmp    s$retry            ; /62/ handle the error please
  744.  
  745. 10$:    tst    skipfl            ; skipping the rest of a file?
  746.     beq    20$            ; no
  747.     spack    #msg$eof,paknum,#1,#sen.06 ; /62/ yes, send "D" in data field
  748.     br    30$
  749. 20$:    spack    #msg$eof,paknum        ; send an EOF packet out now
  750. 30$:    rpack    r2 ,r3    ,#recpkt,#maxpak ; /62/ get the reply please
  751.     scan    r1    ,#40$        ; and take action on the reply
  752.     asl    r0            ; word indexing
  753.     jsr    pc    ,@50$(r0)    ; dispatch based on the packet type
  754.     tst    datauk            ; /62/ need to re-read w/o re-sending?
  755.     bne    30$            ; /62/ ya
  756.     clr    skipfl            ; clear skipfile flg, also clear carry
  757.     return
  758.  
  759.     .save
  760.     .psect    $pdata
  761. 40$:    .byte    msg$err    ,msg$nak,msg$ack,timout    ,badchk
  762.     .byte    0
  763.     .even
  764. 50$:    .word    sndx.$                    ; /62/
  765.     .word    sndx.e    ,seof.n    ,seof.y    ,sndx$$    ,sndx.$    ; /62/ badchk = noise
  766.     .restore
  767.  
  768.     .dsabl    lsb
  769.  
  770.  
  771.     .sbttl    Process response to SEOF
  772.     .enabl    lsb            ; /62/
  773.  
  774. seof$$:    jmp    sndx$$            ; /62/ common code
  775.  
  776. seof.n:    cmp    r3    ,paknum        ; /62/ is NAK for this packet?
  777.     beq    seof$$            ; /62/ ya, resend the data
  778.     dec    r3            ; NAK for next packet
  779.     bge    10$            ; is ACK for current packet
  780.     mov    #63.    ,r3        ; if --paknum<0, 63:paknum
  781. 10$:    cmp    r3    ,paknum        ; well?
  782.     beq    40$            ; /62/ it's an implicit ACK
  783.     br    20$            ; /62/ out of sync, try to fix things
  784.  
  785. seof.y:    cmp    r3    ,paknum        ; ensure ACK is for correct packet
  786.     beq    40$            ; it is
  787. 20$:    cmp    numtry    ,maxtry        ; /62/ it isn't, been here too often?
  788.     blos    30$            ; /62/ not yet
  789.     jmp    s$sync            ; /62/ ya, say so, send error packet
  790.  
  791. 30$:    tst    datauk            ; /62/ already tossed one bad ACK/NAK?
  792.     blt    seof$$            ; /62/ ya, re-send packet
  793.     jmp    bad$ack            ; /62/ listen again, but just once
  794.  
  795. 40$:    clr    datauk            ; /62/ stop read_only loop
  796.     clr    numtry            ; clear the retry count
  797.     incm64    paknum            ; paknum := (paknum+1) mod 64
  798.     calls    close    ,<#lun.in>    ; close the input file
  799.     clr    inopn            ; input file is now closed
  800.     cmp    index    ,#-1        ; force a break here from user
  801.     beq    50$            ; yes
  802.     clr    r0            ; /38/ no errors
  803.     tst    xmode            ; /38/ extended response?
  804.     bne    50$            ; /38/ finish up the transaction
  805.     call    getnxt            ; get the next input file?
  806.     tst    r0            ; did it work?
  807.     bne    50$            ; no
  808.     movb    #sta.fil,r1        ; yes, set new state to file
  809.     return
  810. 50$:    movb    #sta.brk,r1        ; return(break)
  811.     return
  812.  
  813.     .dsabl    lsb            ; /62/
  814.  
  815.     .end
  816.