jac@yoko.rutgers.edu (Jonathan A. Chandross) (06/01/91)
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 $<num>
- jsl ><name>
- (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