Subject: v001SRC066: coff (OMF Disassembler) 01/09 Newsgroups: comp.sources.apple2 Approved: jac@paul.rutgers.edu Submitted-by: Albert Chin-A-Young (26285659t@servax.fiu.edu) Posting-number: Volume 1, Source:66 Archive-name: utility/gs/disassem/coff/part01 Architecture: ONLY_2gs Version-number: 1.1 Coff is an OMF disassembler designed for OMF 1.0 and 2.0 files. Output is similar to the Orca and APW utility 'dumpobj', although OMF and 65816 disassemblies are much cleaner and more readable. This is the first of 9 parts. Enjoy. =Read.Me -* UNIX coff utility -* README file -* -* 1990-1992, tao Developer Project -* -* albert chin-a-young ... 26285659t@servax.fiu.edu - -Coff is an OMF disassembler designed for OMF 1.0 and 2.0 files. Output is -similar to the Orca and APW utility 'dumpobj', although OMF and 65816 -disassemblies are much cleaner and more readable. - -v1.1 marks the first update to coff. - -The attached manual, coff.tex, describes all available options to the coff -utility in addition to a thorough description of the OMF file format. The -manual is formatted with the TeX text processing system. If you would like -a printed copy of this manual, contact me at the address below. - -The 'Apple IIgs GS/OS Reference, Volume 1' describes the OMF file format. -The manual also contains a description of the OMF file format. - -To assemble coff, you must have the Merlin 16+ assembler. Modifications to the -link file must occur if you have older versions of Merlin. Versions of coff -for the following environments are available: Merlin, Orca, and GNO. Edit the -env.h file for the environment you are compiling for. - -To compile coff, invoke the following command from the Merlin command-line: - link make[.orca|.gno] -To compile the resource fork: - compile coff.r keep=[pathname of coff] rez=(-d [MERLIN|ORCA|GNO]) -Make sure to change any absolute pathnames in the Merlin link script. - - -Merlin and Orca: - While coff is executing, pressing any key will pause the output. - Press any other key to resume output. CTRL-C will end coff. -GNO: - Coff supports the GNO signal SIGINT. Thus, CTRL-C will end coff. - CTRL-S will pause output and CTRL-Q resumes output as usual. - - -Coff is free software. Source code is available. If you have any comments, -bug reports, or suggestions on this utility, please contact me at the -following: - e-mail: 26285659t@servax.fiu.edu - post: Albert Chin-A-Young [ preferred ] - PO Box 4133 - Miramar, FL 33083-4133 - - -Below is a short description of the options available in coff. - ----------------------------------------------------------------------- - -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 --D [+nodefault] disable default options --c [+compress] print short form of CONST, LCONST records --e [+exact] match segment, loadsegment names exactly - [+thanks] those who helped in the development of coff - -filename name of file to dump -[segments] names of segments in file to dump -[loadsegments] names of load segments in file to dump - - -Source files for coff v1.1. - ----------------------------------------------------------------------- - -(Place these files in your Merlin PFX4 directory): - - datatype.mac.s HLL data type macros - env.h.s environment defines - env.mac.s environment macros - getopt.h.s GNU getopt defines - getopt.mac.s GNU getopt macros - signal.h.s GNO signal defines - signal.mac.s GNU signal macros - -(Place these files in a 'coff' directory): - - asm.s 65816 OMF disassembler - coff.h.s coff defines - coff.mac.s coff macros - coff.r resource definitions - coff.s main coff source - coff.tex TeX coff manual - data.s coff variables - general.s general purpose routines - gsos.s GS/OS calls - make.gno.s link file for GNO environment - make.orca.s link file for Orca environment - make.rez make file for resource fork - make.s link file for Merlin environment - omf.s OMF disassembler - output.s output routines - structure.s data structure routines - tool.s toolbox call parser - x.* external routine files - -(Place this file in a 'getopt' directory): - - getopt.s GNU getopt utility (not fully functional yet) - - -albert chin-a-young -26285659t@servax.fiu.edu -Version 1.1 -October 1992 - =Manifest - -HISTORY -Read.Me -asm.s -coff.h.s -coff.mac.s -coff.r -coff.s -coff.tex -data.s -datatype.mac.s -env.h.s -env.mac.s -general.s -getopt.h.s -getopt.mac.s -getopt.s -make.gno.s -make.orca.s -make.rez -make.s -omf.s -output.s -structure.s -tool.s -x.asm.s -x.data.s -x.general.s -x.gsos.s -x.omf.s -x.output.s -x.structure.s -x.tool.s - =HISTORY -* UNIX coff utility -* HISTORY file -* -* 1990-1992, tao Developer Project -* -* albert chin-a-young ... 26285659t@servax.fiu.edu - -v1.1 28 September 1992 - added '+compress' option - made relative branch offsets 2 bytes (i.e. BPL, BMI, etc.) - fixed pos/neg bug in relative branch output - fixed parsing of SUPER records - added support for cINTERSEG and INTERSEG records - fixed offset values in SUPER, cRELOC, RELOC records - added length of CONST, LCONST records to output - redirection under Orca now works if filename is last on command-line - (thanks to Jerry Penner for above) - added '+exact' option - a list of all segment/loadsegment names not matched is displayed at - the end of a coff run - changed '+default' option to '+nodefault' - a message is now displayed if coff is unable to parse an OMF record - (which is the case if a test file could not be generated - for the OMF record) - when +hex is added to +header, headers are printed in hex - added a few more error messages - manual rewritten in TeX - -v1.0 16 june 1992 - converted to assembly - parse_kind_1() and parse_kind_2() work - unary expressions printed correctly - MEM disassembly works - xEXPR disassembly more intelligent - extended floating values recognized - moved GS/OS, ROM, Toolbox defines to data fork - support for System 6.0 Toolbox calls - added '+thanks' option - support for pause and cancel options in Merlin and Orca versions - support for CTRL-C GNO cancel signal in GNO version - (thanks to jawaid bazyar) - -v1.0g 30 june 1991 - changed defaults to +label, +infix, +tool - +orca option only enables Orca/M disassembly - +merlin option only enables Merlin disassembly - fixed bug in parse_relexpr() - fixed bug in recognize_record() - meaning of +default reversed - reorganized code - fixed prototype of parse_opcode_1() - -v1.0f 11 june 1991 - added record types: RELOC, cRELOC, SUPER - -v1.0e 5 june 1991 - jsr (addr,x) and jmp (addr,x) where addr is a number are - handled correctly - (thanks to jerry brenne) - mvn opcode now parsed correctly - +hex with dangling asm opcodes at end of OMF segment print in - correct position - exit status changed to 0 from 1 - library file are properly handled - support for verbose kind description fields - -v1.0d 2 may 1991 - +longa, +longi removed and replaced by +shorta, +shorti - fixed bug if OMF file looked like - pea $ - jsl > - (thanks to tim meekins) - fixed bug for dangling asm opcodes at end of OMF segment - (thanks to tim meekins) - -v1.0c 30 april 1991 - 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 coff utility - 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 22 january 1991 - fix pause, oa-period - (thanks to jawaid bazyar, tim meekins) - fix to disassembly routines - set reload bit - -v0.9b 12 january 1991 - 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 21 december 1990 - support for OMF v2.0 headers - added record type: LCONST - -v0.7b 19 december 1990 - added record types: GEQU, MEM, EQU - -v0.6b 18 december 1990 - initial release of beta - =coff.h.s -* UNIX coff utility -* defines -* -* 1990-1992, The UNIX Consortium Developer Project -* -* albert chin-a-young ... 26285659t@servax.fiu.edu - - -NULL equ 0 -EOF equ $ffff -FALSE equ 0 ;boolean false value -TRUE equ 1 ;boolean true value - -CTRL_C equ $03 ;ctrl-c keypress (cancel) - -MERLIN_16 equ %00000001 ;output code for Merlin 16 -ORCA_M equ %00000010 ;output code for Orca/M - -;error messages -ERROR_STRING equ %00000001_00000000 ;parameter to error is C-String -ERROR_LHEX_VALUE equ %00000010_00000000 ;parameter to error is long hex value -ERROR_DEC_VALUE equ %00000100_00000000 ;parameter to error is decimal value -NO_FILENAME equ ERROR_STRING+$00 ;no OMF filename given -INVALID_FILENAME equ ERROR_STRING+$02 ;filename given is incorrect -PREMATURE_END equ ERROR_STRING+$04 ;premature end of file -OMF_VERSION equ ERROR_DEC_VALUE+$06 ;invalid OMF version -INVALID_LENGTH equ ERROR_LHEX_VALUE+$08 ;invalid length of OMF file -MORE_DATA equ ERROR_STRING+$0a ;not enough data in file to make sense of - -MERLIN equ %00000001 ;merlin assembler -ORCA equ %00000010 ;orca assembler - -ERROR equ $ffff -LOADNAME_LEN equ 10 ;length of loadname in OMF header -KIND_LEN equ 40 ;length of kind descriptor -DC equ $0100 -HEADER_LEN equ $38 ;approximate length of OMF header - -HEADER_EDGE equ 15 -ADDRESS_EDGE equ 36 -CHAR_EDGE equ 40 -CONST_EDGE equ 10 -DOUBLE_EDGE equ 36 -EXTENDED_EDGE equ 36 -FLOAT_EDGE equ 36 -HEX_EDGE equ 20 -INT_EDGE equ 36 -INFIX_EDGE equ 32 -POSTFIX_EDGE equ 30 -SOFT_REFERENCE_EDGE equ 36 -SUPER_EDGE equ 11 -INVALID_NAME_EDGE equ 65 - -TRUE_OFFSET equ $80 -FALSE_OFFSET equ $81 -LIBRARY equ $b2 ;library file - -USAGE equ $0001 ;short usage parameters -USAGE_VERBOSE equ $0002 ;verbose usage parameters -VERSION equ $0003 ;coff version number -THANKS equ $0004 ;those who helped in development of coff -DEFAULT equ $0005 ;default options - -GSOS_INLINE equ $e100a8 ;GS/OS inline entry -GSOS_STACK equ $e100b0 ;GS/OS stack entry -PRODOS_MLI equ $bf00 ;ProDOS 8 MLI entry -TOOL_STACK equ $e10000 ;ToolBox stack entry -TOOL_STACK_ALT equ $e10004 ;alt ToolBox stack entry - -KBD equ $e0c000 ;read keyboard -KBDSTRB equ $e0c010 ;clear keyboard - -* segment type subfield -* -CODE equ $0000 -DATA equ $0001 -JUMP_TABLE equ $0002 -PATHNAME equ $0004 -LIBRARY_DICTIONARY equ $0008 -INITIALIZATION equ $0010 -ABSOLUTE_BANK_SEG equ $0011 -DIRECT_PAGE equ $0012 - -* segment attributes bits -* -BANK_RELATIVE equ $0100 -SKIP equ $0200 -RELOAD equ $0400 -ABSOLUTE_BANK equ $0800 -POSITION_INDEPENDENT equ $2000 -PRIVATE equ $4000 -DYNAMIC equ $8000 - -* segment-body record types -* -END equ $00 -ALIGN equ $e0 -ORG equ $e1 -RELOC equ $e2 -INTERSEG equ $e3 -USING equ $e4 -STRONG equ $e5 -GLOBAL equ $e6 -GEQU equ $e7 -MEM equ $e8 -EXPR equ $eb -ZEXPR equ $ec -BEXPR equ $ed -RELEXPR equ $ee -LOCAL equ $ef -EQU equ $f0 -DS equ $f1 -LCONST equ $f2 -LEXPR equ $f3 -ENTRY equ $f4 -cRELOC equ $f5 -cINTERSEG equ $f6 -SUPER equ $f7 -GENERAL equ $fb - -SUPER_RELOC2 equ 0 -SUPER_RELOC3 equ 1 - -* expressions -* -ADD equ $01 -SUB equ $02 -MUL equ $03 -DIV equ $04 -MOD equ $05 -NEGATION equ $06 -BIT_SHIFT equ $07 -AND equ $08 -OR equ $09 -EOR equ $0a -NOT equ $0b -LESS_EQUAL equ $0c -GREATER_EQUAL equ $0d -NOT_EQUAL equ $0e -LESS equ $0f -GREATER equ $10 -EQUAL equ $11 -LOGICAL_AND equ $12 -INCLUSIVE_OR equ $13 -EXCLUSIVE_OR equ $14 -COMPLEMENT equ $15 - -LEFT equ 0 -RIGHT equ 1 -LEFT_RIGHT equ 2 - -LOCATION_COUNTER equ $80 -CONSTANT_OPERAND equ $81 -LABEL_WEAK equ $82 -LABEL_VALUE equ $83 -LABEL_LENGTH equ $84 -LABEL_TYPE equ $85 -LABEL_COUNT equ $86 -RELATIVE_OFFSET equ $87 - -LONGI equ $10 -LONGA equ $20 - -ASL equ $0a -INC equ $1a -ROL equ $2a -DEC equ $3a -LSR equ $4a -ROR equ $6a - -JSR equ $20 -JSL equ $22 -LDX equ $a2 -PEA equ $f4 - -BPL equ $10 -BMI equ $30 -BVC equ $50 -BVS equ $70 -BRA equ $80 -BCC equ $90 -BCS equ $b0 -REP equ $c2 -BNE equ $d0 -SEP equ $e2 -BEQ equ $f0 - -* addressing modes -* -ABSOLUTE equ $01 -ABSOLUTE_INDEX_X equ $02 -ABSOLUTE_INDEX_Y equ $03 -ABSOLUTE_INDEX_INDIRECT equ $04 -ABSOLUTE_INDIRECT equ $05 -ABSOLUTE_INDIRECT_LONG equ $06 -ABSOLUTE_LONG equ $07 -ABSOLUTE_LONG_INDEX_X equ $08 -ACCUMULATOR equ $09 -BLOCK_MOVE equ $0a -DP equ $0b -DP_INDEX_X equ $0c -DP_INDEX_Y equ $0d -DP_INDEX_INDIRECT_X equ $0e -DP_INDIRECT equ $0f -DP_INDIRECT_LONG equ $10 -DP_INDIRECT_INDEX_Y equ $11 -DP_INDIRECT_LONG_INDEX_Y equ $12 -IMMEDIATE equ $13 -IMPLIED equ $14 -PC_RELATIVE equ $15 -PC_RELATIVE_LONG equ $16 -STACK_ABSOLUTE equ $17 -STACK_DP_INDIRECT equ $18 -STACK_INTERRUPT equ $19 -STACK_PC_RELATIVE equ $1a -STACK_PULL equ $1b -STACK_PUSH equ $1c -STACK_RTI equ $1d -STACK_RTL equ $1e -STACK_RTS equ $1f -STACK_RELATIVE equ $20 -SR_INDIRECT_INDEX_Y equ $21 -WDM equ $22 - -;@label structure references -`label_name equ $00 ;name of label -`expr_name equ `label_name+4 ;expression label evaluates to -`type equ `expr_name+4 ;GLOBAL or LOCAL label -`next equ `type+2 ;next label reference -`prev equ `next+4 ;previous label reference -`last equ `prev+4 - -;@stack structure references -stack`str equ $00 ;handle to expression name (string) -stack`oper equ stack`str+4 ;if expression is an operator - -;@label data structure offsets -`lo equ $00 ;handle to array of labels -`hi equ `lo+4 - -;offsets to elements in binary tree -`str equ $00 -`oper equ `str+4 -`left equ `oper+2 ;left tree -`right equ `left+2 ;right tree - - ;@btree data structure offsets -`ptr equ $00 ;pointer to array of binary trees - -;~operator data structure offsets -`prec equ $00 ;operator precedence -`assoc equ `prec+2 ;operator associativity - -;~opcodes data structure offsets -`num_bytes equ $00 ;number of bytes the opcode takes -`m equ `num_bytes+2 ;if 16-bit mode accumulator -`i equ `m+2 ;if 16-bit mode index registers -`mode equ `i+2 ;addressing mode -`syntax equ `mode+2 ;how to format opcode - -;@omf data structure offsets -`offset equ $00 ;offset from beginning of file for this segment -`bytecnt equ `offset+4 ;number of bytes in file that segment requires -`resspc equ `bytecnt+4 ;number of bytes of zeros to add to end of segment -`length equ `resspc+4 ;memory size of segment -`kind equ `length+4 ;type and attributes of segment -`lablen equ `kind+2 ;length of each name or label record in segment -`numlen equ `lablen+2 ;length of each number field in segment body -`version equ `numlen+2 ;version number of OMF segment is compatible with -`revision equ `version+2 ;revision number of OMF v2.0 segment is compatible with -`banksize equ `revision+2 ;maximum memory-bank size for segment -`org equ `banksize+4 ;absolute address at which to load segment -`align equ `org+4 ;boundary on which to align segment -`numsex equ `align+4 ;order of bytes in a number field -`lcbank equ `numsex+2 ;load segment into language card -`segnum equ `lcbank+2 ;segment number -`entry equ `segnum+2 ;offset into segment that corresponds to entry point -`dispname equ `entry+4 ;displacement of the loadname field within segment header -`dispdata equ `dispname+2 ;displacement from start of segment header to start of segment body -`temporg equ `dispdata+2 ;temporary origin of object segment for OMF v2.0 -`loadname equ `temporg+4 ;name of load segment -`segname equ `loadname+LOADNAME_LEN ;name of segment -`displacement equ `segname+4 -`counter equ `displacement+4 -`library equ `counter+4 ;if file is a library -`refNum equ `library+2 ;reference number associated with file - -;global/local data parsing structure -`on equ $00 ;test if parsing on -`data_type equ `on+2 ;type of data to parse -`count equ `data_type+2 ;number of records to parse -`edge equ `count+2 ;right margin for output of data - -;@stack data structure offsets -`lo equ $00 ;array of handles containing stack -`hi equ `lo+4 ;elements -`size equ `hi+4 ;number of elements in stack - -;@expr_list data structure offsets -`lo equ $00 ;array of handles containing stack -`hi equ `lo+4 ;elements -`size equ `hi+4 ;number of elements in stack - -;offset for @Close data structure -Close`pCount equ $00 -Close`refNum equ Close`pCount+2 - -;offset for @Open data structure -Open`pCount equ $00 -Open`refNum equ Open`pCount+2 -Open`pathname equ Open`refNum+2 -Open`requestAccess equ $08 -Open`resourceNumber equ $0a -Open`access equ $0c -Open`fileType equ $0e -Open`auxType equ $10 -Open`storageType equ $14 -Open`createDateTime equ $16 -Open`modDateTime equ $1e -Open`optionList equ $26 -Open`eof equ $2a -Open`blocksUsed equ $2e -Open`resourceEOF equ $32 -Open`resourceBlocks equ $36 - -;offset for @SetMark data structure -SetMark`pCount equ $00 -SetMark`refNum equ SetMark`pCount+2 -SetMark`base equ SetMark`refNum+2 -SetMark`displacement equ SetMark`base+2 - -;offset for @GetMark data structure -GetMark`pCount equ $00 -GetMark`refNum equ $02 -GetMark`position equ $04 - -;offset for @Quit data structure -Quit`pCount equ $00 -Quit`pathname equ $02 -Quit`flags equ $06 - -;offset for @Read data structure -Read`pCount equ $00 -Read`refNum equ $02 -Read`dataBuffer equ $04 -Read`requestCount equ $08 -Read`transferCount equ $0c -Read`cachePriority equ $10 - -GSOSstack equ $e100b0 ;gs/os stack entry point - -Open equ $2010 ;Open call number -Read equ $2012 ;Read call number -Close equ $2014 ;Close call number -SetMark equ $2016 ;SetMark call number -GetMark equ $2017 ;GetMark call number -Quit equ $2029 ;Quit call number =coff.mac.s -* UNIX coff utility -* macros -* -* 1990-1992, tao Developer Project - - -cstr mac - asc ' ' ;space between opcode and operand - asc ]1 - db 0 - eom -absolute mac - dw 3,0,0 - dw ABSOLUTE - asc ]1 - cstr '$%4' - eom -absolute_index_x mac - dw 3,0,0 - dw ABSOLUTE_INDEX_X - asc ]1 - cstr '$%4,x' - eom -absolute_index_y mac - dw 3,0,0 - dw ABSOLUTE_INDEX_Y - asc ]1 - cstr '$%4,y' - eom -absolute_index_indirect mac - dw 3,0,0 - dw ABSOLUTE_INDEX_INDIRECT - asc ]1 - cstr '($%4,x)' - eom -absolute_indirect mac - dw 3,0,0 - dw ABSOLUTE_INDIRECT - asc ]1 - cstr '($%4)' - eom -absolute_indirect_long mac - dw 3,0,0 - dw ABSOLUTE_INDIRECT_LONG - asc ]1 - cstr '[$%4]' - eom -absolute_long mac - dw 4,0,0 - dw ABSOLUTE_LONG - asc ]1 - cstr '%c$%6' - eom -absolute_long_index_x mac - dw 4,0,0 - dw ABSOLUTE_LONG_INDEX_X - asc ]1 - cstr '%c$%6,x' - eom -accumulator macm - dw 1,0,0 - dw ACCUMULATOR - asc ]1 - asc ' ',00 - eom -block_move mac - dw 3,0,0 - dw BLOCK_MOVE - asc ]1 - asc ' $',00 - eom -dp mac - dw 2,0,0 - dw DP - asc ]1 - cstr '$%2' - eom -dp_index_x mac - dw 2,0,0 - dw DP_INDEX_X - asc ]1 - cstr '$%2,x' - eom -dp_index_y mac - dw 2,0,0 - dw DP_INDEX_Y - asc ]1 - cstr '$%2,y' - eom -dp_index_indirect_x mac - dw 2,0,0 - dw DP_INDEX_INDIRECT_X - asc ]1 - cstr '($%2,x)' - eom -dp_indirect mac - dw 2,0,0 - dw DP_INDIRECT - asc ]1 - cstr '($%2)' - eom -dp_indirect_long mac - dw 2,0,0 - dw DP_INDIRECT_LONG - asc ]1 - cstr '[$%2]' - eom -dp_indirect_index_y mac - dw 2,0,0 - dw DP_INDIRECT_INDEX_Y - asc ]1 - cstr '($%2),y' - eom -dp_indirect_long_index_y mac - dw 2,0,0 - dw DP_INDIRECT_LONG_INDEX_Y - asc ]1 - cstr '[$%2],y' - eom -immediate_m mac - dw 2,1,0 - dw IMMEDIATE - asc ]1 - cstr '#$%2' - eom -immediate_i mac - dw 2,0,1 - dw IMMEDIATE - asc ]1 - cstr '#$%2' - eom -immediate_rep mac - dw 2,0,0 - dw IMMEDIATE - asc ]1 - cstr '#$%2' - eom -immediate_sep mac - dw 2,0,0 - dw IMMEDIATE - asc ]1 - cstr '#$%2' - eom -implied mac - dw 1,0,0 - dw IMPLIED - asc ]1 - asc ' ',00 - eom -pc_relative mac - dw 2,0,0 - dw PC_RELATIVE - asc ]1 - cstr '$%4' - eom -pc_relative_long mac - dw 3,0,0 - dw PC_RELATIVE_LONG - asc ]1 - cstr '$%4' - eom -stack_absolute mac - dw 3,0,0 - dw STACK_ABSOLUTE - asc ]1 - cstr '$%4' - eom -stack_dp_indirect mac - dw 2,0,0 - dw STACK_DP_INDIRECT - asc ]1 - cstr '($%2)' - eom -stack_interrupt mac - dw 2,0,0 - dw STACK_INTERRUPT - asc ]1 - cstr '$%2' - eom -stack_pc_relative mac - dw 3,0,0 - dw STACK_PC_RELATIVE - asc ]1 - cstr '$%4' - eom -stack_pull mac - dw 1,0,0 - dw STACK_PULL - asc ]1 - asc ' ',00 - eom -stack_push mac - dw 1,0,0 - dw STACK_PUSH - asc ]1 - asc ' ',00 - eom -stack_rti mac - dw 1,0,0 - dw STACK_RTI - asc ]1 - asc ' ',00 - eom -stack_rtl mac - dw 1,0,0 - dw STACK_RTL - asc ]1 - asc ' ',00 - eom -stack_rts mac - dw 1,0,0 - dw STACK_RTS - asc ]1 - asc ' ',00 - eom -sr mac - dw 2,0,0 - dw STACK_RELATIVE - asc ]1 - cstr '$%2,s' - eom -sr_indirect_index_y mac - dw 2,0,0 - dw SR_INDIRECT_INDEX_Y - asc ]1 - cstr '($%2,s),y' - eom -wdm_ mac - dw 2,0,0 - dw WDM - asc ]1 - cstr '$%2' - eom - -operator mac - dw ]1 ;operator precedence - dw ]2 ;operator associativity - eom - -read_char mac ;read one byte - if ],]1 ;special case reading into a - clc ;dp location - tdc - adc #]1 - tax - ldy #0 - else - ldx #]1 - ldy #^]1 - fin - lda #1 - jsr GSOSread - eom -read_short mac ;read two bytes - if ],]1 ;special case reading into a - clc ;dp location - tdc - adc #]1 - tax - ldy #0 - else - ldx #]1 - ldy #^]1 - fin - lda #2 - jsr GSOSread - eom -read_long mac ;read four bytes - if ],]1 ;special case reading into a - clc ;dp location - tdc - adc #]1 - tax - ldy #0 - else - ldx #]1 - ldy #^]1 - fin - lda #4 - jsr GSOSread - eom -read_float mac ;read one byte - if ],]1 ;special case reading into a - clc ;dp location - tdc - adc #]1 - tax - ldy #0 - else - ldx #]1 - ldy #^]1 - fin - lda #4 - jsr GSOSread - eom -read_double mac ;read one byte - if ],]1 ;special case reading into a - clc ;dp location - tdc - adc #]1 - tax - ldy #0 - else - ldx #]1 - ldy #^]1 - fin - lda #8 - jsr GSOSread - eom -read_extended mac ;read one byte - if ],]1 ;special case reading into a - clc ;dp location - tdc - adc #]1 - tax - ldy #0 - else - ldx #]1 - ldy #^]1 - fin - lda #10 - jsr GSOSread - eom - -_DebugStr mac - pea #^]1 - pea #]1 - ldx #$09ff - jsl $e10000 - eom -_GSOS mac - pea #^]2 - pea #]2 - pea #]1 - jsl GSOSstack - eom -shorta mac - mx %10 - sep %00100000 - eom -longa mac - mx %00 - rep %00100000 - eom -shorti mac - mx %01 - sep %00010000 - eom -longi mac - mx %00 - rep %00010000 - eom - -incr mac ;longword inc - if 1,]0 - inc ]1 - bne end - inc ]1+2 - else - clc - lda ]2 - adc ]1 - sta ]2 - bcc end - inc ]2+2 -end fin - eom -decr mac ;longword dec - if 1,]0 - dec ]1 - bpl end - dec ]1+2 - else - sec - lda ]2 - sbc ]1 - sta ]2 - bcs end - dec ]2+2 -end fin - eom - -_TLStartUp mac - Tool $201 - eom -_TLShutDown mac - Tool $301 - eom -_MMStartUp mac - Tool $202 - eom -_MMShutDown mac - Tool $302 - eom -_DisposeAll mac - Tool $1102 - eom -_StartUpTools mac - Tool $1801 - eom -_ShutDownTools mac - Tool $1901 - eom -Tool mac - ldx #]1 - jsl $e10000 - eom -_LoadResource mac - Tool $e1e - eom -_WriteCString mac - Tool $200c - eom -_WriteString mac - Tool $1c0c - eom -_ErrWriteCString mac - Tool $210c - eom -_ErrWriteChar mac - Tool $190c - eom -_WriteChar mac - Tool $180c - eom -_TextWriteBlock mac - Tool $1e0c - eom -_ResourceStartUp mac - Tool $021e - eom -_ResourceShutDown mac - Tool $031e - eom -_CloseResourceFile mac - Tool $0b1e - eom -_OpenResourceFile mac - Tool $0a1e - eom -_GetOutputDevice mac - Tool $130c - eom -_GetErrorDevice mac - Tool $140c - eom -_LGetPathname2 mac - Tool $2211 - eom -_HLock mac - Tool $2002 - eom -_GetResourceSize mac - Tool $1d1e - eom -_HUnlock mac - Tool $2202 - eom -_NewHandle mac - Tool $902 - eom -_DisposeHandle mac - Tool $1002 - eom -_SetHandleSize mac - Tool $1902 - eom -_Int2Hex mac - Tool $220b - eom -_Int2Dec mac - Tool $260b - eom -_Long2Hex mac - Tool $230b - eom -_Long2Dec mac - Tool $270b - eom -_SysBeep mac - Tool $2c03 - eom - -_SANEDecStr816 mac - Tool $0A0A - eom -_SANEFP816 mac - Tool $090A - eom -_Float2Decimal mac - pea #$020b - _SANEFP816 - eom -_Double2Decimal mac - pea #$010b - _SANEFP816 - eom -_Extended2Decimal mac - pea #$000b - _SANEFP816 - eom -_Dec2Str mac - pea #1 - _SANEDecStr816 - eom =datatype.mac.s -* data types -* -* albert chin-a-young ... 26285659t@servax.fiu.edu - -* integer types -* -UnsignedLong mac - if 0,]0 - ds 4 - else - adrl ]1 - fin - eom -Long mac - if 0,]0 - ds 4 - else - adrl ]1 - fin - eom -UnsignedShort mac - if 0,]0 - ds 2 - else - dw ]1 - fin - eom -Short mac - if 0,]0 - ds 2 - else - dw ]1 - fin - eom -UnsignedChar mac - if 0,]0 - ds 1 - else - db ]1 - fin - eom -Char mac - if 0,]0 - ds 1 - else - ds ]1 - fin - eom -Boolean mac - if 0,]0 - ds 2 - else - adrl ]1 - fin - eom - -* pointer types -* -Handle mac - if 0,]0 - adrl 0 - else - adrl ]1 - fin - eom -Pointer mac - if 0,]0 - adrl 0 - else - adrl ]1 - fin - eom -CharPtr mac - if 0,]0 - ds 4 - else - adrl ]1 - fin - eom -ShortPtr mac - if 0,]0 - ds 4 - else - adrl ]1 - fin - eom - -* string types -* -cStr mac ;C-style string with trailing 0 - asc ]1 - db 0 - eom -pStr mac ;Pascal-style string with leading - str ]1 ;length byte - eom -gsStr mac ;GS/OS-style string with leading - strl ]1 ;length word - eom - -* gs/os types -* -Word mac - if 0,]0 - dw 0 - else - dw ]1 - fin - eom =coff.r -/* - coff - utility to dump contents of OMF files - - 1990-1992, The tao Developer Project - - albert chin-a-young ... 26285659t@servax.fiu.edu -*/ - -#include "types.rez" - -#define USAGE 0x0001 -#define USAGE_VERBOSE 0x0002 -#define VERSION 0x0003 -#define THANKS 0x0004 -#define DEFAULT 0x0005 - -#if defined(MERLIN) -#define RETURN "\n" -#elif defined(ORCA) -#define RETURN "\n\r" -#elif defined(GNO) -#define RETURN "\n\r" -#endif - -resource rText (USAGE) -{ - $$Format (" [-vDdTxltpmoaisnfceh] [segment..] [loadsegment..]%s", RETURN) - $$Format (" [+version] [+nodefault] [+asm] [+tool] [+hex] [+label] [+infix]%s", RETURN) - $$Format (" [+postfix] [+merlin] [+orca] [+shorta] [+shorti] [+header]%s", RETURN) - $$Format (" [+noheader] [+nooffset] [+compress] [+exact] [+thanks] [+help]%s", RETURN) - "\000" -}; - -#if defined(MERLIN) -resource rText (USAGE_VERBOSE) -{ - " [-OPTIONS] filename [segment..] [loadsegment..]\n\n" - " OPTIONS DESCRIPTION\n" - " -v [+version] display version number\n" - " -D [+nodefault] disable default options\n" - " -d [+asm] dump segment body in 65816-format disassembly\n" - " -T [+tool] interpret Toolbox, GS/OS, ProDOS, ROM calls\n" - " -x [+hex] dump segment body in hex (can be used with '+asm')\n" - " -l [+label] print expressions using labels (default is offsets)\n" - " -t [+infix] display expressions in infix form\n" - " -p [+postfix] display expressions in postfix form (default)\n" - " -m [+merlin] format of '+asm' to use merlin opcodes (default)\n" - " -o [+orca] format of '+asm' to use orca/m opcodes\n" - " -a [+shorta] assume 8-bit accumulator for disassembly\n" - " -i [+shorti] assume 8-bit index registers for disassembly\n" - " -s [+header] dump segment headers only\n" - " -n [+noheader] do not print segment headers\n" - " -f [+nooffset] do not print offset into file\n" - " -c [+compress] print short form of CONST, LCONST records\n" - " -e [+exact] match segment, loadsegment names exactly\n" - " [+thanks] those who helped in the development of coff\n" - " -h [+help] print this information, then quit\n\n" - " filename name of OMF file to dump\n" - " [segment] names of segments in file to dump\n" - " [loadsegment] names of load segments in file to dump\n\000" -}; -#elif defined(ORCA) -resource rText (USAGE_VERBOSE) -{ - " [-OPTIONS] filename [segment..] [loadsegment..]\n\r\n\r" - " OPTIONS DESCRIPTION\n\r" - " -v [+version] display version number\n\r" - " -D [+nodefault] disable default options\n\r" - " -d [+asm] dump segment body in 65816-format disassembly\n\r" - " -T [+tool] interpret Toolbox, GS/OS, ProDOS, ROM calls\n\r" - " -x [+hex] dump segment body in hex (can be used with '+asm')\n\r" - " -l [+label] print expressions using labels (default is offsets)\n\r" - " -t [+infix] display expressions in infix form\n\r" - " -p [+postfix] display expressions in postfix form (default)\n\r" - " -m [+merlin] format of '+asm' to use merlin opcodes (default)\n\r" - " -o [+orca] format of '+asm' to use orca/m opcodes\n\r" - " -a [+shorta] assume 8-bit accumulator for disassembly\n\r" - " -i [+shorti] assume 8-bit index registers for disassembly\n\r" - " -s [+header] dump segment headers only\n\r" - " -n [+noheader] do not print segment headers\n\r" - " -f [+nooffset] do not print offset into file\n\r" - " -c [+compress] print short form of CONST, LCONST records\n\r" - " -e [+exact] match segment, loadsegment names exactly\n\r" - " [+thanks] those who helped in the development of coff\n\r" - " -h [+help] print this information, then quit\n\r\n\r" - " filename name of OMF file to dump\n\r" - " [segment] names of segments in file to dump\n\r" - " [loadsegment] names of load segments in file to dump\n\r\000" -}; -#elif defined(GNO) -resource rText (USAGE_VERBOSE) -{ - " [OPTIONS] filename [segment..] [loadsegment..]\n\r\n\r" - "\tOPTIONS\t\tDESCRIPTION\n\r" - "\t-v [+version]\tdisplay version number\n\r" - "\t-D [+nodefault]\tdisable default options\n\r" - "\t-d [+asm]\tdump segment body in 65816-format disassembly\n\r" - "\t-T [+tool]\tinterpret Toolbox, GS/OS, ProDOS, ROM calls\n\r" - "\t-x [+hex]\tdump segment body in hex (can be used with '+asm')\n\r" - "\t-l [+label]\tprint expressions using labels (default is offsets)\n\r" - "\t-t [+infix]\tdisplay expressions in infix form\n\r" - "\t-p [+postfix]\tdisplay expressions in postfix form (default)\n\r" - "\t-m [+merlin]\tformat of '+asm' to use merlin opcodes (default)\n\r" - "\t-o [+orca]\tformat of '+asm' to use orca/m opcodes\n\r" - "\t-a [+shorta]\tassume 8-bit accumulator for disassembly\n\r" - "\t-i [+shorti]\tassume 8-bit index registers for disassembly\n\r" - "\t-s [+header]\tdump segment headers only\n\r" - "\t-n [+noheader]\tdo not print segment headers\n\r" - "\t-f [+nooffset]\tdo not print offset into file\n\r" - "\t-c [+compress]\tprint short form of CONST, LCONST records\n\r" - "\t-e [+exact]\tmatch segment, loadsegment names exactly\n\r" - "\t [+thanks]\tthose who helped in the development of coff\n\r" - "\t-h [+help]\tprint this information, then quit\n\r\n\r" - "\tfilename\tname of OMF file to dump\n\r" - "\t[segment]\tnames of segments in file to dump\n\r" - "\t[loadsegment]\tnames of load segments in file to dump\n\r\000" -}; -#endif - -resource rText (VERSION) -{ - $$Format ("v1.1%s1990-1992, tao Developer Project%s%s", RETURN, RETURN, RETURN) - "\000" -}; - -resource rText (THANKS) -{ - $$Format ("Special thanks to the following:%s", RETURN) - $$Format ("Jawaid Bazyar : Beta Tester, GNO support%s", RETURN) - $$Format ("Soenke Behrens: Reviewing manual%s", RETURN) - $$Format ("Gregg Brekke : Reviewing manual%s", RETURN) - $$Format ("Morgan Davis : Beta Tester, alt Toolbox entry option%s", RETURN) - $$Format ("Dave Lyons : Permission to use NiftyList 'nlist.data' file data%s", RETURN) - $$Format ("Tim Meekins : Beta Tester, minimal parentheses option%s", RETURN) - $$Format ("Jerry Penner : Beta Tester, +compress option, reviewing manual%s", RETURN) - $$Format ("Rose Miller : Thanks%s%s", RETURN, RETURN) - "\000" -}; - -resource rText (DEFAULT) -{ - "+label\000" - "+infix\000" - "+tool\000" -}; - -resource rVersion (0x0001) -{ - { - 0x01, // version 1.1 - 0x01, // no minor release - 0x00, // bug version - final, // final release - 0x00, // non-final release number - }, - verUS, // USA version - "coff", - "1990-1992, tao Developer Project" -}; - -resource rComment (0x0001) -{ - "coff, an Object Module Format (OMF) disassembler.\n\n" - "post:\tAlbert Chin-A-Young\n" - "\tP.O. Box 4133\n" - "\tMiramar, Florida 33083-4133\n\n" - "email:\trichard@serss0.fiu.edu\n" - "\t26285659t@servax.fiu.edu" -}; =make.gno.s -* UNIX coff utility -* GNO link script -* -* 1990-1992, tao Developer Project - - nol - fas ;fast linker mode - - if 4/env.h - - asm coff - asm gsos - asm omf - asm asm - asm output - asm general - asm structure - asm data - asm tool - asm 1/getopt/getopt - - lnk coff.l - lnk gsos.l - lnk omf.l - lnk asm.l - lnk output.l - lnk general.l - lnk structure.l - lnk data.l - lnk tool.l - lnk 5/getopt.l - - -************************************************** - typ exe - sav /dev/gno/bin/coff =make.orca.s -* UNIX coff utility -* Orca link script -* -* 1990-1992, tao Developer Project - - nol - fas ;fast linker mode - - if 4/env.h - - asm coff - asm gsos - asm omf - asm asm - asm output - asm general - asm structure - asm data - asm tool - asm 1/getopt/getopt - - lnk coff.l - lnk gsos.l - lnk omf.l - lnk asm.l - lnk output.l - lnk general.l - lnk structure.l - lnk data.l - lnk tool.l - lnk 5/getopt.l - - -************************************************** - typ exe - sav /dev/orca/utilities/coff =make.rez -echo Compiling resource file for Merlin 16+ -compile coff.r keep=/usr/bin/coff rez=(-d MERLIN) -echo Compiling resource file for Orca -compile coff.r keep=/dev/orca/utilities/coff rez=(-d ORCA) -echo Compiling resource file for GNO -compile coff.r keep=/dev/gno/bin/coff rez=(-d GNO) =make.s -* UNIX coff utility -* Merlin link script -* -* 1990-1992, tao Developer Project - - nol - fas ;fast linker mode - - if 4/env.h - - asm coff - asm gsos - asm omf - asm asm - asm output - asm general - asm structure - asm data - asm tool - asm 1/getopt/getopt - - lnk coff.l - lnk gsos.l - lnk omf.l - lnk asm.l - lnk output.l - lnk general.l - lnk structure.l - lnk data.l - lnk tool.l - lnk 5/getopt.l - - -************************************************** - typ exe - sav 6/coff =x.asm.s -* UNIX coff utility -* 65816 OMF disassembler externals -* -* 1990-1992, tao Developer Project - -display_header_asm ext ;display asm disassembly header -parse_CONST_asm ext ;disassembly entry point -parse_type_attribute ext ;disassemble label type =x.data.s -* UNIX coff utility -* variable externals -* -* 1990-1992, tao Developer Project - -* variables -* -userID ext ;userID returned by MMStartUp -coff ext -long_hex_str ext ;string hex representation of long value -short_hex_str ext ;string hex representation of short value -char_hex_str ext ;string hex representation of char value -long_dec_str ext ;string decimal representation of long value -short_dec_str ext ;string decimal representation of short value -char_dec_str ext ;string decimal representation of char value -blank_str ext ;blank string -vert_separator ext ;separate displacement/bytes -space_vert_bar ext ;spaced vertical bar -space_12 ext ;space between left edge and operand - -DS_asm ext ;ds directive name -GEQU_asm ext ;GEQU directive name -EQU_asm ext ;EQU directive name -hex_asm ext ;merlin hex directive -db_asm ext ;merlin db directive -dw_asm ext ;merlin dw directive -adr_asm ext ;merlin adr directive -adrl_asm ext ;merlin adrl directive -dc_a_asm ext ;orca address directive -dc_d_asm ext ;orca double directive -dc_e_asm ext ;orca extended directive -dc_f_asm ext ;orca float directive -dc_h_asm ext ;orca hex directive -dc_i_asm ext ;orca integer directive - -* boolean variables -* -}version ext ;display version number -}tool ext ;interpret ToolBox, GS/OS, ProDOS, ROM calls -}assembly ext ;dump in asm format -}label ext ;print expressions with labels, not offsets -}infix ext ;display expressions in infix (default for +asm) -}postfix ext ;display expressions in postfix (default) -}hex ext ;nonzero means dump in hex format -}header ext ;nonzero means dump -}noheader ext ;nonzero does not display segment headers -}nooffset ext ;nonzero means don't print offset into file -}help ext ;nonzero means print switch descriptions -}shorta ext ;8-bit accumulator -}shorti ext ;8-bit index registers -}compress ext ;compress OMF listing -}exact ext ;match segment, loadsegment names exactly -}default_opt ext ;disable default options - -* constant variables -* -~assembler ext ;output code for which assembler -~error_msg ext ;error messages -~opcodes ext ;65816 opcodes -~operator ext ;operator precedence -~long_options ext ;command-line options accepted by coff - -* data structures -* -@omf ext ;OMF header structure -@parse_data ext ;global/local data parsing structure -@label ext ;label references -@expr_list ext ;expression list -@btree ext ;binary-tree structure -@stack ext ;stack structure - -* gs/os data structures -* -@Close ext -@GetDirEntry ext -@GetPrefix ext -@Open ext -@GetMark ext -@SetMark ext -@Quit ext -@Read ext =x.general.s -* UNIX coff utility -* general routine externals -* -* 1990-1992, tao Developer Project - -dp_argv ext ;move @argv to dp -error ext ;error routine -get_progname ext ;get program name minus path string -isprint ext ;if character is a printing character -lowercase_hex ext ;convert uppercase hex alpha to lowercase -name_GSOS ext ;convert GSOS call to equivalent name -name_ROM ext ;convert ROM call to equivalent name -name_TOOL ext ;convert TOOLBOX call to equivalent name -print_char_dec ext ;print char value as decimal string -print_short_dec ext ;print short value as decimal string -print_long_dec ext ;print long value as decimal string -print_char_sdec ext ;print signed char value as decimal string -print_char_hex ext ;print char value as hex string -print_short_hex ext ;print short value as hex string -print_long_hex ext ;print long value as hex string -print_fix_char_dec ext ;print char value as fixed decimal string -print_fix_long_dec ext ;print long value as fixed decimal string -print_fix_short_dec ext ;print short value as fixed decimal string -print_fix_char_hex ext ;print char value as fixed hex string -print_fix_long_hex ext ;print long value as fixed hex string -print_fix_short_hex ext ;print short value as fixed hex string -print_double ext ;print double-precision float value -print_extended ext ;print extended-precision float value -print_float ext ;print floating-point value -print_offset ext ;print displacement, counter offset -printf ext ;print formatted output -strchr ext ;search for character in string -strlen ext ;get length of C-string -test_key ext ;test for pause/cancel keypress -usage ext ;print usage string -usage_verbose ext ;print usage-verbose string =x.gsos.s -* UNIX coff utility -* GS/OS i/o external routines -* -* 1990-1992, tao Developer Project - -GSOSclose ext ;close a file -GSOSget_mark ext ;get position in file -GSOSopen ext ;open a file -GSOSread ext ;read data from file -GSOSset_mark ext ;set position in file -GSOSset_mark_plus ext ;set relative position in file =x.omf.s -* UNIX coff utility -* OMF parser externals -* -* 1990-1992, tao Developer Project - -read_header ext ;read header of OMF file -parse_DS ext ;parse DS record -parse_record ext ;parse OMF record -parse_segment_hex ext ;parse segment for +hex option -parse_segment ext ;parse OMF segment -parse_STRONG ext ;parse STRONG record =x.output.s -* UNIX coff utility -* output routine externals -* -* 1990-1992, tao Developer Project - -print_header ext ;print OMF header -parse_kind_1 ext ;parse kind string for OMF 1.0 -parse_kind_2 ext ;parse kind string for OMF 2.0 -print_stack_postfix ext ;output postfix expression -print_stack_infix ext ;output infix expression -newline ext ;generate newline in expression output -print_inorder ext ;output expression inorder =x.structure.s -* UNIX coff utility -* external data structure routines -* -* 1990-1992, tao Developer Project - -add_label ext ;add label to label array -delete_labels ext ;delete labels from label array -delete_expr_list ext ;delete expression list stack -find_operator ext ;match operator with its string representation -match_label ext ;match label name with expression string -push_expr_list ext ;push object on stack =x.tool.s -* UNIX coff utility -* tool, GSOS, ROM externals -* -* 1990-1992, tao Developer Project - -~tool ext ;toolbox names -~gsos ext ;GS/OS call names -~rom ext ;ROM address names =getopt.s - lst off - -* UNIX getopt library utility -* -* 1992, tao Developer Project - - rel - xc - xc - mx %00 - - put 4/memory.h ;memory manager defines - put 4/env.h ;run-time environment settings - - use 4/datatype.mac ;HLL data type macros - use 4/env.mac ;run-time environment macros - use 4/memory.mac ;memory manager macros - use 4/utility.mac ;utility macros - use 4/texttool.mac ;text toolset macros - - -option mac - cStr ]1 ;name of option - Short ]2 ;if option has arguments - ShortPtr ]3 ;flags - Short ]4 ;value of variable if no option assigned - eom - -shorta mac - mx %10 - sep %00100000 - eom -longa mac - mx %00 - rep %00100000 - eom -incr mac ;longword inc - if 1,]0 - inc ]1 - bne end - inc ]1+2 - else - clc - lda ]2 - adc ]1 - sta ]2 - bcc end - inc ]2+2 -end fin - eom - -_DebugStr mac - pea #^]1 - pea #]1 - ldx #$09ff - jsl $e10000 - eom - -OTHER_OPTION_EDGE equ 70 ;right edge to display alternate partial matches - -TAB_CHAR equ $09 ;tab character -EOF equ $ffff -UNRECOGNIZED_OPT equ '?' - -;option data structure offsets -`has_arg equ $00 ;if option has arguments -`flag equ `has_arg+2 ;pointer to variable to set -`val equ `flag+4 ;default value of option -`name equ `val+2 ;long name of option - -;argv data structure offsets -`lo equ $00 ;handle to array of command-line -`hi equ $04 ;options - - -************************************************** -* initialize command-line arguments. setup argc * -* value and argv pointers. * -* ---------------------------------------------- * -* (input) * -* a - userID of calling program. * -* x - LOW of pointer to command-line. * -* y - HOW of pointer to command-line. * -************************************************** -init_getopt ent -]argv_lo = $01 -]argv_hi = ]argv_lo+4 -]argc = ]argv_hi+4 -]db = ]argc+4 -]dp = ]db+2 -]rtl = ]dp+1 -]userID = ]rtl+3 -]command_line = ]userID+2 - - phd ;save direct page - phb ;save data bank register - - sec - tsc - sbc #]dp-3 ;make local dp space - tcs - tcd - - phk - plb - - incr #8;]command_line ;update command-line to first - ;character in command-line - lda #1 - sta ]argc - ldy #0 - lda #0 -:loop shorta - lda []command_line],y - longa - beq :make_argv - cmp #' ' ;spaces and TABS separate arguments - beq :0 - cmp #TAB_CHAR - beq :0 - iny - bra :loop -:0 iny ;test next character. if it is also - shorta ;a space or tab, then the next - lda []command_line],y ;argument hasn't begun. keep scanning. - longa - beq :zero_last ;if at end of command-line, zero - cmp #' ' ;previous space/tab - beq :1 - cmp #TAB_CHAR - bne :next_arg -:zero_last dey - shorta - lda #0 - sta []command_line],y - longa - bra :make_argv -:1 dey - shorta - lda #0 ;pad extra spaces with zeros - sta []command_line],y - iny - sta []command_line],y - longa - bra :0 -:next_arg dey - inc ]argc - shorta - lda #0 ;separate arguments with 0 - sta []command_line],y - longa - iny - bra :loop - -:make_argv pha ;long - space for result - pha - lda ]argc ;long - size of block - sta argc - asl - sta ]argc - pea #0 - pha - pei ]userID ;word - userID to associate with block - pea #attrNoSpec+attrLocked - pha - pha - _NewHandle - plx - ply - stx ]argv_lo - sty ]argv_lo+2 - ldy #2 - lda []argv_lo],y - tay - lda []argv_lo] - sta argv+`lo - sty argv+`lo+2 - sta ]argv_lo - sty ]argv_lo+2 - - pha ;long - space for result - pha - pea #0 ;long - size of block - pei ]argc - pei ]userID ;word - userID to associate with block - pea #attrNoSpec+attrLocked - pha - pha - _NewHandle - plx - ply - stx ]argv_hi - sty ]argv_hi+2 - ldy #2 - lda []argv_hi],y - tay - lda []argv_hi] - sta argv+`hi - sty argv+`hi+2 - sta ]argv_hi - sty ]argv_hi+2 - - ldx #0 ;argument counter -:2 ldy #$ffff ;create pointers to command-line arguments - lda #0 -:3 iny - shorta - lda []command_line],y - longa - bne :3 - txa - inc ;always take last argument - inc - cmp ]argc - beq :5 -:4 iny - shorta - lda []command_line],y - longa - beq :4 -:5 phy - txy - lda ]command_line - sta []argv_lo],y - lda ]command_line+2 - sta []argv_hi],y - clc - pla - adc ]command_line - sta ]command_line - bcc :6 - inc ]command_line+2 -:6 inx - inx - cpx ]argc - bne :2 - - lda #1 ;initialize index into command-line arguments - sta optind - sta argind - stz first_nonopt - stz last_nonopt - stz optarg - stz optarg+2 - - lda ]rtl,s ;move return address to top of stack - sta ]command_line+1,s - lda ]rtl+1,s - sta ]command_line+2,s - - clc - tsc - adc #]dp-3 - tcs - - plb - pld - - clc - tsc - adc #]command_line-]rtl+1 - tcs - rtl - - -************************************************** -* retrieve short options from command-line. * -* ---------------------------------------------- * -* (input) * -* shortopts - C-string of options to search * -* for. * -* (output) * -* a - option found. * -************************************************** -getopt ent - - rts - - -************************************************** -* parse argument list by scanning for short * -* options. * -************************************************** -parse_argument_1 equ * - - rts - - -************************************************** -* retrieve long-options and short-options from * -* command-line. * -* ---------------------------------------------- * -* (input) * -* shortopts - C-string of options to search * -* for. * -* longopts - pointer to long-option structure. * -* longind - index into long options. * -* (output) * -* a - option found. * -************************************************** -getopt_long ent -]buffer = $01 -]argv_lo = ]buffer+4 -]argv_hi = ]argv_lo+4 -]argv = ]argv_hi+4 -]option_struct = ]argv+4 -]long_option_name = ]option_struct+4 -]db = ]long_option_name+4 -]dp = ]db+2 -]rtl = ]dp+1 -]longind = ]rtl+3 -]longopts = ]longind+4 -]shortopts = ]longopts+4 -]retValue = ]shortopts+4 - - phd ;save direct page - phb ;save data bank register - - sec - tsc - sbc #]dp-3 ;make local dp space - tcs - tcd - - phk - plb - - lda #EOF - sta ]retValue - - lda argc ;end if no arguments to parse - cmp #1 - beq :0 - - jsr parse_argument_2 - -:0 lda ]rtl,s ;move return address to first - sta ]retValue-3,s ;parameter - lda ]rtl+1,s - sta ]retValue-2,s - - clc - tsc - adc #]dp-3 - tcs - - plb - pld - - clc - tsc - adc #]retValue-]longind - tcs - rtl - - -************************************************** -* parse argument list by scanning for short * -* and long options. * -************************************************** -parse_argument_2 equ * - - ldx argv+`lo - ldy argv+`lo+2 - stx ]argv_lo - sty ]argv_lo+2 - ldx argv+`hi - ldy argv+`hi+2 - stx ]argv_hi - sty ]argv_hi+2 - lda #0 - shorta - lda []shortopts] - sta shortopt_len - longa - -:loop lda optind - cmp argc - blt :1 - lda first_nonopt - beq :0 - sta optind -:0 rts ;end, no more arguments to parse - -:1 asl - tay - lda []argv_lo],y - sta ]argv - lda []argv_hi],y - sta ]argv+2 - - lda #0 - shorta - lda []argv] - longa - cmp #'-' ;parse short options - bne :2 - jsr parse_short - bra :4 -:2 cmp #'+' ;parse long options - bne :3 - jsr parse_long - bra :4 -:3 lda first_nonopt - bne :set_last - lda optind - sta first_nonopt -:set_last lda optind - sta last_nonopt - sec -:4 longa - bcc :end ;if a matching argument was found, - inc optind ;return it, else search next argument - lda #1 - sta argind - bra :loop -:end rts - - -************************************************** -* parse short options. * -* ---------------------------------------------- * -* (output) * -* c - set if match found. clear if not. * -************************************************** -parse_short equ * - - jsr exchange_argv ;move option before non-options - shorta - ldy argind - lda []argv],y - beq :end_argind - ldy shortopt_len -:test_shortopt cmp []shortopts],y - beq :arg_found - dey - bne :test_shortopt -:end_opt longa - and #$ff - pha ;invalid option character. - jsr get_progname ;option not found. display error - phy ;message and return '?' to user - phx ;indicating unrecognized option. - _WriteCString - pea #^unrecognized_opt - pea #unrecognized_opt - _WriteCString - pea #'-' - _WriteChar - _WriteChar - pea #''' - _WriteChar - put_cr - lda #UNRECOGNIZED_OPT ;return '?' to user - sta ]retValue - clc - rts -:arg_found longa ;argument found so return value - sta ]retValue ;and prepare to parse next option - inc argind ;character - clc - rts -:end_argind longa ;at end of current option string. - sec ;set to parse next option string - rts - - -************************************************** -* parse long options. * -************************************************** -parse_long equ * - - stz :option_offset - stz :option_found - stz :print_partial - stz :offset - stz :option_name_len - jsr exchange_argv ;move option before non-options - -:loop lda :option_offset - asl - tay - lda []longopts],y - sta ]option_struct - clc - adc #`name - sta ]long_option_name - shorta - lda (]long_option_name) - sta :option_name_len - longa - bne :test_longopt ;end of long-options - brl :end - -:test_longopt ldy #1 - shorta -:0 lda []argv],y - beq :1 - cmp (]long_option_name),y - beq :next_char - brl :6 -:next_char iny - cpy :option_name_len - blt :0 - beq :0 -:1 ldy :option_found ;if first option found, test other - bne :2 ;options for partial matches. - ldy :option_offset ;mark first option as found - iny - sty :option_found - brl :6 -:2 longa - lda :print_partial - beq :print_option - brl :3 -:print_option jsr get_progname - phy - phx - phy - phx - _WriteCString - pea #^partial_match - pea #partial_match - _WriteCString - lda optind - asl - tay - lda []argv_hi],y - pha - lda []argv_lo],y - pha - _WriteCString - pea #''' - _WriteChar - put_cr - _WriteCString - pea #^other_options - pea #other_options - _WriteCString - lda :option_found - dec - asl - tay - lda []longopts],y - clc - adc #`name - pei ]longopts+2 - pha - clc - lda #0 - tay - shorta - lda (1,s),y - longa - adc #20 - sta :offset - _WriteString - inc :print_partial -:3 inc :print_partial - clc - lda :offset - adc #3 - adc :option_name_len - sta :offset - cmp #OTHER_OPTION_EDGE - blt :4 - pea #',' - _WriteChar - put_cr - jsr get_progname - phy - phx - _WriteCString - pea #':' - _WriteChar - pea #' ' - _WriteChar - lda :option_name_len - inc - sta :offset - bra :5 -:4 pea #',' - _WriteChar - pea #' ' - _WriteChar -:5 pea #'+' - _WriteChar - pei ]longopts+2 - pei ]long_option_name - _WriteString -:6 longa - inc :option_offset - brl :loop - -:end lda :option_found ;error if no options found - beq :error - ldx :print_partial - bne :multiple_opt - dec - asl - tay - lda []longopts],y - sta ]option_struct - ldy #`val ;return short-option of default - lda (]option_struct),y ;long-option or short-option - sta ]retValue - inc optind ;prepare to search next argument next - lda #1 ;time through getopt - sta argind - clc - rts - -:error jsr get_progname ;option not found. display error - phy ;message and return '?' to user - phx ;indicating unrecognized option. - _WriteCString - pea #^unrecognized_opt - pea #unrecognized_opt - _WriteCString - lda optind - asl - tay - lda []argv_hi],y - pha - lda []argv_lo],y - pha - _WriteCString - pea #''' - _WriteChar -:multiple_opt put_cr - lda #UNRECOGNIZED_OPT ;return '?' to user - sta ]retValue - clc - rts - -:option_offset UnsignedShort ;offset into long option structure -:option_name_len UnsignedShort ;length of long option name -:option_found UnsignedShort ;if first option (partial?) found -:print_partial UnsignedShort -:offset UnsignedShort ;right edge offset - - -************************************************** -* retrieve long-options from command-line. * -* ---------------------------------------------- * -* (input) * -* shortopts - C-string of options to search * -* for. * -* longopts - pointer to long-option structure. * -* longind - index into long options. * -* (output) * -* opt - option found. * -************************************************** -getopt_long_only ent -]dp = $0c+3 -]rtl = ]dp+1 -]longind = ]rtl+3 -]longopts = ]longind+4 -]shortopts = ]longopts+4 -]retValue = ]shortopts+4 - - phd ;save direct page - phb ;save data bank register - - sec - tsc - sbc #]dp-3 ;make local dp space - tcs - tcd - - phk - plb - stz ]retValue - - lda ]rtl,s ;move return address to first - sta ]retValue-3,s ;parameter - lda ]rtl+1,s - sta ]retValue-1,s - - clc - tsc - adc #]dp-3 - tcs - - plb - pld - - clc - tsc - adc #]retValue-]longind - tcs - rts - - -************************************************** -* move non-option arguments before option * -* arguments. * -************************************************** -exchange_argv equ * - - lda first_nonopt ;end if no exchange to take place - beq :end - - lda optind ;save pointer to current option - asl ;argument - tay - lda []argv_lo],y - pha - lda []argv_hi],y - pha - -:0 lda last_nonopt ;move non-options up one - asl - tay - lda []argv_lo],y - iny - iny - sta []argv_lo],y - dey - dey - lda []argv_hi],y - iny - iny - sta []argv_hi],y - dec last_nonopt - lda last_nonopt - cmp first_nonopt - bge :0 - - lda first_nonopt ;store current option in first - asl ;non-option position. all previous - tay ;non-options are now after it. - pla - sta []argv_hi],y - pla - sta []argv_lo],y - - lda first_nonopt - sta optind - stz first_nonopt - stz last_nonopt -:end rts - - -************************************************** -* return pointer to program name string minus * -* path. * -* ---------------------------------------------- * -* (output) * -* x - LOW of pointer to program name. * -* y - HOW of pointer to program name. * -************************************************** -get_progname equ * -]progname = $01 - - lda []argv_lo] ;first argument on command-line is - sta ]progname ;program name - lda []argv_hi] - sta ]progname+2 - - shorta -:start_loop ldy #0 -:loop lda []progname],y - beq :end - cmp #'/' - beq :separator - cmp #':' - beq :separator - iny - bra :loop -:separator clc - tya - inc - adc ]progname - sta ]progname - bcc :start_loop - inc ]progname+2 - bra :start_loop - -:end longa - ldx ]progname - ldy ]progname+2 - rts - - -************************************************** - -* For communication from 'getopt' to the caller. -* When 'getopt' finds an option that takes an argument, -* the argument value is returned here. -* Also, when 'ordering' is RETURN_IN_ORDER, -* each non-option ARGV-element is returned here. - -optarg ent - CharPtr - -* Index in ARGV of the next element to be scanned. -* This is used for communication to and from the caller -* and for communication between successive calls to 'getopt'. -* -* On entry to 'getopt', zero means this is the first call; initialize. -* -* When 'getopt' returns EOF, this is the index of the first of the -* non-option elements that the caller should itself scan. -* -* Otherwise, 'optind' communicates from one call to the next -* how much of ARGV has been scanned so far. - -optind ent ;index into list of arguments - UnsignedShort -argind UnsignedShort ;index into argument - -* Callers store zero here to inhibit the error message 'getopt' prints -* for unrecognized options. - -opterr ent - UnsignedShort - -* If nonzero, '-' can introduce long-named options. -* Set by getopt_long_only. - -_getopt_long_only ent - UnsignedShort - -* The index in GETOPT_LONG_OPTIONS of the long-named option found. -* Only valid when a long-named option has been found by the most -* recent call to 'getopt'. - -option_index ent - UnsignedShort - -argc ent ;number of command-line options - UnsignedShort -argv ent ;array of pointers to command-line options -:lo Pointer -:hi Pointer - -first_nonopt UnsignedShort ;index to first non-option argument -last_nonopt UnsignedShort ;index to last non-option argument -shortopt_len dw 0 ;number of short options - -Getopt str 'getopt' - -unrecognized_opt asc !: unrecognized option '!,00 -partial_match asc !: partial match found for option '!,00 -other_options cStr ': other options are: +' - - -************************************************** - sav 5/getopt.l + END OF ARCHIVE