REWIND=1 ;REWIND SKRECD=2 ;SKIP XXX RECORDS SKFILE=4 ;SKIP XXXFILES BLANFL=10 ;BALNK FILL BLOCKLN=20 ;BLOCK LENGTH LINETR=40 ;LINE TERMINATOR ALLFILE=100 ;COPY ALL FILES ENDOV=200 ;END OF VOLUME ; ; ; .MCALL FINIT$,GCMLB$,CSI$1,CSI$2,CSI$,CSI$SW,CSI$SV,CSI$ND .MCALL OPEN$W,OPEN$R,CLOSE$,GET$,PUT$,ALUN$S,FDRC$A .MCALL QIOW$C,QIOW$S,GCML$,FSRSZ$,FDOP$R,FDBDF$,FDAT$A .MCALL EXIT$S,CLOSE$ ; ; INITIALIZE WORKING VARIABLES ; START: FINIT$ ;FILE INITIALIZATION,EXECUTE ONLY ONCE NEXT: MOV #0,SWMASK ;CLEAR SWITH MACK MOV #0,NRCD ;CLEAR RECORD LENGTH MOVB #0,LINET ;CLEAR LINE TERMINATOR MOV #0,MTFL ;CLEAR MAG TAPE FLAG MOV #0,DISKF ;CLEAR DISK FLAG MOV #0,DEV ;CLEAR DEVICE NAME ; ; ; USE GCML TO RETRIVE A COMMAND LINE OR ; INDIRECT COMMAND FILE, 1 LEVEL PERMITTED ; ; GCML$ #GCLBLK ;GET A COMMAND BCC CSI1 ;ALL OK? CMPB #GE.EOF,GCLBLK+G.ERR ;CHECK EOF BEQ QUIT ;THAT'S ALL MOV GCLBLK+G.ERR,R0 ;NO MOVE ERROR TO R0 QIOW$C IO.WLB,5,1,,ISB,, HALT QUIT: EXIT$S ;STOP ; ; LET'S USE CSI TO PARSE UP COMMAND ; AND CHECK ALL THE SWITCHES ; CSI1: CSI$1 #CSIBLK,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD BCC CSI2 QIOW$C IO.WLB,5,1,,ISB,, MOV CSIBLK+C.FILD+2,R0 ;ADDRESS OF ERROR MOV CSIBLK+C.FILD,R1 ;LENGTH QIOW$S #IO.WLB,#5,#1,,#ISB,, ;WRITE IT OUT EXIT$S CSI2: CSI$2 #CSIBLK,OUTPUT,#SWTBL BCC CHECK1 QIOW$C IO.WLB,5,1,,ISB,, JMP NEXT ; ; LET'S CHECK OUTPUT FILE SPEC. ; CHECK1: MOV CSIBLK+C.DEVD+2,R1 ;ADDRESS OF DEVICE NAME CMPB (R1),#'M ;IS 1ST CHARACTER AN M? BEQ MTASS ;YES FDOP$R #OUTFIL,#1,#CSIBLK+C.DSDS,#DFNAME,#FO.WRT OPEN$W #OUTFIL,,,,,#OPENER ;OPEN UP OUTPUR FILE JMP CHECK2 MTASS: MOVB (R1)+,DEV ;DEVICE NAME TO R3 MOVB (R1)+,DEV+1 MOVB (R1),R4 ;UNIT NUMBER TO R4 SUB #60,R4 ;CONVERT ASCII TO BINARY ;ASSUME ONLY ONE ASCII CHAR. ALUN$S #1,DEV,R4 ;ASSIGN LUN BCC ASNER ASLUNE: QIOW$C IO.WLB,5,1,,ISB,,;ERROR EXIT$S ASNER: MOV #1,MTFL ;SET MAG TAPE OUTPUT FLAG QIOW$C IO.SMO,1,,,,<0> ;SET MAG TAPE CHARACTERISTICS JMP CHECK2 ; ;OPEN ERROR SUBROUTINE ; OPENER: QIOW$C IO.WLB,5,1,,ISB,, EXIT$S ; ; CONTINUE CHECKING COMMAND LINE ; CHECK2: BITB CSIBLK+C.STAT,#CS.EQU ;OUTPUT FILE SPEC GIVEN? BNE NEXTI ;YES TST MTFL ;IS DEVICE A MT BEQ CEEXT ;NO JSR PC,MTONLY ;NO JMP NEXT ;GO GET ANOTHER COMMAND CEEXT: QIOW$C IO.WLB,5,1,,ISB,, ;ERROR EXIT$S ; ; ; CHECK INPUT FILE SPEC., ; NEXTI: CSI$2 #CSIBLK,INPUT,#SWTBL BCC CHK2 QIOW$C IO.WLB,5,1,,ISB,, ;ERROR JMP NEXT CHK2: MOV CSIBLK+C.DEVD+2,R1 ;GET DEVICE NAME ADR CMPB (R1),#'M ;IS IT A MAG TAPE BEQ MTIASS ;YES TST MTFL ;WAS OUTPUT DEVICE A MT BNE 10$ ;YES JMP CEEXT ;NO, ERROR 10$: FDOP$R #OUTFIL,#2,#CSIBLK+C.DSDS,#DFNAME,#FO.RD OPEN$R #OUTFIL,,,,,#OPENER ;OPEN UP INPUT FILE JMP CHECK3 MTIASS: MOVB (R1)+,DEV ;DEVICE NAME MOVB (R1)+,DEV+1 MOVB (R1),R4 ;UNIT NO SUB #60,R4 ;CONVERT ASCII TO BINARY ALUN$S #2,DEV,R4 ;ASSIGN LUN 2 TO MT BCC 10$ ;ADDIGN GO OK? JMP ASLUNE ;NO 10$: QIOW$C IO.SMO,2,,,,<0> ;SET MAG TAPE TST MTFL ;IS OUTPUT DEVICE MT BEQ CHECK3 SS: MOVBO JSR PC,MTMT ;GO COPY TAPES JMP NEXT ; ; ; FIND OUT IF WE ARE READING OR WRITING A MT ; ; CHECK3: TST MTFL BEQ 10$ ;READING ONE JSR PC,WRTMT ;GO WRITE ONE JMP NEXT 10$: JSR PC,RDMT ;GO READ ONE JMP NEXT ; ; ; ; ; ; ; ; ; ; ; SUBROUTINE TO HANDLE REWIND SKIP RECORDS,&SKIP FILES ; ; MTONLY: CMP #1,SWMASK ;REWIND MAG TAPE BNE MTN1 ;NO QIOW$C IO.RWD,1,1,,ISB ;YES REWIND JMP QIOSC ;CHECK STATUS MTN1: CMP #2,SWMASK ;SKIP RECORD SWITCH BNE 40$ ;NO QIOW$S #IO.SPB,#1,#1,,#ISB,,;SKIP XXX RECORDS JMP QIOSC 40$: CMP #4,SWMASK ;SKIP FILE SWITCH BNE 50$ QIOW$S #IO.SPF,#1,#1,,#ISB,,;SKIP XXX FILES JMP QIOSC 50$: CMP #200,SWMASK ;EOV MARK SWITCH BNE ERS ;NO ERROR QIOW$C IO.EOF,1,1,,ISB JMP QIOSC ERS: QIOW$C IO.WLB,5,1,,ISB,,;INVALID SWITCH RTS PC ; ; CHECK ISB FOR ERRORS ; QIOSC: CMPB #IS.SUC,ISB ;SUCCESSFUL COMPLETION BEQ QIORTN CMPB #IE.EOF,ISB ;END OF FILE ENCOUNTERED? BNE QEOV ;NO QIOW$C IO.WLB,5,1,,ISB,, JMP QIORTN QEOV: CMPB #IE.EOV,ISB ;END OF VOLUME ENCOUNTERED? BNE QEOT ;NO QIOW$C IO.WLB,5,1,,ISB,, JMP QIORTN QEOT: CMPB #IE.EOT,ISB ;END OF TAPE ENCOUNTERED? BNE QERR ;NO QIOW$C IO.WLB,5,1,,ISB,, JMP QIOEX QERR: QIOW$C IO.WLB,5,1,,,, MOV #ISBNO,R0 MOVB ISB,R1 MOV #0,R2 CALL $CBDSG QIOW$C IO.WLB,5,1,,ISB,, QIOEX: EXIT$S QIORTN: RTS PC ;RETURN ; ; ; ; ; SUBROUTINE TO HANDLE COPYING MT TO MT ; ; ; MTMT: TST SWMASK ;ANY SWITCHES BEQ MTMTS ;NO CMP #100,SWMASK ;IS IT /AL BEQ MTMTS ;YES QIOW$C IO.WLB,5,1,,ISB,, ;INVALID SWITCH RTS PC MTMTS: QIOW$C IO.RLB,2,1,,ISB,, ;READ A RECORD CMPB #IS.SUC,ISB ;ALL OK? BEQ 10$ ;YES CMPB #IE.EOF,ISB ;IS ERROR EOF? BEQ MTEOF CMPB #IE.EOV,ISB ;IS ERROR END OF VOLUME BEQ MTEOV JSR PC,QIOSC ;SOME OTHER ERROR 10$: QIOW$S #IO.WLB,#1,#1,,#ISB,,<#DABUF,ISB2> ;WRITE TO TAPE CMPB #IS.SUC,ISB ;SUCCESS BEQ 20$ JSR PC,QIOSC ;ERROR 20$: JMP MTMTS ;GET ANOTHER RECORD MTEOF: QIOW$C IO.EOF,1,1,,ISB ;WRITE EOF CMPB #IS.SUC,ISB BEQ 10$ JSR PC,QIOSC ;ERROR 10$: TST SWMASK ;ARE WE FINISHED BEQ MTRTN ;YES JMP MTMTS ;NO MTEOV: QIOW$C IO.EOF,1,1,,ISB ;WRITE EOF AGAIN FOR EOV CMPB #IS.SUC,ISB BEQ MTRTN JSR PC,QIOSC MTRTN: RTS PC ; ; ; ; ; ; SUBROUTINE TO WRITE TO MAG TAPE ; ; ; WRTMT: TST SWMASK ;ANY SWITCHES? BNE 5$ ;YES JMP WCPY ;OTHERWISE JUST COPY 5$: CMP #10,SWMASK BNE 10$ BIT #1,NRCD BNE 30$ JMP WBLF ;WRITE BLANK FILLED 10$: CMP #20,SWMASK BNE 20$ CLR R1 ;CLEAR BUFFER POINTER BIT #1,NRCD BNE 30$ JMP WBLKT ;BLOCK OUTPUT 20$: CMP #60,SWMASK BNE 30$ CLR R1 BIT #1,NRCD BNE 30$ JMP WBLKT ;WRITE BLOCKED WITH LINE TERMINATOR 30$: QIOW$C IO.WLB,5,1,,ISB,, ;INVALID SWITCH CLOSE$ #OUTFIL RTS PC WCPY: GET$ #OUTFIL,,,EOFCK TST DISKF ;DID WE GET AN END OF FILE BEQ WCPYW ;NO QIOW$C IO.EOF,1,1,,ISB ;YES WRITE ONE TO TAPE CMPB #IS.SUC,ISB BEQ 10$ JSR PC,QIOSC 10$: CLOSE$ #OUTFIL RTS PC WCPYW: MOV F.NRBD(R0),R5 ;NO. OF BYTES TO R5 BIT #1,R5 BEQ 10$ MOVB #0,DABUF(R5) ;ADD A NULL IF ODD BYTE COUNT INC R5 10$: CMP #14.,R5 ;AT LEAST 14. BYTES FOR A WRITE BLE 20$ MOV #14.,R4 SUB R5,R4 ;GET DIFFERENCE 15$: MOVB #0,DABUF(R5) ;FILL WITH NULLS INC R5 SOB R4,15$ ;DO IT AGAIN 20$: QIOW$S #IO.WLB,#1,#1,,#ISB,,<#DABUF,R5> CMPB #IS.SUC,ISB ;EVERY THING OK? BEQ WCPY ;YES CLOSE$ #OUTFIL JSR PC,QIOSC ;ERROR ; ; ; WBLF: GET$ #OUTFIL,,,EOFCK ;GET SOME DATA TST DISKF ;DID WE GET AN EOF BEQ WBLFW ;NO QIOW$C IO.EOF,1,1 ;WRITE EOF TO TAPE CLOSE$ #OUTFIL RTS PC WBLFW: MOV F.NRBD(R0),R5 ;NO. OF BYTES TO R5 CMP NRCD,R5 ;IS IT MORE THAN BLOCKING FACTOR BGE WBLN ;NO QIOW$C IO.WLB,5,1,,ISB,, ;YES ERROR CLOSE$ #OUTFIL EXIT$S WBLN: MOV NRCD,R4 ;BLOCKING FACTOR TO R4 SUB R5,R4 ;GET DIFFERENCE TST R4 ;IF ZERO, GO WRITE BEQ 20$ 10$: MOVB #40,DABUF(R5) ;FILL IN WITH BLANKS INC R5 SOB R4,10$ 20$: QIOW$S #IO.WLB,#1,#1,,#ISB,,<#DABUF,NRCD> ;WRITE IT OUT CMPB #IS.SUC,ISB ;ALL OK? BEQ WBLF ;YES CLOSE$ #OUTFIL ;ERROR JSR PC,QIOSC ; ; ; ; ERROR CHECKING SUBROUTINE FOR DISK GET'S AND PUT'S ; ; EOFCK: CMPB #IE.EOF,F.ERR(R0) ;IS ERROR EOF BEQ M1DSK ;YES QIOW$C IO.WLB,5,1,,ISB,, ;ERROR CLOSE$ #OUTFIL EXIT$S M1DSK: MOV #1,DISKF ;SET DISKF FLAG RTS PC ; ; ; ; ; ; ; WBLKT: GET$ #OUTFIL,,,EOFCK ;GET SOME DATA TST DISKF ;DID WE GET AN EOF? BEQ WBLKC ;NO JSR PC,WBFIN ;YES CLOSE$ #OUTFIL RTS PC WBLKC: MOV F.NRBD(R0),R5 ;NO. OF BYTES TO R5 CMP NRCD,R5 ;LARGER THAN BLOCKING FACTOR BGE WBLKM QIOW$C IO.WLB,5,1,,ISB,, CLOSE$ #OUTFIL EXIT$S WBLKM: MOV NRCD,R4 ;BLOCKING FACTOR SIZE TO R4 SUB R1,R4 ;SUBTRACT 2ND BUFFER POINTER SUB R5,R4 ;SUBTRACT NEXT RECVORD SIZE TST LINET ;ADDING LINE TERMINATOR BEQ 10$ ;NO SUB #1,R4 ;YES SUBTRACT IT OFF TOO MOVB LINET,DABUF(R5) ;ADD LINE TERMINATOR TO OUTPUT BUFFER INC R5 ;ADD 1 TO R5 10$: TST R4 BGE 20$ ;STILL GOT ROOM IN 2ND BUFFER JSR PC,ENDBUF ;WRITE OUT BUFFER AND START AGAIN BR 30$ 20$: CLR R3 30$: MOVB DABUF(R3),DBBUF(R1) ;MOVE DATA TO 2ND BUFFER INC R3 INC R1 SOB R5,30$ ;DO IT AGAIN 40$: JMP WBLKT ;GO GET SOME MORE FROM DISK ; ; ; WBFIN: MOV NRCD,R4 SUB R1,R4 BEQ 20$ 10$: MOVB #0,DBBUF(R1) INC R1 SOB R4,10$ 20$: QIOW$S #IO.WLB,#1,#1,,#ISB,,<#DBBUF,R1> CMPB #IS.SUC,ISB ;ALL OK? BEQ 30$ ;YES JSR PC,QIOSC ;ERROR 30$: QIOW$C IO.EOF,1,1 ;WRITE EOF RTS PC ; ; ; ENDBUF: MOV NRCD,R4 ;BLOCKING FACTOR TO R4 CLR R3 SUB R1,R4 ;FIND NO OF BYTES REMAINING IN BUFFER BEQ 15$ 10$: MOVB DABUF(R3),DBBUF(R1) ;MOV DATA INC R3 INC R1 DEC R5 ;UPDATE OTHER POINTER SOB R4,10$ ;DO IT AGAIN 15$: QIOW$S #IO.WLB,#1,#1,,#ISB,,<#DBBUF,NRCD> ;WRITE IT OUT CMPB #IS.SUC,ISB ;ALL OK? BEQ 20$ ;YES CLOSE$ #OUTFIL JSR PC,QIOSC ;ERROR 20$: CLR R1 ;RESET DBBUF POINTER RTS PC ;RETURN ; ; ; ; SUBROUTINE TO READ A MAG TAPE AND PUT IT ON DISK ; ; RDMT: TST SWMASK ;ANY SWITCHES? BEQ RDCOPY ;NO CMP #40,SWMASK ;IS SWITCH /LT BEQ RDBLS ;YES CMP #20,SWMASK BEQ RDDB QIOW$C IO.WLB,5,1,,ISB,, ;ERROR CLOSE$ #OUTFIL RTS PC RDCOPY: QIOW$C IO.RLB,2,1,,ISB,, ;READ SOME DATA CMPB #IS.SUC ,ISB ;ALL OK? BEQ 30$ ;YES CLOSE$ #OUTFIL JSR PC,QIOSC ;CHECK ERROR RTS PC 30$: MOV ISB2,R5 ;NO. OF BYTES READ IN TST R5 ;DID WE READ ANY BEQ RDCOPY ;NO PUT$ #OUTFIL,,R5,EOFCK ;WRITE TO DISK BR RDCOPY ;GET ANOTHER ONE RDBLS: CLR R2 RDBL: QIOW$C IO.RLB,2,1,,ISB,, ;READ SOME DATA CMPB #IS.SUC,ISB ;ALL OK? BEQ 10$ ;YES CLOSE$ #OUTFIL ;ERROR JSR PC,QIOSC ;CHECK IT OUT RTS PC 10$: MOV ISB2,R5 ;NO. OF BYTES TO R5 CLR R1 20$: CMPB DBBUF(R1),LINET ;IS THIS CHARACTER THE LINETERMINATOR BNE 30$ JSR PC,PUTT ;YES 30$: MOVB DBBUF(R1),DABUF(R2) INC R1 INC R2 CMP R5,R1 BGT 20$ BR RDBL PUTT: PUT$ #OUTFIL,,R2,EOFCK CLR R2 INC R1 RTS PC ; ; THIS ROUTINE DEBLOCKS DATA FROM TAPE ACCORDING TO A GIVEN ; LENGTH. CARE SHOULD BE USED TO DETERMINE THE BLOCKING ; FACTOR. IT MUST BE A MULTIPLE OF THE RECORD SIZE ON TAPE ; ELSE DATA WILL BE LOST. ; ; RDDB: QIOW$C IO.RLB,2,1,,ISB,, ;READ CMPB #IS.SUC,ISB ;ALL OK? BEQ 10$ ;YES CLOSE$ #OUTFIL JSR PC,QIOSC ;CHECK ERROR RTS PC ;RETURN HERE IF JUST EOF 10$: MOV NRCD,R1 ;BLOCKING FACTOR TO R1 MOV #DABUF,R2 ;INITIAL STARTING ADD. FOR BUFFER 20$: PUT$ #OUTFIL,R2,R1,EOFCK ;WRITE IT OUT ADD R1,R2 ;UPDATE BUFFER POINTER SUB R1,ISB2 ;DECREMENT NO. OF CHAR. READ IN BGT 20$ ;DO IT AGAIN UNTILL ALL CHAR. ARE OUT JMP RDDB ;READ ANOTHER RECORD FROM TAPE ; ; ; ; ; ; ; ; QIO DATA AREA ; ISB: .WORD ;QIO STATUS AREA ISB2: .WORD COMDE: .ASCII /COMMAND LINE ERROR,CHECK R0/ .EVEN CSI1E: .ASCII /COMMAND SYNTAX ERROR/ .EVEN SWERR: .ASCII /INVALID SWITCH/ .EVEN ASNERR: .ASCII /ASSIGN FAILURE/ .EVEN QIOEOF: .ASCII /END OF FILE/ .EVEN QIOEOV: .ASCII /END OF VOLUME/ .EVEN QIOEOT: .ASCII /END OF TAPE/ .EVEN QIOERR: .ASCII /QIO ERROR/ .EVEN ISBERR: .ASCII /ISB=/ ISBNO: .BLKB 6 .EVEN GETERR: .ASCII /GET ERROR/ .EVEN ILLRS: .ASCII /ILLEGAL RECORD SIZE/ .EVEN COMDER: .ASCII /COMMAND ERROR/ .EVEN OPEER: .ASCII /OPEN ERROR/ .EVEN ; ; ; ; ; ; ; ; ; FILE AREA ; GCLBLK: GCMLB$ 1,MGT,,5 CSI$ .EVEN CSIBLK: .BLKB C.SIZE SWTBL: CSI$SW RW,REWIND,SWMASK,SET CSI$SW SK,SKRECD,SWMASK,SET,,NRECD CSI$SW SF,SKFILE,SWMASK,SET,,NRECD CSI$SW BF,BLANFL,SWMASK,SET,,NRECD CSI$SW BL,BLOCKLN,SWMASK,SET,,NRECD CSI$SW LT, LINETR,SWMASK,SET,,LINT CSI$SW AL,ALLFILE, SWMASK,SET CSI$SW EV,ENDOV,SWMASK,SET CSI$ND NRECD: CSI$SV NUMERIC,NRCD,2 LINT: CSI$SV NUMERIC,LINET,1 CSI$ND ; ; FSRSZ$ 3 OUTFIL: FDBDF$ FDAT$A R.VAR,FD.CR FDRC$A ,DABUF,8000. DFNAME: NMBLK$ ,,,SY,0 DABUF: .BLKB 8000. DBBUF: .BLKB 8000. ; ; ; ; ; ; ; ; DATA AREA SWMASK: .WORD ;SWITCH MASK WORD NRCD: .WORD ;NO. OF RECORDS OR RECORD LENGTH LINET: .BYTE 0 ;LINE TERMINATOR .EVEN MTFL: .WORD 0 ;MT FLAG DISKF: .WORD 0 DEV: .WORD 0 ;DEVICE NAME FOR MT .END START