/************************************************************************* Copyright (c) 1984 by Nick de Smith This software is supplied for interest and non-profit making purposes only. Under no circumstance shall it be lent, copied or otherwise used for profit. All rights regarding the use and ownership of this software shall at all times remain with the author, who does not guarantee the accuracy or reliabilty of this software and who will not accept any liability for its use. This software may not be copied or distributed without the inclusion of the above copyright notice. January 31st 1984 *************************************************************************/ /************************************************************************* Program : CAM Module : CAM.C (the root) Author : Nick de Smith November/December 1982 Description : Root file of the object module disassembler. This module handles all the command parsing and dispatch to the real code. *************************************************************************/ #define MAIN /* Force once only code in CAM.H*/ #include #include "cam.h" #include "camtbl.h" /************************************************************************* * * * m a i n * ------- * * Only entry point to the object module dis-assembler. This * routine called by run-time support $$main. * * The technique used to enable/disable certain features is rather * nasty as it involves explicitly patching the drive tables. At * some later date/in a later version I will include a neat routine * to auto-patch the tables. Maybe "table(0nnnnnn, "inst", new_type)". * *************************************************************************/ global main(argc, argv) char *argv[]; { register int i,c; register char *p, *o; file = NULL; o = option; for (i = 1; i < argc; ++i) { p = argv[i]; #ifdef c_vms if (*p == '-' || *p == '/') { p++; #else if (*p++ == '-') { #endif while (c = *p++) { switch (*o++ = isupper(c) ? tolower(c) : c) { case 'a': /* Disable output of */ /* absolute global defs */ abs_g = FALSE; break; case 'b': /* All binary is to be */ /* .byte/.word types */ b_flag = TRUE; break; case 'c': /* Disable code output */ code = FALSE; break; case 'd': /* Enable debug mode */ debug = TRUE; break; case 'i': /* Ignore load address */ /* mismatches (YUK) */ i_flag = TRUE; break; case 'l': /* Disable line numbers */ lines = FALSE; break; case 'n': /* Resolve numbers in */ /* an STB (not yet!) */ numbers = TRUE; break; case 'o': /* Disable octal output */ octal = FALSE; break; case 'p': /* Enable psect table */ psect_f = TRUE; break; case 'q': /* Output psect defns. */ q_flag = TRUE; break; case 'r': /* Disable output of */ /* referenced globals */ ref_g = FALSE; break; case 's': /* Output sorted abs */ /* global definitions */ sort_g = TRUE; break; case 't': /* Disable ascii output */ ascii = FALSE; break; /* Table patch options */ case 'e': /* Use RSX not RSTS emts*/ x104[0].t_flags = T_END | T_NNN; x104[0].t_next = emtext; x10437[7].t_next = "dir$"; break; case 'f': /* Disable floating pt. */ x1[7].t_flags = T_END | T_NNNNNN; x1[7].t_next = word; break; case 'k': /* Disable kernal opcodes */ /* halt */ x00000[0].t_flags = T_END | T_NNNNNN; x00000[0].t_next = word; /* wait */ x00000[1].t_flags = T_END | T_NNNNNN; x00000[1].t_next = word; /* reset */ x00000[5].t_flags = T_END | T_NNNNNN; x00000[5].t_next = word; /* mfpt */ x00000[7].t_flags = T_END | T_NNNNNN; x00000[7].t_next = word; /* mfpi */ x006[5].t_flags = T_END | T_NNNNNN; x006[5].t_next = word; /* mtpi */ x006[6].t_flags = T_END | T_NNNNNN; x006[6].t_next = word; /* mtps */ x106[4].t_flags = T_END | T_NNNNNN; x106[4].t_next = word; /* mfpd */ x106[5].t_flags = T_END | T_NNNNNN; x106[5].t_next = word; /* mtpd */ x106[6].t_flags = T_END | T_NNNNNN; x106[6].t_next = word; /* mfps */ x106[7].t_flags = T_END | T_NNNNNN; x106[7].t_next = word; break; case 'm': /* Disable 'macros' */ /* change PUSH/POP to MOV */ x0[1].t_flags = T_END | T_SSDD; x0[1].t_next = "mov"; /* change PUSH to CLR -(SP) */ x005[0].t_flags = T_END | T_SS; x005[0].t_next = "clr"; /* change POP to TST (SP)+ */ x005[7].t_flags = T_END | T_SS; x005[7].t_next = "tst"; /* change CALL to JSR */ x00[4].t_flags = T_END | T_RDD; x00[4].t_next = "jsr"; /* change RETURN to RTS */ x0002[0].t_flags= T_END | T_R; x0002[0].t_next = "rts"; /* change JMP/JMPX to JMP */ x000[1].t_flags = T_END | T_SS; break; default: usage(); } } } else if (file) usage(); else file = argv[i]; } if (!file) usage(); disassemble(file); } /************************************************************************* * * * d i s a s s e m b l e * --------------------- * * Dis-assemble the named file. * *************************************************************************/ local disassemble(file_) char *file_; { open(file_); pass_1(); /* Pre-pass for globals/psects */ pass_2(); /* Build local symbol tables */ pass_3(); /* Output code/data */ close(); } /************************************************************************* * * * o p e n * ------- * * Open the named file for input. * *************************************************************************/ local open(file_) char *file_; { dbg("Opening \"%s\"\n", file_); if (!(ip = fopen(file_, "ru"))) error("Failed to open \"%s\"", file_); } /************************************************************************* * * * c l o s e * --------- * * Close the input file. * *************************************************************************/ local close() { dbg("Closing input stream\n"); if (fclose(ip)) bug("Failed to close input stream"); } /************************************************************************* * * * u s a g e * --------- * * How to luse this utility. Give yourself ten points if you can * remember what all the options do (I can't). * *************************************************************************/ local usage() { fprintf(stderr, "Usage: cam file.typ -stealfromnickpbdq"); exit(1); }