#include void printvar(FILE *fp,char* s); int bcd2int(char *bcd); int bcd3int(char *bcd); void printstring(FILE *fp,char* s); void printchar(unsigned char c); void swap4(char a[4]); void swap2(char a[2]); main (int argc, char* argv[]) { FILE *fp; unsigned int lineno; unsigned short int sitmp; unsigned char linelen; int linestart,lineend,linect; int headerlen = 512; unsigned char opcode; char stmp[256]; /* temporary string */ unsigned char ctmp; /* temporary value */ int itmp; float ftmp; unsigned char slen; /* string length */ int i; if ((fp = fopen(argv[1],"r")) == NULL) { fprintf(stderr,"error opening file\n"); exit(1); } fseek(fp,512+32,SEEK_CUR); /* skip LIF headers + file header */ linect = 0; while (fread(&lineno,3,1,fp)) { lineno = bcd3int((char *) &lineno); fread(&linelen,1,1,fp); printf("line: %04d length: %03d filepos: %05d\n", lineno,linelen,ftell(fp)-4-headerlen); lineend = ftell(fp) + linelen; while (ftell(fp) < lineend) { opcode = fgetc(fp); switch (opcode) { case 0001: printvar(fp,"<\\001 fetch scalar variable>"); break; case 0002: printvar(fp,"<\\002 fetch array variable>"); break; case 0003: printvar(fp,"<\\003 fetch string variable>"); break; case 0004: /* 8 byte real number */ fread(&ftmp,8,1,fp); printf("<\\004 real>\n"); break; case 0005: printstring(fp,"<\\005 string>"); break; case 0006: printstring(fp,"<\\006 string>"); break; case 0007: printf("<\\007 store string variable?>\n"); break; case 0010: printf("<\\010 store numeric variable>\n"); break; case 0011: printf("<\\011 1d integer? array subscript>\n"); break; case 0012: printf("<\\012 2d integer? array subscript>\n"); break; case 0013: printf("<\\013 1d real? array subscript>\n"); break; case 0014: printf("<\\014 2d real? array subscript>\n"); break; case 0016: printf("<\\016 end line>\n"); linect++; break; case 0021: printvar(fp,"<\\021 fetch scalar variable address>"); break; case 0022: printvar(fp,"<\\022 fetch array variable address>"); break; case 0023: printvar(fp,"<\\023 fetch string variable address>"); break; case 0024: printf("<\\024 store numeric, multiple assignment?>\n"); break; case 0026: printvar(fp,"<\\026 FN call?>"); printf(" (number of arguments: %02d)\n",fgetc(fp)); break; case 0027: printvar(fp,"<\\027 FN call w/ integer parameter?>"); fread(&sitmp,2,1,fp); swap2((unsigned char*) &sitmp); printf("(parameter: %d)\n",sitmp); break; case 0030: printf("<\\030 GOTO line>"); fread(&itmp,3,1,fp); printf("%05d\n",bcd3int((unsigned char* )&itmp)); break; case 0032: printf("<\\032 integer>"); fread(&itmp,3,1,fp); itmp = bcd3int((char *) &itmp); printf("%d\n",itmp); break; case 0033: printf("<\\033 THEN>"); fread(&itmp,3,1,fp); itmp = bcd3int((char *) &itmp); printf("%d\n",itmp); break; case 0034: printf("<\\034 ELSE>"); fread(&itmp,3,1,fp); itmp = bcd3int((char *) &itmp); printf("%d\n",itmp); break; case 0041: printvar(fp,"<\\041 jump to string label?>"); break; case 0100: printf("<\\100 @ (statement separator)>\n"); break; case 0103: printf("<\\103 ON KEY#>\n"); break; case 0107: printf("<\\107 CLEAR>\n"); break; case 0126: printf("<\\126 DISP>\n"); break; case 0132: printf("<\\132 GOTO line>"); fread(&itmp,3,1,fp); printf("%05d\n",bcd3int((unsigned char* )&itmp)); break; case 0133: printf("<\\135 unknown GOTO line>"); fread(&itmp,3,1,fp); printf("%05d\n",bcd3int((unsigned char* )&itmp)); break; case 0137: printf("<\\137 INPUT>\n"); break; case 0153: printf("<\\153 PRINT>\n"); break; case 0207: printvar(fp,"<\\207 unknown variable command w/ integer parameter?>"); fread(&itmp,3,1,fp); printf("(second parameter: %05d\n",bcd3int((unsigned char* )&itmp)); opcode = fgetc(fp); if (opcode != 003) { printf("\\%03o unexpected parameter\n"); exit(1); } else { printstring(fp,"(third parameter:"); } break; case 0216: printf("<\\216 DISP USING>\n"); break; case 0257: printstring(fp,"<\\257 unknown immediate string?>"); break; case 0262: printvar(fp,"<\\262 unknown error command>"); break; case 0270: printvar(fp,"<\\270 unknown variable command>"); break; case 0300: printf("\\300 "); opcode = fgetc(fp); printf("\\%03o ",opcode); break; case 0347: printf("<\\347 unknown integer>"); fread(&itmp,3,1,fp); itmp = bcd3int((char *) &itmp); printf("%d\n",itmp); break; case 0350: printf("<\\350 input numeric from keyboard>\n"); break; case 0351: printf("<\\351 input string from keyboard>\n"); break; case 0363: printvar(fp,"<\\363 unknown variable command>"); break; case 0367: printf("\\367 "); opcode = fgetc(fp); printf("\\%03o ",opcode); break; case 0370: printf("\\370 "); opcode = fgetc(fp); switch (opcode) { case 0001: printf("\\001 "); opcode = fgetc(fp); switch (opcode) { case 0002: printf("\\002 "); break; default: fseek(fp,-1,SEEK_CUR); break; } break; case 0320: printf("\\320 "); opcode = fgetc(fp); printf("\\%03o ",opcode); break; default: fseek(fp,-1,SEEK_CUR); break; } break; case 0371: printf("\\371 "); opcode = fgetc(fp); switch (opcode) { case 0022: printf("\\022 "); opcode = fgetc(fp); printf("\\%03o ",opcode); break; case 0032: printf("\\032 "); opcode = fgetc(fp); printf("\\%03o ",opcode); break; default: fseek(fp,-1,SEEK_CUR); break; } break; default: printchar(opcode); break; } } fseek(fp,lineend,SEEK_SET); /* recover from parse error */ printf("\n"); if (lineno == 109999) { break; } } printf("linect: %d\n",linect); } void printchar(unsigned char c) { if ((c > 32) && (c < 127)) { printf("%c ",c); } else { printf("\\%03o ",c); } } int bcd1int(unsigned char *bcd) { return (((bcd[0] & 0xf0) >> 4) * 10 + (bcd[0] & 0x0f)); } int bcd2int(char *bcd) { return (((bcd[0] & 0xf0) >> 4) * 10 + (bcd[0] & 0x0f) + ((bcd[1] & 0xf0) >> 4) * 1000 + (bcd[1] & 0x0f) * 100); } int bcd3int(char *bcd) { return (//((bcd[0] & 0xf0) >> 4) * 10 + (bcd[0] & 0x0f) *10000 + ((bcd[1] & 0xf0) >> 4) * 1000 + (bcd[1] & 0x0f) * 100 + ((bcd[2] & 0xf0) >> 4) * 10 + (bcd[2] & 0x0f) ); } void printvar(FILE *fp,char *s) { unsigned int slen; /* variable length */ char stmp[256]; fread(&slen,4,1,fp); swap4((char *) &slen); if (slen > 255) { printf("%s",s); printf(" ***bogus string length: %d\n",slen); exit(1); } fread(stmp,slen,1,fp); stmp[slen] = '\0'; printf("%s`%s'\n",s,stmp); } void printstring(FILE *fp,char* s) { int slen; char stmp[256]; slen = fgetc(fp); fread(stmp,slen,1,fp); stmp[slen] = '\0'; printf("%s`%s'\n",s,stmp); } void swap2(char a[2]) { char tmp; tmp = a[0]; a[0] = a[1]; a[1] = tmp; } void swap4(char a[4]) { char tmp; tmp = a[0]; a[0] = a[3]; a[3] = tmp; tmp = a[1]; a[1] = a[2]; a[2] = tmp; }