.TITLE FFL FAST FLX-TAPE READER .IDENT /V01.7Y/ ; ;PROGRAM TO READ SELECTED FILES FROM FLX-TAPE AND PLACE THEM ;IN DIRECTORY CORRESPONDING TO TAPE UIC ; ;WRITTEN JULY 16,1979 ;HARRY ATHERTON ;UNIVERSITY OF CINCINNATI MEDICAL CENTER ;231 BETHESDA AVE., ROOM 6253 ;CINCINNATI, OHIO 45267 ;PHONE (513) 872-5341 ; ;VERSION 1 JULY 16,1979 ;MODIFICATION LEVEL 7 SEPT 14,1979 ;VERSION 1.7X 10/82 G. EVERHART ; ADDED SEVERAL NEW FILE TYPES AS IMAGE MODE DEFAULTS AND PARAMETRIZED ; EXTENSIONS FOR BOTH IMAGE AND BINARY. ; ALSO /ER SWITCH TO IGNORE TAPE ERRORS (EXCEPT EOF, EOV, EOT) ; ;MISCELLEANOUS PARAMETERS WHICH CONTROL ASSEMBLY ; ;SPECIFY NUMBER OF TABLE ENTRIES FOR INPUT FILE SPECIFICATIONS ;THIS IS MAXIMUM NUMBER OF INPUT FILE SPECIFICATIONS PER COMMAND LINE TABLSZ = 20. ; ; .MCALL GCMLB$,GCML$,CSI$,CSI$1,CSI$2,DIR$,QIOW$ .MCALL FDBDF$,FDOP$A,FDOF$L,NMBLK$,FINIT$,FSRSZ$ .MCALL PUT$,WRITE$,WAIT$ .MCALL CSI$SW,CSI$SV,CSI$ND .MCALL FDAT$R,FDRC$R,FDBK$R,FDBF$R,OPEN$W,CLOSE$ .MCALL FDAT$A,FDRC$A,FDBF$A .MCALL EXIT$S .PAGE .SBTTL DATA BASE ; ;COMMAND LINE ITEMS GCLBLK: GCMLB$ 2,FFL,BUFFER,5,,500. .EVEN ; CSI$ CSIBLK = BUFFER + 600. ;WE HAVE USED THE MAG TAPE READING BUFFERS FOR COMMAND ;LINE STRUCTURES SINCE WE WILL BE DONE WITH THEM BEFORE ;WE DO ANY TAPE READING ; OUTSWT: ;SWITCH TABLE FOR OUTPUT FILE ; CSI$SW SL,SLMSK,SWFLGS,SET,NEG CSI$SW FO,FOMSK,SWFLGS,CLEAR,NEG CSI$SW UF,UFMSK,SWFLGS,SET,NEG CSI$SW ER,SW.ERR,SWRR,SET,NEG ;DEFAULT IS THUS 0 FLAG MEANING /-SL/FO/-UF ;AND SECONDARY FLAG 0 MEANING /-ER (/ER IGNORES INPUT ERRORS) CSI$ND ; ;SWITCH MASK WORD DEFINITIONS SLMSK = 1 ;PRODUCE SUMMARY LISTING WHEN SET FOMSK = 2 ;FILE OWNER IS UIC OF DIRECTORY WHEN NOT SET UFMSK = 4 ;CREATE USER FILE DIRECTORY IF NONE EXISTS ;ADDITIONAL FLAG, SET BY PROGRAM SAMUIC = 1000 ;USE SPECIFIED UIC RATHER THAN FILE'S UIC ; SW.ERR=10 SWRR: .WORD 0 ;DUMMY ERROR IGNORE SWITCH SWFLGS: .WORD 0 ;PUT FLAGS HERE ; MTSWT: ;INPUT (MAG TAPE)SWITCH TABLE CSI$SW DNS,DEMSK,INFLAG,SET,,DEVAL,LONG CSI$SW RW,RWMSK,INFLAG,CLEAR,NEG CSI$ND ;DEFAULT 0 FLAG MEANING /RW, DON'T CHANGE DENSITY ; DEVAL: ;SWITCH VALUE FOR DENSITY CSI$SV DECIMAL,DENS,6 CSI$ND ;SWITCH MASK BITS RWMSK = 1 DEMSK =2 ; INFLAG: .WORD 0 ;INPUT SWITCH FLAG WORD DENS: .WORD 0 ;DENSITY SWITCH VALUE ; ;INPUT FILE SPECIFICATION TABLES ; FNM1: .BLKW TABLSZ ;FIRST 3 CHAR OF FILENAME FNM2: .BLKW TABLSZ ;LAST 3 CHAR OF FILENAME FTYP: .BLKW TABLSZ ;FILE TYPE ;ABOVE ARE STORED IN RAD-50 TO MATCH TAPE LABEL FUIC: .BLKW TABLSZ ;FILE UIC (IN BINARY) FSTS: .BLKW TABLSZ ;FILENAME STATUS WORD ;BIT DEFINITIONS OF FSTS WLDFNM = 1 ;FILENAME IS WILD CARD WLDTYP = 2 ;FILE TYPE IS WILD CARD WLDGRP = 4 ;UIC GROUP CODE IS WILD CARD WLDUSR = 10 ;UIC USER CODE IS WILD CARD ; INFSCT: .WORD 0 ;COUNT OF NUMBER OF ENTRIES IN TABLES ; PRCFLG: .WORD 0 ;TYPE OF PROCESSING FLAG ;PLUS IS FORMATTED BINARY ;ZERO IS IMAGE MODE ;MINUS IS FORMATTED ASCII SAVUIC: .WORD 0 ;SAVE USER'S INITIAL DEFAULT UIC SAVUI2: .WORD 0 ;SAVE LOCATION FOR DIRECTORY CREATION LOGIC DIRFLG: .WORD 0 ;REMEMBER WILD CARD FLAGS OF PREVIOUS DIRECTORY STRING .PAGE TYPTBL: ;TABLE OF RAD-50 ENCODED FILE TYPES ;FIRST 6 ENTRIES ARE TO BE PROCESSED IN IMAGE MODE ;REMAINING 4 ARE PROCESSED IN FORMATTED BINARY ;ALL OTHERS ARE FORMATTED ASCII .RAD50 /TSK/ .RAD50 /OLB/ .RAD50 /MLB/ .RAD50 /SYS/ .RAD50 /SML/ .RAD50 /ULB/ ;ADD .DSK, .DOS, .CLB, .HLB AS IMAGE MODE TYPES. ALSO .EXE FOR VMS. .RAD50 /DSK/ .RAD50 /DOS/ .RAD50 /HLB/ ;HELP LIBRARY .RAD50 /CLB/ ;COMMAND LIBRARY .RAD50 /EXE/ ;VMS EXECUTABLE IMAGES .RAD50 /ULB/ ;UNIVERSAL LIBRARY .RAD50 /TPC/ ;NEW TPC EXTENSION (TO REPLACE .DOS) N$IMG=<.-TYPTBL> ;NUMBER OF IMAGE MODE FILE TYPES IN BYTES... BN..: .RAD50 /OBJ/ .RAD50 /STB/ .RAD50 /BIN/ .RAD50 /LDA/ N$BIN=.-BN.. ; ;MISCELLEANOUS ITEMS FOR ASCII RECORD PROCESSING CRFLAG: .WORD 0 ;INDICATES THAT CR CAUSED LINE TO BE WRITTEN SAVPTR: .WORD 0 ;SAVE BUFFER POINTER DURING PUT OPERATION STRPTR: .WORD 0 ;POINTER TO START OF LINE (BLOCK) ENDPTR: .WORD 0 ;POINTER TO END OF BUFFER ; TRMTBL: ;LIST OF FORMATTED ASCII LINE TERMINATORS ;ORDER IS CRUCIAL SEE PROGRAM LOGIC .BYTE 14 ;FF ;THE REST OF THE TERMINATORS ARE REMOVED ON INPUT .BYTE 13 ;VT .BYTE 12 ;LF .BYTE 15 ;CR .EVEN ; ; ;FDB FOR TAPE INPUT DEVICE ;USED ONLY FOR PARSING COMMAND LINE INFDB: FDBDF$ FDOP$A 2 ;LUN 2 FOR TAPE ; .EVEN BUFFER: ;COMMON BUFFER USED FOR COMMAND LINE INPUT AND TAPE READING .BLKW 256. BUFF2: ;SECOND PART OF BUFFER .BLKW 256. ; ADD SPACE HERE FOR BIG TAPE BUFFERS B2SZ=.-BUFF2 ; ;MAG TAPE QIO'S, USE LUN 2 MTSTC: QIOW$ IO.STC,2,2,,,,<0> ;SET TAPE CHARACTERISTICS,INITIAL DEFAULT IS 800 BPI MTRWD: QIOW$ IO.RWD,2,2 ;REWIND TAPE MTRLB: QIOW$ IO.RLB,2,2,,MTIOSB,, ;READ RECORD MTSKFL: QIOW$ IO.SPF,2,2,,MTIOSB,,<1> ;SPACE OVER REMAINDER OF FILE ; MTIOSB: .BLKW 2 ;MAG TAPE I/O STATUS BLOCK ; .PAGE ;FILE SYSTEM DATA STRUCTURES ; FDOF$L ; FSRSZ$ 1,512. ;ONE FCS FILE, WITH RECORD PROCESSING ; ; ;FDB FOR DISK FILE OUTPUT, USE LUN 1 OUTFDB: FDBDF$ FDOP$A 1,,OUTNBL,FO.WRT ;REST OF INFORMATION IS SUPPLIED AT OPEN TIME SINCE CHARACTERISTICS ;DEPEND ON TYPE OF INPUT FILE ; ;DEFAULT FILENAME BLOCK ;INFORMATION IS FILLED IN THIS BLOCK DURING EXECUTION ;THIS FORM IS USED SINCE THE INFORMATION IS ALREADY CONVERTED OUTNBL: NMBLK$ OUTPUTFIL,DAT,0,,0 ; ;DEFAULT NAME BLOCK USED ON INITIAL PARSE OF OUTPUT FILE SPEC ;THIS WILL USE SY: AS DEFAULT OUTPUT DEVICE ;THE PHYSICAL DEVICE (WHETHER DEFAULT OR SPECIFIED) IS COPIED TO OUTNBL BY PROGRAM SYNBL: NMBLK$ OUTPUTFIL,DAT,0,SY,0 ; ; OUTDSP: ;DATA SET DESCRIPTOR, FOR DIRECTORY STRING .WORD 0,0 ;DEVICE .WORD 0 ;DIRECTORY STRING LENGTH, SET LATER .WORD OUTDIR ;DIRECTORY STRING ADDRESS .WORD 0,0 ;FILENAME ; OUTDIR: .BLKW 5 ;PUT DIRECTORY STRING HERE ; OTIOSB: .BLKW 2 ;IOSB FOR DISK WRITE OPERATIONS ; ;CONTROL STRUCTURES FOR CREATING USER DIRECTORY ;USE LUN 3 FOR THIS DIRFDB: FDBDF$ FDAT$A R.FIX,,16.,1,1 FDRC$A FDOP$A 3,DIRDSP,,FO.WRT FDBF$A 3 DIRDSP: ;DATA SET DISCRIPTOR BLOCK .WORD 5 .WORD DIRDEV .WORD 5 .WORD DIRUIC .WORD 12. .WORD DIRNAM ; .NLIST BEX DIRDEV: .ASCII /SY00:/ DIRUIC: .ASCII /[0,0]/ DIRNAM: .ASCII /777777.DIR;1/ DIREND: .EVEN .PAGE .SBTTL COMMAND INPUT AND DECODING ; .LIST BEX FFL:: FINIT$ ;STARTUP ENTRY POINT ;SAVE DEFAULT VALUES FOR RESTORATION ON SUBSEQUENT CYCLES CALL .RDFUI ;READ USER'S DEFAULT UIC MOV R1,SAVUIC ;KEEP IT ; FF1000: ;RESTORE ITEMS WHICH MAY HAVE BEEN CHANGED ON PREVIOUS CYCLE CLR DIRFLG ;RESET DIRECTORY WILD CARD FLAG MOV #SYNMSG,QIOW+Q.IOPL ;RESTORE SYNTAX ERROR MSG MOV #SYNEND-SYNMSG,QIOW+Q.IOPL+2 ;RESTORE DEFAULT UIC TO STARTING VALUE MOV SAVUIC,R1 CALL .WDFUI CLR R1 ;SET TO USE DEFAULT CALL .WFOWN ;RESTORE FILE OWNER DEFAULT VALUE ; GCML$ #GCLBLK ;GET COMMAND LINE BCC FF1500 ;BRANCH IF NO ERROR ;ERROR, WAS IT END OF FILE ? CMPB #GE.EOF,GCLBLK+G.ERR BNE FF1200 ;BRANCH IF NOT FF1100: EXIT$S ;CTRL-Z FF1200: JMP SYNERR ;GO TO SYNTAX ERROR MESSAGE FF1300: JMP FCSERR ;GO TO FCS ERROR PROCESSOR ; FF1500: ;ANALYSE COMMAND LINE TST GCLBLK+G.CMLD ;WAS THERE ANY INPUT ? BEQ FF1000 ;ASK AGAIN IF NOT CSI$1 #CSIBLK,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD BCS FF1200 ;BRANCH IF SYNTAX ERROR TST CSIBLK+C.CMLD ;IS THERE ANYTHING NOW ? BEQ FF1100 ;EXIT IF NOT CLR SWFLGS ;START WITH SWITCH FLAGS CLEARED CLR INFLAG ;ALSO THE INPUT SWITCH FLAG CSI$2 #CSIBLK,OUTPUT,#OUTSWT BCS FF1200 ;BRANCH IF SYNTAX ERROR ;MAKE SURE BOTH INPUT AND OUTPUT WERE SPECIFIED BITB #CS.EQU,CSIBLK+C.STAT ;IS THERE AND EQUAL SIGN ? BEQ FF1200 ;SYNTAX ERROR IF NOT ;MAKE SURE NO OUTPUT FILE NAME IS SPECIFIED BITB #CS.NMF!CS.WLD!CS.MOR,CSIBLK+C.STAT BNE FF1200 ;SYNTAX ERROR IF ANY ARE SPECIFIED ;IT LOOKS LIKE THIS IS OK ;USE PARSE DEVICE TO DO A REASSIGNMENT IF NECESSARY MOV #OUTFDB,R0 MOV #OUTFDB+F.FNB,R1 MOV #CSIBLK+C.DSDS,R2 ;SPECIFICATION FROM COMMAND LINE MOV #SYNBL,R3 ;HAS SY0: FOR DEFAULT ;DID USER SPECIFY AN OUTPUT UIC ? BITB #CS.DIF,CSIBLK + C.STAT BNE FF1600 ;BRANCH IF YES TO PARSE DEVICE AND UIC CALL .PRSDV ;ONLY PARSE DEVICE ;WILL SUPPLY FILE NAMES LATER BR FF1700 ; .PAGE FF1600: ;DIRECTORY STRING SUPPLIED BIS #SAMUIC,SWFLGS ;SET INDICATOR BIT ;DO A COMPLETE PARSE CALL .PARSE BCC FF1640 ;BRANCH IF NO ERROR ;ANY ERROR IS FATAL SINCE WE WON'T CREATE A DIRECTORY IN THIS SITUATION MOV #DR2MSG,R5 ;ADDRESS OF ERROR MESSAGE MOVB OUTFDB+F.ERR,R1 ;ERROR CODE CLR R2 ;CONVERSION CONTROL MOV #DR2MSG+20.,R0 ;BUFFER FOR NUMBER CALL $CBDSG ;CONVERT MOVB #40,(R0)+ ;INSERT A SPACE ;PUT DEVICE NAME IN BUFFER MOVB OUTFDB+F.FNB+N.DVNM,(R0)+ MOVB OUTFDB+F.FNB+N.DVNM+1,(R0)+ ;PROCESS UNIT NUMBER MOV OUTFDB+F.FNB+N.UNIT,R2 BIT #70,R2 ;IS NUMBER GT 7 ? BEQ FF1610 ;BRANCH IF NOT ;YES, HAVE TO CONVERT TWO DIGITS CLR R3 ASHC #-3,R2 ;SHIFT RIGHT 3 PLACES TO SEPARATE DIGITS ;HIGH DIGIT GOES FIRST BIS #60,R2 ;MAKE IT ASCII MOVB R2,(R0)+ ;PUT IN BUFFER CLR R2 ASHC #3,R2 ;SHIFT LOW DIGIT BACK TO R2 FF1610: BIS #60,R2 ;MAKE IT ASCII MOVB R2,(R0)+ ;PUT IN BUFFER MOVB #':,(R0)+ ;ADD COLON ;INSERT DIRECTORY STRING MOV #CSIBLK+C.DSDS,R1 ;ADDRESS OF DEVICE NAME BLOCK MOV (R1)+,R2 ;BYTE COUNT MOV (R1)+,R3 ;STARTING ADDRESS OF STRING FF1620: MOVB (R3)+,(R0)+ ;COPY TO BUFFER SOB R2,FF1620 ;LOOP UNTIL DONE ;PRINT THE MESSAGE MOV R5,QIOW+Q.IOPL ;BUFFER ADDRESS SUB R5,R0 ;MESSAGE LENGTH MOV R0,QIOW+Q.IOPL+2 ;SET LENGTH DIR$ #QIOW ;THAT IS A FATAL ERROR, START OVER JMP FF1000 ;LET HIM TRY AGAIN ; ; FF1640: ;COPY THE SPECIFIED DIRECTORY STRING TO OUTPUT DATA SET DESCRIPTOR MOV #CSIBLK + C.DIRD,R0 ;ADDRESS OF DIRECTORY STRING BLOCK MOV (R0)+,R1 ;NUMBER OF BYTES IN STRING MOV R1,OUTDSP + 4 ;PUT IN OUTPUT DSP MOV (R0)+,R2 ;ADDRESS OF STRING IN CSI BLOCK MOV #OUTDIR,R3 ;BUFFER FOR DIRECTORY STRING FF1650: MOVB (R2)+,(R3)+ ;COPY FROM CSI BLOCK TO OUTPUT BLOCK SOB R1,FF1650 ;LOOP UNTIL DONE .PAGE FF1700: ;COPY THE DEVICE TO OUTNBL MOV OUTFDB+F.FNB+N.DVNM,OUTNBL+N.DVNM ;NAME MOV OUTFDB+F.FNB+N.UNIT,OUTNBL+N.UNIT ;NUMBER ; ;NOW WE DO THE INPUT FILE SPECS MOV #1,R5 ;INPUT SPECIFICATION COUNTER ; FF2000: ;INPUT FILE SPEC PROCESSING LOOP CSI$2 #CSIBLK,INPUT,#MTSWT BCC FF2020 ;BRANCH IF OK JMP SYNERR ;SYNTAX ERROR IN COMMAND FF2020: ;PARSE LINE TO GET THINGS CONVERTED MOV #INFDB,R0 MOV #INFDB+F.FNB,R1 MOV #CSIBLK+C.DSDS,R2 CLR R3 CALL .PARSE BCC FF2100 ;BRANCH IF OK JMP FCSERR ;ERROR IN FCS OPERATION ; FF2100: ;MAKE FILE SPEC TABLE ENTRY MOV R5,INFSCT ;SAVE TABLE ENTRY COUNT ;CONVERT COUNT TO INDEX DEC R5 ASL R5 CLR FSTS(R5) ;CLEAR FILE NAME STATUS BITS ; ;SEE IF A DIRECTORY STRING HAS BEEN INCLUDED IN THIS FILE SPEC BITB #CS.DIF,CSIBLK+C.STAT BNE FF2120 ;BRANCH IF YES TO PROCESS IT ;NO DIRECTORY IN THIS SPECIFIER TST R5 ;IS THIS THE FIRST INPUT FILE SPEC ? BEQ FF2110 ;BRANCH IF YES ;USE SAME DIRECTORY SPECIFICATION AS LAST TIME MOV FUIC-2(R5),FUIC(R5) ;COPY BINARY UIC BIS DIRFLG,FSTS(R5) ;SET WILD CARD STATUS BR FF2200 ;DONE WITH DIRECTORY FF2110: ;NO DIRECTORY SPECIFIED, USE THE DEFAULT CALL .RDFUI MOV R1,FUIC(R5) ;PUT BINARY VALUE IN TABLE BR FF2200 ;SKIP DIRECTORY STRING DECODING ; FF2120: ;THERE IS A DIRECTORY STRING TO DECODE MOV #CSIBLK+C.DIRDI+2,R2 ;ADDRESS OF ADDRESS OF STRING MOV @R2,R3 ;PICK UP ADDRESS OF STRING MOV -(R2),R4 ;PICK UP STRING LENGTH ;EXAMINE THE STRING FOR A WILD CARD MOV #WLDGRP,R1 ;UIC GROUP WILDCARD STATUS BIT FF2130: ;EXAMINATION LOOP CMPB #'*,@R3 ;IS CHARACTER A WILD CARD ? BNE FF2140 ;BRANCH IF NOT ;YES, SET FLAG BIS R1,FSTS(R5) MOVB #'0,@R3 ;REPLACE WITH 0 SO IT WILL CONVERT FF2140: CMPB #',,(R3)+ ;LOOK FOR GROUP/USER SEPARATOR BNE FF2150 ;BRANCH IF NOT MOV #WLDUSR,R1 ;SET INDICATOR TO USER FF2150: SOB R4,FF2130 ;LOOP UNTIL STRING IS EXAMINED ;STRING HAS BEEN EXAMINED, CONVERT TO BINARY MOV #FUIC,R3 ;UIC TABLE ADDRESS ADD R5,R3 ;ADD OFFSET TO CURRENT ENTRY CALL .ASCPP ;CONVERT ; FF2200: ;MOVE INFORMATION TO TABLES MOV FSTS(R5),DIRFLG ;SAVE WILD CARD STATUS OF THIS DIRECTORY SPEC BIT #NB.SNM,INFDB + F.FNB + N.STAT ;IS FILE NAME WILD CARD ? BNE FF2220 ;BRANCH IF YES ;NO, MOVE FILE NAME MOV INFDB + F.FNB + N.FNAM,FNM1(R5) MOV INFDB + F.FNB + N.FNAM + 2,FNM2(R5) BR FF2240 FF2220: ;WILD CARD, SET STATUS BIT BIS #WLDFNM,FSTS(R5) FF2240: ;CHECK FILE TYPE BIT #NB.STP,INFDB + F.FNB + N.STAT ;IS TYPE A WILD CARD BNE FF2260 ;BRANCH IF IT IS ;NO, MOVE FILE TYPE TO TABLE MOV INFDB + F.FNB + N.FTYP,FTYP(R5) BR FF2280 FF2260: ;WILD CARD, SET STATUS BIT BIS #WLDTYP,FSTS(R5) FF2280: ;FINISHED WITH THIS FILE SPECIFICATION ;IS THERE ANOTHER FILE SPEC ? BITB #CS.MOR,CSIBLK + C.STAT BEQ FF3000 ;BRANCH IF NOT MOV INFSCT,R5 ;PICK UP CURRENT COUNT INC R5 CMP R5,#TABLSZ ;HAVE WE EXCEEDED MAX ? BLE FF2000 ;NO, PROCESS NEXT FILE SPEC JMP TBLERR ;YES, PRINT ERROR MESSAGE ; .PAGE .SBTTL READ FILE LABEL FROM TAPE FF3000: ;FINISHED WITH INPUT FILE SPEC ;GET THE TAPE READY BIT #RWMSK,INFLAG ;DID HE SAY NOT TO REWIND ? BNE FF3030 ;BRANCH IF SO, HOPE HE KNOWS WHAT HE IS DOING DIR$ #MTRWD ;REWIND TAPE FF3030: ;DOES HE WANT TO SET DENSITY ? BIT #DEMSK,INFLAG ;DID HE SPECIFY DENSITY ? BEQ FF3070 ;BRANCH IF NOT, USE WHATEVER WAS SET PREVIOUSLY ;SEE WHAT HE SAID CMP #800.,DENS ;IS IT 800 BPI ? BNE FF3040 ;BRANCH IF NOT ;YES, CLEAR THE BIT FOR 800 BPI BIC #4000,MTSTC+Q.IOPL BR FF3070 FF3040: CMP #1600.,DENS ;IS IT 1600 BPI ? BEQ FF3060 ;BRANCH IF YES ;NEITHER, THERE ARE ONLY TWO CHOICES, SO THIS IS AN ERROR MOV #DENMSG,QIOW+Q.IOPL ;MESSAGE ADDRESS MOV #DENEND-DENMSG,QIOW+Q.IOPL+2 ;LENGTH DIR$ #QIOW ;PRINT MESSAGE JMP FF1000 ;TRY AGAIN FF3060: BIS #4000,MTSTC+Q.IOPL ;SET TO 1600 BPI FF3070: DIR$ #MTSTC ;SET TAPE CHARACTERISTICS FF3100: ;READ THE FILE LABEL DIR$ #MTRLB ;WHAT DID IT DO ? TSTB MTIOSB ;CHECK STATUS BPL FF3150 ;BRANCH IF OK CMPB #IE.EOF,MTIOSB ;IS IT END OF FILE ? BNE FF3130 ;BRANCH IF ERROR FF3129: JMP FF1000 ;EOF, READY FOR NEXT FILE FF3130: BIT #SW.ERR,SWRR ;ERROR IGNORE? BEQ 412$ CMPB #IE.EOV,MTIOSB BEQ 412$ ;EOV IS ERROR WE DON'T IGNORE CMPB #IE.EOT,MTIOSB BEQ 412$ CMPB #IE.PRI,MTIOSB ;ALSO HANDLE NONMOUNTED TAPE BEQ 412$ BR FF3129 ;ELSE JUST ALLOW IT 412$: JMP MTUERR ;PRINT ERROR MESSAGE ; FF3150: ;SEE IF WE GOT THE RIGHT NUMBER OF BYTES CMP #14.,MTIOSB + 2 ;LABEL IS 14. CHARACTERS BEQ FF3160 ;BRANCH IF OK .IF NDF,X$ACT ;ALLOW SOME LATITUDE ... 14 TO 20 BYTES SIZE INCLUSIVE OK CMP MTIOSB+2,#14. ;TOO LOW? BLT 411$ CMP MTIOSB+2,#20. BGT 411$ ;IF TOO SMALL OR TOO LARGE GO TO ERROR PRINT BR FF3160 ;IF IN RANGE, ALLOW. 411$: .ENDC ;ERROR IN TAPE FILE LABEL JMP LBLERR ;PRINT ERROR MESSAGE ; FF3160: ;CHECK THIS FILE NAME WITH TABLE ENTRIES MOV INFSCT,R5 ;NUMBER OF TABLE ENTRIES CLR R4 ;INDEX FF3200: ;TABLE ENTRY CHECKING LOOP BIT #WLDGRP,FSTS(R4) ;IS GROUP WILD ? BNE FF3210 ;BRANCH IF YES ;CHECK UIC GROUP CMPB BUFF2 + 7,FUIC + 1(R4) ;DOES IT MATCH ? BNE FF3250 ;BRANCH IF NOT FF3210: ;CHECK UIC USER BIT #WLDUSR,FSTS(R4) ;IS USER WILD ? BNE FF3220 ;BRANCH IF YES ;CHECK USER CMPB BUFF2 + 6,FUIC(R4) ;DOES IT MATCH ? BNE FF3250 ;BRANCH IF NOT FF3220: ;NOW CHECK FILE NAME BIT #WLDFNM,FSTS(R4) ;IS FILE NAME WILD ? BNE FF3230 ;BRANCH IF YES ;CHECK FILE NAME CMP BUFF2,FNM1(R4) ;CHECK FIRST HALF BNE FF3250 ;BRANCH IF NO MATCH CMP BUFF2 + 2,FNM2(R4) ;SECOND HALF BNE FF3250 ;BRANCH IF NO MATCH FF3230: ;FINALLY FILE TYPE BIT #WLDTYP,FSTS(R4) ;IS FILE TYPE WILD ? BNE FF3400 ;BRANCH IF YES, SELECT THIS FILE ;CHECK FILE TYPE FOR MATCH CMP BUFF2 + 4,FTYP(R4) ;DOES IT MATCH ? BEQ FF3400 ;SELECT IF YES FF3250: ;FILE NAME DOES NOT MATCH THIS TABLE ENTRY ;SEE IF THERE ARE MORE TABLE ENTRIES TO CHECK ADD #2,R4 ;INDEX SOB R5,FF3200 ;LOOP BACK ;THIS FILE DOSN'T PASS, SKIP TO END OF FILE DIR$ #MTSKFL BR FF3100 ;LOOP BACK TO READ NEXT FILE'S LABEL .PAGE .SBTTL GET OUTPUT FDB READY FF3400: ;THIS FILE IS SELECTED, SET UP FILE NAME BLOCK MOV #BUFF2,R3 ;ADDRESS OF FILE LABEL MOV (R3)+,OUTNBL + N.FNAM ;FILE NAME MOV (R3)+,OUTNBL + N.FNAM + 2 ;THIRD PART OF NAME IS OUT OF ORDER IN FILE LABEL MOV BUFF2 + 12.,OUTNBL + N.FNAM + 4 MOV (R3)+,OUTNBL + N.FTYP ;FILE TYPE MOV (R3)+,R1 ;UIC (BINARY) CLR OUTNBL + N.FVER ;SET VERSION TO 0 ;DEVICE HAS BEEN SET BY LOGIC AT FF1700 ;SET THE DIRECTORY BIT #SAMUIC,SWFLGS ;IS THE TAPE UIC TO BE USED ? BNE FF3440 ;BRANCH IF NOT ;SET DIRECTORY TO THE TAPE FILE'S UIC CALL .WDFUI ;SET DIRECTORY STRING IN DATA SET DESCRIPTOR BLOCK ;CONVERT BINARY UIC TO DIRECTORY STRING MOV R1,R3 ;UIC MOV #OUTDIR,R2 ;ADDRESS OF STRING BUFFER CLR R4 ;FORMATTING CONTROL CALL .PPASC ;CONVERT SUB #OUTDIR,R2 ;COMPUTE LENGTH MOV R2,OUTDSP+4 ;SET IN DESCRIPTOR BLOCK ;NOW SET FILE OWNER BIT #FOMSK,SWFLGS ;IS FILE OWNER TO BE SAME AS DIRECTORY ? BNE FF3420 ;BRANCH IF NOT CALL .WFOWN ;SET OWNER TO FILE'S UIC FF3420: ;FILE NAME IS SET ;DO PARSE TO SEE IF DIRECTORY EXISTS MOV #OUTFDB,R0 MOV #OUTFDB+F.FNB,R1 MOV #OUTDSP,R2 ;DIRECTORY STRING IS IN DATA SET DESCRIPTOR MOV #OUTNBL,R3 ;FILENAME INFORMATION IS IN DEFAULT FILENAME CALL .PARSE ;SEE IF THERE IS A DIRECTORY BCC FF3440 ;BRANCH IF EVERYTHING IS OK ;IS THE ERROR NO SUCH FILE CMPB #-26.,OUTFDB+F.ERR ;IS THAT THE ERROR CODE ? BNE FF3425 ;IF ANYTHING ELSE ITS AN ERROR ;DOES HE WANT TO CREATE A DIRECTORY BIT #UFMSK,SWFLGS ;DID HE SAY WE SHOULD ? BEQ FF3425 ;IF NOT IT'S AN ERROR ;CREATE A DIRECTORY ;SAVE THE FILE OWNER WORD IN CASE HE IS BEING FUNNY CALL .RFOWN MOV R1,SAVUI2 ;SAVE IT CALL .RDFUI ;GET THE DIRECTORY WE JUST SET CALL .WFOWN ;SET IT AS OWNER ;ALSO CONVERT IT TO CHARACTER NAME FOR DIRECTORY FILE NAME MOV R1,R3 ;UIC MOV #DIRNAM,R2 ;ADDRESS FOR STRING MOV #3,R4 ;FORMATTING INSTRUCTIONS CALL .PPASC ;CONVERT .PAGE ;PUT DEVICE IN FILENAME BLOCK MOV #DIRDEV,R0 ;DESTINATION ADDRESS MOV OUTFDB + F.FNB +N.DVNM,(R0)+ ;COPY DEVICE NAME MOV OUTFDB + F.FNB +N.UNIT,R2 ;BINARY UNIT NUMBER ;CONVERT TO TWO OCTAL DIGITS (ASCII) CLR R3 ASHC #-3,R2 ;MAKE HIGH DIGIT ASCII BIS #60,R2 MOVB R2,(R0)+ CLR R2 ASHC #3,R2 ;SHIFT BACK LOW DIGIT BIS #60,R2 MOVB R2,(R0)+ ;NOW CREATE DIRECTORY FILE OPEN$W #DIRFDB BCC FF3430 ;BRANCH IF NO ERROR ;ERROR TRYING TO CREATE DIRECTORY MOV #DR3MSG,R5 ;ADDRESS OF MESSAGE MOVB DIRFDB+F.ERR,R1 ;ERROR CODE CLR R2 ;FORMAT CONTROL MOV #DR3MSG+30.,R0 ;BUFFER ADDRESS FOR STRING CALL $CBDSG ;CONVERT ERROR CODE MOVB #40,(R0)+ ;INSERT SPACE ;CALL SUBROUTINE TO SET UP DEVICE, DIRECTORY AND PRINT LINE CALL FIL300 CLOSE$ #DIRFDB ;TRY CLOSING ANYWAY, SO THINGS DON'T GET WORSE ;RESTORE FILE OWNER WORD MOV SAVUI2,R1 CALL .WFOWN ;SKIP THIS FILE ON TAPE JMP FF5140 ;THAT WILL CLEAN UP MAG TAPE SITUATION ; FF3425: ;LINKAGE, BECAUSE IT'S TOO FAR TO BRANCH JMP FF5100 ; FF3430: ;FILE CREATED OK, PRINT MESSAGE MOV #DIRMSG,R5 ;ADDRESS OF MESSAGE MOV #DIRMSG+23.,R0 ;ADDRESS FOR STRING ;SUBROUTINE SUPPLIES REST CALL FIL300 CLOSE$ #DIRFDB ;CLOSE THE NEW DIRECTORY FILE ;RESTORE FILE OWNER WORD MOV SAVUI2,R1 CALL .WFOWN ;READY TO PROCESS THE FILE .PAGE .SBTTL FILE PROCESSING FF3440: ;CHECK FILE TYPE TO SEE HOW IT SHOULD BE PROCESSED MOV #N$IMG+,R5 ;SET MAX INDEX VALUE ;LOOP FROM BACK END OF TABLE. FIRST ELEMENTS CHECKED ARE FORMATTED ;BINARY. THE REST ARE IMAGE MODE. DEFAULT OTHERWISE IS ASCII. ; FF3450: CMP TYPTBL(R5),BUFF2 + 4 ;DOES IT MATCH THIS ENTRY ? BEQ FF3460 ;BRANCH IF YES ;NO, MOVE TO NEXT TABLE ENTRY SUB #2,R5 ;BUMP INDEX BPL FF3450 ;LOOP BACK IF MORE TO CHECK ;ALL DONE, NEGATIVE FLAG MEANS FORMATTED ASCII BR FF4000 FF3460: ;MATCH FOUND WHICH GROUP IS IT SUB #,R5 ;SPLIT TABLE BGT FF4000 ;BRANCH IF PLUS, FORMATTED BINARY ;IT IS IMAGE MODE, SET FLAG TO ZERO CLR R5 ; FF4000: ;R5 FLAG INDICATES PROCESSING MODE ;PLUS IS FORMATTED BINARY ;ZERO IS IMAGE MODE ;NEGATIVE IS FORMATTED ASCII ; MOV R5,PRCFLG ;SAVE THE FLAG ;SET FDB APPROPRIATELY FOR TYPE BEQ FF4010 ;BRANCH IF IMAGE MODE JMP FF6000 ;GO TO VARIABLE RECORD MODE PROCESSING SECTION FF4010: ;SET THE FDB FOR FIXED LENGTH RECORDS FDAT$R #OUTFDB,#R.FIX,,#512.,#-5,#-5 FDBF$R #OUTFDB,#1 ; ;OPEN THE FILE OPEN$W #OUTFDB,#1,#OUTDSP BCS FF5100 ;BRANCH IF ERROR ;PROCESS THE FILE ;READ BLOCK FROM TAPE AND WRITE TO DISK FF4020: DIR$ #MTRLB ;READ A BLOCK FROM TAPE MOV #FF4998,-(SP) ;STORE A RETURN TO FF4998 TSTB MTIOSB ;CHECK FOR ERROR BMI FF5000 ;BRANCH IF ERROR RTS PC ;"RETURN" TO FF4998, POP STACK ;NOW WRITE BLOCK TO DISK FF4998: PUT$ #OUTFDB,#BUFF2,#512. BCS FF5100 ;BRANCH TO PRINT MESSAGE IF ERROR BR FF4020 ;OTHERWISE CONTINUE .PAGE FF5000: ;TAPE ERROR STATUS PROCESSING ;SEE IF ERROR STATUS IS EOF ? CMPB #IE.EOF,MTIOSB BEQ FF5020 ;BRANCH IF IT IS ;NO THERE IS SOME OTHER ERROR BIT #SW.ERR,SWRR ;/ER SWITCH SET TO IGNORE ERRORS? BEQ 513$ ;IF EQ NO, NOTHING SPECIAL CMPB #IE.EOV,MTIOSB BEQ 513$ ;EOV IS ERROR WE DON'T IGNORE CMPB #IE.EOT,MTIOSB BEQ 513$ CMPB #IE.PRI,MTIOSB ;ALSO HANDLE NONMOUNTED TAPE BEQ 513$ RTS PC ;RETURN TO CONTINUE POINT 513$: TST (SP)+ ;POP CONTINUE POINT ADDRESS MOV #MTUMSG,QIOW+Q.IOPL MOV #MTUMSG+22.,R0 ;NUMBER BUFFER MOVB MTIOSB,R1 ;STATUS CLR R2 CALL $CBDSG SUB #MTUMSG,R0 ;COMPUTE MESSAGE LENGTH MOV R0,QIOW+Q.IOPL+2 DIR$ #QIOW ;PRINT THAT LINE ;WRITE FILE NAME MOV #FILMSG,R5 ;MESSAGE ADDRESS MOV #FILMSG+22.,R0 ;STRING AREA BR FF5130 ;PICK UP COMMON ERROR PROCESSING ; FF5020: ;EOF ON TAPE ;DOES HE WANT TO PRINT A COMPLETION MESSAGE ? TST (SP)+ ;POP OFF CONTINUE POINT ADDRESS BIT #SLMSK,SWFLGS BEQ FF5030 ;BRANCH IF NOT ;YES, SET UP MESSAGE MOV #FINMSG,R5 MOV #FINMSG+26.,R0 ;STRING ADDRESS CALL FIL100 ;HE WILL HANDLE DETAILS FF5030: ;OUTPUT PROCESSING SHOULD BE FINISHED, SO CLOSE FILE .IF NDF,ST$$CL CLOSE$ #OUTFDB .IFF MOV #OUTFDB,R0 CALL .TRNCL ;CLOSE/TRUNCATE .ENDC BCC FF5040 ;BRANCH IF NO ERROR ;ERROR CLOSING FILE, PRINT MESSAGE MOV #ER2MSG,R5 MOV #ER2MSG+24.,R0 BR FF5110 ;PRINT ERROR MESSAGE ; ; FF5040: ;EVERYTHING IS OK JMP FF3100 ;READY TO PROCESS NEXT FILE .PAGE FF5100: ;OUTPUT FILE ERROR PROCESSOR ;PUT THIS BETWEEN THE TWO PROCESSING SECTIONS SO A BRANCH WILL REACH (SOMETIMES) MOV #OUTMSG,R5 ;ADDRESS OF ERROR MESSAGE MOV #OUTMSG + 22.,R0 ;BUFFER FOR NUMBER FF5110: MOVB OUTFDB + F.ERR,R1 ;ERROR CODE FF5120: CLR R2 ;CONVERSION CONTROL CODE CALL $CBDSG ;CONVERT MOVB #40,(R0)+ ;ADD A SPACE FF5125: CALL FIL100 ;SUBROUTINE CONVERTS OUTPUT FILE NAME FF5130: ;CLOSE THE OUTPUT FILE ;DON'T TRUNCATE HERE... LEAVE ALL THE JUNK TO SEE IF IT CAN BE FIXED UP... CLOSE$ #OUTFDB FF5140: ;IS THE MAG TAPE POSITIONED AT EOF ? CMPB #IE.EOF,MTIOSB BEQ FF5150 ;BRANCH IF IT IS ;NO, WE WILL HAVE TO POSITION IT DIR$ #MTSKFL ;SKIP TO END OF FILE FF5150: ;READ NEXT FILE'S LABEL JMP FF3100 ; FF5200: MOV #LENMSG,R5 ;ERROR MESSAGE MOV #LENEND,R0 ;BUFFER FOR FILE NAME BR FF5125 .PAGE FF6000: ;BOTH FORMATTED ASCII AND FORMATTED BINARY USE RECORD MODE FDAT$R #OUTFDB,#R.VAR,#FD.CR,,#-5,#-5 FDBF$R #OUTFDB,#1 ;OPEN THE FILE OPEN$W #OUTFDB,#1,#OUTDSP BCS FF5100 ;BRANCH IF ERROR ;PROCESS THE FILE ;RECORD PROCESSING FF6100: ;WE HAVE SUCCESSFULLY OPENED THE OUTPUT FILE ;READY TO START PROCESSING ;INITIALIZE RECORD POINTERS MOV #BUFF2,STRPTR ;SET STARTING POINTER FF6120: DIR$ #MTRLB ;READ A BLOCK FROM TAPE MOV #FF6198,-(SP) ;STORE A RETURN TO FF6198 TSTB MTIOSB ;CHECK FOR ERROR BMI FF500J ;BRANCH IF ERROR RTS PC ;"RETURN" TO FF6198, POP STACK FF500J: JMP FF5000 FF6198: MOV MTIOSB+2,R5 ;BYTE COUNT ADD #BUFF2,R5 ;PRODUCE ENDING ADDRESS (+2) MOV R5,ENDPTR ;SAVE IT ;NOW PROCESSING DEPENDS ON WHETHER WE ARE DOING ASCII OR BINARY TST PRCFLG ;CHECK FLAG BGT FF6500 ;BRANCH IF BINARY ; ; FF6200: ;PROCESS ASCII MOV STRPTR,R5 ;PICK UP STARTING POINTER ;CHECK CHARACTER FOR TERMINATOR FF6210: MOV #TRMTBL,R4 ;PICK UP ADDRESS OF TERMINATOR LIST MOV #4,R3 ;NUMBER IN LIST FF6220: CMPB (R4)+,@R5 ;DOES IT MATCH TERMINATOR ? BEQ FF6250 ;BRANCH IF YES SOB R3,FF6220 ;LOOP ;THIS CHARACTER IS NOT A TERMINATOR CLR CRFLAG ;WE HAVE A NEW LINE INC R5 ;MOVE TO NEXT CHARACTER CMP R5,ENDPTR ;ARE WE AT END OF BUFFER ? BLO FF6210 ;LOOP BACK IF NOT ;WE ARE AT END OF BUFFER ;NEED TO COPY THIS FRAGMENT TO FRONT OF INPUT BUFFER ;COMPUTE NUMBER OF BYTES TO MOVE MOV R5,R0 SUB STRPTR,R0 ;COMPUTE NUMBER OF BYTES ;CHECK THAT R0 IS NOT GT 512. OR ELSE WE ARE IN TROUBLE CMP R0,#512. BGT FF5200 ;PRINT ERROR MESSAGE MOV #BUFF2,R4 ;MOVE IT THERE FF6230: MOVB -(R5),-(R4) SOB R0,FF6230 MOV R4,STRPTR ;SET NEW STARTING POINTER BR FF6120 ;READ NEXT BLOCK .PAGE FF6250: ;A LINE TERMINATOR WAS FOUND MOV R5,SAVPTR ;INSURE CONSISTENT TREATMENT OF POINTER TST CRFLAG ;IS THE CR FLAG SET ? BEQ FF6260 ;BRANCH IF NOT ;YES, THAT MEANS WE WILL NOT WRITE A LINE IF THIS IS A LF CMP #2,R3 BNE FF6260 ;BRANCH IF NOT LF ;IT IS LF, DON'T WRITE ANOTHER LINE CLR CRFLAG BR FF6290 ;RESET POINTERS FF6260: ;LINE TERMINATOR FOUND ;IS IT CR ? CMP #1,R3 BNE FF6270 ;BRANCH IF NOT ;SET CR FLAG SO WE DON'T WRITE A LINE FOR BOTH CR AND LF MOV #1,CRFLAG FF6270: CMP R3,#4 ;IS TERMINATOR TO BE INCLUDED IN LINE ? BLT FF6280 ;BRANCH IF NOT INC R5 ;INCLUDE THE CHARACTER FF6280: ;WRITE THE RECORD SUB STRPTR,R5 ;COMPUTE BYTE COUNT PUT$ #OUTFDB,STRPTR,R5 BCS FF6400 ;BRANCH IF ERROR TO PRINT MESSAGE ; ; FF6290: ;RESTORE BUFFER POINTER MOV SAVPTR,R5 INC R5 ;GET PAST THIS TERMINATOR MOV R5,STRPTR ;SET START OF LINE ;MAKE SURE WE DIDN'T INCREMENT TO END OF BUFFER CMP R5,ENDPTR ;ARE WE AT END OF BUFFER ? BLO FF6200 ;BRANCH IF NOT ;YES, RESET POINTERS AND READ IN ANOTHER BLOCK BR FF6100 ;GET A FRESH START ; ;LINKAGE TO ERROR MESSAGE FF6400: JMP FF5100 .PAGE FF6500: ;PROCESS FORMATTED BINARY MOV STRPTR,R5 ;PICK UP POINTER ;LOOKING FOR A 1 FF6520: CMP (R5)+,#1 BEQ FF6530 ;BRANCH IF IT IS A 1 CMP R5,ENDPTR ;ARE WE AT END OF BUFFER ? BLO FF6520 ;LOOK SOME MORE IF NOT ;START FRESH WITH ANOTHER BUFFER BR FF6100 ; FF6530: ;COMPUTE THE ADDRESS OF THE NEXT 1 MOV @R5,R4 ;RECORD LENGTH ADD R5,R4 ;ADD ADDRESS OF START BIC #1,R4 ;ROUND DOWN IF ODD MOV R4,STRPTR ;SET POINTER FOR NEXT RECORD ;SEE IF ALL OF THIS RECORD IS IN BUFFER MOV (R5)+,R4 ;GET THE LENGTH AGAIN CMP R5,ENDPTR ;MAKE SURE WE AREN'T PICKING UP JUNK BHIS FF6600 ;IF SO BRANCH TO READ IN NEXT BLOCK MOV R4,R3 ;ALSO COMPUTE LENGTH OF RECORD TO WRITE SUB #4,R3 ;ADJUST TO FILES-11 TERMS ADD R5,R4 ;ADDRESS OF START OF DATA SUB #5,R4 ;COMPUTE ENDING ADDRESS OF DATA CMP R4,ENDPTR ;ARE WE PAST END ? BHIS FF6600 ;BRANCH IF YES ; ;READY TO WRITE THIS RECORD ;R3 CONTAINS BYTE COUNT ;R5 CONTAINS BUFFER ADDRESS PUT$ #OUTFDB,R5,R3 BCS FF6400 ;BRANCH IF ERROR ; ;STRPTR IS POINTING TO NEXT 1 (HOPEFULLY) CMP STRPTR,ENDPTR ;ARE WE AT END OF BUFFER ? BLO FF6500 ;BRANCH IF NOT, LOOK FOR ANOTHER 1 JMP FF6100 ;START AGAIN WITH FRESH BUFFER .PAGE FF6600: ;HAVE TO READ IN MORE TO FINISH RECORD SUB #4,R5 ;BACK UP TO POINT TO 1 MOV ENDPTR,R4 ;END OF BUFFER MOV #BUFF2,R3 ;MOVE IT BACK THERE MOV R4,R2 ;COMPUTE BYTE COUNT SUB R5,R2 ;MAKE SURE IT ISN'T MORE THAN 512. BYTES CMP R2,#512. ;IS IT ? BLE FF6610 ;OK IF NOT JMP FF5200 ;IF YES PRINT A MESSAGE AND FORGET THIS FILE FF6610: ASR R2 ;CONVERT TO WORD COUNT FF6620: MOV -(R4),-(R3) SOB R2,FF6620 MOV R3,STRPTR ;START HERE ;NOW READ NEXT BLOCK JMP FF6120 ; ; FCSERR: MOV #FCSMSG,QIOW+Q.IOPL MOV #FCSMSG+12.,R0 MOVB INFDB+F.ERR,R1 CLR R2 CALL $CBDSG SUB #FCSMSG,R0 ;COMPUTE MESSAGE LENGTH MOV R0,QIOW + Q.IOPL + 2 SYNERR: DIR$ #QIOW JMP FF1000 ; TBLERR: MOV #TBLMSG,QIOW + Q.IOPL MOV #TBLEND - TBLMSG,QIOW + Q.IOPL + 2 BR SYNERR ; LBLERR: MOV #LBLMSG,QIOW + Q.IOPL MOV #LBLEND-LBLMSG,QIOW+Q.IOPL+2 BR SYNERR ; MTUERR: MOV #MTUMSG,QIOW+Q.IOPL MOV #MTUMSG+22.,R0 ;NUMBER BUFFER MOVB MTIOSB,R1 ;STATUS CLR R2 CALL $CBDSG SUB #MTUMSG,R0 ;COMPUTE MESSAGE LENGTH MOV R0,QIOW+Q.IOPL+2 BR SYNERR .PAGE .SBTTL MESSAGE SUBROUTINES FIL100: ;SUBROUTINE TO PUT FILE NAME IN MESSAGE BUFFER MOVB OUTFDB+F.FNB+N.DVNM,(R0)+ MOVB OUTFDB+F.FNB+N.DVNM+1,(R0)+ ;PROCESS UNIT NUMBER MOV OUTFDB+F.FNB+N.UNIT,R2 BIT #70,R2 ;IS NUMBER GT 7 ? BEQ FIL110 ;BRANCH IF NOT ;YES, HAVE TO CONVERT TWO DIGITS CLR R3 ASHC #-3,R2 ;SHIFT RIGHT 3 PLACES TO SEPARATE DIGITS ;HIGH DIGIT GOES FIRST BIS #60,R2 ;MAKE IT ASCII MOVB R2,(R0)+ ;PUT IN BUFFER CLR R2 ASHC #3,R2 ;SHIFT LOW DIGIT BACK TO R2 FIL110: BIS #60,R2 ;MAKE IT ASCII MOVB R2,(R0)+ ;PUT IN BUFFER MOVB #':,(R0)+ ;ADD COLON ; ;GET UIC ;COPY DIRECTORY STRING FROM OUTPUT DATA SET DESCRIPTOR MOV OUTDSP+4,R2 ;NUMBER OF BYTES IN STRING MOV #OUTDIR,R3 ;ADDRESS OF STRING FIL115: MOVB (R3)+,(R0)+ ;MOVE IT SOB R2,FIL115 ;NOW CONVERT FILE NAME AND TYPE MOV #OUTNBL+N.FNAM,R4 ;ADDRESS OF FILE NAME MOV #3,R3 ;3 LOOPS FIL120: ;CONVERSION LOOP MOV (R4)+,R1 ;RAD-50 VALUE CALL $C5TA ;CONVERT AND STORE SOB R3,FIL120 ;LOOP UNTIL DONE ;REMOVE TRAILING BLANKS FIL130: CMPB #40,-(R0) ;IS THIS A SPACE ? BEQ FIL130 ;KEEP LOOPING IF YES INC R0 MOVB #'.,(R0)+ ;PUT IN PERIOD MOV OUTNBL+N.FTYP,R1 ;FILE TYPE CALL $C5TA ;CONVERT IT ;AGAIN, REMOVE BLANKS FIL140: CMPB #40,-(R0) ;IS THIS A SPACE ? BEQ FIL140 INC R0 ;PUT IN VERSION NUMBER MOVB #';,(R0)+ ;SEPARATOR MOV OUTFDB+F.FNB+N.FVER,R1 ;VERSION NUMBER CLR R2 ;SUPPRESS LEADING ZEROES CALL $CBOMG ;CONVERT ;READY TO PRINT MESSAGE MOV R5,QIOW+Q.IOPL ;BUFFER ADDRESS SUB R5,R0 ;MESSAGE LENGTH MOV R0,QIOW+Q.IOPL+2 ;SET LENGTH DIR$ #QIOW ; RETURN ;LET CALLING PROGRAM DECIDE WHAT TO DO NEXT .PAGE FIL300: ;SUBROUTINE TO INSERT DEVICE AND DIRECTORY IN MESSAGE BUFFER MOVB DIRFDB+F.FNB+N.DVNM,(R0)+ MOVB DIRFDB+F.FNB+N.DVNM+1,(R0)+ ;PROCESS UNIT NUMBER MOV DIRFDB+F.FNB+N.UNIT,R2 BIT #70,R2 ;IS NUMBER GT 7 ? BEQ FIL310 ;BRANCH IF NOT ;YES, HAVE TO CONVERT TWO DIGITS CLR R3 ASHC #-3,R2 ;SHIFT RIGHT 3 PLACES TO SEPARATE DIGITS ;HIGH DIGIT GOES FIRST BIS #60,R2 ;MAKE IT ASCII MOVB R2,(R0)+ ;PUT IN BUFFER CLR R2 ASHC #3,R2 ;SHIFT LOW DIGIT BACK TO R2 FIL310: BIS #60,R2 ;MAKE IT ASCII MOVB R2,(R0)+ ;PUT IN BUFFER MOVB #':,(R0)+ ;ADD COLON ; ;GET UIC ;DIRECTORY UIC IS IN FSR$2 DEFAULT CALL .RDFUI ;GET THE UIC ;SET UP FOR CONVERSION ROUTINE MOV R1,R3 ;UIC MOV R0,R2 ;BUFFER ADDRESS CLR R4 ;CONTROL FLAGS CALL .PPASC ;CONVERT AND PLACE IN BUFFER ; ;SET UP QIO PARAMETERS MOV R5,QIOW+Q.IOPL ;ADDRESS OF MESSAGE SUB R5,R2 ;COMPUTE LENGTH MOV R2,QIOW+Q.IOPL+2 ;SET LENGTH DIR$ #QIOW RETURN .PAGE .NLIST BEX ; TERMINAL QIO QIOW: QIOW$ IO.WLB,5,5,,,,<,,40> ; ERROR MESSAGES SYNMSG: .ASCII /COMMAND LINE SYNTAX ERROR/ SYNEND: DENMSG: .ASCII /DENSITY MUST BE 800 OR 1600/ DENEND: LBLMSG: .ASCII /ERROR READING TAPE FILE LABEL/ LBLEND: LENMSG: .ASCII /INPUT RECORD TOO LONG / LENEND: .BLKB 26. ;ROOM FOR FILE NAME OUTMSG: .ASCII /OUTPUT FILE FCS ERROR / .BLKB 40. ;ROOM FOR ERROR NUMBER AND FILE NAME TBLMSG: .ASCII /TOO MANY INPUT FILE SPECS/ TBLEND: MTUMSG: .ASCII /MAG TAPE DRIVER ERROR / FCSMSG: .ASCII /FCS ERROR / FCSEND: DR2MSG: .ASCII /DIRECTORY FCS ERROR / .BLKB 26. ;ROOM FOR ERROR NUMBER AND DIRECTORY DR3MSG: .ASCII /ERROR CREATING DIRECTORY, FCS / .BLKB 26. DIRMSG: .ASCII /DIRECTORY FILE CREATED / .BLKB 20. ;ROOM FOR DIRECTORY FILMSG: .ASCII /WHILE PROCESSING FILE / .BLKB 26. ;ROOM FOR FILE NAME ER2MSG: .ASCII /ERROR CLOSING FILE, FCS / .BLKB 26. FINMSG: .ASCII /PROCESSING COMPLETE, FILE / .BLKB 30. .EVEN ; .END FFL .PAGE