/* * print a PDP9/15 DECtape directory * * directory data at offset 040 in block 0100 * 56 entries (or 24 if system tape, with other half of blk for sys files) * * name (in line printer format) * name * extension * starting block (msb set if file active) * */ #include FILE *fp, *fp1; char fileName[15] = { 0,0,0,0,0,0,'_',0,0,0,'.','t','x','t',0}; unsigned int tape[576][256]; unsigned int blk[256]; #define FWD 0 #define REV 1 unsigned int direction = FWD; getblk(blknum) { unsigned int i, j; unsigned int wrd; unsigned int *p,*q; if(blknum > 01077){ fprintf(stderr,"error - blknum too big in getblk %o\n", blknum); exit(1); } // if(direction == FWD){ if(((tape[blknum][255] & 0770000) == 0) || // normal blknum (tape[blknum][255] == 0777777)){ // or EOF // fprintf(stderr,"\n---BLK %o FWD, link %o\n", blknum, tape[blknum][255]); p = blk; for(i=0; i<256; i++) *p++ = tape[blknum][i]; } else{ // blks read REV req obverse compliment // fprintf(stderr,"\n---BLK %o REV, link %o\n", blknum, tape[blknum][255]); p = blk; q = &tape[blknum][255]; while(p != &blk[256]){ wrd = ~(*q--); j = (wrd & 0700000) >>15; j |= (wrd & 0070000) >> 9; j |= (wrd & 0007000) >> 3; j |= (wrd & 0000700) << 3; j |= (wrd & 0000070) << 9; j |= (wrd & 0000007) <<15; *p++ = j; } } } // // 6-bit trimmed code // 0xAB is on a mac // unsigned char tbl[64] = { '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', 0xab, ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?'}; sixbit(fp, i) FILE *fp; unsigned int i; { unsigned int chr; chr = (i >> 12) & 077; if(chr == 0) chr = 040; // change nuls to spaces for file names fprintf(fp, "%c",tbl[chr]); chr = (i >> 6) & 077; if(chr == 0) chr = 040; fprintf(fp, "%c",tbl[chr]); chr = i & 077; if(chr == 0) chr = 040; fprintf(fp, "%c",tbl[chr]); } sixbitstr(p, i) char *p; unsigned int i; { unsigned char chr; *p++ = tbl[(i >> 12) & 077]; *p++ = tbl[(i >> 6) & 077]; *p++ = tbl[ i & 077]; } int nulDetected = 0; unsigned char lastChr = 0; fiveSevenOut(fp,i,j) FILE *fp; unsigned int i,j; { unsigned char c[5]; unsigned char chr; int cnt; if(nulDetected) return; c[0] = (i>>11) &0x7f; c[1] = (i>>4) &0x7f; c[2] = ((i<<3) &0170) | ((j>>15) & 07); c[3] = (j>>8) &0x7f; c[4] = (j>>1) &0x7f; /* * this is all complicated by the fact that there can be * extra words after the end of line, and nuls before the * first * * this code assumes there is only ever a single line ending * in or per record */ for(cnt=0; cnt<5; cnt++){ chr = c[cnt]; if((chr == 0xd)||(chr == 0)){ fputc('\n',fp ); nulDetected++; return; } else fputc(chr, fp); } } main(argc, argv) int argc; char **argv; { unsigned int *p, *dirPtr; unsigned int i, j, n, wrd, n1,n2,n3; unsigned int curblk, blkcnt, dirSlot; unsigned int cnt; int textFile = 0; // read and unpack the entire tape for(i=0; i<576; i++){ for(n=0; n<256; n++){ wrd = getchar(); wrd |= getchar() << 8; wrd |= (getchar() & 3) << 16; getchar(); tape[i][n] = wrd; } } dirPtr = &tape[0100][040]; // addr of start of directory fp1 = fopen("_directory.txt","w"); for(dirSlot=0; dirSlot<56; dirSlot++){ //printf("\n----DIRSLOT %d ", dirSlot); n1 = *dirPtr++; n2 = *dirPtr++; n3 = *dirPtr++; // file name n = *dirPtr++; //printf(" FIRST BLK %o\n", n); fflush(stdout); if((n & 0400000) == 0) continue; n &= 01777; if(n > 01077) continue; // 576 (01100) octal blocks on tape if(n == 0) { printf("\n"); continue; } // system file sixbit(fp1, n1); sixbit(fp1, n2); fprintf(fp1, " "); sixbit(fp1, n3); fprintf(fp1, " %4o ", n); blkcnt = 0; curblk = n; getblk(curblk); fprintf(fp1," %s ",(blk[0] & 7) == 2 ? "TXT": "BIN"); // // extract code // if((blk[0] & 7) != 2) textFile = 0; else textFile = 1; // only extract text files sixbitstr(fileName, n1); sixbitstr(&fileName[3], n2); sixbitstr(&fileName[7], n3); for(i=0; i<10; i++){ if(fileName[i] == '@') fileName[i] = '_'; } if(textFile) fp = fopen(fileName,"w"); while(1){ blkcnt++; //printf("\nCnt: %d Link: %6o %6o\n",blkcnt, blk[254],blk[255]); //printf("curblk = %o next = %o\n", curblk, blk[255]); fflush(stdout); if(textFile) for(j=0; j<254; ){ if(blk[j] == 001005){ //printf("hit sw EOF"); break; } if(blk[j] == 0) break; // extract record length cnt = ((blk[j] >> 9) & 0xff); //printf("\n --typ %d cnt %d : ",blk[j] & 7,cnt); fflush(stdout); nulDetected = 0; j += 2; // extract data // while(--cnt){ //printf("\n%6o %6o ",blk[j], blk[j+1]); //fiveSevenOut(stdout, blk[j], blk[j+1]); fiveSevenOut(fp, blk[j], blk[j+1]); j += 2; } } //if(curblk > blk[255]) direction = REV; else direction = FWD; if(blk[255] == 0777777) break; // last blk in file curblk = blk[255]; getblk(curblk); } if(textFile) fclose(fp); fprintf(fp1,"%d\n",blkcnt); } fclose(fp1); }