/* ppdis.c, dhq, 06/17/2001.ra Mindless hack to disassemble CDC PP programs binary files. 04/09/2023 Updated for modern C and input from `.columntobytes tss.hex > tss.bytes` (prm) 06/24/2001 Added display code characters column to output. 06/17/2001 Initial adaption from a program by Francois Pinard */ #include #include #include #define FATAL 5 #define ASIGN 0400000 //char translated[64]; char bit24[64]={ /* 1 for 24 bit ops */ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 }; /* //int get_sixbits (arg1) */ /* //FILE *arg1; */ /* int get_sixbits (FILE *arg1) */ /* { */ /* static int accumulator; */ /* static int state = 0; */ /* int byte; */ /* int sixbit_byte; */ /* switch (state) */ /* { */ /* case 0: */ /* byte = fgetc (arg1); */ /* if (byte == EOF) */ /* return EOF; */ /* state = 1; */ /* sixbit_byte = (byte >> 2) & 0x3f; */ /* accumulator = byte & 3; */ /* break; */ /* case 1: */ /* byte = fgetc (arg1); */ /* if (byte == EOF) */ /* return EOF; */ /* state = 2; */ /* sixbit_byte = (accumulator << 4) | ((byte >> 4) & 0xf); */ /* accumulator = byte & 0xf; */ /* break; */ /* case 2: */ /* byte = fgetc (arg1); */ /* if (byte == EOF) */ /* return EOF; */ /* state = 3; */ /* sixbit_byte = (accumulator << 2) | ((byte >> 6) & 0x3); */ /* accumulator = byte & 0x3f; */ /* break; */ /* case 3: */ /* state = 0; */ /* sixbit_byte = accumulator; */ /* break; */ /* } */ /* return sixbit_byte; */ /* } */ int get_sixbits (FILE *arg1) { static int accumulator; static int state = 0; int byte1, byte2; int sixbit_byte; switch (state) { case 0: byte2 = fgetc (arg1); // little-endian: least significant byte if (byte2 == EOF) return EOF; byte1 = fgetc (arg1); // little-endian: most significant byte if (byte1 == EOF) return EOF; state = 1; sixbit_byte = (byte1 >> 2) & 0x3f; accumulator = (byte1 & 3) << 4 | ((byte2 >> 4) & 0x0f); break; case 1: state = 0; sixbit_byte = accumulator; break; } return sixbit_byte; } //main(argc,argv) // int argc; // char *argv[]; int main(int argc, char *argv[]) { int pp_byte, opHi, opLo, mHi, mLo; int i,wcnt/*,bcnt*/; long checksum; // char buffer1[21]; /* one byte longer than needed to include room for terminator byte */ // int buffer2[20]; FILE *arg1; FILE *arg2; char translated[65]; short pp, opword, opcode, d, m; long dm; if (argc < 1) // 2) { // fputs("Usage : ppdis . is the name of the file to disassemble.\n" // ,stderr); fputs("Usage : ppdis > . is the name of the file to disassemble.\n" ,stderr); exit(FATAL); } if (!(arg1=fopen(argv[1],"rb"))) { fputs("Error - the input file does not exist.\n",stderr); exit(FATAL); } //if (!(arg2=fopen(argv[2],"wb"))) // { // fputs("Error - you must specify the name of the output file.\n",stderr); // exit(FATAL); // } //bcnt = 0; wcnt = 0; // starting address 0 makes the data and jump addresses match up /* Had some stupid problem with the static char const version in this util. */ translated[0] = 0x00; strcat (translated, ":ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); strcat (translated, "+-*/()$= ,.#[]%"); strcat (translated, "\"_!&'?<>@\\^;"); translated[64] = 0x00; // for (i=0; i<154; i++) // pp_byte = get_sixbits (arg1); // pp_byte = get_sixbits (arg1); // opword = pp_byte << 6 | get_sixbits (arg1); // wcnt = opword + 5; //for (i=0; i<4; i++) // pp_byte = get_sixbits (arg1); /* for (i=0; i<154; i++) pp_byte = get_sixbits (arg1); wcnt = 16; */ while (pp_byte = get_sixbits (arg1), pp_byte != EOF) { printf ("%4o ", wcnt); opHi = pp_byte; opLo = get_sixbits (arg1); opword = opHi << 6 | opLo; ++wcnt; opcode = (opword >> 6) & 077; d = opword & 077; if (bit24[opcode]) { mHi = get_sixbits (arg1); mLo = get_sixbits (arg1); m = mHi << 6 | mLo; dm = (((long) d) << 12) | (m & 07777); printf ("%02o %02o %04o ", opcode, d, m); fputc(translated[opHi], stdout); fputc(translated[opLo], stdout); fputc(translated[mHi], stdout); fputc(translated[mLo], stdout); printf (" "); ++wcnt; } else { printf ("%02o %02o ", opcode, d); fputc(translated[opHi], stdout); fputc(translated[opLo], stdout); printf (" "); } switch (opcode) { case 000: /* pass */ case 024: case 025: printf ("PSN"); break; case 014: /* load d */ printf ("LDN %02oB", d); break; case 015: /* load complement d */ printf ("LCN %02oB", d); break; case 030: /* load (d) */ printf ("LDD %02oB", d); break; case 034: /* store (d) */ printf ("STD %02oB", d); break; case 040: /* load ((d)) */ printf ("LDI %02oB", d); break; case 044: /* store ((d)) */ printf ("STI %02oB", d); break; case 020: /* load dm */ printf ("LDC %06loB", dm); break; case 050: /* load (m+(d)) */ printf ("LDM %04oB,%02oB", m, d); break; case 054: /* store (m+(d)) */ printf ("STM %04oB,%02oB", m, d); break; case 016: /* add d */ printf ("ADN %02oB", d); break; case 017: /* subtract d */ printf ("SBN %02oB", d); break; case 031: /* add (d) */ printf ("ADD %02oB", d); break; case 032: /* subtract (d) */ printf ("SBD %02oB", d); break; case 041: /* add ((d)) */ printf ("ADI %02oB", d); break; case 042: /* subtract ((d)) */ printf ("SBI %02oB", d); break; case 021: /* add dm */ printf ("ADC %06loB", dm); break; case 051: /* add (m+(d)) */ printf ("ADM %04oB,%02oB", m, d); break; case 052: /* subtract (m+(d)) */ printf ("SBM %04oB,%02oB", m, d); break; case 010: /* shift d */ printf ("SHN %02oB", d); break; case 011: /* log diff d */ printf ("LMN %02oB", d); break; case 012: /* log prod d */ printf ("LPN %02oB", d); break; case 013: /* selective clear d */ printf ("SCN %02oB", d); break; case 033: /* log diff (d) */ printf ("LMD %02oB", d); break; case 043: /* log diff ((d)) */ printf ("LMI %02oB", d); break; case 022: /* log prod dm */ printf ("LPC %06loB", dm); break; case 023: /* log diff dm */ printf ("LMC %06loB", dm); break; case 053: /* log diff (m+(d)) */ printf ("LMM %04oB,%02oB", m, d); break; case 035: /* replace add (d) */ printf ("RAD %02oB", d); break; case 036: /* replace add one (d) */ printf ("AOD %02oB", d); break; case 037: /* replace subtract one (d) */ printf ("SOD %02oB", d); break; case 045: /* replace add ((d)) */ printf ("RAI %02oB", d); break; case 046: /* replace add one ((d)) */ printf ("AOI %02oB", d); break; case 047: /* replace subtract one ((d)) */ printf ("SOI %02oB", d); break; case 055: /* replace add (m+(d)) */ printf ("RAM %04oB,%02oB", m, d); break; case 056: /* replace add one (m+(d)) */ printf ("AOM %04oB,%02oB", m, d); break; case 057: /* replace subtract one (m+(d)) */ printf ("SOM %04oB,%02oB", m, d); break; case 003: /* unconditional jump d */ case003: printf ("UJN %02oB", d); break; case 004: /* zero jump d */ printf ("ZJN %02oB", d); break; case 005: /* nonzero jump d */ printf ("NJN %02oB", d); break; case 006: /* plus jump d */ printf ("PJN %02oB", d); break; case 007: /* minus jump d */ printf ("MJN %02oB", d); break; case 001: /* long jump m+(d) */ printf ("LJM %04oB,%02oB", m, d); break; case 002: /* return jump m+(d) */ printf ("RJM %04oB,%02oB", m, d); break; case 026: /* exchange jump */ printf ("EXN %02oB", d); break; case 027: /* read program address */ printf ("RPN %02oB", d); break; case 060: /* central read from (A) to d */ printf ("CRD %02oB", d); break; case 061: /* central read (d) words from (A) to m */ printf ("CRM %04oB,%02oB", m, d); break; case 062: /* central write to (A) from d */ printf ("CWD %02oB", d); break; case 063: /* central write (d) words to (A) from m */ printf ("CWM %04oB,%02oB", m, d); break; case 064: /* jump to m if channel d active */ printf ("AJM %04oB,%02oB", m, d); break; case 065: /* jump to m if channel d inactive */ printf ("IJM %04oB,%02oB", m, d); break; case 066: /* jump to m if channel d full */ printf ("FJM %04oB,%02oB", m, d); break; case 067: /* jump to m if channel d empty */ printf ("EJM %04oB,%02oB", m, d); break; case 070: /* input to A from channel d */ printf ("IAN %02oB", d); break; case 071: /* input (A) words to m from channel d */ printf ("IAM %04oB,%02oB", m, d); break; case 072: /* output from A to channel d */ printf ("OAN %02oB", d); break; case 073: /* output (A) words from m to channel d */ printf ("OAM %04oB,%02oB", m, d); break; case 074: /* activate channel d */ printf ("ACN %02oB", d); break; case 075: /* disconnect channel d */ printf ("DCN %02oB", d); break; case 076: /* function (A) on channel d */ printf ("FAN %02oB", d); break; case 077: /* function m on channel d */ printf ("FNC %04oB,%02oB", m, d); break; } /* end of opcode switch */ printf ("\n"); } fclose(arg1); }