From ebab9328f6395ffee30642cfa7ed3d63ec6de4ea Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 11 Mar 2018 23:56:36 -0400 Subject: [PATCH] CR -> LF conversion. --- DumpOBJ.cc | 2767 ++++++++++++++++++++++++++++++++++++++++++++++++++- doit | 3 +- dumpobj.rez | 23 +- make | 30 +- 4 files changed, 2819 insertions(+), 4 deletions(-) mode change 100755 => 100644 DumpOBJ.cc mode change 100755 => 100644 doit mode change 100755 => 100644 dumpobj.rez mode change 100755 => 100644 make diff --git a/DumpOBJ.cc b/DumpOBJ.cc old mode 100755 new mode 100644 index 481f32a..50c6a87 --- a/DumpOBJ.cc +++ b/DumpOBJ.cc @@ -1 +1,2766 @@ -/************************************************************** * * DumpOBJ 2.0 * * By Phil Montoya * Translation to ORCA/C & 2.0 enhancements by Mike Westerfield. * * DumpOBJ 1.1 Copyright November 1986-88 * By the Byte Works, Inc. * * DumpOBJ 2.0 Copyright 1991 * Byte Works, Inc. * **************************************************************** * * Version 2.0.1, 7 July 94 * Mike Westerfield * * 1. Added resource fork. * ****************************************************************/ #pragma keep "DumpOBJ" #pragma optimize 9 /* GS specific declarations */ /*--------------------------*/ extern pascal void PDosInt(); int toolerror(void); #define WRITE_CONSOLE(parm) (PDosInt(0x015A,parm)) #define GetFileInfoGS(pBlockPtr) PDosInt(0x2006,pBlockPtr) #pragma lint -1 /* Standard C Libraries */ /*----------------------*/ #include #include #include #include /* Constants */ /*-----------*/ #define BOOLEAN int /* boolean variables */ #define TRUE 1 #define FALSE 0 #define FILEMAX 1024 /* max length of file name */ #define NAMEMAX 512 /* maximum size of variable len name */ #define NAMESIZE 11 /* size of label name */ #define OBJFL 177 /* minimum object file type */ #define MAXFL 190 /* maximum object file type */ #define LIBFL 178 /* library file type */ #define BLKSIZE 512 /* size of block */ #define COP 2 /* COP opcode */ #define REP 194 /* REP opcode */ #define SEP 226 /* SEP opcode */ /* Object File Opcodes */ /*---------------------*/ #define OPALIGN 224 /* align to a boundry */ #define OPORG 225 /* set code origin */ #define OPRELOC 226 /* relocation entry */ #define OPINTSEG 227 /* inserseg record */ #define OPUSING 228 /* use data area */ #define OPSTRONG 229 /* force segment inclusion */ #define OPGLOBAL 230 /* define global label */ #define OPGEQU 231 /* define global constant */ #define OPMEM 232 /* reserve absolute memory */ #define OPEXPR 235 /* computed value */ #define OPZEXPR 236 /* computed zero page value */ #define OPBEXPR 237 /* computed local bank value */ #define OPRELEXPR 238 /* computed relative ofset */ #define OPLOCAL 239 /* define local label */ #define OPEQU 240 /* define local constant */ #define OPDS 241 /* define storage */ #define OPLONG 242 /* long constant > $DF bytes */ #define OPLEXPR 243 /* outer segment expression */ #define OPENTRY 244 /* run time lib entry dictionary */ #define OPSRELOC 245 /* short relocation entry */ #define OPSINTSEG 246 /* short interseg entry */ #define OPSUPER 247 /* super compressed records */ /* Program variables */ /*-------------------*/ char fname[FILEMAX]; /* input file name buffer */ char nlist[NAMEMAX]; /* names list */ char symbol[NAMEMAX]; /* symbol name buffer */ BOOLEAN names; /* names list flag */ BOOLEAN sTable; /* found a COP symbol table? */ int act_lablen; /* actual length of label read */ int status; /* shell return status */ int namc; /* name argument counter */ int ftype; /* current file type */ long blocks; /* used to get to next segment */ long constant; /* constant byte counter and flag */ long opcode; /* opcode storage */ long segmark; /* start of segment marker */ long count; /* file counter */ long number; /* number read variable */ long pc; /* segment program counter */ long tkind; /* type of node for tree */ long *root; /* root pointer for expression tree */ FILE *input; /* input file */ /* Output Control Settings */ /*-------------------------*/ int format; /* format of output 0 opcode dump 1 dissassembly dump 2 hex dump */ BOOLEAN shorth; /* print short headers? */ BOOLEAN ireg; /* long index registers? */ BOOLEAN mreg; /* long accumulator? */ BOOLEAN longc; /* print long constants? */ BOOLEAN header; /* print segment headers? */ BOOLEAN body; /* print segment bodies? */ BOOLEAN checkf; /* check file types? */ BOOLEAN colf; /* print displacement numbers? */ /* Object Module Header */ /*----------------------*/ int kind; /* kind of segment */ long blkcnt; /* number of block in segment */ long resspc; /* reserved space at end of segment */ long length; /* length of finished segment */ int kind1; /* this is kind for version 1 */ int lablen; /* label length */ int numlen; /* number length */ int version; /* version number */ long banksize; /* banksize */ int kind2; /* this is kind for version 2 */ int unused; /* undefined field */ long pgorg; /* program org */ long align; /* alignment factor */ int numsex; /* significance of numbers */ int lang_card; /* language card */ int segnum; /* segment number */ long ent_disp; /* disp to beg of segment */ int nam_disp; /* displacment to names */ int bod_disp; /* displacment to body */ char loadname[NAMESIZE]; /* load file name */ char segname[NAMEMAX]; /* segment name */ /* Opcode arrays */ /*---------------*/ char opKind[] = {5,8,5,14,2,2,2,13,5,1,4,5,2,2,2,3, 17,6,12,15,2,9,9,7,5,10,4,5,2,9,9,11, 2,8,2,14,2,2,2,13,5,1,4,5,2,2,2,3, 17,6,12,15,9,9,9,7,5,10,4,5,9,9,9,11, 5,8,5,14,16,2,2,13,5,1,4,5,2,2,2,3, 17,6,12,15,16,9,9,7,5,10,5,5,3,9,9,11, 5,8,5,14,2,2,2,13,5,1,4,5,12,2,2,3, 17,6,12,15,9,9,9,7,5,10,5,5,8,9,9,11, 17,8,17,14,2,2,2,13,5,1,5,5,2,2,2,3, 17,6,12,15,9,9,10,7,5,10,5,5,2,9,9,11, 1,8,1,14,2,2,2,13,5,1,5,5,2,2,2,3, 17,6,12,15,9,9,10,7,5,10,5,5,9,9,10,11, 1,8,1,14,2,2,2,13,5,1,5,5,2,2,2,3, 17,6,12,15,5,9,9,7,5,10,5,5,12,9,9,11, 1,8,1,14,2,2,2,13,5,1,5,5,2,2,2,3, 17,6,12,15,5,9,9,7,5,10,5,5,8,9,9,11}; char opLen[] = {1,1,1,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, 2,1,3,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, 0,1,0,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,3,2,2,3, 0,1,2,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, 1,1,2,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, 5,1,5,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, 5,1,1,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, 5,1,1,1,1,1,1,1,0,4,0,0,2,2,2,3, 1,1,1,1,2,1,1,1,0,2,0,0,2,2,2,3}; char opName[] = "BRKORACOPORATSBORAASLORAPHPORAASLPHDTSBORAASLORA" "BPLORAORAORATRBORAASLORACLCORAINCTCSTRBORAASLORA" "JSRANDJSLANDBITANDROLANDPLPANDROLPLDBITANDROLAND" "BMIANDANDANDBITANDROLANDSECANDDECTSCBITANDROLAND" "RTIEORWDMEORMVPEORLSREORPHAEORLSRPHKJMPEORLSREOR" "BVCEOREOREORMVNEORLSREORCLIEORPHYTCDJMPEORLSREOR" "RTSADCPERADCSTZADCRORADCPLAADCRORRTLJMPADCRORADC" "BVSADCADCADCSTZADCRORADCSEIADCPLYTDCJMPADCRORADC" "BRASTABRLSTASTYSTASTXSTADEYBITTXAPHBSTYSTASTXSTA" "BCCSTASTASTASTYSTASTXSTATYASTATXSTXYSTZSTASTZSTA" "LDYLDALDXLDALDYLDALDXLDATAYLDATAXPLBLDYLDALDXLDA" "BCSLDALDALDALDYLDALDXLDACLVLDATSXTYXLDYLDALDXLDA" "CPYCMPREPCMPCPYCMPDECCMPINYCMPDEXWAICPYCMPDECCMP" "BNECMPCMPCMPPEICMPDECCMPCLDCMPPHXSTPJMLCMPDECCMP" "CPXSBCSEPSBCCPXSBCINCSBCINXSBCNOPXBACPXSBCINCSBC" "BEQSBCSBCSBCPEASBCINCSBCSEDSBCPLXXCEJSRSBCINCSBC"; /**** Utility Subroutines *****************************************/ /*************************************************************** * * fgeti - read an integer from the file * * Inputs: * f - file to read from * * Outputs: * Returns integer read * ***************************************************************/ int fgeti (FILE *f) { return fgetc(f) | (fgetc(f) << 8); } /*************************************************************** * * Error - Writes out an error * ***************************************************************/ void Error (int errnum, char *str) { status = -1; switch (errnum) { case 1: fputs("Format type not supported", stderr); break; case 2: fputs("Could not read segment header", stderr); break; case 3: fputs("Segment version not supported", stderr); break; case 4: fputs("Bad input ", stderr); break; case 5: fputs("Could not open file ", stderr); break; case 6: fputs("Not an object file ", stderr); break; case 7: fputs("Unknown Opcode", stderr); break; case 8: fputs("Illegal header entry", stderr); break; case 9: fputs("End of file encountered", stderr); default: break; } if (str[0] != ' ') fputs(str, stderr); fputc('\n', stderr); } /*************************************************************** * * CheckESC - Checks to see if 'escape' is pressed * * Notes: Returns to shell if open-apple period has been pressed. * ***************************************************************/ void CheckESC (void) { char *keyboard; char *strobe; char *flags; struct { int pcount; char ch; } parm; keyboard = (void *) 0x00C000; strobe = (void *) 0x00C010; flags = (void *) 0x00C025; if (*keyboard & 0x80) { if ((*keyboard & 0x7F) == '.') if (*flags & 0x80) { *strobe = (char) 0; exit(-1); } *strobe = (char) 0; parm.pcount = 1; parm.ch = (char) 27; WRITE_CONSOLE(&parm); parm.ch = (char) 15; WRITE_CONSOLE(&parm); parm.ch = (char) 0x43; WRITE_CONSOLE(&parm); parm.ch = (char) 24; WRITE_CONSOLE(&parm); parm.ch = (char) 14; WRITE_CONSOLE(&parm); parm.ch = (char) 8; WRITE_CONSOLE(&parm); while (! (*keyboard & 0x80)) ; parm.ch = (char) 32; WRITE_CONSOLE(&parm); parm.ch = (char) 8; WRITE_CONSOLE(&parm); if ((*keyboard & 0x7F) == '.') if (*flags & 0x80) { *strobe = (char) 0; exit(-1); } *strobe = (char) 0; } } /**** Segment I/O Subroutines *************************************/ /*************************************************************** * * Checks and updates output header information. * * Returns: * TRUE - if header OK. * FALSE - if header not OK and flags error. * ****************************************************************/ BOOLEAN CheckHead (void) { long talign; if ((version != 1) && (version != 2)) { Error(3," "); return FALSE; } if ((lablen > 256) || (numlen > 4) || (numlen < 1)) { Error(8," "); return FALSE; } if (align) { /* insure only 1 bit set in alignment */ talign = align; while (! (talign & 1)) talign = talign >> 1; if (talign != 1) { Error(8," "); return FALSE; } } return TRUE; } /*************************************************************** * * GetEOF - Returns The End of File Marker * * Returns: mark or -1 if error * ***************************************************************/ long GetEOF (FILE *f) { long mark, pos; pos = ftell(f); if (pos == -1) return -1; if (fseek(f, -1, SEEK_END)) return -1; mark = ftell(f)+1; if (pos == -1) return -1; if (fseek(f, pos, SEEK_SET)) return -1; return mark; } /*************************************************************** * * GetHead - Reads In The Segment Header * * Inputs: * f - file to read the header from * ***************************************************************/ int GetHead (FILE *f) { struct { long blkcnt, resspc, length; char kind1, lablen, numlen, version; long banksize; int kind2, unused; long pgorg, align; char numsex, lang_card; int segnum; long ent_disp; int nam_disp, bod_disp; } header; int i, disp, len; fseek(f, 0, SEEK_CUR); /* read the common parts of the header */ if (fread(&header, sizeof(header), 1, f) != 1) return -1; blkcnt = header.blkcnt; resspc = header.resspc; length = header.length; kind1 = header.kind1; lablen = header.lablen; numlen = header.numlen; version = header.version; banksize = header.banksize; kind2 = header.kind2; unused = header.unused; pgorg = header.pgorg; align = header.align; numsex = header.numsex; lang_card = header.lang_card; segnum = header.segnum; ent_disp = header.ent_disp; nam_disp = header.nam_disp; bod_disp = header.bod_disp; disp = nam_disp-sizeof(header); /* skip any extra stuff */ if (disp) for (i = 0; i < disp; ++i) fgetc(f); for (i = 0; i < 10; ++i) /* read the load segment name */ loadname[i] = fgetc(f); loadname[10] = (char) 0; len = fgetc(f); /* read the code segment name */ for (i = 0; i < len; ++i) segname[i] = fgetc(f); segname[len] = (char) 0; if (version == 2) /* set the kind field */ kind = kind2; else kind = kind1; return 0; } /*************************************************************** * * IsInList - Checks to see if segment is in names list * ***************************************************************/ BOOLEAN IsInList (void) { int len, chpos; if (! names) return TRUE; len = chpos = 0; /* get length of segment name */ while (isalnum(segname[len]) || (segname[len] == '~') || (segname[len] == '_')) len++; while (nlist[chpos]) { /* see if name matches a list name */ while (nlist[chpos] == ' ') chpos++; if ((! strncmp(segname,nlist+chpos,len)) && ((nlist[chpos+len] == ' ') || (! nlist[chpos+len]))) return TRUE; while ((nlist[chpos]) && (nlist[chpos] != ' ')) chpos++; } return FALSE; } /*************************************************************** * * NextSeg - Returns the next segment * * Output: * positions file marker at next segment 0 if at end of file * ***************************************************************/ BOOLEAN NextSeg(void) { if ((format == 2) || ((format == 1) && !header && !checkf)) { numsex = 0; return TRUE; } do { if ((ftype == LIBFL) || (version == 2)) { if (fseek(input, segmark + blocks, SEEK_SET)) return FALSE; } else { if (fseek(input,segmark + (blocks * BLKSIZE), SEEK_SET)) return FALSE; } segmark = ftell(input); /* set next segment marker */ if (segmark >= (GetEOF(input))) return FALSE; GetHead(input); blocks = blkcnt; if (! blocks) return FALSE; fseek(input, segmark, SEEK_SET); } while (! IsInList()); /* check to see if in names list */ return TRUE; } /*************************************************************** * * PutComment - Writes a comment line if colf is not active * ***************************************************************/ void PutComment (void) { if (! colf) printf("! "); } /*************************************************************** * * PutKind - Writes out the kind in name format * ***************************************************************/ void PutKind (int kind) { if (version == 1) { if (kind & 128) printf("dynamic "); else printf("static "); if (kind & 64) printf("private "); if (kind & 32) printf("position independent "); } else { if (kind & 32768) printf("dynamic "); else printf("static "); if (kind & 16384) printf("private "); if (kind & 8192) printf("position independent "); if (kind & 4096) printf("no special memory "); if (kind & 2048) printf("absolute bank "); if (kind & 1024) printf("reload "); } switch(kind & 31) { case 0: printf("code segment"); break; case 1: printf("data segment"); break; case 2: printf("jump table segment"); break; case 4: printf("pathname segment"); break; case 8: printf("library dictionary segment"); break; case 16: printf("initialization segment"); break; case 17: printf("absolute bank segment"); break; case 18: printf("direct page/stack segment"); break; default: printf("unknown segment: $04X", kind); } } /*************************************************************** * * PutHeader - Writes Out The Header * * Returns: FALSE if an error was found, else TRUE. * ***************************************************************/ BOOLEAN PutHeader (void) { long mark; int kind2; mark = ftell(input); /* save the file marker */ if (GetHead(input)) { Error(2," "); return FALSE; } if ((checkf) && ((version != 1) && (version != 2))) { Error(3," "); return FALSE; } blocks = blkcnt; /* set the new block counter */ if (! header) /* split on write/don't write header */ fseek(input,mark,SEEK_SET); else { count = ftell(input) - mark; /* set the file counter */ if (shorth) { /* split on short or long header */ PutComment(); printf("%s (", segname); PutKind(kind); printf(")\n"); return CheckHead(); } else { /* print the full header */ PutComment(); /* write block count */ if (version == 2) printf("Byte count : $%08lX%14ld\n", blkcnt, blkcnt); else printf("Block count : $%08lX%14ld\n", blkcnt, blkcnt); CheckESC(); PutComment(); /* write reserved space */ printf("Reserved space: $%08lX%14ld\n", resspc, resspc); CheckESC(); PutComment(); /* write segment length */ printf("Length : $%08lX%14ld\n", length, length); CheckESC(); PutComment(); /* write label length */ printf("Label length : $%02X%20d\n", lablen, lablen); CheckESC(); PutComment(); /* write number length */ printf("Number length : $%02X%20d\n", numlen, numlen); CheckESC(); PutComment(); /* write segment version */ printf("Version : $%02X%20d\n", version, version); CheckESC(); PutComment(); /* write bank size */ printf("Bank size : $%08lX%14ld\n", banksize, banksize); CheckESC(); PutComment(); /* write segment kind */ if (version == 2) { printf("Kind : $%04X%18d (", kind, kind); kind2 = kind; } else { printf("Kind : $%02X%20d (", kind, kind); kind2 = ((kind & 0xE0) << 8) | (kind & 0x1F); } switch (kind & 0x001F) { case 0x00: printf("code"); break; case 0x01: printf("data"); break; case 0x02: printf("jump table"); break; case 0x04: printf("pathname"); break; case 0x08: printf("library"); break; case 0x10: printf("initialization"); break; case 0x11: printf("absolute bank"); break; case 0x12: printf("direct-page/stack"); break; default: printf("unknown"); break; } if (kind & 0x8000) printf(",dynamic"); else printf(",static"); if (kind & 0x4000) printf(",private"); if (kind & 0x2000) printf(",position independent"); if (kind & 0x1000) printf(",no special memory"); if (kind & 0x0800) printf(",absolute bank"); if (kind & 0x0400) printf(",reload"); if (kind & 0x0200) printf(",skip"); if (kind & 0x0100) printf(",bank relative"); printf(")\n"); CheckESC(); PutComment(); /* write segment org */ printf("Org : $%08lX%14ld\n", pgorg, pgorg); CheckESC(); PutComment(); /* write alignment factor */ printf("Alignment : $%08lX%14ld\n", align, align); CheckESC(); PutComment(); /* write number sex */ printf("Number sex : $%02X%20d\n", numsex, numsex); CheckESC(); if (version == 1) { /* write language card */ PutComment(); printf("Language card : $%02X%20d\n", lang_card, lang_card); CheckESC(); } PutComment(); /* write segment number */ printf("Segment number: $%04X%18d\n", segnum, segnum); CheckESC(); PutComment(); /* write segment entry */ printf("Segment entry : $%08lX%14ld\n", ent_disp, ent_disp); CheckESC(); PutComment(); /* write segment names disp */ printf("Disp to names : $%04X%18d\n", nam_disp, nam_disp); CheckESC(); PutComment(); /* write segment body disp */ printf("Disp to body : $%04X%18d\n", bod_disp, bod_disp); CheckESC(); if (! CheckHead()) /* don't print labels if header error */ return FALSE; PutComment(); /* write load name */ printf("Load name : %s\n", loadname); CheckESC(); PutComment(); /* write segment name */ printf("Segment name : %s\n", segname); CheckESC(); } } return TRUE; } /**** Opcode Dump Subroutines *************************************/ void DoExpr (void); /*************************************************************** * * Reads the opcode into "opcode" * ***************************************************************/ int GetOpCode (void) { ++count; /* advance byte counter */ opcode = fgetc(input); if (opcode == -1) { /* check for end of file */ opcode = 0; Error(9," "); /* end of file encountered */ exit(status); } return opcode; } /*************************************************************** * * NewLine - Issues a Formatted New Line * ***************************************************************/ void NewLine (void) { int count; putchar('\n'); if (colf) count = 33; else count = 17; while (count--) putchar(' '); } /*************************************************************** * * ReadInt - reads an integer * * Inputs: * numsex - number sex * input - reference number of file * numlen - length of number * nPtr - pointer to place result * ***************************************************************/ void ReadInt (long *nPtr, int numlen, FILE *f, int numsex) { int i; long k,n; union { char c[4]; long l; } u; if (numlen <= 4) { u.l = 0; for (i = 0; i < numlen; ++i) u.c[i] = fgetc(f); *nPtr = u.l; if (numsex) { n = *nPtr; for (i = 0; i < 4; ++i) { k = (k << 8) | (n && 0xFF); n = n >> 8; } *nPtr = k; } } } /*************************************************************** * * ReadName - reads in a symbol name * * Inputs: * name - pointer to place the name * lablen - length of name * f - open file ref number * ***************************************************************/ void ReadName (char *name, int lablen, FILE *f) { int i; if (lablen) /* get the label length */ act_lablen = lablen; else act_lablen = fgetc(f); for (i = 0; i < act_lablen; ++i) /* read the name */ name[i] = fgetc(f); name[act_lablen] = (char) 0; /* set the null terminator */ } /*************************************************************** * * PrintW - Writes a word in a string to the console * * Inputs: * str - pointer to the string to write * ***************************************************************/ void PrintW (char *str) { int i = 0; while ((str[i]) && (! isspace(str[i]))) putchar(str[i++]); } /*************************************************************** * * PutConst - Writes the constant bytes for opcode format * * Inputs: * len - number of bytes to write * input - file to get bytes from * ***************************************************************/ void PutConst (long len, int flag) { long k; int i; if (flag) { /* see if we print out record */ i = 0; for (k = 0; k < len; ++k) { ++i; /* allow 23 numbers per line */ if (i == 24) { /* see if we need to issue a new line */ i = 1; NewLine(); } printf("%02X", (int) fgetc(input)); /* write the hex */ CheckESC(); } } else fseek(input, ftell(input)+len, SEEK_SET); } /*************************************************************** * * PutCTPC - Writes the count and program counter * ***************************************************************/ void PutCTPC(void) { putchar('\n'); if (colf) /* check to make sure you write col */ printf("%06lX %06lX | ", count, pc); } /*************************************************************** * * PutNumber - Writes a number * * Inputs: * input - input file * * Outputs: * number - contains number read * ***************************************************************/ void PutNumber (void) { ReadInt(&number,numlen,input,numsex); switch (numlen) { case 1: printf("%02X", (int) number); case 2: printf("%04X", (int) number); case 3: printf("%06lX", (long) number); case 4: printf("%08lX", (long) number); } count = count + numlen; } /*************************************************************** * * Putsymbol - Writes the symbol * * Inputs: * input - input file * * Outputs: * symbol - symbol read * ***************************************************************/ void PutSymbol (void) { ReadName(symbol,lablen,input); PrintW(symbol); if (lablen) count = count + lablen; else count = count + act_lablen + 1; } /*************************************************************** * * PutOpCode - Writes the opcode * * Inputs: * opcode - opcode to write * input - input file * * Outputs: * write opcode * pc, count = updates accordingly * ***************************************************************/ void PutOpCode (void) { long k; int p1, p2, p3; /* temp storage for calculated parms */ if (opcode < OPALIGN) { /* handle short constant opcode */ printf("CONST ($%02X) | ", (int) opcode); pc = pc + opcode; count = count + opcode; PutConst(opcode,longc); /* write the constant opcodes */ } else switch (opcode) { case OPALIGN: /* handle align opcode */ printf("ALIGN ($E0) | "); PutNumber(); pc = pc + (pc % number); break; case OPORG: /* handle org opcode */ printf("ORG ($E1) | "); PutNumber(); pc = pc + number; break; case OPRELOC: /* handle reloc opcode */ p1 = fgetc(input); p2 = fgetc(input); printf("RELOC ($E2) | %02X : %02X : ", p1, p2); PutNumber(); printf(" : "); PutNumber(); count = count + 2; break; case OPINTSEG: /* handle interseg opcode */ p1 = fgetc(input); p2 = fgetc(input); printf("INTERSEG ($E3) | %02X : %02X : ", p1, p2); PutNumber(); printf(" : "); ReadInt(&number,2,input,numsex); printf("%04X : ", (int) number); ReadInt(&number,2,input,numsex); printf("%04X : ", (int) number); PutNumber(); count = count + 6; break; case OPUSING: /* handle using opcode */ printf("USING ($E4) | "); PutSymbol(); break; case OPSTRONG: /* handle strong opcode */ printf("STRONG ($E5) | "); PutSymbol(); break; case OPGLOBAL: /* handle global opcode */ printf("GLOBAL ($E6) | "); PutSymbol(); if (version == 1) { p1 = fgetc(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %02X : %02X : %02X", p1, p2, p3); count = count + 3; } else { p1 = fgeti(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %04X : %02X : %02X", p1, p2, p3); count = count + 4; } break; case OPGEQU: /* handle gequ opcode */ printf("GEQU ($E7) | "); PutSymbol(); if (version == 1) { p1 = fgetc(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %02X : %02X : %02X :", p1, p2, p3); count = count + 3; } else { p1 = fgeti(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %04X : %02X : %02X :", p1, p2, p3); count = count + 4; } DoExpr(); break; case OPMEM: /* handle mem opcode */ printf("MEM ($E8) | "); PutNumber(); printf(" : "); PutNumber(); break; case OPEXPR: /* handle expr opcode */ k = fgetc(input); count++; printf("EXPR ($EB) | %02X :", (int) k); pc = pc + k; DoExpr(); break; case OPZEXPR: /* handle zexpr opcode */ k = fgetc(input); count++; printf("ZEXPR ($EC) | %02X :", (int) k); pc = pc + k; DoExpr(); break; case OPBEXPR: /* handle bexpr opcode */ k = fgetc(input); count++; printf("BEXPR ($ED) | %02X :", (int) k); pc = pc + k; DoExpr(); break; case OPRELEXPR: /* handle relexpr opcode */ k = fgetc(input); count++; printf("RELEXPR ($EE) | %02X : ", (int) k); PutNumber(); pc = pc + k; printf(" :"); DoExpr(); break; case OPLOCAL: /* handle local opcode */ printf("LOCAL ($EF) | "); PutSymbol(); if (version == 1) { p1 = fgetc(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %02X : %02X : %02X", p1, p2, p3); count = count + 3; } else { p1 = fgeti(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %04X : %02X : %02X", p1, p2, p3); count = count + 4; } break; case OPEQU: /* handle equ opcode */ printf("EQU ($F0) | "); PutSymbol(); if (version == 1) { p1 = fgetc(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %02X : %02X : %02X :", p1, p2, p3); count = count + 3; } else { p1 = fgeti(input); p2 = fgetc(input); p3 = fgetc(input); printf(" : %04X : %02X : %02X :", p1, p2, p3); count = count + 4; } DoExpr(); break; case OPDS: /* handle ds opcode */ printf("DS ($F1) | "); PutNumber(); pc = pc + number; break; case OPLONG: /* handle long constant opcode */ printf("LCONST ($F2) | "); PutNumber(); printf(" : "); NewLine(); pc = pc + number; count = count + number; PutConst(number,longc); /* write the constant opcodes */ break; case OPLEXPR: /* handle long expression opcode */ k = fgetc(input); count++; printf("LEXPR ($F3) | %02X :", (int) k); pc = pc + k; DoExpr(); break; case OPENTRY: /* handle entry opcode */ printf("ENTRY ($F4) | "); PutNumber(); printf(" : "); PutSymbol(); break; case OPSRELOC: /* handle short reloc opcode */ p1 = fgetc(input); p2 = fgetc(input); printf("cRELOC ($F5) | %02X : %02X : ", p1, p2); ReadInt(&number,2,input,numsex); printf("%04X : ", (int) number); ReadInt(&number,2,input,numsex); printf("%04X", (int) number); count = count + 6; break; case OPSINTSEG: /* handle short interseg opcode */ p1 = fgetc(input); p2 = fgetc(input); printf("cINTRSEG ($F6) | %02X : %02X : ", p1, p2); ReadInt(&number,2,input,numsex); printf("%04X : %02X : ", (int) number, (int) fgetc(input)); ReadInt(&number,2,input,numsex); printf("%04X", (int) number); count = count + 7; break; case OPSUPER: /* handle short interseg opcode */ printf("SUPER ($F7) | "); ReadInt(&number,4,input,numsex); printf("%08lX : %02X", (long) number, (int) fgetc(input)); NewLine(); count = count + number; PutConst(number-1,1); break; default: Error(7," "); break; } } /*************************************************************** * * PutOpCodeBody - dump the body of one segment in opcode format * ***************************************************************/ void PutOpCodeBody (void) { while (GetOpCode()) { --count; /* adjust the counter */ PutCTPC(); /* write the count and pc */ count++; PutOpCode(); /* write out the opcode */ CheckESC(); } --count; /* write out the end opcode */ PutCTPC(); puts("END ($00)"); /* print end directive */ } /*************************************************************** * * DpOpCode - Dump file in opcode format * ***************************************************************/ void DpOpCode(void) { while (NextSeg()) { count = /* initialize counter and pc */ pc = 0; CheckESC(); if (! PutHeader()) /* write out the header */ return; if (body) { /* write out the body */ if ((! header) && checkf) { count = bod_disp; fseek(input, ftell(input) + bod_disp, SEEK_CUR); } PutOpCodeBody(); } if ((! shorth) || body) puts("\n"); } } /**** Expression Output Subroutines *******************************/ /*************************************************************** * * DoOper - Writes an operation * * Inputs: * space - print a leading space? * ***************************************************************/ void DoOper (BOOLEAN space) { if (space) putchar(' '); switch(opcode) { case 1: /* handle addition */ putchar('+'); break; case 2: /* handle subtraction */ putchar('-'); break; case 3: /* handle multiplication */ putchar('*'); break; case 4: /* handle division */ putchar('/'); break; case 5: /* handle modulo */ putchar('%'); break; case 6: /* handle negation */ if (format != 1) printf("--"); else printf("unary -"); break; case 7: /* handle bit shift */ putchar('|'); break; case 8: /* handle logical and */ printf(".AND."); break; case 9: /* handle logical or */ printf(".OR."); break; case 10: /* handle logical xor */ printf(".EOR."); break; case 11: /* handle logical not */ printf(".NOT."); break; case 12: /* handle less or equal */ printf("<="); break; case 13: /* handle greater or equal */ printf(">="); break; case 14: /* handle not equal */ printf("<>"); break; case 15: /* handle less */ putchar('<'); break; case 16: /* handle greater */ putchar('>'); break; case 17: /* handle equal */ putchar('='); break; case 18: /* handle bit and */ printf(".BAND."); break; case 19: /* handle bit or */ printf(".BOR."); break; case 20: /* handle bit xor */ printf(".BEOR."); break; } } /*************************************************************** * * DoOpnd - Writes an operand * ***************************************************************/ void DoOpnd (void) { switch(opcode) { case 128: /* handle location counter */ printf(" (*)"); break; case 129: /* handle constant */ printf(" $"); PutNumber(); break; case 130: /* handle weak reference */ printf(" W:"); PutSymbol(); break; case 131: /* handle value of label */ putchar(' '); PutSymbol(); break; case 132: /* handle length attribute */ printf(" L:"); PutSymbol(); break; case 133: /* handle type attribute */ printf(" T:"); PutSymbol(); break; case 134: /* handle count attribute */ printf(" C:"); PutSymbol(); break; case 135: /* handle relative ofset */ printf(" ("); PrintW(segname); printf("+$"); PutNumber(); putchar(')'); break; } } /*************************************************************** * * DoExpr - Writes an expression * ***************************************************************/ void DoExpr (void) { while (GetOpCode()) { if (opcode < 128) DoOper(TRUE); else DoOpnd(); } } /**** Disassembler Subroutines ************************************/ /*************************************************************** * * ReadSym - Reads in a symbol and appends it to symbol * ***************************************************************/ void ReadSym (void) { int i,k; k = strlen(symbol); if (lablen) /* handle variable length labels */ act_lablen = lablen; else { act_lablen = fgetc(input); ++count; } for (i=0; i 4) { /* handle avariable I instruction */ if (imode) return 2; return 1; } return len; /* return a fixed length */ } /*************************************************************** * * GtOpName - Returns Pointer to Opcode Name * * Inputs: * opcode - operation code * * Outputs: * pointer to numonic string * * Notes: There is no terminating null on the string. The * caller should use exactly 3 characters. * ***************************************************************/ char *GtOpName (int opcode) { return &opName[opcode*3]; } /*************************************************************** * * IsExpr - Check to see if OPCODE is from an expression * * Inputs: * op - object module opcode * * Outputs: * true if from an expression; else false * Note: if constant != 0 then --constant, return false * if constant == 0 then * if (constant_opcode) set constant, getopcode, return false * else return true * ***************************************************************/ BOOLEAN IsExpr (int op) { if ((! checkf) && (! header)) return FALSE; if (constant) /* handle in a constant */ return FALSE; if (op < OPALIGN) { /* handle short constant */ constant = op; GetOpCode(); return FALSE; } if (op == OPLONG) { /* handle long constant */ ReadInt(&constant,numlen,input,numsex); count = count + numlen; GetOpCode(); return FALSE; } return TRUE; } /*************************************************************** * * PutLSymbol - Writes the symbol * * Inputs: * input - input file * * Outputs: * symbol - symbol read * ***************************************************************/ void PutLSymbol (void) { int i; ReadName(symbol,lablen,input); printf(symbol); for (i=act_lablen; i<8; i++) /* fill out with spaces */ putchar(' '); putchar(' '); if (lablen) /* handle variable length labels */ count = count + lablen; else count = count + act_lablen + 1; } /*************************************************************** * * PutStreg - Writes out the registar status * * Inputs: * mreg - accumulator flag * ireg - index registar flag * ***************************************************************/ void PutStreg (void) { PutCTPC(); printf(" LONGA "); if (mreg) printf("ON"); else printf("OFF"); PutCTPC(); printf(" LONGI "); if (ireg) printf("ON"); else printf("OFF"); } /*************************************************************** * * ReadOpVal - reads an integer from a constant field * * Inputs: * numsex - number sex * input - reference number of file * numlen - length of number * nPtr - pointer to place result * * Outputs: * Returns true if successful, else false. * ***************************************************************/ BOOLEAN ReadOpVal (long *nPtr, int numlen, FILE *f, int numsex) { int i; long k,n; union { char c[4]; long l; } u; if (numlen <= 4) { u.l = 0; for (i = 0; i < numlen; ++i) { if (!constant) { GetOpCode(); if (opcode && (opcode < OPALIGN)) constant = opcode; else return FALSE; } else --constant; u.c[i] = fgetc(f); } *nPtr = u.l; if (numsex) { n = *nPtr; for (i = 0; i < 4; ++i) { k = (k << 8) | (n && 0xFF); n = n >> 8; } *nPtr = k; } } return TRUE; } /*************************************************************** * * PutOpnd - Writes the operand for an instruction * * Outputs: * Returns true if successful, false if an expression * was encountered in the middle of operand. * ***************************************************************/ BOOLEAN PutOpnd (int op) { BOOLEAN success; int i; long addr; i = GtOpLen(op,mreg,ireg); pc = pc + i; if (constant) { /* split on constant or expression */ count = count + i; /* update the file counter */ success = ReadOpVal(&number,i,input,numsex); /* get the value and print it */ printf("$%0*lX", (int) i*2, (long) number); if (op == REP) { /* check for REP */ if (number & 32) mreg = 1; if (number & 16) ireg = 1; PutStreg(); } if (op == SEP) { /* check for SEP */ if (number & 32) mreg = 0; if (number & 16) ireg = 0; PutStreg(); } if (op == COP) { /* special handling for debug COPs */ switch (number) { case 0: case 1: case 2: success = ReadOpVal(&number,2,input,numsex); printf(",%d", (int) number); count += 2; pc += 2; break; case 5: sTable = TRUE; break; } } } else { /* handle case where operand is an exp */ switch(GetOpCode()) { case OPEXPR: case OPZEXPR: case OPBEXPR: case OPLEXPR: fgetc(input); ++count; DoInexp(); /* write expression in infix form */ break; case OPRELEXPR: fgetc(input); ReadInt(&number,numlen,input,numsex); count = count + numlen + 1; DoInexp(); /* write expression in infix form */ break; default: /* case with unexpected input */ printf("???"); break; } } return success; } /*************************************************************** * * Dis_DC - Disassembles a DC format * * Inputs: * op - object module opcode * ***************************************************************/ void Dis_DC (int op) { int i; int p1, p2; /* temps for computed parameters */ switch(op) { case OPGEQU: case OPEQU: /* handle equates */ PutLSymbol(); if (op == OPEQU) printf("EQU "); else printf("GEQU "); fgetc(input); fgetc(input); fgetc(input); count = count+3; if (version == 2) { fgetc(input); ++count; } DoInexp(); break; case OPUSING: /* handle using directives */ printf(" USING "); PutSymbol(); break; case OPLOCAL: case OPGLOBAL: /* handle local and global labels */ PutLSymbol(); if (op == OPLOCAL) printf("ANOP"); else printf("ENTRY"); fgetc(input); fgetc(input); fgetc(input); count = count + 3; if (version == 2) { fgetc(input); ++count; } break; case OPDS: case OPALIGN: /* handle ds and align directive */ if (op == OPALIGN) printf(" ALIGN $"); else printf(" DS $"); PutNumber(); if (op == OPALIGN) pc = pc + (pc % number); else pc = pc + number; break; case OPSTRONG: /* handle strong reference */ printf(" DC R'"); PutSymbol(); putchar('\''); break; case OPORG: /* handle inter-segment org */ printf(" ORG *+$"); PutNumber(); pc = pc + number; break; case OPMEM: /* handle inter-segment mem */ printf(" MEM $"); PutNumber(); printf(",$"); PutNumber(); break; case OPEXPR: case OPZEXPR: /* handle expressions */ case OPBEXPR: case OPLEXPR: case OPRELEXPR: printf(" DC "); i = fgetc(input); if (i == 1) printf("I1'"); else if (i == 2) printf("I2'"); else if (i == 3) printf("I3'"); else printf("I4'"); ++count; pc = pc + i; if (op == OPRELEXPR) { PutNumber(); putchar('+'); } DoInexp(); /* write expression in infix form */ putchar('\''); break; case OPRELOC: /* handle reloc opcode */ p1 = fgetc(input); p2 = fgetc(input); printf("! RELOC ($E2) | %02X : %02X : ", p1, p2); PutNumber(); printf(" : "); PutNumber(); count = count + 2; break; case OPINTSEG: /* handle interseg opcode */ p1 = fgetc(input); p2 = fgetc(input); printf("! INTERSEG ($E3) | %02X : %02X : ", p1, p2); PutNumber(); printf(" : "); ReadInt(&number,2,input,numsex); printf("%04X : ", (int) number); ReadInt(&number,2,input,numsex); printf("%04X : ", (int) number); PutNumber(); count = count + 6; break; case OPENTRY: /* handle entry opcode */ printf("! ENTRY ($F4) | "); PutNumber(); printf(" : "); PutSymbol(); break; default: Error(7," "); break; } } /*************************************************************** * * Disasm - Disassembles OPCODE * * Inputs: * op - assembly language opcode * * Outputs: * Returns true if successful, false if an expression * was hit trying to process an operand. * ***************************************************************/ BOOLEAN Disasm (int op) { BOOLEAN success; int i; char opn[4]; sTable = FALSE; /* no COP symbol table found (yet) */ success = TRUE; /* assume everything will work */ --constant; /* now this is a constant */ ++pc; /* update program counter */ strncpy(opn, GtOpName(op), 3); opn[3] = (char) 0; printf(" %s ", opn); switch(GtOpKind(op)) { /* split on type of output format */ case 1: /* handle '# operand' */ putchar('#'); success = PutOpnd(op); break; case 2: /* handle 'operand' */ success = PutOpnd(op); break; case 3: /* handle '> operand' */ putchar('>'); success = PutOpnd(op); break; case 4: /* handle 'A' */ putchar('A'); break; case 5: /* handle ' ' or 'operand' */ if (GtOpLen(op,mreg,ireg)) success = PutOpnd(op); break; case 6: /* handle '(operand),Y' */ putchar('('); success = PutOpnd(op); printf("),Y"); break; case 7: /* handle '[operand],Y' */ putchar('['); success = PutOpnd(op); printf("],Y"); break; case 8: /* handle '(operand,X)' */ putchar('('); success = PutOpnd(op); printf(",X)"); break; case 9: /* handle 'operand,X' */ success = PutOpnd(op); printf(",X"); break; case 10: /* handle 'operand,Y' */ success = PutOpnd(op); printf(",Y"); break; case 11: /* handle '>operand,X' */ putchar('>'); success = PutOpnd(op); printf(",X"); break; case 12: /* handle '(operand)' */ putchar('('); success = PutOpnd(op); putchar(')'); break; case 13: /* handle '[operand]' */ putchar('['); success = PutOpnd(op); putchar(']'); break; case 14: /* handle 'operand,S' */ success = PutOpnd(op); printf(",S"); break; case 15: /* handle '(operand,S),Y */ putchar('('); success = PutOpnd(op); printf(",S),Y"); break; case 16: /* handle 'operand,operand' */ success = PutOpnd(op); putchar(','); success = PutOpnd(op); break; case 17: /* handle relative branches */ if (constant) { i = GtOpLen(op,mreg,ireg); pc = pc + i; count = count + i; /* update the file counter */ constant = constant - i; /* set new constant number */ number = 0; ReadInt(&number,i,input,numsex); /* get the value and print it */ if (i == 1) { if (number > 127) number = number | -256; } else { if (number > 32767) number = number | -32768; } number = number + i + 1; if (number < 0) { number = -number; printf("*-$"); } else printf("*+$"); printf("%0*lX", (int) i*2, (long) number); } else success = PutOpnd(op); break; default: printf("Operand Error"); status = -1; break; } return success; } /*************************************************************** * * DisSTable - disassemble a COP 5 symbol table * ***************************************************************/ void DisSTable (void) { long tlen; int p1, p2, p3, p4; /* temps for computed parms */ if (!constant) { GetOpCode(); if (opcode && (opcode < OPALIGN)) constant = opcode; else { PutCTPC(); Dis_DC(opcode); } } if (constant >= 2) { ReadInt(&tlen,2,input,numsex); /* get and print the table length */ PutCTPC(); printf(" DC I'%d'", (int) tlen); pc += 2; count += 2; constant -= 2; CheckESC(); while (tlen > 0) { if (!constant) { GetOpCode(); if (opcode && (opcode < OPALIGN)) constant = opcode; } if (constant) { ReadOpVal(&number,4,input,numsex); PutCTPC(); printf(" DC I4'%d'", (long) number); pc += 4; count += 4; } else { PutCTPC(); Dis_DC(opcode); } if (!constant) { GetOpCode(); if (opcode && (opcode < OPALIGN)) constant = opcode; } if (constant) { ReadOpVal(&number,4,input,numsex); PutCTPC(); printf(" DC I4'%d'", (long) number); pc += 4; count += 4; } else { PutCTPC(); Dis_DC(opcode); } if (!constant) { GetOpCode(); if (opcode && (opcode < OPALIGN)) constant = opcode; else { PutCTPC(); Dis_DC(opcode); } } if (constant >= 4) { PutCTPC(); p1 = fgetc(input); p2 = fgetc(input); p3 = fgetc(input); p4 = fgetc(input); printf(" DC H'%02X %02X %02X%02X'", p1, p2, p3, p4); pc += 4; count += 4; constant -= 4; } tlen -= 12; } } } /*************************************************************** * * Dis_Cns - disassemble a constant as a DC statement(s) * ***************************************************************/ void Dis_Cns (int opcode) { int i, delta; int b1,b2; while (opcode != 0) { printf(" DC H'"); i = 16; while ((i != 0) && (opcode != 0)) { if (opcode == 1) { printf("%02X", (int) fgetc(input)); delta = 1; } else { b1 = fgetc(input); b2 = fgetc(input); if (opcode == 2) printf("%02X%02X", (int) b1, (int) b2); else printf("%02X%02X ", (int) b1, (int) b2); delta = 2; } opcode -= delta; i -= delta; pc += delta; count += delta; } putchar('\''); if (opcode != 0) { CheckESC(); PutCTPC(); } } } /*************************************************************** * * DpDisasm - Dump file in disassembled format * ***************************************************************/ void DpDisasm (void) { int i; long mark; long codelen; while (NextSeg()) { count = /* initialize counter and pc */ pc = constant = 0; /* we're not in a constant */ CheckESC(); if (checkf || header) /* write out the header */ if (! PutHeader()) return; if ((! checkf) && (! header)) { /* get segment length */ mark = GetEOF(input); blocks = 30000; } else if ((ftype == LIBFL) || (version == 2)) mark = blkcnt; else mark = blkcnt*512; if (body) { /* write out the body */ if ((! header) && checkf) { count = bod_disp; fseek(input, ftell(input) + bod_disp, SEEK_SET); } PutStreg(); /* write the registar status */ PutCTPC(); printf(segname); /* print the segment name */ for (i=strlen(segname); i<8; i++) /* fill out with spaces */ putchar(' '); if (kind & 1) /* print out segment type */ printf(" DATA"); else printf(" START"); codelen = length-resspc; while (count <= mark) { PutCTPC(); GetOpCode(); if (checkf && ((pc > codelen) || ((! opcode) && (pc == codelen)))) break; if (((kind & 0x001F) == 1) && checkf && (opcode < OPALIGN) && (opcode != 0)) Dis_Cns(opcode); else if (IsExpr(opcode)) Dis_DC(opcode); else if (!Disasm(opcode)) { PutCTPC(); Dis_DC(opcode); } else if (sTable) DisSTable(); CheckESC(); } if (resspc) { printf(" DS $%08lX", (long) resspc); count += resspc; } if (count > mark) PutCTPC(); puts(" END"); /* print out the end directive */ } if ((! shorth) || body) puts("\n"); } } /**** Hex Dump Subroutines ****************************************/ /*************************************************************** * * DpHex - Dump file in hex format * ***************************************************************/ void DpHex (void) { long mark; long ch = 0; char chline[20]; int k, i, space; while (NextSeg()) { count = 0L; CheckESC(); if (! PutHeader()) /* write out the header */ return; /* if we don't print header and we're not doing file checking then dump the entire file and forget about segment scanning */ if ((! checkf) && (! header)) { /* get the segment length */ mark = GetEOF(input); blocks = 30000; } else if ((ftype == LIBFL) || (version == 2)) mark = blkcnt; else mark = blkcnt*512; if (body) { /* write out the body */ if ((! header) && checkf) { count = bod_disp; fseek(input, ftell(input) + bod_disp, SEEK_SET); } while (count <= mark) { putchar('\n'); if (colf) printf("%06lX | ", count); space = 0; for (k=0; k<16; k++) { ch = fgetc(input); count++; if (count > mark) { printf(" "); ch = 0; } else printf("%02X", ch); if ((ch & 127) > 31) chline[k] = ch & 127; else chline[k] = ' '; space++; if (space == 4) { putchar(' '); space = 0; } CheckESC(); } chline[16] = 0; printf(" | %s", chline); CheckESC(); } } if ((! shorth) || body) printf("\n\n"); } } /**** Command Line Input Subroutines ******************************/ /*************************************************************** * * GetFType - Return Type Of File * * Inputs: * name - file name to get the type of * * Returns: file type; 0 if not found * ***************************************************************/ int GetFType (char name[]) { struct FileInfoRecGS { int pCount; struct { int length; char name[FILEMAX]; } *fname; int access; int fileType; } parm; parm.pCount = 3; parm.fname = (void *) malloc (sizeof(int) + FILEMAX); if (parm.fname == NULL) return 0; parm.fname->length = strlen(name); strcpy(parm.fname->name, name); GetFileInfoGS(&parm); free(parm.fname); if (toolerror()) return 0; return parm.fileType; } /*************************************************************** * * CheckFile - Checks For Valid File * ***************************************************************/ BOOLEAN CheckFile (char file[]) { if (! checkf) { /* see if we have to check file type */ ftype = FALSE; /* unspecified file type */ return TRUE; } /* insure file exists and is an OMF type of file */ if (! (ftype = GetFType(file))) { Error(5,file); return FALSE; } if ((ftype < OBJFL) || (ftype > MAXFL)) { Error(6,file); return FALSE; } return TRUE; } /*************************************************************** * * ExpandDev - Expand devices and prefixes * ***************************************************************/ #define INIT_WILDCARD(parm) (PDosInt(0x0149,parm)) #define NEXT_WILDCARD(parm) (PDosInt(0x014A,parm)) void ExpandDev (char name[]) { struct { /* parameter block for Init_Wildcard */ int pcount; struct { int length; char name[FILEMAX]; } *inName; int flags; } iwRec; struct { /* parameter block for Next_Wildcard */ int pcount; struct { int buffLen; int length; char name[FILEMAX]; } *outName; } nwRec; iwRec.inName = (void *) malloc (sizeof(int) + FILEMAX); nwRec.outName = (void *) malloc (sizeof(int)*2 + FILEMAX); if ((iwRec.inName == NULL) || (nwRec.outName == NULL)) { if (iwRec.inName != NULL) free(iwRec.inName); if (nwRec.outName != NULL) free(nwRec.outName); return; } iwRec.pcount = 2; iwRec.inName->length = strlen(name); strcpy(iwRec.inName->name, name); iwRec.flags = 0x4000; nwRec.pcount = 1; nwRec.outName->buffLen = FILEMAX+4; INIT_WILDCARD(&iwRec); if (!toolerror()) { NEXT_WILDCARD(&nwRec); if (!toolerror()) { memcpy(name, nwRec.outName->name, nwRec.outName->length); name[nwRec.outName->length] = (char) 0; } } free(iwRec.inName); free(nwRec.outName); } /*************************************************************** * * SetFlag - Sets the input parameters flags * ***************************************************************/ BOOLEAN SetFlag (char *str) { char ch; if (strlen(str) != 2) { Error(4,str); return FALSE; } ch = toupper(str[1]); if ((str[0]) == '+') { /* handle + flags */ if (ch == 'X') {format = 2;} else if (ch == 'D') {format = 1;} else if (ch == 'S') {shorth = FALSE;} else if (ch == 'I') {ireg = TRUE;} else if (ch == 'L') {longc = TRUE;} else if (ch == 'M') {mreg = TRUE;} else if (ch == 'H') {header = TRUE;} else if (ch == 'O') {body = TRUE;} else if (ch == 'F') {checkf = TRUE;} else if (ch == 'A') {colf = TRUE;} else {Error(4, str); return FALSE;} } else { /* handle - flags */ if (ch == 'X') {format = 0;} else if (ch == 'D') {format = 0;} else if (ch == 'S') {shorth = TRUE;} else if (ch == 'I') {ireg = FALSE;} else if (ch == 'L') {longc = FALSE;} else if (ch == 'M') {mreg = FALSE;} else if (ch == 'H') {header = FALSE;} else if (ch == 'O') {body = FALSE;} else if (ch == 'F') {checkf = FALSE;} else if (ch == 'A') {colf = FALSE;} else {Error(4, str); return FALSE;} } return TRUE; } /*************************************************************** * * Reads the names list and sets up namelist pointers * ***************************************************************/ BOOLEAN GetList (int num, int argc, char *argv[]) { char local[NAMEMAX]; int i, k; if (num == argc) { names = FALSE; return TRUE; } for (i=num; i<=argc; i++) { strncat(nlist, argv[i], strlen(argv[i])); strncat(nlist, " ", 1); } strcpy(local, nlist); if (strlen(nlist) < 8) { Error(4,local); names = FALSE; return FALSE; } for (i=0; i<5; i++) nlist[i] = toupper(nlist[i]); if (strncmp(nlist,"NAMES=(",7) != 0) { Error(4,local); names = FALSE; return FALSE; } for (i=0; i<7; i++) nlist[i] = ' '; i = 0; while (nlist[i] && (nlist[i] != ')')) { if (nlist[i] == ',') nlist[i] = ' '; i++; } if (! nlist[i]) { Error(4,local); names = FALSE; return FALSE; } nlist[i] = 0; names = TRUE; return TRUE; } /*************************************************************** * * GetName - This is the name input routine * ***************************************************************/ void GetName (char *name) { int i, x; char ch; fputs("File name: ", stdout); /* prompt for file name */ name[0] = (char) 0; /* read the file name */ fgets(name, NAMEMAX, stdin); x = strlen(name); /* strip whitespace */ while ((x != 0) && isspace(name[x-1])) name[--x] = (char) 0; while (((x = strlen(name)) != 0) && isspace(name[0])) for (i = 0; i < x; ++i) name[i] = name[i+1]; } /*************************************************************** * * GetParms - Gets the input parameters * ***************************************************************/ BOOLEAN GetParms (int argc, char *argv[]) { char local[NAMEMAX]; int i; i = 1; while (i <= argc) { /* first set the flags */ strcpy(local,argv[i]); ++i; if ((local[0] == '+') || (local[0] == '-')) { if (! SetFlag(local)) return FALSE; } else break; } if (i <= argc) /* get file name */ strcpy(fname,argv[i-1]); else { GetName(fname); /* ask for and get file name */ i = argc; /* no names list */ } ExpandDev(fname); /* expand devices */ if (! CheckFile(fname)) return FALSE; if ((input = fopen(fname,"rb")) == NULL) { Error(5,fname); return FALSE; } return GetList(i, argc, argv); } /**************************************************************** * * Initialize - Initialize variables * ****************************************************************/ void Initialize (void) { puts("DumpOBJ 2.0.1\n"); /* write the header */ format = /* dump in opcode format */ namc = /* no names in namelist */ ftype = /* no specified file type yet */ status = 0; /* assume no errors */ segmark = /* start with begining segment */ blocks = 0L; /* no block yet */ shorth = FALSE; /* don't do "scan" type output */ ireg = /* use long index registars */ mreg = /* use long accumulator */ header = /* print the header */ longc = /* print long constants */ body = /* print the body */ checkf = /* check input file type */ colf = TRUE; /* write out the numbers */ } /**** Main Programs ***********************************************/ /**************************************************************** * * Main - Begin Program * ****************************************************************/ int main (int argc, char * argv[]) { Initialize(); /* initialize variables */ if (GetParms(argc, argv)) { /* get input parameters */ switch (format) { case 0: DpOpCode(); break; /* dump file in opcode format */ case 1: DpDisasm(); break; /* dump file in disassembled format */ case 2: DpHex(); break; /* dump file in hex format */ default: Error(1," "); /* flag error if not one of these */ } } putchar('\n'); return status; } \ No newline at end of file +/************************************************************** +* +* DumpOBJ 2.0 +* +* By Phil Montoya +* Translation to ORCA/C & 2.0 enhancements by Mike Westerfield. +* +* DumpOBJ 1.1 Copyright November 1986-88 +* By the Byte Works, Inc. +* +* DumpOBJ 2.0 Copyright 1991 +* Byte Works, Inc. +* +**************************************************************** +* +* Version 2.0.1, 7 July 94 +* Mike Westerfield +* +* 1. Added resource fork. +* +****************************************************************/ + +#pragma keep "DumpOBJ" +#pragma optimize 9 + +/* GS specific declarations */ +/*--------------------------*/ + +extern pascal void PDosInt(); +int toolerror(void); + +#define WRITE_CONSOLE(parm) (PDosInt(0x015A,parm)) +#define GetFileInfoGS(pBlockPtr) PDosInt(0x2006,pBlockPtr) + +#pragma lint -1 + +/* Standard C Libraries */ +/*----------------------*/ + +#include +#include +#include +#include + +/* Constants */ +/*-----------*/ + +#define BOOLEAN int /* boolean variables */ +#define TRUE 1 +#define FALSE 0 +#define FILEMAX 1024 /* max length of file name */ +#define NAMEMAX 512 /* maximum size of variable len name */ +#define NAMESIZE 11 /* size of label name */ +#define OBJFL 177 /* minimum object file type */ +#define MAXFL 190 /* maximum object file type */ +#define LIBFL 178 /* library file type */ +#define BLKSIZE 512 /* size of block */ +#define COP 2 /* COP opcode */ +#define REP 194 /* REP opcode */ +#define SEP 226 /* SEP opcode */ + +/* Object File Opcodes */ +/*---------------------*/ + +#define OPALIGN 224 /* align to a boundry */ +#define OPORG 225 /* set code origin */ +#define OPRELOC 226 /* relocation entry */ +#define OPINTSEG 227 /* inserseg record */ +#define OPUSING 228 /* use data area */ +#define OPSTRONG 229 /* force segment inclusion */ +#define OPGLOBAL 230 /* define global label */ +#define OPGEQU 231 /* define global constant */ +#define OPMEM 232 /* reserve absolute memory */ +#define OPEXPR 235 /* computed value */ +#define OPZEXPR 236 /* computed zero page value */ +#define OPBEXPR 237 /* computed local bank value */ +#define OPRELEXPR 238 /* computed relative ofset */ +#define OPLOCAL 239 /* define local label */ +#define OPEQU 240 /* define local constant */ +#define OPDS 241 /* define storage */ +#define OPLONG 242 /* long constant > $DF bytes */ +#define OPLEXPR 243 /* outer segment expression */ +#define OPENTRY 244 /* run time lib entry dictionary */ +#define OPSRELOC 245 /* short relocation entry */ +#define OPSINTSEG 246 /* short interseg entry */ +#define OPSUPER 247 /* super compressed records */ + +/* Program variables */ +/*-------------------*/ + +char fname[FILEMAX]; /* input file name buffer */ +char nlist[NAMEMAX]; /* names list */ +char symbol[NAMEMAX]; /* symbol name buffer */ + +BOOLEAN names; /* names list flag */ +BOOLEAN sTable; /* found a COP symbol table? */ + +int act_lablen; /* actual length of label read */ +int status; /* shell return status */ +int namc; /* name argument counter */ +int ftype; /* current file type */ + +long blocks; /* used to get to next segment */ +long constant; /* constant byte counter and flag */ +long opcode; /* opcode storage */ +long segmark; /* start of segment marker */ +long count; /* file counter */ +long number; /* number read variable */ +long pc; /* segment program counter */ + +long tkind; /* type of node for tree */ +long *root; /* root pointer for expression tree */ + +FILE *input; /* input file */ + +/* Output Control Settings */ +/*-------------------------*/ + +int format; /* format of output + 0 opcode dump + 1 dissassembly dump + 2 hex dump + */ +BOOLEAN shorth; /* print short headers? */ +BOOLEAN ireg; /* long index registers? */ +BOOLEAN mreg; /* long accumulator? */ +BOOLEAN longc; /* print long constants? */ +BOOLEAN header; /* print segment headers? */ +BOOLEAN body; /* print segment bodies? */ +BOOLEAN checkf; /* check file types? */ +BOOLEAN colf; /* print displacement numbers? */ + +/* Object Module Header */ +/*----------------------*/ + +int kind; /* kind of segment */ + +long blkcnt; /* number of block in segment */ +long resspc; /* reserved space at end of segment */ +long length; /* length of finished segment */ + +int kind1; /* this is kind for version 1 */ +int lablen; /* label length */ +int numlen; /* number length */ +int version; /* version number */ + +long banksize; /* banksize */ + +int kind2; /* this is kind for version 2 */ +int unused; /* undefined field */ + +long pgorg; /* program org */ +long align; /* alignment factor */ + +int numsex; /* significance of numbers */ +int lang_card; /* language card */ + +int segnum; /* segment number */ + +long ent_disp; /* disp to beg of segment */ + +int nam_disp; /* displacment to names */ +int bod_disp; /* displacment to body */ + +char loadname[NAMESIZE]; /* load file name */ +char segname[NAMEMAX]; /* segment name */ + +/* Opcode arrays */ +/*---------------*/ + +char opKind[] = {5,8,5,14,2,2,2,13,5,1,4,5,2,2,2,3, + 17,6,12,15,2,9,9,7,5,10,4,5,2,9,9,11, + 2,8,2,14,2,2,2,13,5,1,4,5,2,2,2,3, + 17,6,12,15,9,9,9,7,5,10,4,5,9,9,9,11, + 5,8,5,14,16,2,2,13,5,1,4,5,2,2,2,3, + 17,6,12,15,16,9,9,7,5,10,5,5,3,9,9,11, + 5,8,5,14,2,2,2,13,5,1,4,5,12,2,2,3, + 17,6,12,15,9,9,9,7,5,10,5,5,8,9,9,11, + 17,8,17,14,2,2,2,13,5,1,5,5,2,2,2,3, + 17,6,12,15,9,9,10,7,5,10,5,5,2,9,9,11, + 1,8,1,14,2,2,2,13,5,1,5,5,2,2,2,3, + 17,6,12,15,9,9,10,7,5,10,5,5,9,9,10,11, + 1,8,1,14,2,2,2,13,5,1,5,5,2,2,2,3, + 17,6,12,15,5,9,9,7,5,10,5,5,12,9,9,11, + 1,8,1,14,2,2,2,13,5,1,5,5,2,2,2,3, + 17,6,12,15,5,9,9,7,5,10,5,5,8,9,9,11}; + +char opLen[] = {1,1,1,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, + 2,1,3,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, + 0,1,0,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,3,2,2,3, + 0,1,2,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, + 1,1,2,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, + 5,1,5,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, + 5,1,1,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,1,1,1,1,0,2,0,0,2,2,2,3, + 5,1,1,1,1,1,1,1,0,4,0,0,2,2,2,3, + 1,1,1,1,2,1,1,1,0,2,0,0,2,2,2,3}; + +char opName[] = "BRKORACOPORATSBORAASLORAPHPORAASLPHDTSBORAASLORA" + "BPLORAORAORATRBORAASLORACLCORAINCTCSTRBORAASLORA" + "JSRANDJSLANDBITANDROLANDPLPANDROLPLDBITANDROLAND" + "BMIANDANDANDBITANDROLANDSECANDDECTSCBITANDROLAND" + "RTIEORWDMEORMVPEORLSREORPHAEORLSRPHKJMPEORLSREOR" + "BVCEOREOREORMVNEORLSREORCLIEORPHYTCDJMPEORLSREOR" + "RTSADCPERADCSTZADCRORADCPLAADCRORRTLJMPADCRORADC" + "BVSADCADCADCSTZADCRORADCSEIADCPLYTDCJMPADCRORADC" + "BRASTABRLSTASTYSTASTXSTADEYBITTXAPHBSTYSTASTXSTA" + "BCCSTASTASTASTYSTASTXSTATYASTATXSTXYSTZSTASTZSTA" + "LDYLDALDXLDALDYLDALDXLDATAYLDATAXPLBLDYLDALDXLDA" + "BCSLDALDALDALDYLDALDXLDACLVLDATSXTYXLDYLDALDXLDA" + "CPYCMPREPCMPCPYCMPDECCMPINYCMPDEXWAICPYCMPDECCMP" + "BNECMPCMPCMPPEICMPDECCMPCLDCMPPHXSTPJMLCMPDECCMP" + "CPXSBCSEPSBCCPXSBCINCSBCINXSBCNOPXBACPXSBCINCSBC" + "BEQSBCSBCSBCPEASBCINCSBCSEDSBCPLXXCEJSRSBCINCSBC"; + +/**** Utility Subroutines *****************************************/ + +/*************************************************************** +* +* fgeti - read an integer from the file +* +* Inputs: +* f - file to read from +* +* Outputs: +* Returns integer read +* +***************************************************************/ + +int fgeti (FILE *f) + +{ +return fgetc(f) | (fgetc(f) << 8); +} + +/*************************************************************** +* +* Error - Writes out an error +* +***************************************************************/ + +void Error (int errnum, char *str) + +{ +status = -1; +switch (errnum) { + case 1: fputs("Format type not supported", stderr); + break; + case 2: fputs("Could not read segment header", stderr); + break; + case 3: fputs("Segment version not supported", stderr); + break; + case 4: fputs("Bad input ", stderr); + break; + case 5: fputs("Could not open file ", stderr); + break; + case 6: fputs("Not an object file ", stderr); + break; + case 7: fputs("Unknown Opcode", stderr); + break; + case 8: fputs("Illegal header entry", stderr); + break; + case 9: fputs("End of file encountered", stderr); + default: break; + } +if (str[0] != ' ') + fputs(str, stderr); +fputc('\n', stderr); +} + +/*************************************************************** +* +* CheckESC - Checks to see if 'escape' is pressed +* +* Notes: Returns to shell if open-apple period has been pressed. +* +***************************************************************/ + +void CheckESC (void) + +{ +char *keyboard; +char *strobe; +char *flags; +struct { + int pcount; + char ch; + } parm; + +keyboard = (void *) 0x00C000; +strobe = (void *) 0x00C010; +flags = (void *) 0x00C025; + +if (*keyboard & 0x80) { + if ((*keyboard & 0x7F) == '.') + if (*flags & 0x80) { + *strobe = (char) 0; + exit(-1); + } + *strobe = (char) 0; + parm.pcount = 1; + parm.ch = (char) 27; WRITE_CONSOLE(&parm); + parm.ch = (char) 15; WRITE_CONSOLE(&parm); + parm.ch = (char) 0x43; WRITE_CONSOLE(&parm); + parm.ch = (char) 24; WRITE_CONSOLE(&parm); + parm.ch = (char) 14; WRITE_CONSOLE(&parm); + parm.ch = (char) 8; WRITE_CONSOLE(&parm); + while (! (*keyboard & 0x80)) ; + parm.ch = (char) 32; WRITE_CONSOLE(&parm); + parm.ch = (char) 8; WRITE_CONSOLE(&parm); + if ((*keyboard & 0x7F) == '.') + if (*flags & 0x80) { + *strobe = (char) 0; + exit(-1); + } + *strobe = (char) 0; + } +} + +/**** Segment I/O Subroutines *************************************/ + +/*************************************************************** +* +* Checks and updates output header information. +* +* Returns: +* TRUE - if header OK. +* FALSE - if header not OK and flags error. +* +****************************************************************/ + +BOOLEAN CheckHead (void) + +{ +long talign; + +if ((version != 1) && (version != 2)) { + Error(3," "); + return FALSE; + } +if ((lablen > 256) || (numlen > 4) || (numlen < 1)) { + Error(8," "); + return FALSE; + } +if (align) { /* insure only 1 bit set in alignment */ + talign = align; + while (! (talign & 1)) + talign = talign >> 1; + if (talign != 1) { + Error(8," "); + return FALSE; + } + } +return TRUE; +} + +/*************************************************************** +* +* GetEOF - Returns The End of File Marker +* +* Returns: mark or -1 if error +* +***************************************************************/ + +long GetEOF (FILE *f) + +{ +long mark, pos; + +pos = ftell(f); +if (pos == -1) + return -1; +if (fseek(f, -1, SEEK_END)) + return -1; +mark = ftell(f)+1; +if (pos == -1) + return -1; +if (fseek(f, pos, SEEK_SET)) + return -1; +return mark; +} + +/*************************************************************** +* +* GetHead - Reads In The Segment Header +* +* Inputs: +* f - file to read the header from +* +***************************************************************/ + +int GetHead (FILE *f) + +{ +struct { + long blkcnt, resspc, length; + char kind1, lablen, numlen, version; + long banksize; + int kind2, unused; + long pgorg, align; + char numsex, lang_card; + int segnum; + long ent_disp; + int nam_disp, bod_disp; + } header; +int i, disp, len; + +fseek(f, 0, SEEK_CUR); /* read the common parts of the header */ +if (fread(&header, sizeof(header), 1, f) != 1) + return -1; +blkcnt = header.blkcnt; +resspc = header.resspc; +length = header.length; +kind1 = header.kind1; +lablen = header.lablen; +numlen = header.numlen; +version = header.version; +banksize = header.banksize; +kind2 = header.kind2; +unused = header.unused; +pgorg = header.pgorg; +align = header.align; +numsex = header.numsex; +lang_card = header.lang_card; +segnum = header.segnum; +ent_disp = header.ent_disp; +nam_disp = header.nam_disp; +bod_disp = header.bod_disp; +disp = nam_disp-sizeof(header); /* skip any extra stuff */ +if (disp) + for (i = 0; i < disp; ++i) + fgetc(f); +for (i = 0; i < 10; ++i) /* read the load segment name */ + loadname[i] = fgetc(f); +loadname[10] = (char) 0; +len = fgetc(f); /* read the code segment name */ +for (i = 0; i < len; ++i) + segname[i] = fgetc(f); +segname[len] = (char) 0; +if (version == 2) /* set the kind field */ + kind = kind2; +else + kind = kind1; +return 0; +} + +/*************************************************************** +* +* IsInList - Checks to see if segment is in names list +* +***************************************************************/ + +BOOLEAN IsInList (void) + +{ +int len, chpos; + +if (! names) + return TRUE; +len = +chpos = 0; + + /* get length of segment name */ +while (isalnum(segname[len]) || (segname[len] == '~') || + (segname[len] == '_')) len++; +while (nlist[chpos]) { /* see if name matches a list name */ + while (nlist[chpos] == ' ') chpos++; + if ((! strncmp(segname,nlist+chpos,len)) && + ((nlist[chpos+len] == ' ') || (! nlist[chpos+len]))) + return TRUE; + while ((nlist[chpos]) && (nlist[chpos] != ' ')) chpos++; + } +return FALSE; +} + +/*************************************************************** +* +* NextSeg - Returns the next segment +* +* Output: +* positions file marker at next segment 0 if at end of file +* +***************************************************************/ + +BOOLEAN NextSeg(void) + +{ +if ((format == 2) + || ((format == 1) && !header && !checkf)) { + numsex = 0; + return TRUE; + } +do + { + if ((ftype == LIBFL) || (version == 2)) { + if (fseek(input, segmark + blocks, SEEK_SET)) + return FALSE; + } + else { + if (fseek(input,segmark + (blocks * BLKSIZE), SEEK_SET)) + return FALSE; + } + segmark = ftell(input); /* set next segment marker */ + if (segmark >= (GetEOF(input))) + return FALSE; + GetHead(input); + blocks = blkcnt; + if (! blocks) + return FALSE; + fseek(input, segmark, SEEK_SET); + } +while (! IsInList()); /* check to see if in names list */ +return TRUE; +} + +/*************************************************************** +* +* PutComment - Writes a comment line if colf is not active +* +***************************************************************/ + +void PutComment (void) + +{ +if (! colf) + printf("! "); +} + +/*************************************************************** +* +* PutKind - Writes out the kind in name format +* +***************************************************************/ + +void PutKind (int kind) + +{ +if (version == 1) { + if (kind & 128) + printf("dynamic "); + else + printf("static "); + if (kind & 64) + printf("private "); + if (kind & 32) + printf("position independent "); + } +else { + if (kind & 32768) + printf("dynamic "); + else + printf("static "); + if (kind & 16384) + printf("private "); + if (kind & 8192) + printf("position independent "); + if (kind & 4096) + printf("no special memory "); + if (kind & 2048) + printf("absolute bank "); + if (kind & 1024) + printf("reload "); + } +switch(kind & 31) { + case 0: + printf("code segment"); + break; + case 1: + printf("data segment"); + break; + case 2: + printf("jump table segment"); + break; + case 4: + printf("pathname segment"); + break; + case 8: + printf("library dictionary segment"); + break; + case 16: + printf("initialization segment"); + break; + case 17: + printf("absolute bank segment"); + break; + case 18: + printf("direct page/stack segment"); + break; + default: + printf("unknown segment: $04X", kind); + } +} + +/*************************************************************** +* +* PutHeader - Writes Out The Header +* +* Returns: FALSE if an error was found, else TRUE. +* +***************************************************************/ + +BOOLEAN PutHeader (void) + +{ +long mark; +int kind2; + +mark = ftell(input); /* save the file marker */ +if (GetHead(input)) { + Error(2," "); + return FALSE; + } +if ((checkf) && ((version != 1) && (version != 2))) { + Error(3," "); + return FALSE; + } +blocks = blkcnt; /* set the new block counter */ +if (! header) /* split on write/don't write header */ + fseek(input,mark,SEEK_SET); +else { + count = ftell(input) - mark; /* set the file counter */ + if (shorth) { /* split on short or long header */ + PutComment(); + printf("%s (", segname); + PutKind(kind); + printf(")\n"); + return CheckHead(); + } + else { /* print the full header */ + PutComment(); /* write block count */ + if (version == 2) + printf("Byte count : $%08lX%14ld\n", blkcnt, blkcnt); + else + printf("Block count : $%08lX%14ld\n", blkcnt, blkcnt); + CheckESC(); + PutComment(); /* write reserved space */ + printf("Reserved space: $%08lX%14ld\n", resspc, resspc); + CheckESC(); + PutComment(); /* write segment length */ + printf("Length : $%08lX%14ld\n", length, length); + CheckESC(); + PutComment(); /* write label length */ + printf("Label length : $%02X%20d\n", lablen, lablen); + CheckESC(); + PutComment(); /* write number length */ + printf("Number length : $%02X%20d\n", numlen, numlen); + CheckESC(); + PutComment(); /* write segment version */ + printf("Version : $%02X%20d\n", version, version); + CheckESC(); + PutComment(); /* write bank size */ + printf("Bank size : $%08lX%14ld\n", banksize, banksize); + CheckESC(); + PutComment(); /* write segment kind */ + if (version == 2) { + printf("Kind : $%04X%18d (", kind, kind); + kind2 = kind; + } + else { + printf("Kind : $%02X%20d (", kind, kind); + kind2 = ((kind & 0xE0) << 8) | (kind & 0x1F); + } + switch (kind & 0x001F) { + case 0x00: printf("code"); + break; + case 0x01: printf("data"); + break; + case 0x02: printf("jump table"); + break; + case 0x04: printf("pathname"); + break; + case 0x08: printf("library"); + break; + case 0x10: printf("initialization"); + break; + case 0x11: printf("absolute bank"); + break; + case 0x12: printf("direct-page/stack"); + break; + default: printf("unknown"); + break; + } + if (kind & 0x8000) + printf(",dynamic"); + else + printf(",static"); + if (kind & 0x4000) printf(",private"); + if (kind & 0x2000) printf(",position independent"); + if (kind & 0x1000) printf(",no special memory"); + if (kind & 0x0800) printf(",absolute bank"); + if (kind & 0x0400) printf(",reload"); + if (kind & 0x0200) printf(",skip"); + if (kind & 0x0100) printf(",bank relative"); + printf(")\n"); + CheckESC(); + PutComment(); /* write segment org */ + printf("Org : $%08lX%14ld\n", pgorg, pgorg); + CheckESC(); + PutComment(); /* write alignment factor */ + printf("Alignment : $%08lX%14ld\n", align, align); + CheckESC(); + PutComment(); /* write number sex */ + printf("Number sex : $%02X%20d\n", numsex, numsex); + CheckESC(); + if (version == 1) { /* write language card */ + PutComment(); + printf("Language card : $%02X%20d\n", lang_card, lang_card); + CheckESC(); + } + PutComment(); /* write segment number */ + printf("Segment number: $%04X%18d\n", segnum, segnum); + CheckESC(); + PutComment(); /* write segment entry */ + printf("Segment entry : $%08lX%14ld\n", ent_disp, ent_disp); + CheckESC(); + PutComment(); /* write segment names disp */ + printf("Disp to names : $%04X%18d\n", nam_disp, nam_disp); + CheckESC(); + PutComment(); /* write segment body disp */ + printf("Disp to body : $%04X%18d\n", bod_disp, bod_disp); + CheckESC(); + if (! CheckHead()) /* don't print labels if header error */ + return FALSE; + PutComment(); /* write load name */ + printf("Load name : %s\n", loadname); + CheckESC(); + PutComment(); /* write segment name */ + printf("Segment name : %s\n", segname); + CheckESC(); + } + } +return TRUE; +} + +/**** Opcode Dump Subroutines *************************************/ + +void DoExpr (void); + +/*************************************************************** +* +* Reads the opcode into "opcode" +* +***************************************************************/ + +int GetOpCode (void) + +{ +++count; /* advance byte counter */ +opcode = fgetc(input); +if (opcode == -1) { /* check for end of file */ + opcode = 0; + Error(9," "); /* end of file encountered */ + exit(status); + } +return opcode; +} + +/*************************************************************** +* +* NewLine - Issues a Formatted New Line +* +***************************************************************/ + +void NewLine (void) + +{ +int count; + +putchar('\n'); +if (colf) + count = 33; +else + count = 17; +while (count--) + putchar(' '); +} + +/*************************************************************** +* +* ReadInt - reads an integer +* +* Inputs: +* numsex - number sex +* input - reference number of file +* numlen - length of number +* nPtr - pointer to place result +* +***************************************************************/ + +void ReadInt (long *nPtr, int numlen, FILE *f, int numsex) + +{ +int i; +long k,n; +union { + char c[4]; + long l; + } u; + +if (numlen <= 4) { + u.l = 0; + for (i = 0; i < numlen; ++i) + u.c[i] = fgetc(f); + *nPtr = u.l; + if (numsex) { + n = *nPtr; + for (i = 0; i < 4; ++i) { + k = (k << 8) | (n && 0xFF); + n = n >> 8; + } + *nPtr = k; + } + } +} + +/*************************************************************** +* +* ReadName - reads in a symbol name +* +* Inputs: +* name - pointer to place the name +* lablen - length of name +* f - open file ref number +* +***************************************************************/ + +void ReadName (char *name, int lablen, FILE *f) + +{ +int i; + +if (lablen) /* get the label length */ + act_lablen = lablen; +else + act_lablen = fgetc(f); +for (i = 0; i < act_lablen; ++i) /* read the name */ + name[i] = fgetc(f); +name[act_lablen] = (char) 0; /* set the null terminator */ +} + +/*************************************************************** +* +* PrintW - Writes a word in a string to the console +* +* Inputs: +* str - pointer to the string to write +* +***************************************************************/ + +void PrintW (char *str) + +{ +int i = 0; + +while ((str[i]) && (! isspace(str[i]))) + putchar(str[i++]); +} + +/*************************************************************** +* +* PutConst - Writes the constant bytes for opcode format +* +* Inputs: +* len - number of bytes to write +* input - file to get bytes from +* +***************************************************************/ + +void PutConst (long len, int flag) + +{ +long k; +int i; + +if (flag) { /* see if we print out record */ + i = 0; + for (k = 0; k < len; ++k) { + ++i; /* allow 23 numbers per line */ + if (i == 24) { /* see if we need to issue a new line */ + i = 1; + NewLine(); + } + printf("%02X", (int) fgetc(input)); /* write the hex */ + CheckESC(); + } + } +else + fseek(input, ftell(input)+len, SEEK_SET); +} + +/*************************************************************** +* +* PutCTPC - Writes the count and program counter +* +***************************************************************/ + +void PutCTPC(void) + +{ +putchar('\n'); +if (colf) /* check to make sure you write col */ + printf("%06lX %06lX | ", count, pc); +} + +/*************************************************************** +* +* PutNumber - Writes a number +* +* Inputs: +* input - input file +* +* Outputs: +* number - contains number read +* +***************************************************************/ + +void PutNumber (void) + +{ +ReadInt(&number,numlen,input,numsex); +switch (numlen) { + case 1: printf("%02X", (int) number); + case 2: printf("%04X", (int) number); + case 3: printf("%06lX", (long) number); + case 4: printf("%08lX", (long) number); + } +count = count + numlen; +} + +/*************************************************************** +* +* Putsymbol - Writes the symbol +* +* Inputs: +* input - input file +* +* Outputs: +* symbol - symbol read +* +***************************************************************/ + +void PutSymbol (void) + +{ +ReadName(symbol,lablen,input); +PrintW(symbol); +if (lablen) + count = count + lablen; +else + count = count + act_lablen + 1; +} + +/*************************************************************** +* +* PutOpCode - Writes the opcode +* +* Inputs: +* opcode - opcode to write +* input - input file +* +* Outputs: +* write opcode +* pc, count = updates accordingly +* +***************************************************************/ + +void PutOpCode (void) + +{ +long k; +int p1, p2, p3; /* temp storage for calculated parms */ + +if (opcode < OPALIGN) { /* handle short constant opcode */ + printf("CONST ($%02X) | ", (int) opcode); + pc = pc + opcode; + count = count + opcode; + PutConst(opcode,longc); /* write the constant opcodes */ + } +else switch (opcode) { + case OPALIGN: /* handle align opcode */ + printf("ALIGN ($E0) | "); + PutNumber(); + pc = pc + (pc % number); + break; + case OPORG: /* handle org opcode */ + printf("ORG ($E1) | "); + PutNumber(); + pc = pc + number; + break; + case OPRELOC: /* handle reloc opcode */ + p1 = fgetc(input); + p2 = fgetc(input); + printf("RELOC ($E2) | %02X : %02X : ", p1, p2); + PutNumber(); + printf(" : "); + PutNumber(); + count = count + 2; + break; + case OPINTSEG: /* handle interseg opcode */ + p1 = fgetc(input); + p2 = fgetc(input); + printf("INTERSEG ($E3) | %02X : %02X : ", p1, p2); + PutNumber(); + printf(" : "); + ReadInt(&number,2,input,numsex); + printf("%04X : ", (int) number); + ReadInt(&number,2,input,numsex); + printf("%04X : ", (int) number); + PutNumber(); + count = count + 6; + break; + case OPUSING: /* handle using opcode */ + printf("USING ($E4) | "); + PutSymbol(); + break; + case OPSTRONG: /* handle strong opcode */ + printf("STRONG ($E5) | "); + PutSymbol(); + break; + case OPGLOBAL: /* handle global opcode */ + printf("GLOBAL ($E6) | "); + PutSymbol(); + if (version == 1) { + p1 = fgetc(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %02X : %02X : %02X", p1, p2, p3); + count = count + 3; + } + else { + p1 = fgeti(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %04X : %02X : %02X", p1, p2, p3); + count = count + 4; + } + break; + case OPGEQU: /* handle gequ opcode */ + printf("GEQU ($E7) | "); + PutSymbol(); + if (version == 1) { + p1 = fgetc(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %02X : %02X : %02X :", p1, p2, p3); + count = count + 3; + } + else { + p1 = fgeti(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %04X : %02X : %02X :", p1, p2, p3); + count = count + 4; + } + DoExpr(); + break; + case OPMEM: /* handle mem opcode */ + printf("MEM ($E8) | "); + PutNumber(); + printf(" : "); + PutNumber(); + break; + case OPEXPR: /* handle expr opcode */ + k = fgetc(input); + count++; + printf("EXPR ($EB) | %02X :", (int) k); + pc = pc + k; + DoExpr(); + break; + case OPZEXPR: /* handle zexpr opcode */ + k = fgetc(input); + count++; + printf("ZEXPR ($EC) | %02X :", (int) k); + pc = pc + k; + DoExpr(); + break; + case OPBEXPR: /* handle bexpr opcode */ + k = fgetc(input); + count++; + printf("BEXPR ($ED) | %02X :", (int) k); + pc = pc + k; + DoExpr(); + break; + case OPRELEXPR: /* handle relexpr opcode */ + k = fgetc(input); + count++; + printf("RELEXPR ($EE) | %02X : ", (int) k); + PutNumber(); + pc = pc + k; + printf(" :"); + DoExpr(); + break; + case OPLOCAL: /* handle local opcode */ + printf("LOCAL ($EF) | "); + PutSymbol(); + if (version == 1) { + p1 = fgetc(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %02X : %02X : %02X", p1, p2, p3); + count = count + 3; + } + else { + p1 = fgeti(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %04X : %02X : %02X", p1, p2, p3); + count = count + 4; + } + break; + case OPEQU: /* handle equ opcode */ + printf("EQU ($F0) | "); + PutSymbol(); + if (version == 1) { + p1 = fgetc(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %02X : %02X : %02X :", p1, p2, p3); + count = count + 3; + } + else { + p1 = fgeti(input); + p2 = fgetc(input); + p3 = fgetc(input); + printf(" : %04X : %02X : %02X :", p1, p2, p3); + count = count + 4; + } + DoExpr(); + break; + case OPDS: /* handle ds opcode */ + printf("DS ($F1) | "); + PutNumber(); + pc = pc + number; + break; + case OPLONG: /* handle long constant opcode */ + printf("LCONST ($F2) | "); + PutNumber(); + printf(" : "); + NewLine(); + pc = pc + number; + count = count + number; + PutConst(number,longc); /* write the constant opcodes */ + break; + case OPLEXPR: /* handle long expression opcode */ + k = fgetc(input); + count++; + printf("LEXPR ($F3) | %02X :", (int) k); + pc = pc + k; + DoExpr(); + break; + case OPENTRY: /* handle entry opcode */ + printf("ENTRY ($F4) | "); + PutNumber(); + printf(" : "); + PutSymbol(); + break; + case OPSRELOC: /* handle short reloc opcode */ + p1 = fgetc(input); + p2 = fgetc(input); + printf("cRELOC ($F5) | %02X : %02X : ", p1, p2); + ReadInt(&number,2,input,numsex); + printf("%04X : ", (int) number); + ReadInt(&number,2,input,numsex); + printf("%04X", (int) number); + count = count + 6; + break; + case OPSINTSEG: /* handle short interseg opcode */ + p1 = fgetc(input); + p2 = fgetc(input); + printf("cINTRSEG ($F6) | %02X : %02X : ", p1, p2); + ReadInt(&number,2,input,numsex); + printf("%04X : %02X : ", (int) number, (int) fgetc(input)); + ReadInt(&number,2,input,numsex); + printf("%04X", (int) number); + count = count + 7; + break; + case OPSUPER: /* handle short interseg opcode */ + printf("SUPER ($F7) | "); + ReadInt(&number,4,input,numsex); + printf("%08lX : %02X", (long) number, (int) fgetc(input)); + NewLine(); + count = count + number; + PutConst(number-1,1); + break; + default: + Error(7," "); + break; + } +} + +/*************************************************************** +* +* PutOpCodeBody - dump the body of one segment in opcode format +* +***************************************************************/ + +void PutOpCodeBody (void) + +{ +while (GetOpCode()) { + --count; /* adjust the counter */ + PutCTPC(); /* write the count and pc */ + count++; + PutOpCode(); /* write out the opcode */ + CheckESC(); + } +--count; /* write out the end opcode */ +PutCTPC(); +puts("END ($00)"); /* print end directive */ +} + +/*************************************************************** +* +* DpOpCode - Dump file in opcode format +* +***************************************************************/ + +void DpOpCode(void) + +{ +while (NextSeg()) { + count = /* initialize counter and pc */ + pc = 0; + CheckESC(); + if (! PutHeader()) /* write out the header */ + return; + if (body) { /* write out the body */ + if ((! header) && checkf) { + count = bod_disp; + fseek(input, ftell(input) + bod_disp, SEEK_CUR); + } + PutOpCodeBody(); + } + if ((! shorth) || body) + puts("\n"); + } +} + +/**** Expression Output Subroutines *******************************/ + +/*************************************************************** +* +* DoOper - Writes an operation +* +* Inputs: +* space - print a leading space? +* +***************************************************************/ + +void DoOper (BOOLEAN space) + +{ +if (space) + putchar(' '); +switch(opcode) { + case 1: /* handle addition */ + putchar('+'); + break; + case 2: /* handle subtraction */ + putchar('-'); + break; + case 3: /* handle multiplication */ + putchar('*'); + break; + case 4: /* handle division */ + putchar('/'); + break; + case 5: /* handle modulo */ + putchar('%'); + break; + case 6: /* handle negation */ + if (format != 1) + printf("--"); + else + printf("unary -"); + break; + case 7: /* handle bit shift */ + putchar('|'); + break; + case 8: /* handle logical and */ + printf(".AND."); + break; + case 9: /* handle logical or */ + printf(".OR."); + break; + case 10: /* handle logical xor */ + printf(".EOR."); + break; + case 11: /* handle logical not */ + printf(".NOT."); + break; + case 12: /* handle less or equal */ + printf("<="); + break; + case 13: /* handle greater or equal */ + printf(">="); + break; + case 14: /* handle not equal */ + printf("<>"); + break; + case 15: /* handle less */ + putchar('<'); + break; + case 16: /* handle greater */ + putchar('>'); + break; + case 17: /* handle equal */ + putchar('='); + break; + case 18: /* handle bit and */ + printf(".BAND."); + break; + case 19: /* handle bit or */ + printf(".BOR."); + break; + case 20: /* handle bit xor */ + printf(".BEOR."); + break; + } +} + +/*************************************************************** +* +* DoOpnd - Writes an operand +* +***************************************************************/ + +void DoOpnd (void) + +{ +switch(opcode) { + case 128: /* handle location counter */ + printf(" (*)"); + break; + case 129: /* handle constant */ + printf(" $"); + PutNumber(); + break; + case 130: /* handle weak reference */ + printf(" W:"); + PutSymbol(); + break; + case 131: /* handle value of label */ + putchar(' '); + PutSymbol(); + break; + case 132: /* handle length attribute */ + printf(" L:"); + PutSymbol(); + break; + case 133: /* handle type attribute */ + printf(" T:"); + PutSymbol(); + break; + case 134: /* handle count attribute */ + printf(" C:"); + PutSymbol(); + break; + case 135: /* handle relative ofset */ + printf(" ("); + PrintW(segname); + printf("+$"); + PutNumber(); + putchar(')'); + break; + } +} + +/*************************************************************** +* +* DoExpr - Writes an expression +* +***************************************************************/ + +void DoExpr (void) + +{ +while (GetOpCode()) { + if (opcode < 128) + DoOper(TRUE); + else + DoOpnd(); + } +} + +/**** Disassembler Subroutines ************************************/ + +/*************************************************************** +* +* ReadSym - Reads in a symbol and appends it to symbol +* +***************************************************************/ + +void ReadSym (void) + +{ +int i,k; + +k = strlen(symbol); +if (lablen) /* handle variable length labels */ + act_lablen = lablen; +else { + act_lablen = fgetc(input); + ++count; + } +for (i=0; i 4) { /* handle avariable I instruction */ + if (imode) + return 2; + return 1; + } +return len; /* return a fixed length */ +} + +/*************************************************************** +* +* GtOpName - Returns Pointer to Opcode Name +* +* Inputs: +* opcode - operation code +* +* Outputs: +* pointer to numonic string +* +* Notes: There is no terminating null on the string. The +* caller should use exactly 3 characters. +* +***************************************************************/ + +char *GtOpName (int opcode) + +{ +return &opName[opcode*3]; +} + +/*************************************************************** +* +* IsExpr - Check to see if OPCODE is from an expression +* +* Inputs: +* op - object module opcode +* +* Outputs: +* true if from an expression; else false +* Note: if constant != 0 then --constant, return false +* if constant == 0 then +* if (constant_opcode) set constant, getopcode, return false +* else return true +* +***************************************************************/ + +BOOLEAN IsExpr (int op) + +{ +if ((! checkf) && (! header)) + return FALSE; +if (constant) /* handle in a constant */ + return FALSE; +if (op < OPALIGN) { /* handle short constant */ + constant = op; + GetOpCode(); + return FALSE; + } +if (op == OPLONG) { /* handle long constant */ + ReadInt(&constant,numlen,input,numsex); + count = count + numlen; + GetOpCode(); + return FALSE; + } +return TRUE; +} + +/*************************************************************** +* +* PutLSymbol - Writes the symbol +* +* Inputs: +* input - input file +* +* Outputs: +* symbol - symbol read +* +***************************************************************/ + +void PutLSymbol (void) + +{ +int i; + +ReadName(symbol,lablen,input); +printf(symbol); +for (i=act_lablen; i<8; i++) /* fill out with spaces */ + putchar(' '); +putchar(' '); +if (lablen) /* handle variable length labels */ + count = count + lablen; +else + count = count + act_lablen + 1; +} + +/*************************************************************** +* +* PutStreg - Writes out the registar status +* +* Inputs: +* mreg - accumulator flag +* ireg - index registar flag +* +***************************************************************/ + +void PutStreg (void) + +{ +PutCTPC(); +printf(" LONGA "); +if (mreg) + printf("ON"); +else + printf("OFF"); +PutCTPC(); +printf(" LONGI "); +if (ireg) + printf("ON"); +else + printf("OFF"); +} + +/*************************************************************** +* +* ReadOpVal - reads an integer from a constant field +* +* Inputs: +* numsex - number sex +* input - reference number of file +* numlen - length of number +* nPtr - pointer to place result +* +* Outputs: +* Returns true if successful, else false. +* +***************************************************************/ + +BOOLEAN ReadOpVal (long *nPtr, int numlen, FILE *f, int numsex) + +{ +int i; +long k,n; +union { + char c[4]; + long l; + } u; + +if (numlen <= 4) { + u.l = 0; + for (i = 0; i < numlen; ++i) { + if (!constant) { + GetOpCode(); + if (opcode && (opcode < OPALIGN)) + constant = opcode; + else + return FALSE; + } + else + --constant; + u.c[i] = fgetc(f); + } + *nPtr = u.l; + if (numsex) { + n = *nPtr; + for (i = 0; i < 4; ++i) { + k = (k << 8) | (n && 0xFF); + n = n >> 8; + } + *nPtr = k; + } + } +return TRUE; +} + +/*************************************************************** +* +* PutOpnd - Writes the operand for an instruction +* +* Outputs: +* Returns true if successful, false if an expression +* was encountered in the middle of operand. +* +***************************************************************/ + +BOOLEAN PutOpnd (int op) + +{ +BOOLEAN success; +int i; +long addr; + +i = GtOpLen(op,mreg,ireg); +pc = pc + i; +if (constant) { /* split on constant or expression */ + count = count + i; /* update the file counter */ + success = ReadOpVal(&number,i,input,numsex); /* get the value and print it */ + printf("$%0*lX", (int) i*2, (long) number); + if (op == REP) { /* check for REP */ + if (number & 32) mreg = 1; + if (number & 16) ireg = 1; + PutStreg(); + } + if (op == SEP) { /* check for SEP */ + if (number & 32) mreg = 0; + if (number & 16) ireg = 0; + PutStreg(); + } + if (op == COP) { /* special handling for debug COPs */ + switch (number) { + case 0: + case 1: + case 2: + success = ReadOpVal(&number,2,input,numsex); + printf(",%d", (int) number); + count += 2; + pc += 2; + break; + case 5: + sTable = TRUE; + break; + } + } + } +else { /* handle case where operand is an exp */ + switch(GetOpCode()) { + case OPEXPR: case OPZEXPR: case OPBEXPR: case OPLEXPR: + fgetc(input); + ++count; + DoInexp(); /* write expression in infix form */ + break; + case OPRELEXPR: + fgetc(input); + ReadInt(&number,numlen,input,numsex); + count = count + numlen + 1; + DoInexp(); /* write expression in infix form */ + break; + default: /* case with unexpected input */ + printf("???"); + break; + } + } +return success; +} + +/*************************************************************** +* +* Dis_DC - Disassembles a DC format +* +* Inputs: +* op - object module opcode +* +***************************************************************/ + +void Dis_DC (int op) + +{ +int i; +int p1, p2; /* temps for computed parameters */ + +switch(op) { + case OPGEQU: case OPEQU: /* handle equates */ + PutLSymbol(); + if (op == OPEQU) + printf("EQU "); + else + printf("GEQU "); + fgetc(input); fgetc(input); fgetc(input); + count = count+3; + if (version == 2) { + fgetc(input); + ++count; + } + DoInexp(); + break; + case OPUSING: /* handle using directives */ + printf(" USING "); + PutSymbol(); + break; + case OPLOCAL: case OPGLOBAL: /* handle local and global labels */ + PutLSymbol(); + if (op == OPLOCAL) + printf("ANOP"); + else + printf("ENTRY"); + fgetc(input); fgetc(input); fgetc(input); + count = count + 3; + if (version == 2) { + fgetc(input); + ++count; + } + break; + case OPDS: case OPALIGN: /* handle ds and align directive */ + if (op == OPALIGN) + printf(" ALIGN $"); + else + printf(" DS $"); + PutNumber(); + if (op == OPALIGN) + pc = pc + (pc % number); + else + pc = pc + number; + break; + case OPSTRONG: /* handle strong reference */ + printf(" DC R'"); + PutSymbol(); + putchar('\''); + break; + case OPORG: /* handle inter-segment org */ + printf(" ORG *+$"); + PutNumber(); + pc = pc + number; + break; + case OPMEM: /* handle inter-segment mem */ + printf(" MEM $"); + PutNumber(); + printf(",$"); + PutNumber(); + break; + case OPEXPR: case OPZEXPR: /* handle expressions */ + case OPBEXPR: case OPLEXPR: case OPRELEXPR: + printf(" DC "); + i = fgetc(input); + if (i == 1) + printf("I1'"); + else if (i == 2) + printf("I2'"); + else if (i == 3) + printf("I3'"); + else + printf("I4'"); + ++count; + pc = pc + i; + if (op == OPRELEXPR) { + PutNumber(); + putchar('+'); + } + DoInexp(); /* write expression in infix form */ + putchar('\''); + break; + case OPRELOC: /* handle reloc opcode */ + p1 = fgetc(input); + p2 = fgetc(input); + printf("! RELOC ($E2) | %02X : %02X : ", p1, p2); + PutNumber(); + printf(" : "); + PutNumber(); + count = count + 2; + break; + case OPINTSEG: /* handle interseg opcode */ + p1 = fgetc(input); + p2 = fgetc(input); + printf("! INTERSEG ($E3) | %02X : %02X : ", p1, p2); + PutNumber(); + printf(" : "); + ReadInt(&number,2,input,numsex); + printf("%04X : ", (int) number); + ReadInt(&number,2,input,numsex); + printf("%04X : ", (int) number); + PutNumber(); + count = count + 6; + break; + case OPENTRY: /* handle entry opcode */ + printf("! ENTRY ($F4) | "); + PutNumber(); + printf(" : "); + PutSymbol(); + break; + default: + Error(7," "); + break; + } +} + +/*************************************************************** +* +* Disasm - Disassembles OPCODE +* +* Inputs: +* op - assembly language opcode +* +* Outputs: +* Returns true if successful, false if an expression +* was hit trying to process an operand. +* +***************************************************************/ + +BOOLEAN Disasm (int op) + +{ +BOOLEAN success; +int i; +char opn[4]; + +sTable = FALSE; /* no COP symbol table found (yet) */ +success = TRUE; /* assume everything will work */ +--constant; /* now this is a constant */ +++pc; /* update program counter */ +strncpy(opn, GtOpName(op), 3); +opn[3] = (char) 0; +printf(" %s ", opn); +switch(GtOpKind(op)) { /* split on type of output format */ + case 1: /* handle '# operand' */ + putchar('#'); + success = PutOpnd(op); + break; + case 2: /* handle 'operand' */ + success = PutOpnd(op); + break; + case 3: /* handle '> operand' */ + putchar('>'); + success = PutOpnd(op); + break; + case 4: /* handle 'A' */ + putchar('A'); + break; + case 5: /* handle ' ' or 'operand' */ + if (GtOpLen(op,mreg,ireg)) + success = PutOpnd(op); + break; + case 6: /* handle '(operand),Y' */ + putchar('('); + success = PutOpnd(op); + printf("),Y"); + break; + case 7: /* handle '[operand],Y' */ + putchar('['); + success = PutOpnd(op); + printf("],Y"); + break; + case 8: /* handle '(operand,X)' */ + putchar('('); + success = PutOpnd(op); + printf(",X)"); + break; + case 9: /* handle 'operand,X' */ + success = PutOpnd(op); + printf(",X"); + break; + case 10: /* handle 'operand,Y' */ + success = PutOpnd(op); + printf(",Y"); + break; + case 11: /* handle '>operand,X' */ + putchar('>'); + success = PutOpnd(op); + printf(",X"); + break; + case 12: /* handle '(operand)' */ + putchar('('); + success = PutOpnd(op); + putchar(')'); + break; + case 13: /* handle '[operand]' */ + putchar('['); + success = PutOpnd(op); + putchar(']'); + break; + case 14: /* handle 'operand,S' */ + success = PutOpnd(op); + printf(",S"); + break; + case 15: /* handle '(operand,S),Y */ + putchar('('); + success = PutOpnd(op); + printf(",S),Y"); + break; + case 16: /* handle 'operand,operand' */ + success = PutOpnd(op); + putchar(','); + success = PutOpnd(op); + break; + case 17: /* handle relative branches */ + if (constant) { + i = GtOpLen(op,mreg,ireg); + pc = pc + i; + count = count + i; /* update the file counter */ + constant = constant - i; /* set new constant number */ + number = 0; + ReadInt(&number,i,input,numsex); /* get the value and print it */ + if (i == 1) { + if (number > 127) + number = number | -256; + } + else { + if (number > 32767) + number = number | -32768; + } + number = number + i + 1; + if (number < 0) { + number = -number; + printf("*-$"); + } + else + printf("*+$"); + printf("%0*lX", (int) i*2, (long) number); + } + else + success = PutOpnd(op); + break; + default: + printf("Operand Error"); + status = -1; + break; + } +return success; +} + +/*************************************************************** +* +* DisSTable - disassemble a COP 5 symbol table +* +***************************************************************/ + +void DisSTable (void) + +{ +long tlen; +int p1, p2, p3, p4; /* temps for computed parms */ + +if (!constant) { + GetOpCode(); + if (opcode && (opcode < OPALIGN)) + constant = opcode; + else { + PutCTPC(); + Dis_DC(opcode); + } + } +if (constant >= 2) { + ReadInt(&tlen,2,input,numsex); /* get and print the table length */ + PutCTPC(); + printf(" DC I'%d'", (int) tlen); + pc += 2; + count += 2; + constant -= 2; + CheckESC(); + while (tlen > 0) { + if (!constant) { + GetOpCode(); + if (opcode && (opcode < OPALIGN)) + constant = opcode; + } + if (constant) { + ReadOpVal(&number,4,input,numsex); + PutCTPC(); + printf(" DC I4'%d'", (long) number); + pc += 4; + count += 4; + } + else { + PutCTPC(); + Dis_DC(opcode); + } + if (!constant) { + GetOpCode(); + if (opcode && (opcode < OPALIGN)) + constant = opcode; + } + if (constant) { + ReadOpVal(&number,4,input,numsex); + PutCTPC(); + printf(" DC I4'%d'", (long) number); + pc += 4; + count += 4; + } + else { + PutCTPC(); + Dis_DC(opcode); + } + if (!constant) { + GetOpCode(); + if (opcode && (opcode < OPALIGN)) + constant = opcode; + else { + PutCTPC(); + Dis_DC(opcode); + } + } + if (constant >= 4) { + PutCTPC(); + p1 = fgetc(input); + p2 = fgetc(input); + p3 = fgetc(input); + p4 = fgetc(input); + printf(" DC H'%02X %02X %02X%02X'", p1, p2, p3, p4); + pc += 4; + count += 4; + constant -= 4; + } + tlen -= 12; + } + } +} + +/*************************************************************** +* +* Dis_Cns - disassemble a constant as a DC statement(s) +* +***************************************************************/ + +void Dis_Cns (int opcode) + +{ +int i, delta; +int b1,b2; + +while (opcode != 0) { + printf(" DC H'"); + i = 16; + while ((i != 0) && (opcode != 0)) { + if (opcode == 1) { + printf("%02X", (int) fgetc(input)); + delta = 1; + } + else { + b1 = fgetc(input); + b2 = fgetc(input); + if (opcode == 2) + printf("%02X%02X", (int) b1, (int) b2); + else + printf("%02X%02X ", (int) b1, (int) b2); + delta = 2; + } + opcode -= delta; + i -= delta; + pc += delta; + count += delta; + } + putchar('\''); + if (opcode != 0) { + CheckESC(); + PutCTPC(); + } + } +} + +/*************************************************************** +* +* DpDisasm - Dump file in disassembled format +* +***************************************************************/ + +void DpDisasm (void) + +{ +int i; +long mark; +long codelen; + +while (NextSeg()) { + count = /* initialize counter and pc */ + pc = + constant = 0; /* we're not in a constant */ + CheckESC(); + if (checkf || header) /* write out the header */ + if (! PutHeader()) + return; + if ((! checkf) && (! header)) { /* get segment length */ + mark = GetEOF(input); + blocks = 30000; + } + else if ((ftype == LIBFL) || (version == 2)) + mark = blkcnt; + else + mark = blkcnt*512; + if (body) { /* write out the body */ + if ((! header) && checkf) { + count = bod_disp; + fseek(input, ftell(input) + bod_disp, SEEK_SET); + } + PutStreg(); /* write the registar status */ + PutCTPC(); + printf(segname); /* print the segment name */ + for (i=strlen(segname); i<8; i++) /* fill out with spaces */ + putchar(' '); + if (kind & 1) /* print out segment type */ + printf(" DATA"); + else + printf(" START"); + codelen = length-resspc; + while (count <= mark) { + PutCTPC(); + GetOpCode(); + if (checkf && ((pc > codelen) || ((! opcode) && (pc == codelen)))) + break; + if (((kind & 0x001F) == 1) && checkf + && (opcode < OPALIGN) && (opcode != 0)) + Dis_Cns(opcode); + else if (IsExpr(opcode)) + Dis_DC(opcode); + else + if (!Disasm(opcode)) { + PutCTPC(); + Dis_DC(opcode); + } + else if (sTable) + DisSTable(); + CheckESC(); + } + if (resspc) { + printf(" DS $%08lX", (long) resspc); + count += resspc; + } + if (count > mark) + PutCTPC(); + puts(" END"); /* print out the end directive */ + } + if ((! shorth) || body) + puts("\n"); + } +} + +/**** Hex Dump Subroutines ****************************************/ + +/*************************************************************** +* +* DpHex - Dump file in hex format +* +***************************************************************/ + +void DpHex (void) + +{ +long mark; +long ch = 0; +char chline[20]; +int k, i, space; + +while (NextSeg()) { + count = 0L; + CheckESC(); + if (! PutHeader()) /* write out the header */ + return; + /* if we don't print header and we're not doing file checking then + dump the entire file and forget about segment scanning */ + if ((! checkf) && (! header)) { /* get the segment length */ + mark = GetEOF(input); + blocks = 30000; + } + else if ((ftype == LIBFL) || (version == 2)) + mark = blkcnt; + else + mark = blkcnt*512; + if (body) { /* write out the body */ + if ((! header) && checkf) { + count = bod_disp; + fseek(input, ftell(input) + bod_disp, SEEK_SET); + } + while (count <= mark) { + putchar('\n'); + if (colf) + printf("%06lX | ", count); + space = 0; + for (k=0; k<16; k++) { + ch = fgetc(input); + count++; + if (count > mark) { + printf(" "); + ch = 0; + } + else + printf("%02X", ch); + if ((ch & 127) > 31) + chline[k] = ch & 127; + else + chline[k] = ' '; + space++; + if (space == 4) { + putchar(' '); + space = 0; + } + CheckESC(); + } + chline[16] = 0; + printf(" | %s", chline); + CheckESC(); + } + } + if ((! shorth) || body) printf("\n\n"); + } +} + +/**** Command Line Input Subroutines ******************************/ + +/*************************************************************** +* +* GetFType - Return Type Of File +* +* Inputs: +* name - file name to get the type of +* +* Returns: file type; 0 if not found +* +***************************************************************/ + +int GetFType (char name[]) + +{ +struct FileInfoRecGS { + int pCount; + struct { + int length; + char name[FILEMAX]; + } *fname; + int access; + int fileType; + } parm; + +parm.pCount = 3; +parm.fname = (void *) malloc (sizeof(int) + FILEMAX); +if (parm.fname == NULL) + return 0; +parm.fname->length = strlen(name); +strcpy(parm.fname->name, name); +GetFileInfoGS(&parm); +free(parm.fname); +if (toolerror()) + return 0; +return parm.fileType; +} + +/*************************************************************** +* +* CheckFile - Checks For Valid File +* +***************************************************************/ + +BOOLEAN CheckFile (char file[]) + +{ +if (! checkf) { /* see if we have to check file type */ + ftype = FALSE; /* unspecified file type */ + return TRUE; + } +/* insure file exists and is an OMF type of file */ +if (! (ftype = GetFType(file))) { + Error(5,file); + return FALSE; + } +if ((ftype < OBJFL) || (ftype > MAXFL)) { + Error(6,file); + return FALSE; + } +return TRUE; +} + +/*************************************************************** +* +* ExpandDev - Expand devices and prefixes +* +***************************************************************/ + +#define INIT_WILDCARD(parm) (PDosInt(0x0149,parm)) +#define NEXT_WILDCARD(parm) (PDosInt(0x014A,parm)) + +void ExpandDev (char name[]) + +{ +struct { /* parameter block for Init_Wildcard */ + int pcount; + struct { + int length; + char name[FILEMAX]; + } *inName; + int flags; + } iwRec; + +struct { /* parameter block for Next_Wildcard */ + int pcount; + struct { + int buffLen; + int length; + char name[FILEMAX]; + } *outName; + } nwRec; + +iwRec.inName = (void *) malloc (sizeof(int) + FILEMAX); +nwRec.outName = (void *) malloc (sizeof(int)*2 + FILEMAX); +if ((iwRec.inName == NULL) || (nwRec.outName == NULL)) { + if (iwRec.inName != NULL) + free(iwRec.inName); + if (nwRec.outName != NULL) + free(nwRec.outName); + return; + } +iwRec.pcount = 2; +iwRec.inName->length = strlen(name); +strcpy(iwRec.inName->name, name); +iwRec.flags = 0x4000; +nwRec.pcount = 1; +nwRec.outName->buffLen = FILEMAX+4; +INIT_WILDCARD(&iwRec); +if (!toolerror()) { + NEXT_WILDCARD(&nwRec); + if (!toolerror()) { + memcpy(name, nwRec.outName->name, nwRec.outName->length); + name[nwRec.outName->length] = (char) 0; + } + } +free(iwRec.inName); +free(nwRec.outName); +} + +/*************************************************************** +* +* SetFlag - Sets the input parameters flags +* +***************************************************************/ + +BOOLEAN SetFlag (char *str) + +{ +char ch; + +if (strlen(str) != 2) { + Error(4,str); + return FALSE; + } +ch = toupper(str[1]); +if ((str[0]) == '+') { /* handle + flags */ + if (ch == 'X') {format = 2;} + else if (ch == 'D') {format = 1;} + else if (ch == 'S') {shorth = FALSE;} + else if (ch == 'I') {ireg = TRUE;} + else if (ch == 'L') {longc = TRUE;} + else if (ch == 'M') {mreg = TRUE;} + else if (ch == 'H') {header = TRUE;} + else if (ch == 'O') {body = TRUE;} + else if (ch == 'F') {checkf = TRUE;} + else if (ch == 'A') {colf = TRUE;} + else {Error(4, str); return FALSE;} + } +else { /* handle - flags */ + if (ch == 'X') {format = 0;} + else if (ch == 'D') {format = 0;} + else if (ch == 'S') {shorth = TRUE;} + else if (ch == 'I') {ireg = FALSE;} + else if (ch == 'L') {longc = FALSE;} + else if (ch == 'M') {mreg = FALSE;} + else if (ch == 'H') {header = FALSE;} + else if (ch == 'O') {body = FALSE;} + else if (ch == 'F') {checkf = FALSE;} + else if (ch == 'A') {colf = FALSE;} + else {Error(4, str); return FALSE;} + } +return TRUE; +} + +/*************************************************************** +* +* Reads the names list and sets up namelist pointers +* +***************************************************************/ + +BOOLEAN GetList (int num, int argc, char *argv[]) + +{ +char local[NAMEMAX]; +int i, k; + +if (num == argc) { + names = FALSE; + return TRUE; + } +for (i=num; i<=argc; i++) { + strncat(nlist, argv[i], strlen(argv[i])); + strncat(nlist, " ", 1); + } +strcpy(local, nlist); +if (strlen(nlist) < 8) { + Error(4,local); + names = FALSE; + return FALSE; + } +for (i=0; i<5; i++) + nlist[i] = toupper(nlist[i]); +if (strncmp(nlist,"NAMES=(",7) != 0) { + Error(4,local); + names = FALSE; + return FALSE; + } +for (i=0; i<7; i++) + nlist[i] = ' '; +i = 0; +while (nlist[i] && (nlist[i] != ')')) { + if (nlist[i] == ',') nlist[i] = ' '; + i++; + } +if (! nlist[i]) { + Error(4,local); + names = FALSE; + return FALSE; + } +nlist[i] = 0; +names = TRUE; +return TRUE; +} + +/*************************************************************** +* +* GetName - This is the name input routine +* +***************************************************************/ + +void GetName (char *name) + +{ +int i, x; +char ch; + +fputs("File name: ", stdout); /* prompt for file name */ +name[0] = (char) 0; /* read the file name */ +fgets(name, NAMEMAX, stdin); +x = strlen(name); /* strip whitespace */ +while ((x != 0) && isspace(name[x-1])) + name[--x] = (char) 0; +while (((x = strlen(name)) != 0) && isspace(name[0])) + for (i = 0; i < x; ++i) + name[i] = name[i+1]; +} + +/*************************************************************** +* +* GetParms - Gets the input parameters +* +***************************************************************/ + +BOOLEAN GetParms (int argc, char *argv[]) + +{ +char local[NAMEMAX]; +int i; + +i = 1; +while (i <= argc) { /* first set the flags */ + strcpy(local,argv[i]); + ++i; + if ((local[0] == '+') || (local[0] == '-')) { + if (! SetFlag(local)) + return FALSE; + } + else break; + } +if (i <= argc) /* get file name */ + strcpy(fname,argv[i-1]); +else { + GetName(fname); /* ask for and get file name */ + i = argc; /* no names list */ + } +ExpandDev(fname); /* expand devices */ +if (! CheckFile(fname)) + return FALSE; +if ((input = fopen(fname,"rb")) == NULL) { + Error(5,fname); + return FALSE; + } +return GetList(i, argc, argv); +} + +/**************************************************************** +* +* Initialize - Initialize variables +* +****************************************************************/ + +void Initialize (void) + +{ +puts("DumpOBJ 2.0.1\n"); /* write the header */ + +format = /* dump in opcode format */ +namc = /* no names in namelist */ +ftype = /* no specified file type yet */ +status = 0; /* assume no errors */ + +segmark = /* start with begining segment */ +blocks = 0L; /* no block yet */ + +shorth = FALSE; /* don't do "scan" type output */ + +ireg = /* use long index registars */ +mreg = /* use long accumulator */ +header = /* print the header */ +longc = /* print long constants */ +body = /* print the body */ +checkf = /* check input file type */ +colf = TRUE; /* write out the numbers */ +} + +/**** Main Programs ***********************************************/ + +/**************************************************************** +* +* Main - Begin Program +* +****************************************************************/ + +int main (int argc, char * argv[]) + +{ +Initialize(); /* initialize variables */ +if (GetParms(argc, argv)) { /* get input parameters */ + switch (format) { + case 0: DpOpCode(); break; /* dump file in opcode format */ + case 1: DpDisasm(); break; /* dump file in disassembled format */ + case 2: DpHex(); break; /* dump file in hex format */ + default: Error(1," "); /* flag error if not one of these */ + } + } +putchar('\n'); +return status; +} diff --git a/doit b/doit old mode 100755 new mode 100644 index 04126e5..2f5869f --- a/doit +++ b/doit @@ -1 +1,2 @@ -make copy -c dumpobj 17 \ No newline at end of file +make +copy -c dumpobj 17 diff --git a/dumpobj.rez b/dumpobj.rez old mode 100755 new mode 100644 index d9194e5..35b9cd0 --- a/dumpobj.rez +++ b/dumpobj.rez @@ -1 +1,22 @@ -/*--------------------------------------------------------------*/ /* */ /* Resources for DumpOBJ */ /* */ /*--------------------------------------------------------------*/ #include "types.rez" /*- Finder Interface -------------------------------------------*/ resource rVersion(1) { { 2, /* Major revision */ 0, /* Minor revision */ 1, /* Bug version */ release, /* Release stage */ 0, /* Non-final release # */ }, verUS, /* Region code */ "DumpOBJ", /* Short version number */ "Copyright 1994, Byte Works, Inc." /* Long version number */ }; \ No newline at end of file +/*--------------------------------------------------------------*/ +/* */ +/* Resources for DumpOBJ */ +/* */ +/*--------------------------------------------------------------*/ + +#include "types.rez" + +/*- Finder Interface -------------------------------------------*/ + +resource rVersion(1) { + { + 2, /* Major revision */ + 0, /* Minor revision */ + 1, /* Bug version */ + release, /* Release stage */ + 0, /* Non-final release # */ + }, + verUS, /* Region code */ + "DumpOBJ", /* Short version number */ + "Copyright 1994, Byte Works, Inc." /* Long version number */ + }; diff --git a/make b/make old mode 100755 new mode 100644 index bcfd20e..0df6c1c --- a/make +++ b/make @@ -1 +1,29 @@ -* * DumpOBJ * unset exit Newer DumpOBJ DumpOBJ.rez if {Status} != 0 set exit on echo compile DumpOBJ.rez keep=DumpOBJ compile DumpOBJ.rez keep=DumpOBJ unset exit end MoreRecent DumpOBJ.a DumpOBJ.cc if {Status} != 0 set exit on echo compile +t +e DumpOBJ.cc compile +t +e DumpOBJ.cc unset exit end set auxtype $DB01 echo set auxtype $DB01 echo link DumpOBJ keep=DumpOBJ link DumpOBJ keep=DumpOBJ rename dumpobj DumpOBJ \ No newline at end of file +* +* DumpOBJ +* + +unset exit + +Newer DumpOBJ DumpOBJ.rez +if {Status} != 0 + set exit on + echo compile DumpOBJ.rez keep=DumpOBJ + compile DumpOBJ.rez keep=DumpOBJ + unset exit +end + +MoreRecent DumpOBJ.a DumpOBJ.cc +if {Status} != 0 + set exit on + echo compile +t +e DumpOBJ.cc + compile +t +e DumpOBJ.cc + unset exit +end + +set auxtype $DB01 +echo set auxtype $DB01 + +echo link DumpOBJ keep=DumpOBJ +link DumpOBJ keep=DumpOBJ + +rename dumpobj DumpOBJ