.title K11REC recieve processing .ident /T2.23/ .include /IN:K11MAC.MAC/ .include /IN:K11DEF.MAC/ .psect .enabl gbl ; 13-Oct-84 14:06:43 Brian Nelson ; ; Creation: Moved from K11PAK ; ; ; Copyright (C) 1983 1984 Change Software, Inc. ; ; ; This software is furnished under a license and may ; be used and copied only in accordance with the ; terms of such license and with the inclusion of ; the above copyright notice. This software or any ; other copies thereof may not be provided or other- ; wise made available to any other person. No title ; to and ownership of the software is hereby trans- ; ferred. ; ; The information in this software is subject to ; change without notice and should not be construed ; as a commitment by the author. ; ; .sbttl recsw state table controller for receiving files recsw:: clr paknum ; packet_number := 0 rec.sw::movb @r5 ,state ; assume RECEIVE-INIT for starters clr cccnt ; control_c_count := 0 mov $image ,image ; insure correct default for mode movb #defchk ,chktyp ; reset checksum type to default mov #1 ,chksiz ; the size of the checksum clr numtry ; number_trys := 0 clr oldtry ; add pcnt.r+0,reccnt ; save rec packet count call clrsta ; clear the stats out now clr outopn ; say nothing is open now tst remote ; local or remote bne 5$ ; remote call ttrini ; perhaps special init for local tt: 5$: call rechdr 10$: call recdeb ; perhaps debugging should be done scan state ,#200$ ; case state of asl r0 ; dispatch to correct routine jsr pc ,@210$(r0) bcc 10$ 100$: movb #defchk ,chktyp ; reset type of checksum to 1 mov #1 ,chksiz ; the size of the checksum save ; insure files are closed tst remote ; remote or local bne 105$ ; remote call ttrfin ; local, perhaps clean up console 105$: tst outopn ; file open from a failure ? beq 110$ ; no calls close ,<#lun.ou> ; insure that it's closed clr outopn 110$: unsave ; pop exit status code please return 200$: .byte STA.RIN ,STA.FIL,STA.DAT,STA.COM,STA.ABO,0 .even 210$: .word recs.$ .word recs.r ,recs.f ,recs.d ,recs.c ,recs.a recs.$: clc ; Unknown state return ; back to caller recs.r: call rinit ; receive-init movb r1 ,state ; set state and exit clc ; saying there is more to come return ; bye recs.f: call rfile ; receive-file movb r1 ,state clc return recs.d: call rdata ; receive-data movb r1 ,state clc return recs.c: clr r0 ; complete sec return recs.a: mov sp ,r0 ; abort sec return global .sbttl debugging and logging for receive recdeb: save sub #50 ,sp mov sp ,r1 ; allocate a small buffer mov #200$ ,r2 ; point to a header 10$: movb (r2)+ ,(r1)+ ; copy a header please bne 10$ ; until we find a null dec r1 ; all done movb state ,(r1)+ ; copy the current state over movb #40 ,(r1)+ ; sub sp ,r1 ; get the record length mov sp ,r0 ; and point back to the record bit #log$st ,trace ; debugging for RECSW beq 30$ ; if trace is on then dump the calls putrec ,; dump it 30$: tst debug ; terminal debugging on ? beq 40$ ; no print r0 ,r1 .newli ; and a crlf 40$: tst remote ; running locally ? bne 100$ ; no tst xmode ; simply printing text to ti: ? bne 100$ ; yes, skip the packet stats then call reclog 100$: add #50 ,sp unsave return 200$: .asciz /Recsw - state is / .even global .sbttl rinit receive initialization ; R I N I T ; ; input: nothing .enabl lsb rinit: save ; get registers we use saved inc numtry ; check for retry count cmp numtry ,maxtry ; been here too often ? blos 10$ ; no call m$retry ; log/send the reason for the abort movb #STA.ABO,r1 ; yes, return ABORT state br 100$ 10$: rpack r2,r3,#packet ; get the next packet please scan r1,#200$ ; look for the packet type asl r0 ; and dispatch to it jsr pc ,@210$(r0) ; simple 100$: unsave return 200$: .byte 'S&137 ,'E&137 ,timout ,badchk ,0 .even 210$: .word rini.$ .word rini.S ,rini.E ,rini$$ ,rini$$ .dsabl lsb rini.$: ; unknown packet type rini$$: spack #'N,paknum,#0,#null ; error, send a NAK movb state ,r1 ; and exit return rini.e: calls prerrp ,<#packet> movb #STA.ABO,r1 return rini.s: calls rpar ,<#packet,r2> ; SEND-INIT calls spar ,<#packet> ; get other sides init and fill with spack #'Y,paknum,sparsz,#packet; ours mov numtry ,oldtry clr numtry incm64 paknum ; paknum := (paknum+1) mod 64 call inirepeat ; initialize repeat processing movb #STA.FIL,r1 ; state := FILE-RECEIVE return .sbttl rfile receive file header rfile: save ; get registers we use saved call clratr ; insure attribute stuff is cleared movb conpar+p.chkt,chktyp ; time to use new checksum ? movb chktyp ,chksiz ; compute the checksum size also sub #'0 ,chksiz ; simple mov $image ,image ; insure correct default for mode inc numtry ; check for retry count cmp numtry ,maxtry ; been here too often ? blos 5$ ; no call m$retry ; log why we aborted please movb #STA.ABO,r1 ; yes, return ABORT state br 100$ 5$: tst xgottn ; already get the x packet ? beq 10$ ; no movb #STA.TYP,r1 ; yes, fake that we already got it br 20$ 10$: rpack r2,r3,#packet ; get the next packet please 20$: scan r1,#200$ ; look for the packet type asl r0 ; and dispatch to it jsr pc ,@210$(r0) ; simple 100$: unsave return 200$: .byte 'S&137 ,'Z&137 ,'F&137 ,'B&137 ,'E&137 ,'X&137 .byte timout ,badchk ,0 .even 210$: .word rfil.$ .word rfil.s ,rfil.z ,rfil.f ,rfil.b ,rfil.e ,rfil.x .word rfil$$ ,rfil$$ .sbttl more rfile rfil.$: ; unknow packet type rfil$$: spack #'N,paknum,#0,#null ; timeout or checksum error, send movb state ,r1 ; NAK and continue in current state return rfil.b: cmp r3 ,paknum ; Break XMIT (EOT) beq 10$ ; insure BREAK is for current packet call m$synch ; for abort, say we are out of synch movb #STA.ABO,r1 ; no, return 'ABORT" return ; exit 10$: spack #'Y,paknum,#0,#null ; ACK the BREAK movb #STA.COM,r1 ; and return state as 'COMPLETE' return rfil.e: calls prerrp ,<#packet> ; error packet, print it out movb #STA.ABO,r1 ; return 'ABORT' return rfil.s: inc oldtry ; SEND-INIT, must have lost ours cmp oldtry ,maxtry ; tried this too many times ? blos 10$ ; no call m$retry ; log the reason for the abort movb #STA.ABO,r1 ; yes, return 'ABORT' return 10$: mov paknum ,r1 ; see if thispacket=(paknum+63) mod 64 add #77 ,r1 ; ie, check if this data packet was the clr r0 ; one sent the last time. if so, we div #100 ,r0 ; must reack that packet and remain clr r0 ; in the current state. cmp r3 ,r1 ; bne 20$ ; no calls spar ,<#packet> ; resend our SEND-INIT stuff spack #'Y,r3,sparsz,#packet ; reack this then clr numtry ; clear out retry counter movb state ,r1 ; and return current state return 20$: call m$synch ; log the reason for this event please movb #STA.ABO,r1 ; otherwise return ABORT since we must return ; be way out of synch then. rfil.z: inc oldtry ; END-OF-FILE ? cmp oldtry ,maxtry ; tried this too many times ? blos 10$ ; no call m$retry ; log the reason for this event movb #STA.ABO,r1 ; yes, return 'ABORT' return 10$: mov paknum ,r1 ; see if thispacket=(paknum+63) mod 64 add #77 ,r1 ; ie, check if this data packet was the clr r0 ; one sent the last time. if so, we div #100 ,r0 ; must reack that packet and remain clr r0 ; in the current state. cmp r3 ,r1 ; bne 20$ ; not the last one after all spack #'Y,r3,#0,#null ; reack this then clr numtry ; clear out retry counter movb state ,r1 ; and return current state return 20$: call m$retry ; log the reason for this please movb #STA.ABO,r1 ; otherwise return ABORT since we must return ; be way out of synch then. .sbttl more rfile subroutines ; Move the actual file create to RDATA so we can create ; the output file after all attribute packets have come. ; Thus, when we get the first DATA packet is when we go ; and create the file. ; ; 18-Apr-84 10:24:45 Brian Nelson rfil.f: cmp r3 ,paknum ; FILE name beq 10$ ; insure correct packet numer call m$synch ; log the reason for this ABORT movb #STA.ABO,r1 ; no, return 'ABORT' return ; bye 10$: calls fparse ,<#packet,#filnam>; parse and fill in defaults tst outopn ; output already open as if from beq 20$ ; a NAK or something calls close ,<#lun.ou> ; yes, close it please clr outopn ; it's closed 20$: spack #'Y,paknum ; please ack the fileheader packet mov numtry ,oldtry ; update number of retrys clr numtry ; and init the current retry count incm64 paknum ; paknum := (paknum+1) mod 64 movb #STA.DAT,r1 ; return 'DATA' return rfil.x: cmp r3 ,paknum ; X header name beq 10$ ; insure correct packet numer movb #STA.ABO,r1 ; no, return 'ABORT' return ; bye 10$: spack #'Y,paknum,#0,#null ; ACK the filename clr outlun ; not a real file to output to clr outopn ; nothing is open for output mov sp ,xmode ; flag this also please mov numtry ,oldtry ; update number of retrys clr numtry ; and init the current retry count incm64 paknum ; paknum := (paknum+1) mod 64 movb #STA.DAT,r1 ; return 'DATA' return global global .sbttl rdata receive data from pc ; R D A T A ; ; input: nothing ; output: global paknum packet number ; oldtry retry count ; packet packet just received ; numtry ; r1 returned state rdata: save clr r0 ; error := 0 inc numtry ; abort of retry count is too large cmp numtry ,maxtry ; been here too many times ? blos 10$ ; no call m$retry ; log/send error message about it movb #STA.ABO,r1 ; yes, return state(abort) br 100$ ; bye 10$: rpack r2,r3,#packet ; get the next imcoming packet scan r1 ,#200$ ; look for the packet type and dispatch asl r0 ; to the correct routine. ie, a crude jsr pc ,@210$(r0) ; case statement 100$: unsave return 200$: .byte 'A&137 ,'D&137 ,'E&137 ,'F&137 ,'Z&137 ,'X&137 .byte timout ,badchk ,0 .even 210$: .word rdat.$ .word rdat.a ,rdat.d ,rdat.e ,rdat.f ,rdat.z ,rdat.x .word rdat$$ ,rdat$$ global .sbttl rdata packet handlers rdat.d: tst xmode ; do we need to create the file bne 10$ ; no tst outopn ; did we already open the file up? bne 10$ ; yes, please don't try again then. calls create ,<#filnam,#lun.ou,image>; now create it tst r0 ; did the file create work ? beq 5$ ; yes mov #lun.ou ,outlun ; set a real LUN for output calls syserr , ; no, get the system error text calls error ,<#3,#230$,#errtxt,#filnam> movb #STA.ABO,r1 ; return 'ABORT' return 5$: calls fillog ,<#0,#filnam> ; log to disk perhaps ? calls printm ,<#2,#240$,#filnam> mov sp ,outopn ; flag output as being open mov #lun.ou ,outlun ; set a real LUN for output 10$: cmp r3 ,paknum ; case "D" beq 40$ ; Correct packet number ? inc oldtry ; no, see if retry limit expired cmp oldtry ,maxtry ; if so, return ABORT blos 20$ ; no call m$retry ; log/send notice of what happened movb #STA.ABO,r1 ; yes, return 'ABORT' return ; bye 20$: mov paknum ,r1 ; see if thispacket=(paknum+63) mod 64 add #77 ,r1 ; ie, check if this data packet was the clr r0 ; one sent the last time. if so, we div #100 ,r0 ; must reack that packet and remain clr r0 ; in the current state. cmp r3 ,r1 ; insure r0 is not affected bne 30$ ; not the last packet spack #'Y,r3,#6,#packet ; reack this then clr numtry ; clear out retry counter movb state ,r1 ; and return current state return 30$: call m$synch ; log/send the reason for the abort movb #STA.ABO,r1 ; otherwise return ABORT since we must return ; be way out of synch then. 40$: calls bufemp ,<#packet,r2> ; correct packet, get the data out tst r0 ; did BUFEMP return any errors? beq 41$ ; no calls syserr , ; it failed, send error packet calls error ,<#2,#200$,#errtxt> br 100$ ; take the abort exit please 41$: tst remote ; are we a local kermit today ? bne 70$ ; no, just ack normally tst cccnt ; we are local. check for control bne 60$ ; c abort for this file please call chkabo ; check for abort via ^X and ^Z cmpb r0 ,#'E&37 ; control E aborts NOW beq 60$ ; yes, abort please cmpb r0 ,#'Z&37 ; did the user type a control Z? beq 50$ ; yes cmpb r0 ,#'X&37 ; no, what about a control X then? bne 70$ ; no 45$: spack #'Y,paknum,#1,#220$ ; ^X typed, send an X in the data br 80$ 50$: spack #'Y,paknum,#1,#210$ ; yes, send an ACK with "Z" data br 80$ ; 60$: spack #'E,paknum ; control E, abort this mess br 100$ ; bye 70$: spack #'Y,paknum,#0,#null ; ack it 80$: mov numtry ,oldtry ; oldtry_count:= numtry clr numtry ; numtry := 0 incm64 paknum ; increment packet number mod 64 movb #STA.DAT,r1 ; switch to data state return ; bye 100$: mov #STA.ABO,r1 ; abort for some reason return global 200$: .asciz /Local KERMIT error: / 210$: .byte 'Z&137,0 220$: .byte 'X&137,0 230$: .asciz /Create failed - / 240$: .asciz /Created file - / .even .sbttl rdata subroutines, continued ; 'F', got a FILE HEADER rdat.x: ; 'X', also handle EXTENED REPLY rdat.f: inc oldtry ; no, see if retry limit expired cmp oldtry ,maxtry ; if so, return ABORT blos 10$ ; no call m$retry ; log/send the reason for the abort movb #STA.ABO,r1 ; yes, return 'ABORT' return ; bye 10$: mov paknum ,r1 ; see if thispacket=(paknum+63) mod 64 add #77 ,r1 ; ie, check if this data packet was the clr r0 ; one sent the last time. if so, we div #100 ,r0 ; must reack that packet and remain clr r0 ; in the current state. cmp r3 ,r1 ; bne 20$ ; not the last packet spack #'Y,r3,#0,#null ; reack this then clr numtry ; clear out retry counter movb state ,r1 ; and return current state return 20$: call m$synch ; log/send the reason for the abort movb #STA.ABO,r1 ; else return ABORT return rdat.e: calls prerrp ,<#packet> ; flag error, print it movb #STA.ABO,r1 ; return ABORT return rdat.z: cmp paknum ,r3 ; END OF FILE. If not correct packet beq 10$ ; the return 'ABORT' call m$synch ; log/send the reason for the abort movb #STA.ABO,r1 ; switch to abort state return ; and exit 10$: mov #lun.ou ,r2 ; assume that we close a disk file tst outopn ; real output or to the terminal bne 20$ ; it's a for real disk file today clr r2 ; no, it's the console terminal 20$: calls close , ; do the close now call clratr ; attributes no longer valid clr outopn ; flag it spack #'Y,r3,#0,#null ; acknowledge the eof packet incm64 paknum ; paknum := (paknum+1) mod 64 movb #STA.FIL,r1 ; back to receive file state clr xgottn ; don't have an X packet anymore return rdat.$: ; unknown packet type rdat$$: spack #'N,paknum,#0,#null ; timed out or checksum error movb state ,r1 ; NAK it and return current state return global .sbttl receive data attribute packets rdat.a: cmp r3 ,paknum ; case "A" beq 40$ ; Correct packet number ? inc oldtry ; no, see if retry limit expired cmp oldtry ,maxtry ; if so, return ABORT blos 20$ ; no call m$retry ; log/send the reason for the abort movb #STA.ABO,r1 ; yes, return 'ABORT' return ; bye 20$: mov paknum ,r1 ; see if thispacket=(paknum+63) mod 64 add #77 ,r1 ; ie, check if this data packet was the clr r0 ; one sent the last time. if so, we div #100 ,r0 ; must reack that packet and remain clr r0 ; in the current state. cmp r3 ,r1 ; insure r0 is not affected bne 30$ ; not the last packet spack #'Y,r3 ; reack this then clr numtry ; clear out retry counter movb state ,r1 ; and return current state return 30$: movb #STA.ABO,r1 ; otherwise return ABORT since we must return ; be way out of synch then. 40$: calls r$attr ,<#packet> ; simple tst r0 ; was this successful ? bne 50$ ; no spack #'Y,paknum mov numtry ,oldtry ; oldtry_count:= numtry clr numtry ; numtry := 0 incm64 paknum ; increment packet number mod 64 movb state ,r1 ; retain current state br 100$ ; all done 50$: movb #STA.ABO,r1 ; new state br 100$ ; bye 100$: return ; exti 200$: .asciz /Attribute packet error - / .even .end