/* * dasm.c * * (C) Copyright 2003 by Robert Krten, all rights reserved. * Please see the LICENSE file for more information. * * This module contains the PDP-8 disassembler. * Note that the 8/I and 8/L are featured at this point; other models * should be added (particularly the 8/E's EAE instructions, as well * as new IOT decodings, etc) * * 2003 12 16 R. Krten created */ #include #include #include #include #include #include "iot.h" // decode table for IOTs extern char *progname; // main.c extern char *version; // version.c extern int optv; // main.c /* * dasm8 * * This takes the current address and the instruction value * and prints the decoded instruction. A static variable * is used to kludge up 2-word instructions (e.g., MUY ). * * The IOTs are coded in a table; in some cases, conflicts exist, you'll * need to select the appropriate #defines to make them go away :-) * As shipped, the #defines match my preferences. */ static const char *codes [8] = {"AND", "TAD", "ISZ", "DCA", "JMS", "JMP", "IOT", "OPR"}; static unsigned short int two_word = 0; // set to hold two-word instruction, else zero (instruction 0 is not a two-word instruction) void dasm8 (int addr, unsigned short int buf) { int indirect; int curpage; // calculate the indirect and curpage flags; only valid for instructions 0000 -> 05777 indirect = buf & 00400; curpage = buf & 00200; if (two_word) { printf ("%04o\n", buf); two_word = 0; return; } printf ("%04o, %04o ", addr, buf); switch (buf & 07000) { case 00000: // AND case 01000: // TAD case 02000: // ISZ case 03000: // DCA case 04000: // JMS case 05000: // JMP printf (" %-4s %c%c %04o\n", codes [buf >> 9], indirect ? 'I' : ' ', curpage ? ' ' : 'Z', curpage ? (addr & 07600) + (buf & 00177) : buf & 00177); break; case 06000: // IOT printf (" %-4s\n", iots [buf & 00777]); break; case 07000: // OPR // perform "short form" OPRs here first... // switch/case the few that exist... switch (buf) { case 07000: printf (" NOP\n"); break; case 07041: printf (" CIA\n"); break; case 07120: printf (" STL\n"); break; case 07204: printf (" GLK\n"); break; case 07240: printf (" STA\n"); break; case 07410: printf (" SKP\n"); break; case 07604: printf (" LAS\n"); break; case 07621: printf (" CAM\n"); break; default: // determine group (0401 is 0000/0001 for group 1, 0400 for group 2, 0401 for EAE) switch (buf & 00401) { case 00000: // group 1 case 00001: // group 1 printf (" "); // sequence 1 if (buf & 00200) { printf ("CLA "); } if (buf & 00100) { printf ("CLL "); } // sequence 2 if (buf & 00040) { printf ("CMA "); } if (buf & 00020) { printf ("CML "); } // sequence 3 if (buf & 00001) { printf ("IAC "); } // sequence 4 if (buf & 00010) { if (buf & 00002) { printf ("RTR "); } else { printf ("RAR "); } } if (buf & 00004) { if (buf & 00002) { printf ("RTL "); } else { printf ("RAL "); } } printf ("\n"); break; case 00400: // group 2 printf (" "); // sequence 1 if (buf & 00100) { if (buf & 00010) { printf ("SPA "); } else { printf ("SMA "); } } if (buf & 00040) { if (buf & 00010) { printf ("SNA "); } else { printf ("SZA "); } } if (buf & 00020) { if (buf & 00010) { printf ("SZL "); } else { printf ("SNL "); } } // sequence 2 if (buf & 00200) { printf ("CLA "); } // sequence 3 if (buf & 00004) { printf ("OSR "); } if (buf & 00002) { printf ("HLT "); } printf ("\n"); break; case 00401: // EAE printf (" "); // sequence 1 if (buf & 00200) { printf ("CLA "); } // sequence 2 if (buf & 00100) { printf ("MQA "); } if (buf & 00040) { printf ("SCA "); } if (buf & 00020) { printf ("MQL "); } // sequence 3 switch (buf & 00016) { case 0: // no further ops, done printf ("\n"); break; case 002: printf ("SCL "); two_word = buf; break; case 004: printf ("MUY "); two_word = buf; break; case 006: printf ("DVI "); two_word = buf; break; case 010: printf ("NMI\n"); break; case 012: printf ("SHL "); two_word = buf; break; case 014: printf ("ASR "); two_word = buf; break; case 016: printf ("LSR "); two_word = buf; break; } break; } break; } break; } }