/* Reader for ENTROPY Document Reader files */ /* By Stuart Brady */ /* This code really is dreadful. Sorry. */ #include #include #include #define PAGES 257 char *dcpname; char *magname; FILE *jynfd; char *magic1 = "\x7f" "1991 Cookie"; char *magic2 = "\x7f" " 1992 ENTROPY"; long baseaddr; int remaining; char *tokens1[] = { "address ", "screens ", "screen ", " issue ", "memory ", "screen ", " don't ", " SAMCO ", " SAMCo ", "Coupe ", " FRED ", "bytes ", " data ", " it's ", " from ", " SAM ", "0x7f"" 199", "code ", "Code ", "Data ", "ould ", " out ", " had ", "Coupe", "SAMCO", "SAMCo", "The ", "the ", "tion", " at ", "empt", "0x7f""199", "comp", "Comp", "cons", "Cons", "... ", " you", "'ll ", "ere ", "You ", " it ", ".) ", "n't", "ity", "At ", "199", "ing", "een", "and", "And", "ght", "mag", "pro", "oum", "ove", "age", " - ", "'m ", "'s ", "You", " I ", "ant", "ial", " ", " (", "er", ", ", " ", ". ", "! ", "? ", "A ", "or", "ss", "ee", "ch", "sh", "un", "ly", "th", "Th", "To", "to", "ow", "qu", "Qu", "Be", "be", "Up", "up", "Re", "re", "en", "En", "us", "Us", "ed", "oo", ".\"", "!\"", "?\"", "; ", ": ", ") ", "pe", "Pe", "ir", "Ir", "my", "pp", "I ", "dd", "ea", "ff", "ss", "it", "rr", "at", "At", "e ", "y ", "ic" }; char *tokens2[] = { "you'll", "ould", "ouse", "cons", "comp", "I'll", "entr", "ight", " ", "ent", "ing", "out", "ang", "cei", "ial", "ant", "mag", "pro", "age", "I'm", "'ll", "had", "n't", "ean", "eem", "ove", "I'd", "een", "all", "oup", "SAM", "the", "The", "dis", "key", "ave", "opy", "oil", "air", "eer", "ure", "ion", "vis", "ban", "mon", "hor", "ard", "ish", "nal", " ", ". ", ", ", "'s", "om", "sh", "ch", "ew", "ng", "ic", "tr", "cr", "it", "ff", "ss", "ee", "oo", "ou", "ie", "ei", "'m", "nt", "fl", "ph", "qu", "be", "up", "re", "en", "us", "ed", "to", "ow", "rr", "ea", "ar", "pe", "mu", "th", "Th", "ll", "ff", "In", "in", "pp", "my", "I ", "or", "on", "et", "sc", "ut", "ex", "ce", "ck", "at", "At", "A ", "a ", "It", "is", "Is", "su", "Co", "er", "de", "di", "bi", "ey", "sp", "go", "aw", "ay", "il", "op", "an", "oc", "id" }; unsigned char addrtab[PAGES*3]; /* page, lsb, msb */ struct dcpdata_s { int ver; int numpages; unsigned char *addrtab; }; int readdcp(struct dcpdata_s *d) { FILE *fd; unsigned char header[15]; if (!(fd = fopen(dcpname, "rb"))) { fprintf(stderr, "Can't open DCP file!\n"); return 1; } if (fread(header, 1, 15, fd) < 15) { fprintf(stderr, "read error\n"); fclose(fd); return 1; } if (!memcmp(magic1, header, 12)) { fprintf(stderr, "version 1.0/1.1 format detected\n"); d->ver = 1; d->numpages = header[12]; baseaddr = 38233; } else if (!memcmp(magic2, header, 14)) { fprintf(stderr, "version 1.2 format detected\n"); d->ver = 2; d->numpages = header[14]; baseaddr = 38300; } else { fprintf(stderr, "magic string not found\n"); fclose(fd); return 1; } /* title page is not included in the file's page count */ d->numpages++; if (d->numpages > PAGES) { fprintf(stderr, "too many pages\n"); fclose(fd); return 1; } if (fread(d->addrtab, 1, d->numpages*3, fd) < d->numpages*3) { fprintf(stderr, "read error\n"); fclose(fd); return 1; } if (magname) { fclose(fd); } else { /* jyn file */ jynfd = fd; } return 0; } void bufputc(unsigned char *buf, int *pos, unsigned char val) { buf[(*pos)++] = val; if (*pos >= 1500) { fwrite (buf, 1, *pos, stdout); *pos = 0; } } int dumpdata(FILE *fd, struct dcpdata_s *d, char **tokens, int limit) { unsigned char buf1[500]; unsigned char buf2[1500]; char *p; int n, m, s; int x, y; /* todo: limit output to one page */ m = s = x = y = 0; while (y < limit && fread(buf1, 1, 500, fd)) { for (n = 0; n<500; n++) { if (s) { int i; for (i = 0; i=64) { x = 0; y++; bufputc(buf2, &m, '\n'); } if (y == limit) { break; } } s = 0; } else if ((buf1[n] >= 32 && buf1[n] < 128) || buf1[n] == '\n') { if (buf1[n] == '`') { bufputc(buf2, &m, '£'); } else { bufputc(buf2, &m, buf1[n]); } if (buf1[n] == '\n') { x = 0; y++; } else if (++x>=64) { x = 0; y++; bufputc(buf2, &m, '\n'); } } else if (buf1[n] > 128) { for (p = tokens[buf1[n]-129]; *p; p++) { bufputc(buf2, &m, *p); if (++x >= 64) { x = 0; y++; bufputc(buf2, &m, '\n'); } if (y == limit) { break; } } } else if(buf1[n] == 128) { s = 1; } /* else { char tmp[10]; char *p; bufputc(buf2, &m, '<'); snprintf(tmp, 10, "%i", buf1[n]); tmp[10] = '\0'; for (p=tmp; *p; p++) { bufputc(buf2, &m, *p); } bufputc(buf2, &m, '>'); } */ if (y == limit) { break; } } } fwrite(buf2, 1, m, stdout); } int readmag(struct dcpdata_s *d) { FILE *fd; long offset; int page; char **tokens; if (d->ver == 1) { tokens = tokens1; } else { tokens = tokens2; } if (magname) { if (!(fd = fopen(magname, "rb"))) { fprintf(stderr, "can't open mag file\n"); return 1; } } else { /* jynfile */ fd = jynfd; baseaddr -= ftell(fd); } for (page = 0; page < d->numpages; page++) { if (page != 0) { printf("\n"); } printf("pg %i:\n\n", page); offset = (((unsigned long)d->addrtab[page * 3 + 0] << 14) | ((unsigned long)d->addrtab[page * 3 + 1]) | ((unsigned long)d->addrtab[page * 3 + 2] << 8)) + 16384 - baseaddr; fseek(fd, offset, SEEK_SET); dumpdata(fd, d, tokens, 21); } fclose(fd); return 0; } int main(int argc, char **argv) { struct dcpdata_s d; int i; if (argc != 2 && argc != 3) { fprintf(stderr, "usage: fredread DCPFILE [MAGFILE]\n"); return 1; } dcpname = argv[1]; if (argc == 3) { magname = argv[2]; } else { /* jyn file */ magname = NULL; } d.addrtab = addrtab; if ((i = readdcp(&d))) { return i; } return readmag(&d); }