Subject: v001SRC057: coff -- Dump OMF Files Under Orca (GS), Part02/04 Newsgroups: comp.sources.apple2 Approved: jac@paul.rutgers.edu Submitted-by: Albert Chin (acmfiu@fiu.edu) Posting-number: Volume 1, Source:57 Archive-name: util/gs/shell/orca/coff/part02 Architecture: ONLY_2gs Version-number: 1.00 =coff.c -/* - utility to dump contents of OMF files - - 1990-1991, The UNIX Consortium developer project - - albert chin-a-young ... acmfiu@fiu.edu ... 26285659t@servax.fiu.edu - - ------------------------------------------------------------------- - - calling parameters: - coff [-OPTIONS] filename [segments..] [loadsegments..] - - OPTIONS DESCRIPTION - -v [+version] display coff's version number - -d [+asm] dump segment body in 65816-format disassembly - -T [+tool] interpret Toolbox, GS/OS, ProDOS, ROM calls - -x [+hex] dump segment body in hex (can be used with '+asm') - -l [+label] print expressions using labels (default is offsets) - -t [+infix] display expressions in infix form - -p [+postfix] display expressions in postfix form (default) - -m [+merlin] format of '+asm' to use merlin opcodes (default) - -o [+orca] format of '+asm' to use orca/m opcodes - -a [+shorta] 8-bit accumulator - -i [+shorti] 8-bit index registers - -s [+header] dump segment headers only - -n [+noheader] do not print segment headers - -f [+nooffset] do not print offset into file - -h [+help] print this information, then quit - - filename name of file to dump - [segments] names of segments in file to dump - [loadsegments] names of load segments in file to dump - - ---------------------------------------------------------------------- - - history: - - v1.0d may 2, 1991 albert chin - +longa, +longi removed and replaced by - +shorta, +shorti - fixed bug if OMF file looked like - pea $ - jsl > - (thanks tim meekins) - fixed bug for dangling asm opcodes at end - of OMF segment - (thanks tim meekins) - - v1.0c april 30, 1991 albert chin - new implementation of hex mode - (thanks to tim meekins) - +tool option recognizes toolbox, GS/OS, - ProDOS calls, ROM addresses - (thanks to morgan davis, dave lyons) - removed all global variables except flags - removed inline asm bug fix (my fault) - cleaned up code - minimal speed improvement - program name changed to 'coff' to match UNIX - minor bug fixes - bug fix to 65816 expression at end of CONST - record. parsing the syntax of this opcode - was dead wrong. - minimize parentheses routine for disassembly - (thanks to tim meekins) - - v1.0b january 22, 1991 albert chin - fix pause, oa-period - (thanks to jawaid bazyar, tim meekins) - fix to disassembly routines - set reload bit - - v0.9b january 12, 1991 albert chin - fix to disasm routines - fix to displacement, code counter - +infix option working - +nooffset option working - +postfix option added - +label option added - all file i/o converted to GS/OS calls - added record tyep: BEXPR - - v0.8b december 21, 1990 albert chin - support for OMF v2.0 headers - added record type: LCONST - - v0.7b december 19, 1990 albert chin - added record types: GEQU, MEM, EQU - - v0.6b december 18, 1990 albert chin - initial release of beta - */ - - -#include "coff.h" - -asm short -key (void) -{ - sep #0x20 - lda >0xe0c000 - bpl end - cmp #0xae /* oa-period */ - bne wait - lda >0xe0c025 - and #0x80 - beq wait - - lda >0xe0c010 - rep #0x20 - lda #TRUE - rtl - - wait: lda >0xe0c010 - rdkey: lda >0xe0c000 - bpl rdkey - lda >0xe0c010 - - end: rep #0x20 - lda #FALSE - rtl -} - -void -bye (HEADER *omf) -{ - GSOSclose (omf->refNum); - free (omf); - ResourceShutDown (); - MMShutDown (userID); - - exit (1); -} - -void -read_header (HEADER *omf) -{ - unsigned char kind, lablen; - - read_long (omf->refNum, omf->bytecnt); - read_long (omf->refNum, omf->resspc); - read_long (omf->refNum, omf->length); - read_char (omf->refNum, kind); - omf->kind = kind; - read_char (omf->refNum, omf->lablen); - read_char (omf->refNum, omf->numlen); - read_char (omf->refNum, omf->version); - omf->revision = 0; - read_long (omf->refNum, omf->banksize); - if (omf->version != 1) - { - unsigned short unused; - - read_int (omf->refNum, omf->kind); - read_int (omf->refNum, unused); - } - else - { - unsigned long unused; - - read_long (omf->refNum, unused); - } - read_long (omf->refNum, omf->org); - read_long (omf->refNum, omf->align); - read_char (omf->refNum, omf->numsex); - read_char (omf->refNum, omf->lcbank); /* not visible in OMF 2.x */ - read_int (omf->refNum, omf->segnum); - read_long (omf->refNum, omf->entry); - read_int (omf->refNum, omf->dispname); - read_int (omf->refNum, omf->dispdata); - if (omf->version != 1) - read_long (omf->refNum, omf->temporg); - - GSOSset_mark (omf->refNum, omf->offset + omf->dispname); - GSOSread (omf->refNum, omf->loadname, LOADNAME_LEN); - omf->loadname[LOADNAME_LEN] = '\0'; - if (omf->lablen) - lablen = omf->lablen; - else - read_char (omf->refNum, lablen); - - omf->segname = malloc (lablen + 1); - GSOSread (omf->refNum, omf->segname, lablen); - omf->segname[lablen] = '\0'; -} - -void -print_header (HEADER *omf) -{ - printf ("%s : $%0.8lx%35lu\n", (omf->version >= 2 ? "byte count " : "block count"), omf->bytecnt, omf->bytecnt); - printf ("reserved space: $%0.8lx%35lu\n", omf->resspc, omf->resspc); - printf ("length : $%0.8lx%35lu\n", omf->length, omf->length); - printf ("label length : $%0.2x%41u\n", (unsigned short)omf->lablen, (unsigned short)omf->lablen); - printf ("number length : $%0.2x%41u\n", (unsigned short)omf->numlen, (unsigned short)omf->numlen); - printf ("version : $%0.2x%41u\n", (unsigned short)omf->version, (unsigned short)omf->version); - if (omf->revision) - printf ("revision : $%0.2x%41u\n", (unsigned short)omf->revision, (unsigned short)omf->revision); - printf ("bank size : $%0.8lx%35lu\n", omf->banksize, omf->banksize); - if (omf->version == 1) - printf ("kind : $%0.2x%41s\n", omf->kind, parse_kind_1 (omf->kind)); - else - printf ("kind : $%0.4x%39s\n", omf->kind, parse_kind_2 (omf->kind)); - printf ("org : $%0.8lx%35lu\n", omf->org, omf->org); - printf ("alignment : $%0.8lx%35lu\n", omf->align, omf->align); - printf ("number sex : $%0.2x%41u\n", (unsigned short)omf->numsex, (unsigned short)omf->numsex); - printf ("segment number: $%0.4x%39u\n", omf->segnum, omf->segnum); - printf ("entry : $%0.8lx%35lu\n", omf->entry, omf->entry); - printf ("disp to names : $%0.4x%39u\n", omf->dispname, omf->dispname); - printf ("disp to data : $%0.4x%39u\n", omf->dispdata, omf->dispdata); - printf ("load name : %s\n", omf->loadname); - printf ("segment name : %s\n\n", omf->segname); -} - -char * -parse_kind_1 (unsigned short kind) -{ - static char kind_str[KIND_LEN]; - unsigned short i, type[] = { POSITION_INDEPENDENT, PRIVATE }; - - kind_str[0] = '\0'; - - if (kind & DYNAMIC) - strcat (kind_str, "dynamic"); - else - strcat (kind_str, "static"); - - for (i = 0; i < 2; ++i) - switch ((kind << 8) & type[i]) - { - case POSITION_INDEPENDENT: - strcat (kind_str, " position independent"); - break; - - case PRIVATE: - strcat (kind_str, " private"); - break; - } - - if ((kind & 0x1f) == 0) - strcat (kind_str, " code"); - if ((kind & DATA) == DATA) - strcat (kind_str, " data"); - if ((kind & JUMP_TABLE) == JUMP_TABLE) - strcat (kind_str, " jump-table"); - if ((kind & PATHNAME) == PATHNAME) - strcat (kind_str, " pathname"); - if ((kind & LIBRARY_DICTIONARY) == LIBRARY_DICTIONARY) - strcat (kind_str, " library dictionary"); - if ((kind & INITIALIZATION) == INITIALIZATION) - strcat (kind_str, " initialization"); - if ((kind & ABSOLUTE_BANK_SEG) == ABSOLUTE_BANK_SEG) - strcat (kind_str, " absolute_bank"); - if ((kind & DIRECT_PAGE) == DIRECT_PAGE) - strcat (kind_str, " direct-page/stack"); - - return (kind_str); -} - -char * -parse_kind_2 (unsigned short kind) -{ - static char kind_str[KIND_LEN]; - unsigned short i, type[] = { PRIVATE, POSITION_INDEPENDENT, - ABSOLUTE_BANK, RELOAD, SKIP, - BANK_RELATIVE }; - - kind_str[0] = '\0'; - - if (kind & DYNAMIC) - strcat (kind_str, "dynamic"); - else - strcat (kind_str, "static"); - - for (i = 0; i < 6; ++i) - switch (kind & type[i]) - { - case BANK_RELATIVE: - strcat (kind_str, " bank-relative"); - break; - - case SKIP: - strcat (kind_str, " skip"); - break; - - case RELOAD: - strcat (kind_str, " reload"); - break; - - case ABSOLUTE_BANK: - strcat (kind_str, " absolute_bank"); - break; - - case POSITION_INDEPENDENT: - strcat (kind_str, " position independent"); - break; - - case PRIVATE: - strcat (kind_str, " private"); - break; - } - - if ((kind & 0xfffe) == CODE) - strcat (kind_str, " code"); - if ((kind & DATA) == DATA) - strcat (kind_str, " data"); - if ((kind & JUMP_TABLE) == JUMP_TABLE) - strcat (kind_str, " jump-table"); - if ((kind & PATHNAME) == PATHNAME) - strcat (kind_str, " pathname"); - if ((kind & LIBRARY_DICTIONARY) == LIBRARY_DICTIONARY) - strcat (kind_str, " library dictionary"); - if ((kind & INITIALIZATION) == INITIALIZATION) - strcat (kind_str, " initialization"); - if ((kind & DIRECT_PAGE) == DIRECT_PAGE) - strcat (kind_str, " direct-page/stack"); - - return (kind_str); -} - -void -display_header_asm (HEADER *omf) -{ - switch (assembler) - { - case merlin: - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - puts (" xc"); - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - puts (" xc"); - asm_status_bit (omf, LONGA); - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%-10s equ *\n", omf->segname); - break; - - case orca: - asm_status_bit (omf, LONGA); - asm_status_bit (omf, LONGI); - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%-10s %s\n", omf->segname, ((omf->kind & DATA == DATA) ? "data" : "start")); - break; - } -} - -void -asm_status_bit (HEADER *omf, unsigned short status_bit) -{ - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf (" "); - - switch (assembler) - { - case merlin: - printf ("mx %%%u%u\n", (unsigned short)shorta, - (unsigned short)shorti); - break; - - case orca: - if (status_bit == LONGA) - printf ("longa %s\n", (shorta ? "on" : "off")); - else - printf ("longi %s\n", (shorti ? "on" : "off")); - break; - } - -} - -void -parse_opcode_1 (HEADER *omf, unsigned char opcode) -{ - printf ("%s ", opcodes[opcode].syntax); - if (opcodes[opcode].mode == ACCUMULATOR && assembler == orca) - putchar ('a'); - else - putchar (' '); - print_hex_ascii (opcode, 0, 1, 8); - - ++omf->displacement; - ++omf->counter; -} - -unsigned long -parse_opcode_2 (HEADER *omf, LABEL *lab, unsigned long count, unsigned char opcode) -{ - unsigned short uval; - signed short sval; - - if ((opcodes[opcode].m && !shorta) || (opcodes[opcode].i && !shorti)) - { - if (count >= 3) - { - omf->displacement += 3; - omf->counter += 3; - read_int (omf->refNum, sval); - uval = sval; - if (tool && opcode == LDX) - count = parse_stack (omf, opcode, uval, count); - else - print_opcode_3 (omf, opcode, sval); - - return (count -= 3); - } - else - if ((omf->counter + 3) >= omf->length) - print_byte (omf, count, opcode); - else - parse_expr_asm (omf, lab, opcode); - } - else - { - if (count >= 2) - { - print_opcode_2 (omf, opcode); - return (count -= 2); - } - else - if ((omf->counter + 2) >= omf->length) - print_byte (omf, count, opcode); - else - parse_expr_asm (omf, lab, opcode); - } - - return (0); -} - -void -print_opcode_2 (HEADER *omf, unsigned char opcode) -{ - signed char sval; - unsigned char uval; - unsigned int tmp, num; - - read_char (omf->refNum, sval); - uval = sval; - if (opcodes[opcode].mode == PC_RELATIVE) - { - printf (opcodes[opcode].syntax, (unsigned short)(omf->counter + sval + 2), &tmp); - num = tmp; - printf (" {%c%0.2x}%n", (sval < 0 ? '-' : '+'), - (unsigned short)(sval > 0 ? sval : -sval), &num); - num += tmp; - } - else - printf (opcodes[opcode].syntax, uval, &num); - - print_hex_ascii (opcode, uval, 2, num); - if (opcode == REP || opcode == SEP) - parse_rep_sep (omf, opcode, uval); - omf->displacement += 2; - omf->counter += 2; -} - -unsigned long -parse_opcode_3 (HEADER *omf, LABEL *lab, unsigned long count, unsigned char opcode) -{ - unsigned long tmp; - signed short sval; - unsigned short uval; - - if (count >= 3) - { - omf->displacement += 3; - omf->counter += 3; - read_int (omf->refNum, sval); - uval = sval; - if (tool) - { - if (opcode == JSR) - { - tmp = parse_inline_3 (omf, lab, uval, count); - if (tmp == count) - print_opcode_3 (omf, opcode, sval); - else - count = tmp; - } - else - if (opcode == PEA) - count = parse_stack (omf, opcode, uval, count); - else - print_opcode_3 (omf, opcode, sval); - } - else - print_opcode_3 (omf, opcode, sval); - - return (count -= 3); - } - else - if ((omf->counter + 3) >= omf->length) - print_byte (omf, count, opcode); - else - parse_expr_asm (omf, lab, opcode); - - return (0); -} - -void -print_opcode_3 (HEADER *omf, unsigned char opcode, signed short sval) -{ - unsigned short uval = sval; - unsigned int tmp, num; - Handle name = NULL; - - if (tool && opcodes[opcode].mode == ABSOLUTE) - { - name = LoadResource (rROM, (Longword)uval); - if (name) - printf ("%.3s %s%n", opcodes[opcode].syntax, *name, &num); - else - printf (opcodes[opcode].syntax, uval, &num); - } - else - if (opcodes[opcode].mode == PC_RELATIVE_LONG) - { - printf (opcodes[opcode].syntax, (unsigned short)(omf->counter + sval + 2), &tmp); - num = tmp; - printf (" {%c%0.4x}%n", (sval < 0 ? '-' : '+'), - (unsigned short)(sval > 0 ? sval : -sval), &num); - num += tmp; - } - else - printf (opcodes[opcode].syntax, uval, &num); - - print_hex_ascii (opcode, uval, 3, num); -} - -unsigned long -parse_inline_3 (HEADER *omf, LABEL *lab, unsigned short toolnum, unsigned long count) -{ - Handle name = NULL; - enum assembler tmp_asm = assembler; - unsigned char callnum; - unsigned short parmblock; - unsigned long mark; - - if (toolnum != PRODOS_MLI) - return (count); - - mark = GSOSget_mark (omf->refNum); - switch (count) - { - case 3: - return (count); - break; - - case 4: - read_char (omf->refNum, callnum); - name = LoadResource (rGSOS, (Longword)callnum); - if (!name) - { - GSOSset_mark (omf->refNum, mark); - return (count); - } - ++omf->displacement; - ++omf->counter; - printf ("_%s ", *name); - assembler = merlin; - parse_expr_asm (omf, lab, DC); - assembler = tmp_asm; - return (3); - break; - - default: - read_char (omf->refNum, callnum); - read_int (omf->refNum, parmblock); - name = LoadResource (rGSOS, (Longword)callnum); - if (!name) - { - GSOSset_mark (omf->refNum, mark); - return (count); - } - printf ("_%s $%x\n", *name, parmblock); - omf->displacement += 3; - omf->counter += 3; - return (count -= 3); - break; - } -} - -unsigned long -parse_stack (HEADER *omf, unsigned char opcode, unsigned short callnum, unsigned long count) -{ - unsigned long mark, toolnum = 0; - signed short sval = callnum; - unsigned char jsl; - - if (count >= 7) - { - mark = GSOSget_mark (omf->refNum); - read_char (omf->refNum, jsl); - GSOSread (omf->refNum, &toolnum, 3); - if (tool && jsl == JSL && (toolnum == GSOS_STACK || toolnum == TOOL_STACK || toolnum == TOOL_STACK_ALT)) - { - Handle name = NULL; - - if (toolnum == GSOS_STACK) - name = LoadResource (rGSOS, (Longword)callnum); - else - name = LoadResource (rTool, (Longword)callnum); - - if (name) - { - omf->displacement += 4; - omf->counter += 4; - printf ("_%s\n", *name); - count -= 4; - } - else - { - GSOSset_mark (omf->refNum, mark); - print_opcode_3 (omf, opcode, sval); - } - } - else - { - GSOSset_mark (omf->refNum, mark); - print_opcode_3 (omf, opcode, sval); - } - } - else - print_opcode_3 (omf, opcode, sval); - - return (count); -} - -unsigned long -parse_opcode_4 (HEADER *omf, LABEL *lab, unsigned long count, unsigned char opcode) -{ - unsigned long val = 0, tmp; - - if (count >= 4) - { - omf->displacement += 4; - omf->counter += 4; - GSOSread (omf->refNum, &val, 3); - if (tool && opcode == JSL) - { - tmp = parse_inline_4 (omf, lab, val, count); - if (tmp == count) - print_opcode_4 (omf, opcode, val); - else - count = tmp; - } - else - print_opcode_4 (omf, opcode, val); - - return (count -= 4); - } - else - if ((omf->counter + 4) >= omf->length) - print_byte (omf, count, opcode); - else - parse_expr_asm (omf, lab, opcode); - - return (0); -} - -void -print_opcode_4 (HEADER *omf, unsigned char opcode, unsigned long val) -{ - unsigned int num; - unsigned char bank; - unsigned short addr; - Handle name = NULL; - - if (tool && opcodes[opcode].mode == ABSOLUTE_LONG) - { - bank = (char)((val & 0xff0000) >> 16); - addr = (unsigned short)(val & 0x00ffff); - if (bank == 0xe0) - name = LoadResource (rROM, (Longword)addr); - else - name = LoadResource (rROM, val); - if (name) - printf ("%.7s%s%s%n", opcodes[opcode].syntax, - bank == 0xe0 ? "e0_" : "", *name, &num); - else - printf (opcodes[opcode].syntax, (assembler == merlin ? '|' : '>'), val, &num); - } - else - printf (opcodes[opcode].syntax, (assembler == merlin ? '|' : '>'), val, &num); - - print_hex_ascii (opcode, val, 4, num); -} - -unsigned long -parse_inline_4 (HEADER *omf, LABEL *lab, unsigned long toolnum, unsigned long count) -{ - Handle name = NULL; - enum assembler tmp_asm = assembler; - unsigned short callnum; - unsigned long parmblock, mark; - - if (toolnum != GSOS_INLINE) - return (count); - - mark = GSOSget_mark (omf->refNum); - switch (count) - { - case 4: - return (count); - break; - - case 6: - read_int (omf->refNum, callnum); - name = LoadResource (rGSOS, (Longword)callnum); - if (!name) - { - GSOSset_mark (omf->refNum, mark); - return (count); - } - omf->displacement += 2; - omf->counter += 2; - printf ("_%s ", *name); - assembler = merlin; - parse_expr_asm (omf, lab, DC); - assembler = tmp_asm; - return (4); - break; - - default: - read_int (omf->refNum, callnum); - read_long (omf->refNum, parmblock); - name = LoadResource (rGSOS, (Longword)callnum); - if (!name) - { - GSOSset_mark (omf->refNum, mark); - return (count); - } - printf ("_%s $%lx\n", *name, parmblock); - omf->displacement += 6; - omf->counter += 6; - return (count -= 6); - break; - } -} - -void -print_hex_ascii (unsigned char opcode, unsigned long val, unsigned short bytes, unsigned int num) -{ - unsigned char val1 = val; - unsigned short val2 = val; - unsigned long val4 = val; - - if (!hex) - { - putchar ('\n'); - return; - } - - printf ("%*c", 33 - num, ' '); - switch (bytes) - { - case 1: - printf ("%0.2x - ", (unsigned short)opcode); - if (isprint (opcode)) - putchar (opcode); - else - putchar ('.'); - break; - - case 2: - printf ("%0.2x %0.2x - ", (unsigned short)opcode, - (unsigned short)val1); - if (isprint (opcode)) - putchar (opcode); - else - putchar ('.'); - if (isprint (val1)) - putchar (val1); - else - putchar ('.'); - break; - - case 3: - printf ("%0.2x %0.2x %0.2x - ", (unsigned short)opcode, - val2 & 0x00ff, (val2 & 0xff00) >> 8); - if (isprint (opcode)) - putchar (opcode); - else - putchar ('.'); - if (isprint ((char)(val2 & 0x00ff))) - putchar ((char)(val2 & 0x00ff)); - else - putchar ('.'); - if (isprint ((char)((val2 & 0xff00) >> 8))) - putchar ((char)((val2 & 0xff00) >> 8)); - else - putchar ('.'); - break; - - case 4: - printf ("%0.2x %0.2lx %0.2lx %0.2lx - ", (unsigned short)opcode, - val4 & 0x0000ff, (val4 & 0x00ff00) >> 8, (val4 & 0xff0000) >> 16); - if (isprint (opcode)) - putchar (opcode); - else - putchar ('.'); - if (isprint ((char)(val4 & 0x0000ff))) - putchar ((char)(val4 & 0x0000ff)); - else - putchar ('.'); - if (isprint ((char)((val4 & 0x00ff00) >> 8))) - putchar ((char)((val4 & 0x00ff00) >> 8)); - else - putchar ('.'); - if (isprint ((char)((val4 & 0xff0000) >> 16))) - putchar ((char)((val4 & 0xff0000) >> 16)); - else - putchar ('.'); - break; - } - - putchar ('\n'); -} - -void -parse_expr_asm (HEADER *omf, LABEL *lab, unsigned short opcode) -{ - unsigned char record; - unsigned short n; - char *syntax, *str; - - read_char (omf->refNum, record); - if (recognize_record (record)) - { - print_byte (omf, 1, opcode); - - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - n = parse_record (omf, lab, record, FALSE, 0); - if (n > 0) - puts (assembler == merlin ? "" : "\'"); - } - else - if (opcode != DC) - { - enum assembler tmp = assembler; - - switch (opcodes[opcode].mode) - { - case ABSOLUTE_LONG: - case ABSOLUTE_LONG_INDEX_X: - syntax = opcodes[opcode].syntax; - str = strchr (syntax, '%'); - printf ("%.*s %c", (int)(str - syntax - 1), syntax, assembler == merlin ? '|' : '>'); - assembler = merlin; - n = parse_record (omf, lab, record, FALSE, 0); - str = strchr (str, 'x'); - if (strlen (str) - 3) - printf ("%.*s", (int)(strlen (str) - 3), str + 1); - putchar ('\n'); - break; - - case BLOCK_MOVE: - assembler = merlin; - syntax = opcodes[opcode].syntax; - str = strchr (syntax, '%'); - printf ("%.*s", (int)(str - syntax - 1), syntax); - n = parse_record (omf, lab, record, FALSE, 0); - printf (", "); - read_char (omf->refNum, record); - n = parse_record (omf, lab, record, FALSE, n + 2); - putchar ('\n'); - break; - - default: - assembler = merlin; - syntax = opcodes[opcode].syntax; - str = strchr (syntax, '%'); - printf ("%.*s", (int)(str - syntax - 1), syntax); - parse_record (omf, lab, record, FALSE, 0); - str = strchr (str, 'x'); - if (strlen (str) - 3) - printf ("%.*s", (int)(strlen (str) - 3), str + 1); - putchar ('\n'); - break; - } - - assembler = tmp; - ++omf->counter; - } - else - { - n = parse_record (omf, lab, record, FALSE, 0); - if (n > 0) - putchar ('\n'); - } - - ++omf->displacement; -} - -void -print_byte (HEADER *omf, unsigned long count, unsigned char opcode) -{ - unsigned char val; - unsigned short num = 2, i, j = count; - char ptr[5]; - - omf->displacement += count; - omf->counter += count; - if (assembler == merlin) - printf ("hex %0.2x", (unsigned short)opcode); - else - printf ("dc h'%0.2x", (unsigned short)opcode); - - ptr[count] = opcode; - while (--count) - { - read_char (omf->refNum, val); - printf ("%0.2x", (unsigned short)val); - ptr[count] = val; - num += 2; - } - - if (assembler == orca) - putchar ('\''); - if (hex) - { - printf ("%*c", 26 - num - (assembler == merlin ? 0 : 2), ' '); - for (i = j; i > 0; --i) - printf ("%0.2x ", (unsigned short)ptr[i]); - printf ("%*c- ", (int)(12 - (3 * j)), ' '); - for (i = j; i > 0; --i) - if (isprint (ptr[i])) - putchar (ptr[i]); - else - putchar ('.'); - } - - putchar ('\n'); -} - -void -parse_rep_sep (HEADER *omf, unsigned char opcode, unsigned char val) -{ - switch (opcode) - { - case REP: - if (val & LONGA) - { - shorta = FALSE; - if (assembler == orca) - asm_status_bit (omf, LONGA); - } - if (val & LONGI) - { - shorti = FALSE; - if (assembler == orca) - asm_status_bit (omf, LONGI); - } - if (assembler == merlin) - asm_status_bit (omf, LONGA); - break; - - case SEP: - if (val & LONGA) - { - shorta = TRUE; - if (assembler == orca) - asm_status_bit (omf, LONGA); - } - if (val & LONGI) - { - shorti = TRUE; - if (assembler == orca) - asm_status_bit (omf, LONGI); - } - if (assembler == merlin) - asm_status_bit (omf, LONGI); - break; - } -} - -void -parse_segment_hex (HEADER *omf) -{ - unsigned long num = omf->offset; - - if (omf->version == 1) - num += (512 * omf->bytecnt); - else - num += omf->bytecnt; - - while (omf->displacement <= num) - { - unsigned short loop; - Longword tmp; - char ptr[20]; - - if (key ()) - bye (omf); - - tmp = GSOSread (omf->refNum, ptr, 15); - if (toolerror () || (tmp == 0)) - break; - - printf ("%0.6lx | ", omf->displacement); - omf->displacement += tmp; - - for (loop = 0; loop < tmp; ++loop) - printf ("%0.2x ", (unsigned short)ptr[loop]); - - printf ("%*s", (int)(3 * (15 - tmp) + 2), "- "); - - for (loop = 0; loop < tmp; ++loop) - { - if (isprint (ptr[loop])) - putchar (ptr[loop]); - else - putchar ('.'); - } - putchar ('\n'); - } - putchar ('\n'); -} - -void -parse_segment (HEADER *omf, LABEL *lab) -{ - unsigned char record; - - if (assembly) - display_header_asm (omf); - - GSOSset_mark (omf->refNum, omf->displacement); - do - { - if (key ()) - bye (omf); - - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - read_char (omf->refNum, record); - ++omf->displacement; - parse_record (omf, lab, record, TRUE, 0); - } while (record != END); - - if (assembly) - printf ("%14s\n\n", "end"); - else - puts ("END (00)\n"); - - delete_labels (lab, LOCAL); -} - -unsigned short -parse_record (HEADER *omf, LABEL *lab, unsigned char record, unsigned short space, unsigned short n) -{ - unsigned char truncate_size; - - switch (record) - { - case END: - break; - - case USING: - parse_USING (omf, record); - break; - - case STRONG: - parse_STRONG (omf, lab, record); - break; - - case GLOBAL: - case LOCAL: - parse_GLOBAL_LOCAL (omf, lab, record); - break; - - case GEQU: - case EQU: - n = parse_GEQU_EQU (omf, lab, record, n); - break; - - case MEM: - n = parse_MEM (omf, lab, record, n); - break; - - case EXPR: - case BEXPR: - case LEXPR: - case RELEXPR: - if (record == EXPR || record == BEXPR || record == LEXPR) - truncate_size = parse_EXPR_BEXPR_LEXPR (omf, record); - else - truncate_size = parse_RELEXPR (omf, record); - - if (assembly && space) - { - printf (" %s", assembler == merlin ? "db " : "dc i"); - if (assembler == orca) - printf ("%u\'", (unsigned short)truncate_size); - } - n = parse_expr (omf, lab, n); - if (assembly && space && (n > 0)) - puts (assembler == merlin ? "" : "\'"); - omf->counter += truncate_size; - break; - - case DS: - if (assembly) - printf (" "); - parse_DS (omf, record); - break; - - case LCONST: - if (assembly) - parse_CONST_asm (omf, lab, record); - else - parse_CONST (omf, record); - break; - - default: - if (assembly) - parse_CONST_asm (omf, lab, record); - else - parse_CONST (omf, record); - break; - } - - return (n); -} - -void -parse_CONST (HEADER *omf, unsigned char record) -{ - unsigned long count, outer = 0, i, j; - unsigned short edge; - char ptr[CONST_EDGE + CONST_EDGE]; - - if (record == LCONST) - { - printf ("LCONST (%0.2x) | ", (unsigned short)record); - read_long (omf->refNum, count); - omf->displacement += 4; - } - else - { - printf ("CONST (%0.2x) | ", (unsigned short)record); - count = record; - } - - edge = CONST_EDGE + (nooffset == TRUE ? 5 : 0); - while (outer < count) - { - unsigned short tmp_num = 0, num = 0, inner = 0; - - if (key ()) - bye (omf); - - j = outer + edge; - for (i = outer; i < j && i < count; ++i) - { - read_char (omf->refNum, ptr[inner]); - printf ("%0.2x %n", (unsigned short)ptr[inner++], &num); - tmp_num += num; - } - - printf ("%*s", (3 * edge) + 2 - tmp_num, "- "); - for (i = 0; i < inner; ++i) - putchar (isprint (ptr[i]) ? ptr[i] : '.'); - putchar ('\n'); - - outer += inner; - omf->counter += inner; - omf->displacement += inner; - - if (outer < count) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%15c ", '|'); - } - } -} - -void -parse_CONST_asm (HEADER *omf, LABEL *lab, unsigned char record) -{ - unsigned long count; - - if (record == LCONST) - { - read_long (omf->refNum, count); - omf->displacement += 4; - } - else - count = record; - - while (count) - { - unsigned char opcode; - - if (key ()) - bye (omf); - - read_char (omf->refNum, opcode); - ++omf->displacement; - - printf (" "); - switch (opcodes[opcode].bytes) - { - case 1: - parse_opcode_1 (omf, opcode); - --count; - break; - - case 2: - count = parse_opcode_2 (omf, lab, count, opcode); - break; - - case 3: - count = parse_opcode_3 (omf, lab, count, opcode); - break; - - case 4: - count = parse_opcode_4 (omf, lab, count, opcode); - break; - } - - if (count && !nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - } -} - -unsigned short -recognize_record (unsigned char record) -{ - switch (record) - { - case USING: - case STRONG: - case GLOBAL: - case GEQU: - case MEM: - case LOCAL: - case EQU: - case DS: - case LCONST: - return (TRUE); - break; - - default: - return (FALSE); - break; - } -} - -void -parse_USING (HEADER *omf, unsigned char record) -{ - unsigned char length; - char *name; - - read_char (omf->refNum, length); - name = malloc (length + 1); - GSOSread (omf->refNum, name, length); - name[length] = '\0'; - - if (!assembly) - printf ("USING (%0.2x) | %s\n", (unsigned short)record, name); - else - printf (" using %s\n", name); - - free (name); - omf->displacement += length + 1; -} - -void -parse_STRONG (HEADER *omf, LABEL *lab, unsigned char record) -{ - unsigned char length; - char *name, *str; - - str = malloc (strlen (omf->segname) + (sizeof (long) * 2) + 5); - sprintf (str, "(%s+$%lx)", omf->segname, omf->counter); - if (!match_label (lab, str) && assembly) - printf ("%11c", ' '); - - read_char (omf->refNum, length); - name = malloc (length + 1); - GSOSread (omf->refNum, name, length); - name[length] = '\0'; - - if (!assembly) - printf ("STRONG (%0.2x) | %s\n", (unsigned short)record, name); - else - printf ("dc r'%s'\n", name); - - free (str); - free (name); - omf->displacement += length; -} - -void -parse_GLOBAL_LOCAL (HEADER *omf, LABEL *lab, unsigned char record) -{ - unsigned char length, type, private; - char *name; - - read_char (omf->refNum, length); - name = malloc (length + 1); - GSOSread (omf->refNum, name, length); - name[length] = '\0'; - - if (label) - { - char *expr; - - expr = malloc (strlen (omf->segname) + (sizeof (long) * 2) + 5); - sprintf (expr, "(%s+$%lx)", omf->segname, omf->counter); - add_label (lab, name, expr, record); - } - read_char (omf->refNum, length); - read_char (omf->refNum, type); - read_char (omf->refNum, private); - - if (!assembly) - { - printf ("%s (%0.2x) | %s\n", record == GLOBAL ? "GLOBAL" : "LOCAL ", (unsigned short)record, name); - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%15c len: %0.2x, type: %c", '|', (unsigned short)length, type); - if (private) - printf (", private"); - putchar ('\n'); - } - else - parse_type_attribute (omf, lab, type, name, length); - - if (!label) - free (name); - omf->displacement += length + 4; -} - -void -parse_type_attribute (HEADER *omf, LABEL *lab, unsigned char type, char *name, unsigned char length) -{ - switch (type) - { - case 'A': - parse_GLOBAL_type_A (omf, lab, name, length); - break; - - case 'C': - parse_GLOBAL_type_C (omf, lab, name); - break; - - case 'D': - parse_GLOBAL_type_D (omf, lab, name); - break; - - case 'F': - parse_GLOBAL_type_F (omf, lab, name); - break; - - case 'H': - parse_GLOBAL_type_H (omf, lab, name); - break; - - case 'I': - parse_GLOBAL_type_I (omf, lab, name, length); - break; - - case 'K': - parse_GLOBAL_type_K (omf, lab, name); - break; - - case 'L': - parse_GLOBAL_type_L (omf, lab, name, length); - break; - - case 'N': - parse_GLOBAL_type_N (omf, lab, name); - break; - - case 'S': - parse_GLOBAL_type_S (omf, name); - break; - } -} - -void -parse_GLOBAL_type_A (HEADER *omf, LABEL *lab, char *name, unsigned char length) -{ - unsigned char record; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("%s", assembler == merlin ? "db " : "dc a"); - read_char (omf->refNum, record); - if (assembler == orca) - if (record >= 0x01 && record <= 0xdf) - putchar ('\''); - else - printf ("%u\'", (unsigned short)length); - - parse_GLOBAL_type (omf, lab, record); -} - -void -parse_GLOBAL_type_C (HEADER *omf, LABEL *lab, char *name) -{ - unsigned char record; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - read_char (omf->refNum, record); - if (record != DS) - printf ("%s", assembler == merlin ? "asc \'" : "dc c\'"); - - if (!parse_GLOBAL_type (omf, lab, record)) - { - unsigned char i, j, num, outer = 0; - unsigned short edge; - - edge = CHAR_EDGE + (nooffset == TRUE ? 16 : 0); - while (outer < record) - { - j = outer + edge; - for (i = outer; i < j && i < record; ++i) - { - read_char (omf->refNum, num); - putchar (num); - } - - puts ("\'"); - omf->displacement += i - outer; - omf->counter += i - outer; - outer = i; - if (outer < record) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf (" %s", assembler == merlin ? "asc \'" : "dc c\'"); - } - } - } -} - -void -parse_GLOBAL_type_D (HEADER *omf, LABEL *lab, char *name) -{ - unsigned char record; - enum assembler tmp_asm; - - tmp_asm = assembler; - assembler = orca; - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("dc d\'"); - - read_char (omf->refNum, record); - if (!parse_GLOBAL_type (omf, lab, record)) - { - unsigned short num_char = 0, edge; - unsigned int tmp; - unsigned char outer = 0; - double num; - - edge = DOUBLE_EDGE + (nooffset == TRUE ? 16 : 0); - record /= sizeof (double); - while (outer++ < record) - { - GSOSread (omf->refNum, &num, sizeof (double)); - printf ("%g%n", num, &tmp); - num_char += tmp; - - omf->displacement += sizeof (double); - omf->counter += sizeof (double); - if (num_char > edge) - { - puts ("\'"); - num_char = 0; - if (outer < record) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf (" dc d\'"); - } - } - else - if (outer < record) - putchar (','); - } - if (num_char) - puts ("\'"); - } - - assembler = tmp_asm; -} - -void -parse_GLOBAL_type_F (HEADER *omf, LABEL *lab, char *name) -{ - unsigned char record; - enum assembler tmp_asm; - - tmp_asm = assembler; - assembler = orca; - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("dc f\'"); - - read_char (omf->refNum, record); - if (!parse_GLOBAL_type (omf, lab, record)) - { - unsigned short num_char = 0, edge; - unsigned int tmp; - unsigned char outer = 0; - float num; - - edge = FLOAT_EDGE + (nooffset == TRUE ? 16 : 0); - record /= sizeof (float); - while (outer++ < record) - { - GSOSread (omf->refNum, &num, sizeof (float)); - printf ("%g%n", num, &tmp); - num_char += tmp; - - omf->displacement += sizeof (float); - omf->counter += sizeof (float); - if (num_char > edge) - { - puts ("\'"); - num_char = 0; - if (outer < record) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf (" dc f\'"); - } - } - else - if (outer < record) - putchar (','); - } - if (num_char) - puts ("\'"); - } - - assembler = tmp_asm; -} - -void -parse_GLOBAL_type_H (HEADER *omf, LABEL *lab, char *name) -{ - unsigned char record; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("%s", assembler == merlin ? "hex " : "dc h\'"); - - read_char (omf->refNum, record); - if (!parse_GLOBAL_type (omf, lab, record)) - { - unsigned char i, j, num, outer = 0; - unsigned short edge; - - edge = HEX_EDGE + (nooffset == TRUE ? 16 : 0); - while (outer < record) - { - j = outer + edge; - for (i = outer; i < j && i < record; ++i) - { - read_char (omf->refNum, num); - printf ("%0.2x", (unsigned short)num); - } - - puts (assembler == merlin ? "" : "\'"); - omf->displacement += i - outer; - omf->counter += i - outer; - outer = i; - if (outer < record) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf (" %s", assembler == merlin ? "hex " : "dc h\'"); - } - } - } -} - -void -parse_GLOBAL_type_I (HEADER *omf, LABEL *lab, char *name, unsigned char length) -{ - unsigned char record; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("%s", assembler == merlin ? "db " : "dc i"); - read_char (omf->refNum, record); - if (assembler == orca) - if (record >= 0x01 && record <= 0xdf) - putchar ('\''); - else - printf ("%u\'", (unsigned short)length); - - if (!parse_GLOBAL_type (omf, lab, record)) - { - unsigned short num_char = 0, edge; - unsigned int tmp; - unsigned char outer = 0; - signed char num; - - edge = INT_EDGE + (nooffset == TRUE ? 16 : 0); - while (outer++ < record) - { - read_char (omf->refNum, num); - printf ("%d%n", (short)num, &tmp); - num_char += tmp; - - ++omf->displacement; - ++omf->counter; - if (num_char > edge) - { - puts (assembler == merlin ? "" : "\'"); - num_char = 0; - if (outer < record) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf (" %s", assembler == merlin ? "db " : "dc i\'"); - } - } - else - if (outer < record) - putchar (','); - } - if (num_char) - puts (assembler == merlin ? "" : "\'"); - } -} - -void -parse_GLOBAL_type_K (HEADER *omf, LABEL *lab, char *name) -{ - unsigned char record; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - read_char (omf->refNum, record); - parse_STRONG (omf, lab, record); -} - -void -parse_GLOBAL_type_L (HEADER *omf, LABEL *lab, char *name, unsigned char length) -{ - unsigned char record; - enum assembler tmp_asm; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("dc s"); - read_char (omf->refNum, record); - if (record >= 0x01 && record <= 0xdf) - putchar ('\''); - else - printf ("%u\'", (unsigned short)length); - - tmp_asm = assembler; - assembler = orca; - parse_GLOBAL_type (omf, lab, record); - assembler == tmp_asm; -} - -void -parse_GLOBAL_type_N (HEADER *omf, LABEL *lab, char *name) -{ - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - printf ("%s\n", assembler == merlin ? "equ *" : "entry"); - if (label) - { - char *expr; - - expr = malloc (strlen (omf->segname) + (sizeof (long) * 2) + 5); - sprintf (expr, "(%s+$%lx)", omf->segname, omf->counter); - add_label (lab, name, expr, GLOBAL); - } -} - -void -parse_GLOBAL_type_S (HEADER *omf, char *name) -{ - unsigned long num; - unsigned char val; - - printf ("%-11s", name); - if (strlen (name) >= 11) - putchar (' '); - read_char (omf->refNum, val); - read_long (omf->refNum, num); - printf ("ds %lu\n", num); - omf->displacement += num; - omf->counter += num; -} - -unsigned short -parse_GLOBAL_type (HEADER *omf, LABEL *lab, unsigned char record) -{ - unsigned short n; - - switch (record) - { - case EXPR: - case BEXPR: - case RELEXPR: - case LEXPR: - n = parse_record (omf, lab, record, FALSE, 0); - if (assembler == orca) - putchar ('\''); - if (assembly && (n > 0)) - putchar ('\n'); - break; - - case DS: - parse_DS (omf, record); - break; - - default: - return (FALSE); - break; - } - - return (TRUE); -} - -unsigned short -parse_GEQU_EQU (HEADER *omf, LABEL *lab, unsigned char record, unsigned short n) -{ - unsigned char length, type, private; - enum assembler tmp_asm = assembler; - char *name; - - read_char (omf->refNum, length); - name = malloc (length + 1); - GSOSread (omf->refNum, name, length); - name[length] = '\0'; - read_char (omf->refNum, length); - read_char (omf->refNum, type); - read_char (omf->refNum, private); - - if (!assembly) - { - printf ("%s (%0.2x) | %s\n", record == GEQU ? "GEQU" : "EQU ", (unsigned short)record, name); - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%15c len: %0.2x, type: %c", '|', (unsigned short)length, type); - if (private) - printf (", private"); - putchar ('\n'); - parse_expr (omf, lab, n); - } - else - { - printf ("%-11s%s ", name, record == GLOBAL ? "gequ" : "equ "); - ++omf->displacement; - assembler = merlin; - n = parse_expr (omf, lab, n); - if (n > 0) - putchar ('\n'); - assembler = tmp_asm; - } - - free (name); - omf->displacement += length + 4; - return (n); -} - -unsigned short -parse_MEM (HEADER *omf, LABEL *lab, unsigned char record, unsigned short n) -{ - unsigned long adr1, adr2; - - read_long (omf->refNum, adr1); - read_long (omf->refNum, adr2); - - if (!assembly) - { - printf ("MEM (%0.2x) | reserve: ", (unsigned short)record); - printf ("$%0.2x/%0.4x - ", - (unsigned short)((adr1 & 0xff0000) >> 16), - (unsigned short)(adr1 & 0xffff)); - printf ("$%0.2x/%0.4x\n", - (unsigned short)((adr2 & 0xff0000) >> 16), - (unsigned short)(adr2 & 0xffff)); - n = parse_expr (omf, lab, n); - } - else - printf ("%14s $%lx,$%lx\n", "mem", adr1, adr2); - - omf->displacement += 8; - return (n); -} - -unsigned char -parse_EXPR_BEXPR_LEXPR (HEADER *omf, unsigned char record) -{ - unsigned char truncate_size; - - read_char (omf->refNum, truncate_size); - if (!assembly) - { - switch (record) - { - case EXPR: - printf ("EXPR "); - break; - - case BEXPR: - printf ("BEXPR"); - break; - - case LEXPR: - printf ("LEXPR"); - break; - } - printf (" (%0.2x) | truncate result to %u %s\n", - (unsigned short)record, (unsigned short)truncate_size, - (truncate_size == 1 ? "byte" : "bytes")); - } - - ++omf->displacement; - return (truncate_size); -} - -unsigned char -parse_RELEXPR (HEADER *omf, unsigned char record) -{ - unsigned char truncate_size; - long offset; - - read_char (omf->refNum, truncate_size); - if (!assembly) - printf ("RELEXPR (%0.2x) | truncate result to %u %s\n", - (unsigned short)record, (unsigned short)truncate_size, - (truncate_size == 1 ? "byte" : "bytes")); - - read_long (omf->refNum, offset); - omf->displacement += 5; - if (!assembly) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%15c offset: $%0.8x\n", '|', offset); - } - - return (truncate_size); -} - -void -parse_DS (HEADER *omf, unsigned char record) -{ - unsigned long num_zeros; - - read_long (omf->refNum, num_zeros); - if (!assembly) - printf ("DS (%0.2x) | insert %lu %s\n", - (unsigned short)record, num_zeros, - (num_zeros > 1 ? "zeros" : "zero")); - else - printf ("ds %lu\n", num_zeros); - - omf->displacement += 5; - omf->counter += num_zeros; -} - -unsigned short -parse_expr (HEADER *omf, LABEL *lab, unsigned short n) -{ - LIST list = { 0, NULL, NULL }; - unsigned char expr; - unsigned long num; - - do - { - read_char (omf->refNum, expr); - ++omf->displacement; - - switch (expr) - { - case LABEL_WEAK: - parse_expr_weak_reference (omf, &list); - break; - - case LABEL_VALUE: - parse_expr_label_value (omf, &list); - break; - - case RELATIVE_OFFSET: - num = parse_expr_relative_offset (omf, &list); - break; - - case CONSTANT_OPERAND: - num = parse_expr_constant_operand (omf, &list); - break; - - case ADD: - case SUB: - case MUL: - case DIV: - case MOD: - case NEGATION: - case BIT_SHIFT: - case AND: - case OR: - case EOR: - case NOT: - case LESS_EQUAL: - case GREATER_EQUAL: - case NOT_EQUAL: - case LESS: - case GREATER: - case EQUAL: - case LOGICAL_AND: - case INCLUSIVE_OR: - case EXCLUSIVE_OR: - case COMPLEMENT: - push (&list, NULL, expr); - break; - } - } while (expr != END); - - if (infix) - n = print_stack_infix (omf, &list, lab, n); - else - n = print_stack_postfix (omf, list.stack, lab, n); - delete_stack (list.stack); - return (n); -} - -void -parse_expr_weak_reference (HEADER *omf, LIST *list) -{ - char *ptr; - unsigned char num; - - read_char (omf->refNum, num); - omf->displacement += num; - ptr = malloc (num + 1); - GSOSread (omf->refNum, ptr, num); - ptr[num] = '\0'; - - if (assembly) - push (list, ptr, 0); - else - { - char *str; - - str = malloc (strlen (ptr) + 8); - strcpy (str, "weak ("); - strcat (str, ptr); - strcat (str, ")"); - push (list, str, 0); - free (str); - } - - free (ptr); -} - -void -parse_expr_label_value (HEADER *omf, LIST *list) -{ - char *ptr; - unsigned char num; - - read_char (omf->refNum, num); - omf->displacement += num; - ptr = malloc (num + 1); - GSOSread (omf->refNum, ptr, num); - ptr[num] = '\0'; - push (list, ptr, 0); - free (ptr); -} - -unsigned long -parse_expr_relative_offset (HEADER *omf, LIST *list) -{ - unsigned long num; - char *str; - - str = malloc (strlen (omf->segname) + (sizeof (long) * 2) + 5); - read_long (omf->refNum, num); - sprintf (str, "(%s+$%lx)", omf->segname, num); - push (list, str, 0); - free (str); - omf->displacement += omf->numlen; - return (num); -} - -unsigned long -parse_expr_constant_operand (HEADER *omf, LIST *list) -{ - unsigned long num; - char str[10]; - - read_long (omf->refNum, num); - sprintf (str, "$%lx", num); - push (list, str, 0); - omf->displacement += omf->numlen; - return (num); -} - -/* - stack routines - */ - -void -push (LIST *list, char *str, unsigned char oper) -{ - STACK *s; - - s = malloc (sizeof (STACK)); - if (str) - { - s->str = malloc (strlen (str) + 1); - s->oper = 0; - strcpy (s->str, str); - } - else - { - s->str = NULL; - s->oper = oper; - } - s->next = NULL; - - if (list->last) - { - list->last->next = s; - ++list->size; - } - else - list->stack = s; - list->last = s; -} - -void -delete_stack (STACK *s) -{ - while (s) - { - STACK *tmp_s; - - tmp_s = s->next; - free (s->str); - free (s); - s = tmp_s; - } -} - -void -add_label (LABEL *lab, char *name, char *expr, unsigned char type) -{ - LABEL *l; - - while (lab->next) - lab = lab->next; - - l = malloc (sizeof (LABEL)); - l->label = name; - l->expr = expr; - l->type = type; - l->next = NULL; - l->prev = lab; - lab->next = l; -} - -void -delete_labels (LABEL *lab, unsigned short type) -{ - while (lab = lab->next) - if (lab->type == type) - { - lab->next->prev = lab->prev; - lab->prev->next = lab->next; - free (lab->label); - free (lab->expr); - free (lab); - } -} - -char * -match_label (LABEL *lab, char *expr) -{ - while (lab = lab->next) - if (!strcmp (lab->expr, expr)) - return (lab->label); - - return (NULL); -} - -unsigned short -print_stack_postfix (HEADER *omf, STACK *stack, LABEL *lab, unsigned short n) -{ - unsigned short edge; - - edge = POSTFIX_EDGE + (nooffset == TRUE ? 16 : 0); - if (!assembly) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%15c ", '|'); - } - - while (stack) - { - do - { - char *expr; - - if (stack->str) - { - if (!(label && (expr = match_label (lab, stack->str)))) - expr = stack->str; - } - else - expr = find_operator (stack->oper); - - n += strlen (expr); - printf ("%s", expr); - - if ((stack = stack->next) && !(n > edge && assembly)) - { - putchar (' '); - ++n; - } - } while (stack && (n <= edge)); - - if (stack && (n > edge)) - { - putchar ('\n'); - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - if (assembly) - printf ("%20c", ' '); - else - printf ("%15c ", '|'); - n = 0; - } - } - - if (!assembly) - putchar ('\n'); - return (n); -} - -unsigned short -print_stack_infix (HEADER *omf, LIST *list, LABEL *lab, unsigned short n) -{ - BTREE **t; - STACK *stack; - unsigned short size = 0; - - t = malloc (sizeof (BTREE *) * list->size); - stack = list->stack; - while (stack) - { - BTREE *tmp; - - tmp = malloc (sizeof (BTREE)); - tmp->str = stack->str; - tmp->oper = stack->oper; - if (!stack->str) - { - tmp->right = t[--size]; - tmp->left = t[--size]; - } - else - { - tmp->right = NULL; - tmp->left = NULL; - } - - t[size++] = tmp; - stack = stack->next; - } - - if (!assembly) - { - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - printf ("%15c ", '|'); - } - - n = print_inorder (omf, t[0], lab, n, operator[t[0]->oper - 1].prec + 1); - if (n > 0 && !assembly) - putchar ('\n'); - - delete_btree (t[0]); - free (t); - return (n); -} - -unsigned short -newline (HEADER *omf, unsigned short n) -{ - unsigned short edge; - - edge = INFIX_EDGE + (nooffset == TRUE ? 16 : 0); - if (n > edge) - { - n = 0; - putchar ('\n'); - - if (!nooffset) - printf ("%0.6lx %0.6lx | ", omf->displacement, omf->counter); - if (assembly) - printf ("%20c", ' '); - else - printf ("%15c ", '|'); - } - - return (n); -} - -unsigned short -print_inorder (HEADER *omf, BTREE *t, LABEL *lab, unsigned short n, unsigned short prec) -{ - unsigned char oper; - char *oper_str; - - if (t != NULL) - { - if (t->str == NULL) - { - oper = t->oper; - if ((operator[oper - 1].prec > prec) || ((operator[oper - 1].prec == prec) && (operator[oper - 1].assoc == LEFT))) - { - putchar ('('); - ++n; - } - n = print_inorder (omf, t->left, lab, n, operator[oper - 1].prec); - oper_str = find_operator (oper); - n += 2 + strlen (oper_str); - n = newline (omf, n); - printf (" %s ", oper_str); - if (n == 0) - n = strlen (oper_str); - n = print_inorder (omf, t->right, lab, n, operator[oper - 1].prec); - if ((operator[oper - 1].prec > prec) || ((operator[oper - 1].prec == prec) && (operator[oper - 1].assoc == LEFT))) - { - putchar (')'); - ++n; - } - } - else - { - char *expr; - - if (!(label && (expr = match_label (lab, t->str)))) - expr = t->str; - n += strlen (expr); - n = newline (omf, n); - printf ("%s", expr); - if (n == 0) - n = strlen (expr); - } - } - - return (n); -} - -char * -find_operator (unsigned char operator) -{ - switch (operator) - { - case ADD: - return ("+"); - break; - - case SUB: - return ("-"); - break; - - case MUL: - return ("*"); - break; - - case DIV: - return ("/"); - break; - - case MOD: - return ("%%"); - break; - - case NEGATION: - return ("~"); - break; - - case BIT_SHIFT: - return ("<<"); - break; - - case AND: - return ("&&"); - break; - - case OR: - return ("||"); - break; - - case EOR: - return (".eor."); - break; - - case NOT: - return ("!"); - break; - - case LESS_EQUAL: - return ("<="); - break; - - case GREATER_EQUAL: - return (">="); - break; - - case NOT_EQUAL: - return ("<>"); - break; - - case LESS: - return ("<"); - break; - - case GREATER: - return (">"); - break; - - case EQUAL: - return ("="); - break; - - case LOGICAL_AND: - return ("&"); - break; - - case INCLUSIVE_OR: - return ("|"); - break; - - case EXCLUSIVE_OR: - return (".beor."); - break; - - case COMPLEMENT: - return (".bnot."); - break; - } -} - -void -delete_btree (BTREE *t) -{ - if (t != NULL) - { - delete_btree (t->left); - delete_btree (t->right); - free (t); - } -} - -int -decode_switches (int argc, char **argv) -{ - int c, longind; - - while ((c = getopt_long (argc, argv, "vDdTxltpmoaisnfh", long_options, &longind)) != EOF) - { - if (c == 0) - c = long_options[longind].val; - - switch (c) - { - case 'D': - read_default (argv[0]); - break; - - default: - set_option (c, argv[0]); - break; - } - } - - return (optind); -} - -void -read_default (char *progname) -{ - Handle name; - Longword size; - - name = LoadResource (rText, (Longword)DEFAULT); - size = GetResourceSize (rText, (Longword)DEFAULT); - HLock (name); - while (size) - { - int opt; - - opt = get_option (*name); - if (opt != ERROR) - set_option (opt, progname); - size -= strlen (*name) + 1; - *name += strlen (*name) + 1; - } - HUnlock (name); -} - -int -get_option (char *arg) -{ - int i = 0; - - while (long_options[i].val) - { - if ((*arg == '-') && (long_options[i].val == *(arg + 1))) - return (long_options[i].val); - else - if (!strcmp (long_options[i].name, arg + 1)) - return (long_options[i].val); - ++i; - } - - return (ERROR); -} - -void -set_option (int opt, char *progname) -{ - Handle h; - - switch (opt) - { - case 'v': - h = LoadResource (rText, VERSION); - fprintf (stderr, *h, progname); - break; - - case 'd': - assembly = TRUE; - assembler = merlin; - infix = TRUE; - label = TRUE; - break; - - case 'T': - tool = TRUE; - break; - - case 'x': - hex = TRUE; - break; - - case 'l': - label = TRUE; - break; - - case 't': - infix = TRUE; - postfix = FALSE; - break; - - case 'p': - postfix = TRUE; - infix = FALSE; - break; - - case 'm': - assembler = merlin; - assembly = TRUE; - infix = TRUE; - label = TRUE; - break; - - case 'o': - assembler = orca; - assembly = TRUE; - infix = TRUE; - label = TRUE; - break; - - case 'a': - shorta = TRUE; - break; - - case 'i': - shorti = TRUE; - break; - - case 's': - header = TRUE; - break; - - case 'n': - noheader = TRUE; - break; - - case 'f': - nooffset = TRUE; - break; - - case 'h': - usage_verbose (progname); - break; - - default: - usage (progname); - break; - } -} - -void -usage (char *progname) -{ - Handle h; - - h = LoadResource (rText, (Longword)USAGE); - fprintf (stderr, *h, progname); - - ResourceShutDown (); - MMShutDown (userID); - exit (1); -} - -void -usage_verbose (char *progname) -{ - Handle h; - - h = LoadResource (rText, (Longword)USAGE_VERBOSE); - fprintf (stderr, *h, progname, progname); - - ResourceShutDown (); - MMShutDown (userID); - exit (0); -} - -void -GSOSset_mark (Word refNum, Longword displacement) -{ - SetPositionRecGS info = { 3 }; - - info.refNum = refNum; - info.base = startPlus; - info.displacement = displacement; - SetMark (&info); -} - -Longword -GSOSget_mark (Word refNum) -{ - PositionRecGS info = { 2 }; - - info.refNum = refNum; - GetMark (&info); - return (info.position); -} - -Longword -GSOSread (Word refNum, void *dataBuffer, Longword requestCount) -{ - IORecGS info = { 5 }; - - info.refNum = refNum; - info.dataBuffer = (char *)dataBuffer; - info.requestCount = requestCount; - info.cachePriority = cacheOff; - Read (&info); - - return (info.transferCount); -} - -Word -GSOSopen (char *filename) -{ - OpenRecGS info = { 12 }; - GSString255 name; - - info.optionList = NULL; - name.length = strlen (filename); - strcpy (name.text, filename); - info.pathname = &name; - info.requestAccess = readEnable; - info.resourceNumber = 0; - Open (&info); - - return (info.refNum); -} - -void -GSOSclose (Word refNum) -{ - IORecGS info = { 1 }; - - info.refNum = refNum; - Close (&info); -} - -Longword -GSOSget_eof (Word refNum) -{ - EOFRecGS info = { 2 }; - - info.refNum = refNum; - GetEOF (&info); - return (info.eof); -} - -HEADER * -init_globals (void) -{ - HEADER *omf; - - version = FALSE; - tool = FALSE; - assembly = FALSE; - label = FALSE; - infix = FALSE; - postfix = TRUE; - hex = FALSE; - header = FALSE; - noheader = FALSE; - nooffset = FALSE; - help = FALSE; - shorta = FALSE; - shorti = FALSE; - - omf = malloc (sizeof (HEADER)); - omf->offset = 0; - return (omf); -} - -int -main (int argc, char **argv) -{ - HEADER *omf; - LABEL lab = { NULL, NULL, 0, NULL, NULL }; - int i, names; - LongWord file_len; - GSString255 *prog; - - userID = MMStartUp (); - prog = (GSString255 *)LGetPathname2 (userID, (Word)1); - ResourceStartUp (userID); - OpenResourceFile (readEnable, NULL, prog); - omf = init_globals (); - i = decode_switches (argc, argv); - - omf->refNum = GSOSopen (argv[i]); - if (toolerror ()) - { - if (i == argc) - puts ("object filename not specified"); - else - perror (argv[0]); - usage (argv[0]); - } - - file_len = GSOSget_eof (omf->refNum); - names = (++i < argc ? TRUE : FALSE); - - do - { - GSOSset_mark (omf->refNum, omf->offset); - if (toolerror () || (names && (i == argc))) - break; - - read_header (omf); - omf->displacement = omf->offset + omf->dispdata; - omf->counter = 0; - - if (names) - { - char j, flag = FALSE; - - for (j = i; j < argc; ++j) - if (!strncmp (omf->loadname, argv[j], (int)strlen (argv[j])) || - !strncmp (omf->segname, argv[j], (int)strlen (argv[j]))) - { - flag = TRUE; - break; - } - - if (flag) - { - if (!noheader) - print_header (omf); - if (!header) - if (hex && !assembly) - parse_segment_hex (omf); - else - parse_segment (omf, &lab); - - if (j != i) - argv[j] = argv[i]; - ++i; - } - } - else - { - if (!noheader) - print_header (omf); - if (!header) - if (hex && !assembly) - parse_segment_hex (omf); - else - parse_segment (omf, &lab); - } - - free (omf->segname); - if (omf->version == 1) - omf->offset += (omf->bytecnt * 512); - else - omf->offset += omf->bytecnt; - } while (file_len > omf->offset); - - delete_labels (&lab, GLOBAL); - bye (omf); -} + END OF ARCHIVE