💾 Archived View for mirrors.apple2.org.za › archive › apple.cabi.net › Languages.Programming › OMF ›… captured on 2023-03-20 at 23:24:39.
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
Subject: v001SRC068: coff (OMF Disassembler) 03/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:68 Archive-name: utility/gs/disassem/coff/part03 Architecture: ONLY_2gs Version-number: 1.1 =coff.s - lst off - -* UNIX coff utility -* startup code -* -* 1990-1992, tao Developer Project - - rel - xc - xc - mx %00 - - put coff.h ;global defines - put x.data ;data externals - put x.general ;general externals - put x.gsos ;GS/OS i/o externals - put x.output ;output externals - put x.structure ;data structure externals - put x.asm ;65816 OMF disassembler externals - put x.omf ;OMF parser externals - - put 4/gsos.h ;GS/OS defines - put 4/memory.h ;memory manager defines - put 4/resource.h ;resouce manager defines - put 4/texttool.h ;text tool defines - put 4/getopt.h ;getopt command-line option defines - put 4/env.h ;run-time environment settings - put 4/signal.h ;signal defines - - use coff.mac ;macro definitions - use 4/datatype.mac ;HLL data types - use 4/env.mac ;run-time environment macros - use 4/signal.mac ;signal macros - - -************************************************** -* start of program * -************************************************** - - phk ;program bank is data bank - plb - - jsr init_tool ;startup tools - jsr init_default ;init default values - do ENV&GNO_ENV - jsr init_signal ;setup signal handlers - fin - pea #0 ;flag indicating next address is return - jsr start ;address - jsr end_tool - - jsr GSOSclose ;close input file - - _GSOS Quit;@Quit - - -************************************************** -* startup tools * -************************************************** -init_tool equ * - - sta userID ;acc contains userID - stx command_line+2 ;save pointers to command-line - sty command_line - - lda userID - pha - _ResourceStartUp - rts - - -************************************************** -* initialize default values of variables. * -************************************************** -init_default equ * -]label_handle = $f0 ;handle to linked list of labels -]label_ptr = $f4 - - stz }version - stz }tool - stz }assembly - stz }shorta - stz }shorti - stz }label - stz }infix - stz }hex - stz }header - stz }noheader - stz }nooffset - stz }help - stz }compress - stz }exact - stz @omf+`library - stz segname_found - stz segname_found+2 - - lda #TRUE - sta }postfix ;output expressions in postfix form - sta }default_opt ;read in default options - - stz @omf+`offset ;zero offset into OMF file - stz @omf+`offset+2 - - stz @label+`label_name ;initialize @label linked list - stz @label+`label_name+2 - stz @label+`expr_name - stz @label+`expr_name+2 - stz @label+`type - stz @label+`next - stz @label+`next+2 - stz @label+`prev - stz @label+`prev+2 - stz @label+`last - stz @label+`last+2 - rts - - do ENV&GNO_ENV -************************************************** -* initialize signal handlers for GNO * -* environment. * -************************************************** -init_signal equ * - - signal SIGINT;stop_signal;:errno ;set up ctrl-c signal handler - rts - -:errno dw 0 ;signal call error number - -************************************************** -* ctrl-c signal handler. * -************************************************** -stop_signal equ * -]rtl = $01 -]signal_num = $04 -]code = $06 - - phk - plb - - jsr end_tool - jsr GSOSclose ;close input file - - _GSOS Quit;@Quit - rtl - fin - - -************************************************** -* end program * -************************************************** -end_tool equ * - - lda segname_found - tax - ora segname_found+2 - beq :0 - ldy segname_found+2 - phy - phx - _DisposeHandle - -:0 lda resourceID - pha - _CloseResourceFile - lda userID - pha ;word - user ID - _DisposeAll - _ResourceShutDown - rts - - -************************************************** -* parse command-line arguments. * -************************************************** -decode_switches equ * -]ret_value = $20 ;value returned by getopt -]longind = $22 ;index into long options -]long_option = $24 ;option currently examining -]argv_lo = $28 ;pointer to first argument in command-line -]argv_hi = $2c - -:get_options pha ;word - result - pea #^:cl_options ;longword - pointer to command-line - pea #:cl_options ; short options - pea #^~long_options ;longword - pointer to program long - pea #~long_options options - clc ;long - pointer to variable holding - tdc ; option index - adc #]longind - pea #0 - pha - jsl getopt_long - pla - cmp #EOF - beq :end - - sta ]ret_value - bne :test_opt - lda ]longind - asl - tax - lda ~long_options,x - sta ]long_option - ldy #`val - lda (]long_option),y - sta ]ret_value - -:test_opt lda ]ret_value - cmp #'D' - bne :default - stz }default_opt - bra :get_options -:default lda #]argv_lo - jsr dp_argv - lda []argv_lo] ;first argument on command-line is - tax ;program name - lda []argv_hi] - tay - lda ]ret_value - jsr set_option - bra :get_options - -:end rts - -:cl_options str 'vDdTxltpmoaisnfceh' ;command-line options - - -************************************************** -* return short-option of C-string based option * -* name (short/long). * -* ---------------------------------------------- * -* (input) * -* x - LOW of cstring. * -* y - HOW of cstring. * -* (output) * -* a - option value. * -************************************************** -get_option equ * -]option_str = $80 ;option string to search -]option_offset = $84 ;index into long-options -]option_struct = $86 ;pointer to individual long-option structures -]long_option_name = $88 ;long-option name -]option_name_len = $8a ;length of option name - - stx ]option_str - sty ]option_str+2 - stz ]option_offset - stz ]option_name_len - -:loop lda ]option_offset - asl - tax - lda ~long_options,x - sta ]option_struct - clc - adc #`name - sta ]long_option_name - shorta - lda (]long_option_name) - sta ]option_name_len - longa - beq :error ;error if at end of long-options - ldy #`val - lda (]option_struct),y - beq :2 - tax ;save short-option value - shorta ;if option string has short-option - ldy #1 ;as second character (i.e. '-x'), then - cmp []option_str],y ;test for '-' character; else test - bne :0 ;for long-option - lda []option_str] - cmp #'-' - bne :0 - longa - txa ;return short-option value - rts - -:0 ldy #1 - shorta -:1 lda (]long_option_name),y - cmp []option_str],y - bne :2 - iny - cpy ]option_name_len - blt :1 - beq :1 - longa - ldy #`val ;return short-option of default - lda (]option_struct),y ;long-option or short-option - rts -:2 longa - inc ]option_offset - bra :loop - -:error lda #ERROR - rts - - -************************************************** -* set command-line option. * -* ---------------------------------------------- * -* (input) * -* a - option to set. * -* x - LOW of program name ("coff"). * -* y - HOW of program name ("coff"). * -************************************************** -set_option equ * -]str_handle = $80 ;handle to string in resource fork -]str_ptr = $84 -]option = $88 ;option to set -]progname = $8a ;name of program - - sta ]option - stx ]progname - sty ]progname+2 - - ldx #TRUE ;set options -:version cmp #'v' ;test 'version' option - bne :asm - pha ;long - result - pha - pea #rText ;word - type of resource - pea #^VERSION ;long - ID Of resource - pea #VERSION - _LoadResource - plx - ply - stx ]str_handle - sty ]str_handle+2 - ldy #2 - lda []str_handle],y - pha - lda []str_handle] - pha - pei ]progname+2 - pei ]progname - _WriteCString - pea #' ' - _WriteChar - _WriteCString - rts -:asm cmp #'d' ;test 'asm' option - bne :tool - lda #MERLIN_16 - sta ~assembler - stx }assembly - stz }compress - rts -:tool cmp #'T' ;test 'tool' option - bne :hex - stx }tool - rts -:hex cmp #'x' ;test 'hex' option - bne :label - stx }hex - rts -:label cmp #'l' ;test 'label' option - bne :infix - stx }label - rts -:infix cmp #'t' ;test 'infix' option - bne :postfix - stx }infix - stz }postfix - rts -:postfix cmp #'p' ;test 'postfix' option - bne :merlin - stx }postfix - stz }infix - rts -:merlin cmp #'m' ;test 'merlin' option - bne :orca - lda #MERLIN_16 - sta ~assembler - stx }assembly - stz }compress - rts -:orca cmp #'o' ;test 'orca' option - bne :shorta - lda #ORCA_M - sta ~assembler - stx }assembly - stz }compress - rts -:shorta cmp #'a' ;test 'shorta' option - bne :shorti - stx }shorta - rts -:shorti cmp #'i' ;test 'shorti' option - bne :header - stx }shorti - rts -:header cmp #'s' ;test 'header' option - bne :noheader - stx }header - stz }noheader - rts -:noheader cmp #'n' ;test 'noheader' option - bne :nooffset - stx }noheader - stz }header - rts -:nooffset cmp #'f' ;test 'nooffset' option - bne :compress - stx }nooffset - rts -:compress cmp #'c' ;test 'compress' option - bne :exact - stx }compress - rts -:exact cmp #'e' ;test 'exact' option - bne :help - stx }exact - rts -:help cmp #'h' ;test 'help' option - bne :thanks - ldx ]progname - ldy ]progname+2 - jmp usage_verbose -:thanks cmp #1 ;test 'thanks' option - bne :default - pha ;long - result - pha - pea #rText ;word - type of resource - pea #^THANKS ;long - ID Of resource - pea #THANKS - _LoadResource - plx - ply - stx ]str_handle - sty ]str_handle+2 - ldy #2 - lda []str_handle],y - pha - lda []str_handle] - pha - _WriteCString - rts -:default ldx ]progname - ldy ]progname+2 - jmp usage - - -************************************************** -* read default options from resource fork. * -************************************************** -read_default equ * -]argv_lo = $20 ;pointer to first argument in command-line -]argv_hi = $24 -]default_handle = $28 ;handle to DEFAULT option text -]default_ptr = $2c -]option = $30 ;default short-option -]progname = $32 ;program name - - lda }default_opt ;end if not to read default options - bne :read_default - rts - -:read_default lda #]argv_lo - jsr dp_argv - lda []argv_lo] ;first argument on command-line is - tax ;program name - lda []argv_hi] - tay - stx ]progname - sty ]progname+2 - - pha ;long - result - pha - pea #rText ;word - type of resource - pea #^DEFAULT ;long - ID Of resource - pea #DEFAULT - _LoadResource - plx - ply - stx ]default_handle - sty ]default_handle+2 - phy - phx - phy - phx - _HLock - lda []default_handle] - sta ]default_ptr - ldy #2 - lda []default_handle],y - sta ]default_ptr+2 - - pha ;long - space for result - pha - pea #rText ;word - type of resource - pea #^DEFAULT ;long - ID of resource - pea #DEFAULT - _GetResourceSize - plx - pla - -:loop cpx #0 ;parse default options until no more - beq :end - phx -:0 ldx ]default_ptr - ldy ]default_ptr+2 - jsr get_option - sta ]option - cmp #ERROR - beq :1 - ldx ]progname - ldy ]progname+2 - jsr set_option -:1 plx - lda #0 - ldy #0 -:2 shorta - lda []default_ptr] - longa - dex - inc ]default_ptr - bne :3 - inc ]default_ptr+2 -:3 cmp #0 - bne :2 - bra :loop -:end _HUnlock - rts - - -************************************************** -* main entry point of coff. * -************************************************** -start equ * -]argv_lo = $00 ;pointer to first argument in -]argv_hi = $04 ;command-line -]seg_name = $08 ;display segment or loadsegments in file? -]filename = $0a ;offset into argv of OMF filename -]file_len = $0c ;length of OMF file -]omf_bytecnt = $10 ;temp @omf+`bytecnt -]segname_found = $14 ;pointer of handle 'name_found' -]invalid_name_msg = $18 ;if 'invalid name ...' message printed -]progname = $1a ;program name -]offset = $1e ;current offset into printing segment names not found - - plx - ply - phx - phy - - pha ;long - result - pha - lda userID ;word - userID to find - pha - pea #1 ;word - find current file - _LGetPathname2 - plx - ply - pha ;word - result - pea #readEnable ;word - file access - pea #NULL ;long - pointer to resource map - pea #NULL - phy - phx - _OpenResourceFile - pla - sta resourceID - - ldx command_line - ldy command_line+2 - lda userID - phy - phx - pha - jsl init_getopt ;init command-line arguments - jsr decode_switches ;interpret command-line arguments - lda optind - sta ]filename - cmp argc ;error if no filename given - bne :0 - lda #NO_FILENAME - ldx #0 - txy - jmp error - -:0 lda }default_opt - beq :1 - jsr read_default ;read in default options -:1 lda #]argv_lo - jsr dp_argv - lda optind ;open OMF file - asl - tay - lda []argv_lo],y - tax - lda []argv_hi],y - tay - jsr GSOSopen - bcc :2 - lda optind - asl - tay - lda []argv_lo],y - tax - lda []argv_hi],y - tay - lda #INVALID_FILENAME - jmp error - -:2 stx ]file_len - sty ]file_len+2 - inc optind ;point to next filename - stz ]seg_name ;default is no segment/loadsegment names - lda optind ;on command-line - cmp argc - beq :3 - sta ]seg_name - -:3 sec - lda argc - sbc optind - beq :4 - pha ;long - result - pha - lda argc - pea #0 ;long - block size - pha - lda userID ;word - user ID of block - pha - pea #attrNoSpec+attrFixed ;word - block attributes - pha ;long - start of block - pha - _NewHandle - plx - ply - stx segname_found - sty segname_found+2 - stx ]segname_found - sty ]segname_found+2 - ldy #2 - lda []segname_found],y - tax - lda []segname_found] - sta ]segname_found - stx ]segname_found+2 - shorta - ldy argc - lda #0 -:zero_segname dey - sta []segname_found],y - bne :zero_segname - longa - lda optind ;save optind value - sta []segname_found] - -:4 do ENV&{MERLIN_ENV.ORCA_ENV} - jsr test_key - fin - - ldx @omf+`offset+2 - ldy @omf+`offset - jsr GSOSset_mark ;move to segment in file to disassemble - bcc :read_header ;error means end of file - brl :end -:read_header ldx ]file_len - ldy ]file_len+2 - jsr read_header ;read header of OMF file - clc ;update displacement into OMF file - lda @omf+`offset - adc @omf+`dispdata - sta @omf+`displacement - lda @omf+`offset+2 - adc #0 - sta @omf+`displacement+2 - stz @omf+`counter ;initialize counter - stz @omf+`counter+2 - - lda ]seg_name - beq :5 - jsr parse_segname - lda optind ;if no more segments to parse, end - cmp argc - blt :6 - bra :end -:5 jsr parse_OMF - -:6 lda @omf+`version - cmp #1 - bne :inc_offset_2 ;update offset for OMF 2.0 - lda @omf+`library ;library files have byte offsets even - bne :inc_offset_2 ;though they might be OMF 1.0 -:inc_offset_1 lda @omf+`bytecnt - ldx @omf+`bytecnt+2 - stx ]omf_bytecnt+2 - asl ;each block is 512 bytes - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - asl - rol ]omf_bytecnt+2 - clc - adc @omf+`offset - tax - lda ]omf_bytecnt+2 - adc @omf+`offset+2 - bra :test_eof -:inc_offset_2 clc - lda @omf+`offset - adc @omf+`bytecnt - tax - lda @omf+`offset+2 - adc @omf+`bytecnt+2 -:test_eof sta @omf+`offset+2 - stx @omf+`offset - cmp ]file_len+2 - beq :8 - bge :end - brl :4 -:8 cpx ]file_len - bge :end - brl :4 - -:end lda segname_found - ora segname_found+2 - beq :11 - stz ]invalid_name_msg - lda []segname_found] - tay -:loop shorta -:9 lda []segname_found],y - beq :error - iny - cpy argc - bne :9 - longa -:10 lda ]invalid_name_msg - beq :11 - brl :15 -:11 pla - rts - -:error longa - phy - ldx ]invalid_name_msg - bne :12 - jsr get_progname - stx ]progname - sty ]progname+2 - sty ]invalid_name_msg - - phy ;long - pointer to C-string - phx - _WriteCString - pea #^:invalid_name - pea #:invalid_name - _WriteCString - lda #36 - sta ]offset - -:12 lda 1,s - asl - tay - lda []argv_lo],y ;get length of string - tax - lda []argv_hi],y - tay - phy - phx - jsr strlen - phy ;save length of string - clc - tya - adc ]offset - sta ]offset - cmp #INVALID_NAME_EDGE - blt :13 - put_cr - pei ]progname+2 - pei ]progname - _WriteCString - pea #':' - _WriteChar - pea #' ' - _WriteChar - lda 1,s - sta ]offset - -:13 pla - _WriteCString - ply - shorta -:14 iny - cpy argc - bge :15 - lda []segname_found],y - bne :14 - phy - longa - pea #',' - _WriteChar - pea #' ' - _WriteChar - inc ]offset - inc ]offset - ply - brl :loop - -:15 longa - put_cr - lda []argv_lo] ;first argument on command-line is - tax ;program name - lda []argv_hi] - tay - jmp usage - -:invalid_name cStr ': segment/loadsegment name not found: ' - - -************************************************** -* disassemble segment or loadsegment names on * -* command-line. * -************************************************** -parse_segname equ * -]name_found = $18 ;if segment or loadsegment name found -]argv_name = $1a -]segname = $1e -]segname_len = $22 ;length of segment name -]optind = $24 - - stz ]name_found ;default is false - - ldx @omf+`segname - ldy @omf+`segname+2 - stx ]segname - sty ]segname+2 - ldy #2 - lda []segname],y - tay - lda []segname] - sta ]segname - sty ]segname+2 - lda []segname] - sta ]segname_len - incr #2;]segname - - ldx optind -:loop txa - asl - tay - lda []argv_lo],y - sta ]argv_name - lda []argv_hi],y - sta ]argv_name+2 - - lda }exact ;compare command-line name against - beq :test_partial ;current segment name. must be -:test_exact shorta ;exact match. - ldy #0 -:segname_exact lda []argv_name],y - beq :0 - cmp []segname],y - bne :0 - iny - cpy ]segname_len - blt :segname_exact - lda []argv_name],y - beq :parse - -:0 ldy #0 ;compare command-line name against -:loadname_exact lda []argv_name],y ;current loadsegment name. must be - beq :next_argv ;exact match. - cmp @omf+`loadname,y - bne :next_argv - iny - cpy #LOADNAME_LEN - blt :loadname_exact - bra :parse - -:next_argv inx - cpx argc - blt :loop - longa - rts - -:test_partial shorta - ldy #0 -:segname_part lda []argv_name],y ;parse if at end of command-line - beq :parse ;name - cmp []segname],y - bne :1 - iny - cpy ]segname_len - blt :segname_part - lda []argv_name],y - beq :parse - -:1 ldy #0 -:loadname_part lda []argv_name],y - beq :parse - cmp @omf+`loadname,y - bne :next_argv - iny - cpy #LOADNAME_LEN - blt :loadname_part - bra :next_argv - -:parse txa - txy - sta []segname_found],y - longa - stx ]optind - lda }noheader ;display header? - bne :2 - jsr print_header -:2 lda }header ;display only headers? - bne :end - lda }assembly - bne :parse_segment - lda }hex - beq :parse_segment - jsr parse_segment_hex - bra :end -:parse_segment jsr parse_segment -:end lda optind - cmp ]optind - beq :3 - asl - tay - lda []argv_lo],y - tax - lda []argv_hi],y - pha - lda ]optind - asl - tay - pla - sta []argv_hi],y - txa - sta []argv_lo],y -:3 lda }exact - beq :rts - inc optind -:rts rts - - -************************************************** -* disassemble segment. * -************************************************** -parse_OMF equ * - - lda }noheader ;display header? - bne :0 - jsr print_header -:0 lda }header ;display only headers? - bne :end - lda }assembly - bne :parse_segment - lda }hex - beq :parse_segment - jsr parse_segment_hex - bra :end -:parse_segment jsr parse_segment -:end rts - - -************************************************** -startstop_rec adrl 0 ;reference to StartStop record -command_line adrl 0 ;pointer to command-line -segname_found adrl 0 ;if segment/loadsegment name found -resourceID dw 0 ;file ID of resource file - - -************************************************** - sav coff.l =data.s - lst off - -* UNIX coff utility -* variables -* -* 1990-1992, tao Developer Project - - rel - xc - xc - mx %00 - - put coff.h ;coff defines - put 4/getopt.h ;getopt command-line library definitions - - use coff.mac ;macro file - use 4/datatype.mac ;data-type definitions - use 4/getopt.mac - -* variables -* -coff ent - str 'coff' -userID ent ;userID returned by MMStartUp - dw 0 -long_hex_str ent ;string hex representation of long value -short_hex_str ent ;string hex representation of short value -char_hex_str ent ;string hex representation of char value -long_dec_str ent ;string decimal representation of long value -short_dec_str ent ;string decimal representation of short value -char_dec_str ent ;string decimal representation of char value - ds 11 -blank_str ent ;blank string - ds 80,' ' -vert_separator ent ;separate displacement/bytes - cStr ') | ' -space_vert_bar ent ;spaced vertical bar - cStr ' | ' -space_12 ent ;space between left edge and operand - cStr ' ' - -;assembly record names -DS_asm ent ;DS directive - cStr 'ds ' -GEQU_asm ent ;GEQU directive - cStr 'gequ ' -EQU_asm ent ;EQU directive - cStr 'equ ' -hex_asm ent ;merlin hex directive - cStr 'hex ' -db_asm ent ;merlin db directive - cStr 'db ' -dw_asm ent ;merlin dw directive - cStr 'dw ' -adr_asm ent ;merlin adr directive - cStr 'adr ' -adrl_asm ent ;merlin adrl directive - cStr 'adrl ' -dc_a_asm ent ;orca address directive - cStr 'dc a' -dc_h_asm ent ;orca hex directive - asc !dc h'!,00 -dc_i_asm ent ;orca integer directive - cStr 'dc i' -dc_d_asm ent ;orca double directive - asc !dc d'!,00 -dc_e_asm ent ;orca extended directive - asc !dc e'!,00 -dc_f_asm ent ;orca float directive - asc !dc f'!,00 - - -* boolean bariables -* -}version ent ;display version number - Boolean -}tool ent ;interpret ToolBox, GS/OS, ProDOS, ROM calls - Boolean -}assembly ent ;dump in asm format - Boolean -}label ent ;print expressions with labels, not offsets - Boolean -}infix ent ;display expressions in infix (default for +asm) - Boolean -}postfix ent ;display expressions in postfix (default) - Boolean -}hex ent ;nonzero means dump in hex format - Boolean -}header ent ;nonzero means dump - Boolean -}noheader ent ;nonzero does not display segment headers - Boolean -}nooffset ent ;nonzero means don't print offset into file - Boolean -}help ent ;nonzero means print switch descriptions - Boolean -}shorta ent ;8-bit accumulator - Boolean -}shorti ent ;8-bit index registers - Boolean -}compress ent ;compress OMF listing - Boolean -}exact ent ;match segment, loadsegment names exactly - Boolean -}default_opt ent ;disable default options - Boolean - -* constant variables -* -~assembler ent ;output code for which assembler - dw 0 ;00000001 - Merlin 16 -;00000010 - Orca/M -~error_msg ent ;error messages - dw :no_filename,:invalid_filename - dw :premature_end,:omf_version - dw :invalid_length,:more_data -:no_filename cStr 'object filename not specified' -:invalid_filename cStr 'error opening OMF file: ' -:premature_end cStr 'premature end of file' -:omf_version cStr 'OMF v1.0 and v2.0 supported. received: v' -:invalid_length cStr 'segment length must be less than 64k. received: