/* DECtape image scanner */ #include #define psym(k) fputc((k),stdout) #define NL '\n' #define CR '\r' #define space() psym(' ') #define newline() psym(NL) static int *B; void die (char *s, int n) {fprintf(stderr,"**SHIT(%o): %s\n",n,s); exit(1);} int mangle (int n) { int i,m; n = ~n; m = (n&7)<<15; m += (n&070)<<9; m += (n&0700)<<3; m += (n&07000)>>3; m += (n&070000)>>9; return m+((n&0700000)>>15); } void mangleblock (int block) { int min,max,val; min = block*256; max = min+255; /*fprintf(stderr,"Mangling block %o %o:%o %o %o,",*/ /*block,min,max,B[min],B[max]);*/ while (min=0; i-=6) { j = (n>>i)&63; if (j) {if ((j&32)==0) j+=64; psym(j);} } } void aa1 (int n) { int i,j,k; for (i=12; i>=0; i-=6) { j = (n>>i)&63; if (j) { if ((j&32)==0) j+=64; if (j=='"') j = NL; if (j=='^') j = '@'; psym(j); } } } void dec1 (int n) { n = n&127; if (n==CR) n = NL; if (n) psym(n); } void dec5 (int a, int b) { dec1(a>>11); dec1(a>>4); dec1((a<<3)+((b>>15)&7)); dec1(b>>8); dec1(b>>1); } int bitmap (int fileno) { if (fileno<0) die("Fileno negative",fileno); if (fileno==0) return 256*64; if (fileno>56) die("Fileno excessive",fileno); return 256*57+((fileno-1)*32); } int blocksused (int bitmap) { int i,j,m,n; n=0; for (i=0; i<32; i++) { m = B[bitmap++]; j = 0400000; while (j) {if (m&j) n++; j >>= 1;} } return n; } int filedesc (int fileno) { if (fileno<1) die("Fileno too small",fileno); if (fileno>56) die ("Fileno too big",fileno); return 256*64+(fileno-1)*4+32; } void printname (int d) { sixbt(B[d]); sixbt(B[d+1]); space(); sixbt(B[d+2]); } void dir () { int i,d,m,u; for (i=1; i<=24; i++) { d = filedesc(i); m = bitmap(i); u = blocksused(m); if (u || B[d+3]&0400000) { printf("%02d %3d ",i,u); printname(d); newline(); } } printf("%11d\n",blocksused(0)); } void decfile (int start) { int p,lim,pairs,mangled=0,next; while (start>0) { /*fprintf(stderr,"//Next block %o\n",start);*/ p = start*256; lim = p+254; while (p>8,p&255,B[p]);*/ if (B[p]==0) break; if (B[p]==01005) break; if ((B[p]&0777)!=2) die("DEC format mode not 2",p); pairs = B[p]>>9; p += 2; while(--pairs>0) { if (p>=lim) die("DEC record error",p-lim); dec5(B[p],B[p+1]); p += 2; } } next = B[lim+1]; if (mangled) mangleblock(start); if (next=01100) start = -1; } } void aa1file (int start) { int p,lim,sum=010161,w,mangled=0,next; while (start>0) { p = start*256; lim = p+255; /*fprintf(stderr,"Block %o %o:%o %06o %06o sum %06o\n",*/ /*start,p,lim,B[p],B[lim],sum);*/ if (B[p++]!=(sum&0777777)) die("AA1 checksum error",p-1); while (p=01100) start = -1; } } main (int c, char *v[]) { int size=576*256*4; int i,f; FILE *tape,*origstdout; origstdout = stdout; stdout = stderr; B = (int*) malloc(size); if (c<2) die ("No tape file name",c); tape = fopen(v[1],"rb"); if (tape==0) die("No tape file",0); i = fread(B,1,size,tape); printf("Got %d out of %d bytes\n\n",i,size); printf("Directory\n\n"); dir(); scanf("%d",&i); if (i==0) exit(0); printf("Going for file %d\n",i); f = i; if (i<0) i =-i; i = filedesc(i); printf("That's file "); printname(i); i = B[i+3]; printf(", First block %o\n",i); stdout = origstdout; i = i&01777; if (f<0) {aa1file(i);} else decfile(i); }