.TITLE MIP .CSECT MIP .LIST TTM .SBTTL INTRODUCTION ; ;TAPE FORMAT ; ;RECORD 0 ; ;EOF ; ;RECORD 1 ; ;HEADER ; HEADER FORMAT: 512 WORD BLOCK ; FIRST 9 WORDS UIC ; AT LOCATION START +100 = FILENAME ; AT LOCATION START+400 = FILE DESCRIPTOR INFO ; AT LOCATION START+500 = SIZE OF CONTIGUOUS FILE ; ;RECORD 2->RECORD 2+N ; ;DATA RECORDS: ;SIZE = 4096. WORDS ; ;RECORD 2+N+1 ; ;EOF ; ;RECORD 2+N+2 ; ;HEADER ; ;RECORD 2+N+3 ;DATA RECORDS ; ;ETC. .PAGE .MCALL FDBDF$,FDAT$R,FDRC$A,FDBK$A,FDOP$A,FDRC$R,FDBK$R .MCALL FSRSZ$ .MCALL NMBLK$,GTSK$S .MCALL GCMLB$,CSI$ .MCALL GCML$,CSI$1,CSI$2,CSI$SW,CSI$ND .MCALL WRITE$,WAIT$,PUT$,PRINT$ .MCALL OPEN$M,OPEN$W,CLOSE$,READ$,OPEN$R .MCALL ALUN$S,GLUN$S .MCALL DIR$,QIOW$,QIOW$C .MCALL EXIT$S .MCALL BIOMAC .MCALL ENDIF BIOMAC .PAGE .SBTTL IMPUURE AREAS AND DATA AREAS .PSECT $DPB$$ ;FOR CONSISTENCY WITH QIO'S OUTLUN = 2 INLUN = 3 CMDLUN = 4 TTYLUN = 5 ; ;DEFINE GET-COMMAND-LINE BLOCK ; GCLBLK: GCMLB$ 1,MIP,,CMDLUN ;PROMPT IS 'MIP' ; ;DEFINE COMMAND-STRING-INTERPRETER BLOCK ; CSI$ .EVEN CSIOUT: .BLKB C.SIZE .EVEN CSIIN: .BLKB C.SIZE .EVEN .EVEN ; ;SWITCHES TO BE DECODED SWTBL: CSI$SW LI,001,MASKX ;DIRECTORY CSI$SW SP,002,MASKX,CLEAR,NEG ;SPOOL DIRECTORY TO LP CSI$SW ZE,004,MASKX ;ZERO TAPE CSI$ND MASKX: .WORD 0 ; ; ; ; ; ; ;FILE-DESCRIPTOR-BLOCK FOR DISK FILE ; FDBDSK: FDBDF$ ;DEFINES AREA AND OFFSETS FDOP$A OUTLUN,CSIIN+C.DSDS ; ; ;ALLOCATE BUFFER SPACE FOR GCML ; FSRSZ$ 1,512.,$DPB$$ ; ;STATUS BLOCKS FOR MAGTAPE INPUT AND OUTPUT ; TSTAT: .BLKW 2 DSTAT: .BLKW 2 ; ;MESSAGE AND RESPONSE AREA ; QIOMES: QIOW$ IO.WVB,TTYLUN,11.,,,, QIOSE: QIOW$ IO.WVB,TTYLUN,11.,,,, .NLIST BEX ; MSGSE: .ASCII /MIP -- SYNTAX ERROR/ 1$: .EVEN CNTSE = 1$-MSGSE ; ; MSGII: .ASCII /MIP -- INVALID INPUT DEVICE/ 1$: .EVEN CNTII = 1$-MSGII ; MSGDE: .ASCII /MIP -- DISK ERROR ON FILE:/ 1$: .EVEN CNTDE = 1$-MSGDE ; ; ; MSGTE: .ASCII /MIP -- TAPE ERROR/ 1$: .EVEN CNTTE = 1$-MSGTE ; MSGDO: .ASCII /MIP -- FILE NOT FOUND ON MAGTAPE/ 1$: .EVEN CNTDO = 1$-MSGDO ; MSGSPL: .ASCII /MIP -- ERROR ON SPOOLING/ 2$: .EVEN CNTSPL = 2$-MSGSPL ; MSGZER: .ASCII /MIP -- TAPE NOT ZEROED/ 3$: .EVEN CNTZER = 3$-MSGZER .LIST BEX ; ;ASSORTED QIO DPB'S FOR MAGTAPE OPERATIONS ; QIORWD: QIOW$ IO.RWD,INLUN,12.,,TSTAT ;REWIND QIOSKT: QIOW$ IO.SPB,INLUN,12.,,TSTAT,,<-1> ;SPACE BLOCK QIORDT: QIOW$ IO.RLB,INLUN,12.,,TSTAT,, ;READ BLOCK QIOWRT: QIOW$ IO.WLB,INLUN,12.,,TSTAT,, ;WRITE BLOCK QIOEFT: QIOW$ IO.EOF,INLUN,12.,,TSTAT ;EOF ; ; MAXOF=12. RSPOF: .BLKB MAXOF FLAG: .WORD 0 F.WRT=1 ;WRITE FLAG F.FND=2 ;FOUND FLAG SYLOC: .BYTE 'S .BYTE 'Y DUIC: .BLKW 30 ;FOR WILDCARD UIC AND FILE NAME DNAME: .BLKB 30 ;FOR PARSED FILE NAME TNAME: .BLKB 30 ;FOR PARSED FILE NAME FROM TAPE VBNADR: .BLKW 2 TAPBUF: .BLKW 8196. ;MAIN MAGTAPE BUFFER CHAR=TAPBUF+1000 .PAGE .SBTTL GET AND CHECK COMMAND LINE .PSECT ; ;THE FOLLOWING GCML WILL PROMPT WITH 'MIP' AND ACCEPT A COMMAND FROM ; THE COMMAND DEVICE, WHICH MAY BE ONE LEVEL OF INDIRECT COMMAND FILE. ; ANY ERROR IN THE FETCH WILL CAUSE THE PROMPT SEQUENCE TO BE REPEATED. ; UNTIL THE USER GETS IT RIGHT, OR HITS CTRL-Z. ; ; ;BEFORE YOU START ANYTHING COMMANDEER THE TAPE UNIT AND REWIND ; MT:: QIOW$C IO.ATT,INLUN,12.,,TSTAT,,<>,,TAPERR ;ATTACH TAPE QIOW$C IO.STC,INLUN,12.,,TSTAT,,<0>,,TAPERR ;SET CHARACTER DIR$ #QIORWD,TAPERR ;REWIND TAPE .PAGE HEAD MTSTRT MTSTRT:: ; ;REPEAT THIS LOOP UNTIL YOU GET A CONTROL Z ; WHILEB GCLBLK+G.ERR,NE,#GE.EOF GCML$ #GCLBLK ;GET COMMAND LINE IF CC ;IF GET-COMMAND SUCCEEDS ; ;COMMAND OK ;CHECK OUT THE COMMAND LINE ; CLR MASKX ;TURN OFF ALL SWITCHES CSI$1 #CSIIN,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD IF CS ;SYNTAX ERROR? ; ;INPUT ERROR ; JMP SYNERR END ; CSI$1 #CSIOUT,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD IF CS JMP SYNERR END ; ; ;GET OUTPUT STRING ; CSI$2 #CSIOUT,OUTPUT,#SWTBL IF CS JMP SYNERR END ; ;DO INPUT STRING ; CSI$2 #CSIIN,INPUT,#SWTBL IF CS JMP SYNERR END ; ;CHECK FOR SWITCHES ; IF MASKX,NE ; ;THERE IS A SWITCH ;PROCESS SWITCH REQUEST ; IF #F.WRT,SETON,FLAG DIR$ #QIOEFT,TAPERR ;EOF ON TAPE END DIR$ #QIORWD,TAPERR ;REWIND TAPE CALL SWITCH ENDIF ELSE ; ;IF THERE IS NO DEVICE SPECIFIED ATTACH 'SY' ; IF CSIOUT+C.DEVD,EQ MOV #CSIOUT+C.DEVD,R1 CALL GETSY END ; ; ; ;IF THERE IS NO NAME THIS IS A SYNTAX ERROR ; IF CSIIN+C.FILD,EQ JMP SYNERR END ; ;IF THERE IS NO DEVICE ATTACH 'SY' ; IF CSIIN+C.DEVD,EQ MOV #CSIIN+C.DEVD,R1 CALL GETSY END ; ;IF THERE IS NO UIC, GET ONE ; IF CSIIN+C.DIRD,EQ CALL GETUIC END ; ;DECIDE WHERE THIS IS AN INPUT REQUEST OR AN OUTPUT REQUEST ; MOV CSIIN+C.DEVD+2,R4 ;POINT TO DEVICE NAME IFB (R4),EQ,#'M ANDB 1(R4),EQ,#'T ; ;MT INPUT ;ATTACH OUTPUT DEVICE TO CSIIN BLOCK ; MOV CSIOUT+C.DEVD,CSIIN+C.DEVD MOV CSIOUT+C.DEVD+2,CSIIN+C.DEVD+2 ; ;DOING MAGTAPE INPUT ; ;FIRST TERMINATE THIS TAPE IF YOU WERE WRITING ; IF #F.WRT,SETON,FLAG DIR$ #QIOEFT,TAPERR ;WRITE EOF ON END OF TAPE END BIC #F.WRT,FLAG CALL MTIN ENDIF ELSE ; ;NOT MAGTAPE INPUT ;IF NOT MAGTAPE OUTPUT, SYNTAX ERROR ; MOV CSIOUT+C.DEVD+2,R4 IFB (R4),EQ,#'M ANDB 1(R4),EQ,#'T ; ;MT OUTPUT ; ; ;PROCESS COMMAND ; CALL MTOUT ENDIF ELSE ; ;NO 'MT' AS INPUT OR OUTPUT DEVICE, ERROR JMP SYNERR END END END END END ; ;DONE ;CLEAN UP THE MESS ; EXIT: IF #F.WRT,SETON,FLAG ;TERMINATE TAPE IF IN WRITE MODE DIR$ #QIOEFT,TAPERR ;EOF END DIR$ #QIORWD,TAPERR ;REWIND TAPE QIOW$C IO.DET,INLUN,12.,,TSTAT ;RELEASE MT EXIT$S .PAGE SUBR MTOUT .SBTTL TRANSFER TO MAGTAPE ; ;THIS ROUTINE TRANSFERS FILES FROM DISK TO MAGTAPE ; ; ;SET TAPE TO THE PROPER POSITION FOR WRITING ;POSITION THE TAPE TO TWO EOF'S ;THEN BACKSPACE ONE AND START WRITING ; IF #F.WRT,SETOFF,FLAG ; ;HAVE NOT STARTED TO WRITE YET ; MOV #8192.,QIORDT+Q.IOPL+2 ;NUMBER OF BYTES TO READ ; ; ;CHECK FOR FIRST RECORD FOR EOF ;IF NOT EOF, ERROR ON TAPE ; DIR$ #QIORDT,TAPERR ;READ A BLOCK OF TAPE IFB #IE.EOF,NE,TSTAT QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR RTS PC END DIR$ #QIORWD,TAPERR ; ;LOOK FOR 2 EOF'S ; CLRB TSTAT ; ;REPEAT UNTIL AN EOF ; WHILEB TSTAT,NE,#IE.EOF WHILEB TSTAT,NE,#IE.EOF DIR$ #QIORDT,TAPERR ;READ A BLOCK OF TAPE END DIR$ #QIORDT,TAPERR ;READ A BLOCK OF TAPE END ; ;GO TO TWO EOF'S ;BACKSPACE ONE ; DIR$ #QIOSKT,TAPERR BIS #F.WRT,FLAG ;TURN ON WRITE FLAG END .PAGE ; ;SET UP MAGTAPE HEADER BLOCK ;MOVE DEVICE, UIC AND NAME TO TAPBUF ; MOV CSIIN+C.DIRD,R0 ;NUMBER OF BYTES IN UIC INFORMATION MOV CSIIN+C.DIRD+2,R1 ;POINTER TO UIC INFORMATION MOV #TAPBUF,R2 ;WHERE THE UIC IS SUPPOSED TO GO CALL MOVSTF ;STUFF UIC INTO CORE MOV CSIIN+C.FILD,R0 ;NUMBER OF BYTES IN FILE NAME MOV CSIIN+C.FILD+2,R1 ;POINTER TO FILE NAME MOV #TAPBUF+100,R2 ;WHERE THE FILE NAME IS SUPPOSED TO GO CALL MOVSTF ;STUFF FILE NAME INTO CORE .PAGE ; ;SET UP THE STATISTICS BLOCK FOR THIS FILE ; MOV #TAPBUF+40,FDBDSK+F.STBK ;FILE STATISTICS LOCATION FDAT$R #FDBDSK,#R.FIX,,#512. FDRC$R #FDBDSK,#FD.RWM FDBK$R #FDBDSK,#TAPBUF,#512.,#VBNADR,#10.,#DSTAT OPEN$R #FDBDSK,,,,,,DSKERR ;OPEN TO READ ; ;SAVE ATTRIBUTES OF FILE FOR BACKING IN ; MOV #TAPBUF+400,R0 ;LOCATION ON TAPE MOV #FDBDSK+F.RTYP,R1 ;LOCATION IN FDB FOR BLOCK I/O MOV #20,R2 ;SAVE 16 BYTES WHILE R2,NE MOVB (R1)+,(R0)+ DEC R2 END ; ;SAVE INFORMATION ABOUT CONTIGUOUS AND NON-CONTIGUOUS FILES ; CLR TAPBUF+500 ;INITIALIZE SIZE IF TAPBUF+40+2,NE MOV TAPBUF+40+6,TAPBUF+500 ;LENGTH OF THE CONTIGUOUS FILE IF TAPBUF+40,LT ;IF <0 NEGATATE SIZE OF FILE NEG TAPBUF+500 END END .PAGE .PAGE .SBTTL TRANSFER SECTORS FROM DISK TO TAPE ; ; ;WRITE FIRST BLOCK ON MAGTAPE MOV #512.,QIOWRT+Q.IOPL+2 ;TRANSFER 512. BYTES MOV #TAPBUF,QIORDT+Q.IOPL ;ADDRESS FOR TRANSFER ; DIR$ #QIOWRT,TAPERR ; ;READ FROM DISK ; MOV #20000,QIOWRT+Q.IOPL+2 ;NUMBER OF BYTES TO PUT ON TAPE READ: CLR R3 MOV #TAPBUF,R4 ;BUFFER FOR READ WHILE R3,NE,#20000 ;READ UNTIL BUFFER FULL READ$ #FDBDSK,R4,,,,,,DSKERR WAIT$ #FDBDSK,,,DSKERR ADD #1000,R3 ;COUNT BYTES READ ADD #1000,R4 ;NEXT PART OF THE BUFFER TO READ INTO END DIR$ #QIOWRT,TAPERR BR READ ;WRITE EOF ON TAPE FIN1: IF R3,NE MOV R3,QIOWRT+Q.IOPL+2 ;NUMBER OF BYTES TO WRITE ON TAPE DIR$ #QIOWRT,TAPERR ;WRITE OUT LAST BLOCK ON TAPE END DIR$ #QIOEFT,TAPERR ;WRITE AN EOF ON TAPE CLOSE$ #FDBDSK END MTOUT .PAGE SUBR MTIN ; ;BACKING IN FROM MAGTAPE ;READ FILE HEADER RECORDS OFF OF MAGTAPE UNTIL YOU ;FIND THE FILE SPECIFIED BY THE INPUT COMMAND STRING. ; ; ; ;START PROCESSING TAPE ; BIC #F.FND,FLAG ;HAVE NOT FOUND A FILE YET DIR$ #QIORWD,TAPERR ;REWIND TAPE DIR$ #QIORDT,TAPERR ;READ A BLOCK OF TAPE IFB TSTAT,NE,#IE.EOF ; ;FIRST BLOCK OF TAPE NOT AN EOF ;ERROR!! ; QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR RTS PC END MTIN1: ; ;READ RECORDS OFF OF MAGTAPE UNTIL YOU FIND A HEADER THAT MATCHES ;THIS NAME ; MOV #512.,QIORDT+Q.IOPL+2 ;NUMBER OF BYTES TO BE TRANSFERRED MOV #TAPBUF,QIORDT+Q.IOPL ;BUFFER FOR READ DIR$ #QIORDT,TAPERR ; ;IS THIS A RECORD OR END OF VOLUME INDICATOR? ; IFB TSTAT,EQ,#IE.EOF IF #F.FND,SETOFF,FLAG QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR END RTS PC END CLR R3 ;TRUE/FALSE FLAG ;SEE IF UIC AND FILE NAMES OF TAPE FILE AND INPUT FILE MATCH ; MOV #TAPBUF+1,R5 ;UIC GROUP MOV CSIIN+C.DIRD+2,R4 ;INPUT UIC GROUP INC R4 CALL UICTST ;SEE IF YOU HAVE A MATCH ; ;IF R3=0 HAVE MATCH ; ;IF UIC'S MATCH CHECK FILE NAMES FROM INPUT AND TAPE ; IF R3,EQ ; ;COMPARE FILE NAMES,EXTENSIONS AND VERSION NUMBERS ; MOV #TAPBUF+100,R5 ;TAPE FILE NAME MOV CSIIN+C.FILD+2,R4 ;INPUT FILE NAME CALL NAMTST ;SEE IF FILE NAMES MATCH END ; ;IF ANY WILD CARDS ATTACH NAME AND UIC TO FILE FROM TAPE ;FILE NAME AND UIC ; IF R3,EQ ;STILL NO ERROR ON PARSE? ANDB CSIIN+C.STAT,SETON,#CS.WLD ;ANY WILD CARDS? MOV #CSIOUT+C.DSDS,FDBDSK+F.DSPT ;USE OUTPUT BLOCK FOR DISK OUTPUT CALL WLDCRD ;PROCESS FOR WILD CARD ENDIF ELSE MOV #CSIIN+C.DSDS,FDBDSK+F.DSPT END ; ;IS THIS THE FILE YOU WANT? IF R3,NE ;NO, READ UNTIL AN EOF WHILEB TSTAT,NE,#IE.EOF MOV #1000,QIORDT+Q.IOPL+2 ;NUMBER OF BYTES TO READ DIR$ #QIORDT,TAPERR END ENDIF ELSE ; ;THIS IS THE FILE YOU WANT ;GET IT FROM MAGTAPE AND PUT IT ON DISK ; BIS #F.FND,FLAG ;HAVE FOUND A FILE CALL DSKWRT END ; ;DONE WITH THIS MAGTAPE FILE ;CHECK IF SUCCESSFUL GETTING THE FILE TO DISK ;IF YOU GOT THE FILE YOU WANTED AND THERE ARE NO ;WILDCARDS YOU ARE DONE ; IF R3,NE ORB CSIIN+C.STAT,SETON,#CS.WLD JMP MTIN1 END END MTIN .PAGE SUBR DSKWRT .SBTTL TRANSFER RECORDS FROM TAPE TO DISK ; ;TRANSFER TAPE RECORDS TO DISK ; ; ; ;GET FILE ATTRIBUTES FROM THE TAPE BUFFER AND MOVE THEM TO ;FILE DESCRIPTOR BLOCK(FDB) ; MOV #TAPBUF+400,R0 ;LOCATION IN TAPE BUFFER MOV #FDBDSK+F.RTYP,R1 ;LOCATION TO GO IN FDB MOV #20,R2 ;# OF BYTES WHILE R2,NE MOVB (R0)+,(R1)+ DEC R2 END MOV TAPBUF+500,FDBDSK+F.CNTG ;SIZE OF CONTIGUOUS FILE IFB TAPBUF+400+F.RTYP,EQ,#1 FDAT$R #FDBDSK,#R.FIX,,#512. FDRC$R #FDBDSK,#FD.RWM FDBK$R #FDBDSK,#TAPBUF,#512.,#VBNADR,#10.,#DSTAT ENDIF ELSE FDAT$R #FDBDSK,#R.VAR,#FD.CR FDRC$R #FDBDSK,#FD.INS,#TAPBUF END OPEN$W #FDBDSK ;OPEN FILE FOR WRITE MOV #8192.,QIORDT+Q.IOPL+2 ;NUMBER OF BYTES TO READ DIR$ #QIORDT,TAPERR ;READ FIRST DATA RECORD OFF TAPE MOV #TAPBUF,R1 WHILEB TSTAT,NE,#IE.EOF IFB FDBDSK+F.RTYP,EQ,#1 ;RECORD OR BLOCK I/O? MOV #TAPBUF,R2 WHILE TSTAT+2,NE ;DO UNTIL ALL BYTES FROM TAPE WRITTEN ON DISK WRITE$ #FDBDSK,R2,,,,,,DSKERR WAIT$ #FDBDSK,,,DSKERR SUB #1000,TSTAT+2 ;DECREMENT BYTE COUNT ADD #1000,R2 ;POINT TO NEW BUFFER FOR WRITE END DIR$ #QIORDT,TAPERR ;READ NEXT TAPE RECORD ENDIF ELSE ;CLEAR SECOND BUFFER BEFORE READ!! ; MOV #TAPBUF+8192.,R2 WHILE R2,LT,#TAPBUF+8192.+8182. CLR (R2)+ END MOV #TAPBUF+8192.,QIORDT+Q.IOPL ;READ FROM TAPE INTO OTHER DOUBLE BUFFER DIR$ #QIORDT,TAPERR WHILEB 1(R1),EQ AND R1,LE,#TAPBUF+8192. MOV (R1),R2 ADD #2,R1 IF R2,NE PUT$ #FDBDSK,R1,R2,DSKERR END ADD R2,R1 IF #1,SETON,R1 INC R1 END END MOV #TAPBUF,R0 MOV #TAPBUF+8192.,R4 WHILE R0,NE,#TAPBUF+8192. MOV (R4)+,(R0)+ END SUB #8192.,R1 ;POINT R1 INTO FIRST BUFFER END END MOV #TAPBUF,QIORDT+Q.IOPL CLOSE$ #FDBDSK END DSKWRT ; .PAGE .SBTTL ERROR HANDLERS TTYERR: TST (SP)+ ;GIVE UP JMP EXIT ; TAPERR: TST (SP)+ ;SAY TAPE ERROR AND THEN GIVE UP QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR JMP EXIT ; DSKERR: TST (SP)+ ;SAY DISK ERROR AND GIVE UP IFB FDBDSK+F.ERR,EQ,#366 ;EOF? JMP FIN1 ;YES FINISH UP THIS BACK UP END QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR CALL DSKMES ;OUTPUT DISK FILE NAME CLOSE$ #FDBDSK IF #F.WRT,SETOFF,FLAG ANDB CSIIN+C.STAT,SETON,#CS.WLD JMP MTIN1 ENDIF ELSE JMP MTSTRT ;CONTINUE WITH BACKUP END .PAGE .PAGE SUBR MOVSTF ;THIS ROUTINE MOVES DATA FROM THE COMMAND LINE BUFFER TO ;THE TAPE BUFFER ; CLR R3 ;BYTE COUNTER WHILE R3,LT,R0 MOVB (R1)+,(R2)+ INC R3 END MOVB #136,(R2) ;TERMINATE LINE WITH AN UP ARROW END .PAGE .SBTTL CRACK THE COMMAND STRING SUBR UICTST ; ;TEST IF THE UIC STRING POINTED TO BY R4= THE UIC STRING POINTED ;TO BY R5 ; MOVB #54,CHAR ;FIRST SEPARATOR USED CALL STRCHK ;CHECK THE STRINGS UNTIL A COMMA ; ;STRINGS EQUAL? ; IF R3,NE ; ;NO STRINGS NOT EQUAL ; RETURN END ; ;STRINGS DO MATCH SO FAR ;NOW TEST USER NUMBERS ; MOVB #'],CHAR ;END SEPARATOR CALL STRCHK ;CHECK THESE SUBSTRINGS END UICTST ;RETURN .PAGE SUBR STRCHK ; ;CHECK TWO SUBSTRINGS POINTED TO BY R4 AND R5 ;UNTIL YOU HIT A SEPARATOR=CHAR ;IF THE STRINGS ARE NOT EQUAL MAKE R3 NOT ZERO ; IFB (R4),NE,#'* ;CHECK FOR WILD CARD ; ;GO UNTIL YOU HIT A SEPARATOR ; WHILEB (R4),NE,CHAR AND R3,EQ ANDB (R4),NE,#'^ ;END OF STRING MARK ; ;TEST THE BYTES ; IFB (R4)+,NE,(R5)+ INC R3 ;ERROR, NO MATCH END END ENDIF ELSE ADD #1,R4 ;POINT PAST WILD CARD WHILEB (R5)+,NE,CHAR END DEC R5 END IFB (R4)+,NE,(R5)+ INC R3 END END STRCHK .PAGE SUBR NAMTST ; ;CHECK THE FILE NAME FROM THE TAPE INFORMATION AND THE COMMAND ;STRING ;IF THEY ARE EQUAL RETURN WITH R3=0 ;ELSE R3 NOT EQUAL TO ZERO ; ;MARK THE END OF THE COMMAND STRING WITH A ^ ; MOV R4,R3 ADD CSIIN+C.FILD,R3 ;ADD IN NUMBER OF CHARACTERS MOVB #'^,(R3) MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 MOV #DNAME,R1 ;BUFFER FOR INPUT FILE NAME MOV R4,R2 ;POINT TO TITLE STRING TO BE PARSED ; ;NOW PARSE THE STRING INTO FILE NAME, EXTENSION AND VERSION NUMBER ;STRINGS ARE TERMINATED BY A ZERO BYTE ;IF THERE IS NO STRING THERE WILL BE A ZERO IN THE FIRST BYTE ;OF THE STRING ; CALL PARSE ;PARSE INPUT FILE NAME MOV #TNAME,R1 ;BUFFER FOR TAPE FILE NAME MOV R5,R2 ;POINT TO TAPE STRING TO BE PARSED CALL PARSE ;PARSE TAPE FILE NAME CLR R3 ;TURN OFF ERROR INDICATION CALL NSTRING ;COMPARE THESE TWO STRINGS MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R1 ;RESTORE R1 END NAMTST .PAGE SUBR PARSE ; ;PARSE THE INPUT STRING INTO FILE NAME, EXTENSION, AND VERSION ;R1 POINTS TO THE BUFFER TO PUT THE STRING IN ;R2 POINTS TO THE STRING TO BE CRUNCHED ; MOV R1,R3 ;SAVE BUFFER POINTER ; ;REPEAT UNTIL YOU HIT A SEPARATOR ; WHILEB #'.,NE,(R2) ANDB #73,NE,(R2) ANDB #'^,NE,(R2) MOVB (R2)+,(R1)+ END CLRB (R1) ;TERMINATE STRING ; ;DONE WITH FILE NAME, NOW DO EXTENSION ; MOV R3,R1 ;RESTORE BUFFER POINTER ADD #14,R1 ;POINT TO EXTENSION PART OF BUFFER ; ;PROCEDE UNTIL YOU HIT A SEPARATOR ; WHILEB #73,NE,(R2) ANDB #'^,NE,(R2) MOVB (R2)+,(R1)+ END CLRB (R1) ; ;DONE WITH FILE EXTENSION ;LOOK AT VERSION NUMBER ; MOV R3,R1 ADD #22,R1 ; ;PROCEDE UNTIL YOU HIT A SEPARATOR ; WHILEB #'^,NE,(R2) MOVB (R2)+,(R1)+ END CLRB (R1) END PARSE .PAGE SUBR NSTRING ; ;COMPARE THE FILE NAME STRINGS IN DNAME AND TNAME ; MOV #DNAME,R1 MOV #TNAME,R2 ; ;COMPARE FILE NAMES ; IFB #'*,NE,(R1) ;SKIP ON WILDCARD! CALL CHECK IF R3,NE RETURN END END ADD #14,R1 ADD #14,R2 IFB #'*,NE,1(R1) ;SKIP ON WILDCARD! CALL CHECK IF R3,NE RETURN END END ; ;DO YOU HAVE A VERSION NUMBER ON INPUT STRING ; ADD #6,R1 IFB (R1),EQ RETURN END IFB #'*,NE,1(R1) ;SKIP ON WILDCARD! ADD #6,R2 CALL CHECK END END NSTRING .PAGE SUBR CHECK ; ;CHECK TWO SUBSTRINGS ; MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 WHILEB (R1),NE ANDB (R2),NE ANDB (R1),EQ,(R2) INC R1 INC R2 END IFB (R1),NE,(R2) INC R3 END MOV (SP)+,R2 ;RESTORE R2 MOV (SP)+,R1 ;RESTORE R1 END CHECK .PAGE SUBR DSKMES ; ;OUTPUT THE FILE NAME IN CSIIN TO THE TTY ; MOV #TAPBUF,R1 ;CHARACTER BUFFER FOR OUTPUT ; ;MOVE UIC FROM CSIIN TO TAPBUF ; IFB CSIIN+C.STAT,SETON,#CS.WLD MOV CSIOUT+C.DIRD,R2 MOV CSIOUT+C.DIRD+2,R3 ENDIF ELSE MOV CSIIN+C.DIRD,R2 ;NUMBER OF CHARACTERS IN UIC MOV CSIIN+C.DIRD+2,R3 ;LOCATION OF CHARACTERS END CALL MES ;OUTPUT UIC IFB CSIIN+C.STAT,SETON,#CS.WLD MOV CSIOUT+C.FILD,R2 MOV CSIOUT+C.FILD+2,R3 ENDIF ELSE MOV CSIIN+C.FILD,R2 ;NUMBER OF CHARACTERS IN NAME MOV CSIIN+C.FILD+2,R3 ;LOCATION OF FILE NAME END CALL MES ; ;SET UP CHARACTER COUNT IN QIO ; SUB #TAPBUF,R1 MOV R1,QIOMES+Q.IOPL+2 ;# OF CHARACTERS DIR$ #QIOMES,TTYERR ;OUTPUT MESSAGE END .PAGE SUBR MES ; ;MOVE CHARACTERS TO MESSAGE BUTTON ; WHILE R2,NE MOVB (R3)+,(R1)+ DEC R2 END END MES .PAGE .SBTTL CREATE A DIRECTORY OF THE TAPE SUBR DIRECT ; ;CREATE A DIRECTORY OF THE MAGTAPE ; ;IF NO DEVICE SPECIFIED PUT IF ON SY ; IF CSIOUT+C.DEVD,EQ ;ANY DEVICE SPECIFIED? MOV #CSIOUT+C.DEVD,R1 CALL GETSY ;NO, ATTACH 'SY' TO THIS COMMAND END ; ;IF NO UIC USE THIS UIC ; IF CSIOUT+C.DIRD,EQ ;ANY UIC SPECIFIED? MOV #CSIOUT+C.DIRD,R1 CALL GETUIC ;NO, GET THIS UIC FOR DEFAULT END ; ;POINT DISK AT THIS FILE NAME ; MOV #CSIOUT+C.DSDS,FDBDSK+F.DSPT DIR$ #QIORWD,TAPERR ;REWIND TAPE DIR$ #QIORDT,TAPERR ;READ FIRST RECORD OFF TAPE IFB TSTAT,NE,#IE.EOF ; ;FIRST BLOCK OF TAPE NOT AN EOF ;ERROR!! ; QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR RTS PC END DIR$ #QIORDT,TAPERR ; ;SET UP FDB FOR OUTPUT ; FDAT$R #FDBDSK,#R.VAR,#FD.CR FDRC$R #FDBDSK,#FD.INS,#TAPBUF OPEN$W #FDBDSK ;OPEN FOR WRITE ; ;DO UNTIL TAPE DONE ; WHILEB TSTAT,NE,#IE.EOF MOV #TAPBUF+400,R2 ;BUFFER FOR CHARACTERS MOV #TAPBUF,R1 ;DATA LOCATION CLR R3 ;NUMBER OF CHARACTERS ;MOVE IN UIC WHILEB (R1),NE,#'^ MOVB (R1)+,(R2)+ INC R3 END ; ;TAB OVER ; MOVB #11,(R2)+ INC R3 ; ;MOVE IN FILE NAME ; MOV #TAPBUF+100,R1 WHILEB (R1),NE,#'^ MOVB (R1)+,(R2)+ INC R3 END ; ;DONE WITH CONSTRUCTING DATA ; PUT$ #FDBDSK,#TAPBUF+400,R3,DSKERR ;READ UNTIL NEXT EOF WHILEB TSTAT,NE,#IE.EOF DIR$ #QIORDT,TAPERR END ;READ NEXT HEADER DIR$ #QIORDT,TAPERR END ; ;EITHER CLOSE THE DIRECTORY FILE OR SPOOL IT ; IF #2,SETON,MASKX CLOSE$ #FDBDSK ENDIF ELSE PRINT$ #FDBDSK IF CS QIOW$C IO.WVB,TTYLUN,11.,,,,,,TTYERR END END MOV #CSIIN+C.DSDS,FDBDSK+F.DSPT END DIRECT .PAGE SUBR GETSY MOV #2,(R1) ;TWO CHARACTERS MOV #SYLOC,2(R1) ;LOCATION OF 'SY' END GETSY .PAGE SUBR GETUIC GTSK$S #TAPBUF ;GET TASK CHARACTERISTICS MOV #DUIC,R0 ;CHARACTER BUFFER MOV R0,CSIIN+C.DIRD+2 ;POINT CSIIN DIRECTORY POINT AT CHARACTER BUFFER MOVB #'[,(R0)+ ;FIRST CHARACTER IN UIC STRING MOVB TAPBUF+G.TSGC,R1 ;GROUP CODE IN BINARY BIC #177400,R1 ;CLEAR HIGH BYTE CALL BINASC ;CONVERT BINARY TO THREE ASCII CHARACTERS MOVB #54,(R0)+ ;GROUP',' MOVB TAPBUF+G.TSPC,R1 ;MEMBER CODE IN BINARY BIC #177400,R1 ;CLEAR HIGH BYTE CALL BINASC ;CONVERT BINARY TO ASCII MOVB #'],(R0)+ ;LAST CHARACTER OF UIC STRING SUB #DUIC,R0 ;HOW MANY CHARACTERS IN STRING? MOV R0,CSIIN+C.DIRD ;STICK IN CHARACTER COUNT END .PAGE SUBR BINASC ; ;CONVERT A BINARY BYTE TO THREE ASCII CHARACTERS ; ;R0 POINTS TO CHARACTER BUFFER ON INPUT ;ON OUTPUT IT POINTS ONE PAST THE LAST CHARACTER INSERTED ; ;R1 HAS THE BYTE TO BE TRANSFORMED ; ;R2 IS USED AS A WORK REGISTER ; ;LEADING ZEROS ARE SUPPRESSED ; MOV R1,R2 ASH #-6,R2 ;SHIFT TOP DIGIT TO LOW THREE BITS IF R2,NE CALL PIIBF ;PUT IT IN THE BUFFER END MOV R1,R2 ASH #-3,R2 ;SHIFT OVER NEXT DIGIT IF R2,NE ;IS THIS DIGIT A ZERO? CALL PIIBF ;PUT IT IN THE BUFFER END MOV R1,R2 CALL PIIBF ;PUT IT IN THE BUFFER END .PAGE SUBR PIIBF ; ;THIS ROUTINE IS PASSED THREE BITS IN R2 TO BE CONVERTED INTO ;ASCII AND PUT INTO THE CHARACTER BUFFER ; BIC #177770,R2 ;CLEAR ALL BUT LOW THREE BITS BIS #'0,R2 ;SET ASCII CONVERSION MOVB R2,(R0)+ END PIIBF .PAGE SUBR WLDCRD ; ;A WILD CARD IS IN THE INPUT STRING ;PICK UP THE UIC AND FILE NAME FROM THE TAPE HEADER ; MOV #DUIC,R0 ;SCRATCH AREA MOV R0,CSIOUT+C.DIRD+2 ;FDB UIC LOCATION CLR CSIOUT+C.DIRD ;ZERO CHARACTER COUNT MOV #TAPBUF,R1 ;LOCATION OF UIC IN TAPE BUFFER ; ;CONTINUE UNTIL UIC DONE ; WHILEB (R1),NE,#'^ MOVB (R1)+,(R0)+ ;MOVE THE CHARCTER OVER INC CSIOUT+C.DIRD ;INCREMENT CHARACTER COUNT END ; ;NOW DO FILE NAME ; MOV #DUIC+12,R0 ;SCRATCH AREA FOR FILE NAME MOV R0,CSIOUT+C.FILD+2 ;POINT FDB AT FILE NAME BUFFER CLR CSIOUT+C.FILD ;ZERO CHARACTER COUNT MOV #TAPBUF+100,R1 ;LOCATION OF FILE NAME IN TAPE BUFFER ; ;CONTINUE UNTIL FILE NAME MOVED ; WHILEB (R1),NE,#'^ MOVB (R1)+,(R0)+ INC CSIOUT+C.FILD ;INCREMENT CHARACTER COUNT END END WLDCRD .PAGE SUBR SWITCH IF MASKX,SETON,#4 ; ;ZERO TAPE ; DIR$ #QIOEFT,TAPERR ;EOF DIR$ #QIOEFT,TAPERR ;EOF DIR$ #QIORWD,TAPERR ;REWIND END IF MASKX,SETON,#1 ; ;DIRECTORY ; CALL DIRECT END END SWITCH .PAGE SUBR SYNERR DIR$ #QIOSE,TTYERR ;INFORM OF ERROR CALL DSKMES ;PRINT OUT FILE NAME JMP MTSTRT ;TRY AGAIN .END MT