.TITLE RECEIVE .NLIST LOC .NLIST BIN .NLIST BEX .LIST TTM .IDENT /BCZ/ .MCALL QIOW$S,EXIT$S,FINIT$,WRITE$,OPEN$W,ASTX$S .MCALL FDBDF$,FDAT$A,FDRC$A,FDOP$A,NMBLK$,WSIG$S .MCALL CLOSE$,FSRSZ$,ALUN$S,GCMLB$,CSI$,CSI$SW .MCALL CSI$ND,CSI$SV,GCML$,CSI$1,CSI$2,QIOW$ .MCALL DIR$,FDBK$A,FDAT$R,FDOFF$,NBOFF$,WTSE$S .MCALL READ$,OPEN$R NBOFF$ DEF$L FDOFF$ DEF$L CHKTBF: QIOW$ SF.GMC,1,20.,,,, START: QIOW$S #IO.ATA,#1,#30,,#ISB,,<#RCVAST> QIOW$S #IO.WVB,#1,#20.,,,,<#RECV,#RECVE,#0> ; PRINT OUT RECV> STAR1$: WSIG$S ; WAIT FOR SIG EVENT 2$: CMPB #1,TST2 ; CHECK FOR OTHER CODES BNE STAR1$ ; NOTHING FROM RECV. GOTO STAR1$ CLRB TST2 ; CLEAR RECV FLAG JSR PC,TRNOFF MOV #BUFTMP,R1 ; MOVE TEMPORARY BUFFER ADDR INTO R1 MOV CHRCT2,R4 JSR PC,CRC ; GO TO CRC ROUTINE CMP CRCOUT,#0 ; CHECK FOR CRC ERROR BEQ 3$ ; SUCCESS, GO TO 3$ MOV #"F2,HEADER ; WRITE ERROR MSG HEADER MOV #2,CHRCT1 ; 2 CHARS IN BUFF JSR PC,SNDOUT ; GO TO SNDOUT ROUTINE JMP STAR1$ ; GO BACK AND WAIT FOR MORE 3$: MOV #BUFTMP,R1 ; MOVE TEMPORARY BUFFER ADDR INTO R1 MOVB 1(R1),R5 ; MOVE NUMBER CODE INTO R5 BIC #60,R5 ; CLR BITS TO READ NUMBER ASL R5 ; MULTIPLY BY TWO (WORD ALIGN) CMPB #'F,(R1) ; FAILURE? BNE 4$ ; NO, GO TO 4$ JMP @FAILUR(R5) ; JMP TO OFFSET OF FAILUR 4$: CMPB #'S,(R1) ; IS THIS A SUCCESS? BNE 5$ ; NO, GO TO 5$ JMP @SUCESS(R5) ; JMP TO OFFSET OF SUCESS 5$: JMP EXIT ; JMP TO THE EXIT ROUTINE S0$: MOV #"S4,HEADER ; LOAD FILE MSG HEADER READ$ #FILNAM,#BUFFER,#512.,,#23. ; READ IN BLOCK BCC 3$ ; BRANCH IF NO ERROR TO F2$ CMPB #IE.EOF,F.ERR(R0) ; IS ERROR END OF FILE? BNE 1$ ; NO, BRANCH TO 1$ MOV #"S1,HEADER ; YES, TELL RECEIVER BR 2$ ; BRANCH TO 2$ 1$: MOV #"F1,HEADER ; MOVE ERROR CODE INTO HEADER 2$: MOV #2,CHRCT1 ; 2 CHARS IN BUFF JSR PC,SNDOUT ; AND SEND IT OUT JMP EXIT ; GO AWAY, JOB WELL DONE 3$: WTSE$S #23. MOV #514.,CHRCT1 ; 514 CHARS TO BE SENT F2$: JSR PC,SNDOUT ; SEND OUT BLOCK JMP STAR1$ ; GO BACK AND WAIT FOR REPLY S1$: MOV #FILNAM,R2 ; MOVE FDB INTO R2 MOV HIBK,F.HIBK(R2) ; SET UP FDB BEFORE CLOSING MOV HIBK+2,F.HIBK+2(R2) ; MOV EFBK,F.EFBK(R2) MOV EFBK+2,F.EFBK+2(R2) ; MOV FFBY,F.FFBY(R2) ; CLOSE$ #FILNAM ; AND THEN CLOSE FILE CLRB TRNFLG ; CLEAR TRNFLG JMP EXIT ; EXIT S2$: GCML$ #GCMBLK,#PROMT1,#PRMCT1 CSI$1 #CSIBLK,GCMBLK+G.CMLD+2,GCMBLK+G.CMLD CSI$2 #CSIBLK,OUTPUT FINIT$ OPEN$R #FILNAM,,,#FD.RWM ; OPEN FILE FOR READ ACCESS BCC 1$ ; NO ERROR, BRANCH TO 1$ MOV #"F0,HEADER ; LOAD ERROR MSG INTO HEADER MOV #2,CHRCT1 ; 2 CHARS IN BUFF JSR PC,SNDOUT ; AND SEND IT OUT JMP EXIT ; AND DIE 1$: MOV #FILNAM,R1 ; MOVE FDB ADDRESS TO R1 MOV #BUFFER,R2 ; MOVE BUFFER ADDRESS TO R2 MOVB F.RTYP(R1),(R2)+ ; MOVE IMPORTANT FILE PARAMETERS MOVB F.RATT(R1),(R2)+ ; FROM THE BUFFER INTO THE FDB MOVB F.RSIZ(R1),(R2)+ ; SO WHEN THE FILE IS OPEN ON THE MOVB F.RSIZ+1(R1),(R2)+ ; TRANS END, IT WILL HAVE THE SAME MOVB F.FFBY(R1),(R2)+ ; INFORMATION AS THE ORIGINAL FILE MOVB F.FFBY+1(R1),(R2)+ ; I.E. IF IT IS CONTIGUOUS ON RECV MOVB F.RCTL(R1),(R2)+ ; END, IT WILL BE CONTIGUOUS ON MOVB F.EOBB(R1),(R2)+ ; THE TRANS END. INFORMATION ALSO MOVB F.EOBB+1(R1),(R2)+ ; NEEDED TO GET STATUS MOVB F.HIBK(R1),(R2)+ ; MOVB F.HIBK+1(R1),(R2)+ ; MOVB F.HIBK+2(R1),(R2)+ ; MOVB F.HIBK+3(R1),(R2)+ ; MOVB F.EFBK(R1),(R2)+ ; MOVB F.EFBK+1(R1),(R2)+ ; MOVB F.EFBK+2(R1),(R2)+ MOVB F.EFBK+3(R1),(R2) MOV #"S3,HEADER ; LOAD SUCCESS MSG INTO HEADER MOV #19.,CHRCT1 ; SENDING OUT 19 BYTES JSR PC,SNDOUT ; AND SEND IT OUT JMP STAR1$ ; GO BACK AND WAIT S3$: GCML$ #GCMBLK,#PROMT1,#PRMCT1 CSI$1 #CSIBLK,GCMBLK+G.CMLD+2,GCMBLK+G.CMLD CSI$2 #CSIBLK,OUTPUT FINIT$ MOV #FILNAM,R1 ; MOVE FDB ADDRESS TO R1 MOV #BUFTMP,R2 ; MOVE BUFFER ADDRESS TO R2 INC R2 INC R2 MOVB (R2)+,F.RTYP(R1) ; MOVE IMPORTANT FILE PARAMETERS MOVB (R2)+,F.RATT(R1) ; FROM THE BUFFER INTO THE FDB MOVB (R2)+,F.RSIZ(R1) ; SO WHEN THE FILE IS OPEN ON THE MOVB (R2)+,F.RSIZ+1(R1) ; TRANS END, IT WILL HAVE THE SAME MOVB (R2)+,FFBY ; INFORMATION AS THE ORIGINAL FILE MOVB (R2)+,FFBY+1 ; I.E. IF IT IS CONTIGUOUS ON RECV MOVB (R2)+,F.RCTL(R1) ; END, IT WILL BE CONTIGUOUS ON MOVB (R2)+,F.EOBB(R1) ; THE TRANS END. INFORMATION ALSO MOVB (R2)+,F.EOBB+1(R1) ; NEEDED TO GET STATUS MOVB (R2)+,HIBK ; MOVB (R2)+,HIBK+1 ; MOVB (R2)+,HIBK+2 ; MOVB (R2)+,HIBK+3 ; MOVB (R2)+,EFBK MOVB (R2)+,EFBK+1 ; MOVB (R2)+,EFBK+2 MOVB (R2),EFBK+3 CMP #512.,F.RSIZ(R1) ; IS RECORD SIZE 512 BYTES? BNE 1$ ; NO, JUST OPEN FILE NORMALLY CMPB #1,F.RTYP(R1) ; SHOULD FILE BE CONTIGUOUS? BNE 1$ ; NO, JUST OPEN FILE NORMALLY MOV HIBK+2,CNTG ; MOVE SIZE OF CONTIG FILE INTO CNTG FDAT$R #FILNAM,#R.FIX,,#512.,CNTG,#1 ; MAKE FILE CONTIGUOUS 1$: OPEN$W #FILNAM,,,#FD.RWM ; AND OPEN FILE BCC 2$ ; NO ERROR, BRANCH TO 2$ MOV #"F0,HEADER ; LOAD ERROR MSG INTO HEADER BR 3$ ; BRANCH TO 2$ 2$: MOV #"S0,HEADER ; LOAD SUCCESS MSG INTO HEADER 3$: MOV #2,CHRCT1 ; 2 CHARS IN BUFF JSR PC,SNDOUT ; AND SEND IT OUT JMP STAR1$ ; GO BACK AND WAIT S4$: MOV #512.,R3 MOV #BUFFER,R2 MOV #BUFTMP,R1 INC R1 INC R1 10$: MOVB (R1)+,(R2)+ SOB R3,10$ MOV #2,CHRCT1 ; 2 CHARS IN BUFF WRITE$ #FILNAM,#BUFFER,#512.,,#24. ; WRITE BLOCK TO FILE BCC 1$ ; NO ERROR, BRANCH TO 1$ MOV #"F0,HEADER ; LOAD ERROR MSG INTO HEADER JSR PC,SNDOUT ; AND SEND IT OUT JMP STAR1$ ; GO BACK AND WAIT 1$: WTSE$S #24. MOV #"S0,HEADER ; MOVE SUCCESS CODE INTO HEADER JSR PC,SNDOUT ; SEND IT OUT JMP STAR1$ ; WAIT FOR REPLY F0$: CMPB TRNFLG,#1 ; IS THIS THE RECEIVING END? BEQ 1$ ; YES, BRANCH TO 1$ JMP F3$ ; NO, THEN TERMINATE FOR FATAL ERROR 1$: CLRB TRNFLG ; CLEAR TRNFLG FLAG JMP STAR1$ ; GO BACK TO TRANSPARENCY MODE F1$: CMPB TRNFLG,#1 ; IS THIS THE RECEIVING END? BEQ 1$ ; YES, BRANCH TO 1$ JMP F3$ ; NO, THEN TERMINATE FOR FATAL ERROR 1$: CLOSE$ #FILNAM ; CLOSE FILE CLRB TRNFLG ; CLEAR TRNFLG FLAG JMP STAR1$ ; GO BACK TO TRANSPARENCY MODE F3$: CLOSE$ #FILNAM ; CLOSE FILE EXIT: EXIT$S FAILCR: MOV #"F3,HEADER ; MOVE TERMINATE INTO HEADER MOV #2,CHRCT1 ; TWO CHARS JSR PC,SNDOUT ; AND SEND IT JMP EXIT ; AND EXIT TRNSPR: MOV #HEADER,BUFPNT MOV #BUFOUT,BUFOPT CLR R1 1$: DEC TMPCNT ; HAVE WE REACHED END OF DATA IN BUFFER? BGE 2$ ; NO, GO TO 2$ MOV R1,BUFOPT RTS PC ; YES, RETURN 2$: BITB #200,@BUFPNT BNE 3$ CMPB @BUFPNT,#0 BEQ 3$ CMPB @BUFPNT,#33 BLE 5$ ; YES, GO TO 5$ 3$: MOVB @BUFPNT,@BUFOPT 4$: INC BUFPNT INC BUFOPT INC R1 BR 1$ ; GO TO 1$ 5$: MOVB #33,@BUFOPT INC BUFOPT INC R1 MOVB @BUFPNT,@BUFOPT BISB #100,@BUFOPT BR 4$ ; GO TO 1$ GCMBLK: GCMLB$ ,FIL CSI$ .EVEN LUNBLK: GCMLB$ ,LUN,LUNBUF,,,10. .EVEN LUNBUF: .BLKB 10. .EVEN CSIBLK: .BLKB C.SIZE .EVEN FILNAM: FDBDF$ FDBK$A BUFFER,512.,,20. FDOP$A 3,CSIBLK+C.DSDS,,FO.RD!FA.SHR FDBF$A FSRSZ$ 1 RCVAST: MOVB (SP)+,CHAR CMPB #1,SOHTST BEQ 40$ CMPB #1,CHAR BNE 60$ MOV #BUFTMP,BFTPNT MOVB #1,SOHTST BR 60$ 40$: CMPB #4,CHAR BNE 50$ MOV BFTPNT,CHRCT2 SUB #BUFTMP,CHRCT2 CLRB SOHTST MOVB #1,TST2 BR 60$ 50$: MOVB CHAR,@BFTPNT INC BFTPNT 60$: ASTX$S TRNOFF: MOV CHRCT2,R1 MOV #BUFTMP,BFTPNT ; MOV ADR OF BUFTMP INTO POINTER MOV #BUFTMP,TBFPNT ; MOV ADR OF BUFTMP INTO TMP POINTER CLRB TRNTST 10$: CMPB TRNTST,#1 BEQ 15$ CMPB @TBFPNT,#33 BNE 20$ BITB #200,CHAR BNE 20$ MOVB #1,TRNTST BR 30$ 15$: CLRB TRNTST BICB #100,@TBFPNT 20$: MOVB @TBFPNT,@BFTPNT INC BFTPNT 30$: INC TBFPNT SOB R1,10$ MOV BFTPNT,CHRCT2 SUB #BUFTMP,CHRCT2 RTS PC CRC: MOV R4,TMPCNT ; R4 HOLDS # OF CHARS IN BUFFER BGT 15$ JMP FAILCR 15$: MOV R1,CRCPNT ; MOVE ADR OF BUFFER TO POINTER CRCPNT CLR R1 ; CLEAR R1 TO PREPARE FOR CHAR INPUT 1$: MOVB @CRCPNT,R2 ; GET CHAR TO BE PROCESSED INC CRCPNT ; SET CRCPNT TO NEXT CHAR MOV POLYNO,R3 ; GET CRC POLYNOMIAL MOV #8.,R5 ; NUMBER OF BITS PER CHAR 2$: CLC ; ZERO TO BE SHIFTED IN ROR R1 ; DIVIDE RESIDUE BY 2 ROR R2 ; DIVIDE CHAR BY 2 BVC 3$ ; BRANCH IF NO XOR REQUIRED XOR R3,R1 ; ADJUST RESIDUE 3$: SOB R5,2$ ; CONTINUE UNTIL 8 BITS DONE SOB R4,1$ ; CONTINUE UNTIL ALL CHARS ARE DONE MOV R1,CRCOUT ; MOVE RESIDUE TO BE OUTPUTTED MOV #CRCOUT,R1 ; MOVB (R1)+,@CRCPNT ; INC CRCPNT ; MOVB (R1),@CRCPNT ; 77$: ADD #2,TMPCNT RTS PC ; RETURN SNDOUT: MOV #HEADER,R1 ; MOVE HEADER ADDR INTO R1 FOR CRC MOV CHRCT1,R4 JSR PC,CRC JSR PC,TRNSPR ; ADD IN THE TRANSPARENCY QIOW$S #IO.WAL,#1,#21.,,,,<#SOHTXT,#1,#0> ; SEND START OF MSG CHAR QIOW$S #IO.WAL,#1,#21.,,,,<#BUFOUT,BUFOPT,#0> ; SEND OUTPUT BUFFER QIOW$S #IO.WAL,#1,#21.,,,,<#EOTTXT,#1,#0> ; SEND END OF MSG CHAR RTS PC ; RETURN FAILUR: .WORD F0$ ; ERROR DURING OPEN .WORD F1$ ; ERROR DURING READ .WORD F2$ ; CRC ERROR .WORD F3$ ; TERMINATE RECV SUCESS: .WORD S0$ ; SUCCESSFULL TRANSFER. .WORD S1$ ; FILE TRANSFER COMPLETE .WORD S2$ ; OPEN FILE AT RECV .WORD S3$ ; FILE HEADER TYPE MESSAGE .WORD S4$ ; FILE TEXT TYPE MESSAGE POLYNO: .WORD 102010 ; POLYNOMIAL FOR DETERMINING CRC BUFPNT: .WORD 0 ; VARIABLE USED AS POINTER INTO BUFFER BFTPNT: .WORD 0 ; POINTER INTO BUFTMP CRCPNT: .WORD 0 ; POINTER FOR THE CRC BUFFER TMPCNT: .WORD 0 BUFOPT: .WORD 0 CRCONT: .WORD 0 TBFPNT: .WORD 0 SOHTXT: .BYTE 1 EOTTXT: .BYTE 4 SOHTST: .BYTE 0 TIMOUT: .BYTE 1 TRNFLG: .BYTE 0 TRNTST: .BYTE 0 .EVEN YESNO: .BYTE 0 .EVEN BUFTST: .BYTE 0 .EVEN CTRLQ: .BYTE 17. CTRLS: .BYTE 19. SETBF: .BYTE TC.TBF BUFCHK: .BYTE 0 HEADER: .BLKB 2 BUFFER: .BLKB 512. ; SPACE FOR INPUT BUFFER CRCOUT: .BLKB 2 BUFTMP: .BLKB 1024. ; SPACE FOR TEMPORARY BUFFER BUFOUT: .BLKB 1024. ; SPACE FOR OUTPUT BUFFER CHRCT1: .WORD 0 CHRCT2: .WORD 0 TST2: .BYTE 0 .EVEN CNTG: .WORD -5. HIBK: .BLKB 4 EFBK: .BLKB 4 FFBY: .BLKB 2 CHAR: .BYTE 0 .EVEN ISB: .BLKB 4 NEWLIN: .BYTE 15 .EVEN RECV: .ASCII <15><12>/RECV> / RECVE=.-RECV PROMT1: .ASCII <15><12><12>/ ENTER VAX FILENAME.EXT ==> / PRMCT1=.-PROMT1 .EVEN .END START