;******************************************************************************* ; D A T A G R D R . M A C ;******************************************************************************* .TITLE DATAGRDR - DATA GENERAL FORMAT TAPE READER UTILITY .IDENT /DTG1.0/ .NLIST BEX .ENABL LC .SBTTL AUTHOR'S CREDITS ; PROGRAMMER: HENRY TUMBLIN ; THE JACKSON LABORATORY COMPUTER SERVICE. ; DATE: MARCH 22,1978 ; VERSION: 1.0 ; RESIDENCE: DB1:[1,21]DATAGRDR.MAC ; MODULE NAME: DATAGRDR -- DATAG(DATA GENERAL) TAPE READER ; FOR: SYSTEMS/UTILITIES ; CORE REQUIREMENTS: 3-K ; MACHINE/SYSTEM: PDP11/45-IAS V2.0 ; TYPE/LANGUAGE: MAIN/ASSEMBLER ; INDIRECT COMMAND FILE: DATAGRDR.CMD ; ABSTRACT: THIS PROGRAM READS A TAPE WRITTEN BY ; A DATA GENERAL MACHINE, DEBLOCKS IT AND ; STORES IT IN DISK. FOR A FULL DESCRIPTION, ; SEE PAGE 5 OF THIS LISTING. ; EDITS: 22-MAR-78 ADAPTED THIS VERSION FROM ANSI TAPE READER ;******************************************************************************* .SBTTL TELL THE ASSEMBLER WHICH LIBMACS TO USE ;******************************************************************************* .MCALL DIR$,QIOW$,OPEN$W,CLOSE$,FDBDF$,FDOP$A,FINIT$ .MCALL FDAT$A,FDRC$A,PUT$,FSRSZ$,GCMLB$,GCML$,CSI$ .MCALL CVTA$,C$C,CSI$1,CSI$2,ALUN$,EXIT$S,PUSH,POP .MCALL CSI$SW,CSI$ND,.CLC. ; DEFINE ALL CC CHARACTERS. C$C ; DEFINE ALL LUNS INLUN=1 ;TAPE DRIVE INPUT TERLUN=2 ;TERMINAL I/O OUTLUN=3 ;DISK LUN ; DEFINE ALL LOCAL MACROS. .MACRO PRINT,A,B MOV A,WRITE+Q.IOPL MOV B,WRITE+Q.IOPL+2 DIR$ #WRITE .ENDM PRINT .MACRO TREAD,A,B ;TAPE READ MACRO MOV A,READT+Q.IOPL MOV B,READT+Q.IOPL+2 DIR$ #READT .ENDM TREAD .MACRO INPUT,A,B MOV A,READ+Q.IOPL MOV B,READ+Q.IOPL+2 DIR$ #READ .ENDM INPUT ;******************************************************************************* .SBTTL SET UP THE QIO'S ;******************************************************************************* .PSECT IMPUR,RW,D,REL READT: QIOW$ IO.RLB,INLUN,5,200,IOSTAT,,<0,0> ;TAPE READ QIO IOSTAT: .WORD 0. ;IOSTATUS LENGTH: .WORD 0. ;READ LENGTH INBUF: .BLKB 850. ;INPUT BUFFER. READ: QIOW$ IO.RVB,TERLUN,4,200,IOSB,,<0,0,> ;TERMINAL READ QIO. IOSB: .WORD 0. ;STATUS BLOCK LEN1: .WORD 0. ;LENGTH WRITE: QIOW$ IO.WVB,TERLUN,4,200,,,<0,0,> ;TERMINAL WRITE QIO ATT: QIOW$ IO.ATT,INLUN,3,200,ATSB ;ATTACH TAPE DRIVE ATSB: .BLKW 2. DEATT: QIOW$ IO.DET,INLUN,3,200,ATSB ;DEATTACH TAPE DRIVE REWD: QIOW$ IO.RWD,INLUN,2,200,ATSB ;REWIND TAPE. ALUN: ALUN$ INLUN,MM,0 ;ASSIGN MM0: TO LUN 1 ;******************************************************************************* .SBTTL THE FCS AND GCML STUFF ;******************************************************************************* .EVEN GCLBUF: .BLKB 80. FSRSZ$ 1 ;1 BLOCK. .SBTTL THE FCS STUFF OUTFDB: FDBDF$ ;DEFINE THE FDB FDAT$A R.VAR,FD.CR FDRC$A ,GCLBUF,80. ; FDOP$A OUTLUN,OFDES,,FO.WRT OFDES: .WORD DEVS,DEV .WORD UICS,UIC .WORD FNAMS,FNAM DEV: .ASCII /DB1:/ DEVS=.-DEV UIC: .ASCII /[1,22]/ UICS=.-UIC FNAM: .ASCII /DATAGR000.DGB/ FNAMS=.-FNAM .EVEN COUNT: .WORD 0. FNUM: .WORD 100. ;DATAG FILE NUMBER(BASE 100.) FLE: .ASCII /FILE/ ;TO BE USED IN FINDING FILES ;******************************************************************************* .SBTTL START THE R/O CODE ;******************************************************************************* .PSECT PUR$,RO,I,REL START: FINIT$ ;FOR FCS PURPOSES CLR COUNT ;RESET THE COUNT RD.OPN: OPEN$W #OUTFDB ;OPEN OUTPUT FILE DIR$ #ALUN ;ASSIGN THE LUN TO THE TAPE DRIVE DIR$ #ATT ;ATTACH THE DRIVE TO US DIR$ #REWD ;MAKE SURE THAT THE DRIVE HAS BEEN REWOUND FIRST ; THE DATA GENERAL TAPE HAS BEEN WRITTEN IN THE FOLLOWING FORMAT: ; 514-BYTE BLOCKS, NO TAPE MARK BETWEEN FILES, BUT TAPE MARK ; WRITTEN AT END OF TAPE. FILES ARE DELIMITED BY A SINGLE RECORD ; OF THE FORM >>> FILE #N <<<<. (IGNORE THE >><< CHARACTERS) ; THE RECORDS WITHIN THE BLOCKS ARE DELIMITED BY A SINGLE ; CARRIAGE RETURN (OCTAL 015). RECORDS ARE ALLOWED TO CROSS ; BLOCK BOUNDARIES. ; ; THE BASIC FLOW OF THIS PROGRAM IS AS FOLLOWS: ; ; 1) THE TAPE DRIVE IS ASSIGNED TO A LUN(1). THEN THE DRIVE ; IS ATTACHED AND A REWIND IS SENT TO THE DRIVE TO INSURE THAT ; IT IS AT THE BOT. ; 2) NEXT THE FIRST OUTPUT FILE IS OPENED. THE FILENAMES OF THE ; OUTPUT FILES ARE ASSIGNED AS FOLLOWS: ; THE BASE FILE NAME IS DATAG100. THE FILETYPE IS DGB.(DATA GENERAL ; BASIC). EACH TIME A FILE DELIMITER IS ENCOUNTERED IN THE INPUT ; FILE, THE CURRENTLY OPEN FILE IS CLOSED, AND A NEW FILE IS ; OPENED. THE FILE NAME ALGORITHM IS AS FOLLOWS: BASE VALUE=100. ; NEW VALUE = BASE VALUE + 1. NEW FILENAME = DATAG101, ETC. THE ; PROGRAM WILL CHANGE THE FILENAME FOR EACH OCCURANCE OF A FILE ; SEPARATOR WITHIN THE FILE. ; 3) A TAPE BLOCK IS THEN READ INTO MEMORY AND PROCESSED. ALL RECORDS ; WITHIN THE TAPE BLOCK ARE DELIMITED BY A CARRIAGE RETURN AT THE ; END OF A RECORD. WHEN THE END OF THE CURRENT DATA BLOCK IN MEMORY ; IS REACHED, THEN THE NEXT SEQUENTIAL BLOCK IS READ AND THE ; PROCESS CONTINUES UNTIL A END-OF-FILE(TAPE MARK) IS READ. ; 4) IF A FILE DELIMITER IS FOUND, THEN THE FILE IS SPOOLED TO THE ; LINE PRINTER TO BE CLOSED, BUT THE FILE ITSELF IS PRESERVED ; ON DB1:[1,22]. ; 5) WHEN A TAPE MARK IS READ, THEN THE FOLLOWING ACTION OCCURS: ; THE FILE CURRENTLY OPEN IS CLOSED AND SPOOLED TO THE LINE ; PRINTER. THE TAPE IS REWOUND. THE TAPE DRIVE IS DETATTACHED, AND ; THE PROGRAM EXITS NORMALLY. NOTE THAT THERE IS NO REAL ; ERROR PROCESSING CONTAINED WITHIN THIS PROGRAM BECAUSE I ; DON'T THINK THAT I'LL BE READING ANYMORE DATA GENERAL TAPES ; RIGHT AWAY. ; RIGHT AWAY. ALL THE HOOKS ARE THERE TO PERFORM ERROR PROCESSING, ; SO WHEN THE NEED ARISES, THEY'LL STILL BE THERE. ; ; NOW START PROCESSING THE TAPE. ; (THE HEART OF THIS PROGRAM) LP1: TREAD #INBUF,#600. ;READ A RECORD. CLR COUNT ;INITIALIZE POINTERS AND COUNTERS MOV IOSTAT+2,R1 ;SET BLOCK BUFFER COUNT MOV #INBUF,R2 ;SET BUFFER POINTER MOV #GCLBUF,R3 ;USE THIS BUFFER AS WELL AG2A: CMPB #CR,(R2) ;IS IT A CARRIAGE RETURN?? BEQ PUTREC ;YES, THEN WRITE OUT THE RECORD. MOVB (R2)+,(R3)+ ;ELSE MOV INTO TEMP BUFFER INC COUNT ;BUMP UP RECORD BYTE COUNT DEC R1 ;DECREASE THE BLOCK BUFFER BYTE COUNT BEQ NXTBLK ;ZERO, THEN WE'VE GOT TO READ THE NEXT BLOCK BR AG2A ;AND GO CHECK NEXT BYTE NXTBLK: TREAD #INBUF,#600. ;READ ANOTHER TAPE BLOCK. CMPB #IE.EOF,IOSTAT ;END OF FILE, THEN QUIT BNE 1$ ; JMP FINISH ;GO TO FINISH UP ROUTINE 1$: MOV #INBUF,R2 ;RESET BLOCK POINTER MOV IOSTAT+2,R1 ;AND THE BYTE COUNT BR AG2A ;AND GO BACK AND RESUME PROCESSING. PUTREC: ADD #2,COUNT ; PRINT #OTBUF,COUNT ;DISPLAY TO SCREEN FIRST SUB #2,COUNT PUT$ #OUTFDB,#GCLBUF,COUNT ;AND WRITE TO THE OUTPUT FILE MOV #GCLBUF,R3 ;RESET RECORD POINTER CLR COUNT ;RESET RECORD BYTE COUNT INC R2 ;POINT TO NEXT BYTE IN BUFFER PUSH ;SAVE THESE REGISTERS .CLC. #FLE,R2,#4 ;SEE IF IT'S A NEW FILE COMING UP BCS ARND1 ;CS- NOT A NEW FILE .MCALL PRINT$ ;SET UP TO SPOOL THE OUTPUT FILES PRINT$ #OUTFDB,,,,,,,,#1 ;SPOOL THE OUTPUT TO LP0: INC FNUM ;CHANGE THE FILE NAME .MCALL CVTA$ CVTA$ FNUM,#FNAM+6,#0 ;CONVERT TO ASCII THE NEW FILE NUMBER FDOP$R #OUTFDB,,#OFDES ;SET UP THE NEW FILE OPEN$W #OUTFDB ;OPEN A NEW FILE ARND1: POP ;RESTORE THESE REGISTERS DEC R1 ;DECREMENT BLOCK BYTE COUNT BNE ARND ;IF >1, THEN WE STILL HAVE RECORDS LEFT MOV #INBUF,R2 ;RESET POINTERS JMP NXTBLK ;GO READ ANOTHER BLOCK ARND: JMP AG2A ;ELSE PROCESS THE NEXT RECORD IN BUFFER FINISH: PRINT$ #OUTFDB,,,,,,,,#1 ;AND QUEUE UP THE FILE ON LP0: DIR$ #REWD ;REWIND THE MAGTAPE DIR$ #DEATT ;DEATTACH THE TAPE DRIVE EXIT$S ;EXIT QUIETLY .END START