💾 Archived View for mirrors.apple2.org.za › archive › apple.cabi.net › Languages.Programming › OMF ›… captured on 2023-03-20 at 23:24:42.
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
Subject: v001SRC071: coff (OMF Disassembler) 06/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:71 Archive-name: utility/gs/disassem/coff/part06 Architecture: ONLY_2gs Version-number: 1.1 =omf.s - lst off - -* UNIX coff utility -* OMF parser -* -* 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 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/env.h ;run-time environment settings - - use coff.mac ;macro definitions - use 4/datatype.mac ;HLL data types - use 4/env.mac ;run-time environment macros - - -* dp $40-$80 taken - -************************************************** -* read header of OMF file into @omf structure. * -* ---------------------------------------------- * -* (input) * -* x - LOW of length of file. * -* y - HOW of length of file. * -************************************************** -read_header ent -]segname_handle = $80 ;handle to segment name -]segname_ptr = $84 -]file_len = $88 ;length of OMF file - - stx ]file_len - sty ]file_len+2 - jsr GSOSget_mark - clc - tya - adc #HEADER_LEN - tay - txa - adc #0 - cmp ]file_len+2 - blt :read_header - cpy ]file_len - blt :read_header - lda #MORE_DATA - ldx #0 - txy - jmp error - -:read_header read_long @omf+`bytecnt - read_long @omf+`resspc - read_long @omf+`length - lda @omf+`length+2 ;OMF length of segment must be - beq :read_kind ;<= $10000 - cmp #2 - bge :length_error - lda @omf+`length - beq :read_kind -:length_error lda #INVALID_LENGTH - ldx @omf+`length - ldy @omf+`length+2 - jmp error -:read_kind read_char @omf+`kind - read_char @omf+`lablen - read_char @omf+`numlen - read_char @omf+`version - lda @omf+`version - cmp #3 - blt :read_bank - lda #OMF_VERSION - ldx @omf+`version - ldy #0 - jmp error -:read_bank stz @omf+`revision ;default value of revision - read_long @omf+`banksize - - lda @omf+`version - cmp #1 - beq :0 - read_short @omf+`kind - read_short :tmp - bra :1 -:0 read_long :tmp -:1 read_long @omf+`org - read_long @omf+`align - read_char @omf+`numsex - read_char @omf+`lcbank - read_short @omf+`segnum - read_long @omf+`entry - read_short @omf+`dispname - read_short @omf+`dispdata - - lda @omf+`version - cmp #1 - beq :2 - read_long @omf+`temporg -:2 clc - lda @omf+`offset - adc @omf+`dispname - tay - lda @omf+`offset+2 - adc #0 - tax - jsr GSOSset_mark - lda #LOADNAME_LEN - ldx #@omf+`loadname - ldy #^@omf+`loadname - jsr GSOSread - lda @omf+`lablen - beq :3 - sta :lablen - bra :4 -:3 read_char :lablen -:4 lda @omf+`segname ;if handle already created, just - ora @omf+`segname+2 ;resize it - beq :5 - ldx @omf+`segname - ldy @omf+`segname+2 - stx ]segname_handle - sty ]segname_handle+2 - lda :lablen ;long - new size of handle - inc - inc - pea #0 - pha - pei ]segname_handle+2 ;long - handle to resize - pei ]segname_handle - _SetHandleSize - bra :6 -:5 pha ;long - result - pha - lda :lablen ;long - size of block - inc - inc - pea #0 - pha - lda userID ;word - user ID associated with block - pha - pea #attrNoCross ;word - attributes of block - pha ;long - where block is to begin - pha - _NewHandle - plx - ply - stx @omf+`segname - sty @omf+`segname+2 - stx ]segname_handle - sty ]segname_handle+2 -:6 lda []segname_handle] - sta ]segname_ptr - ldy #2 - lda []segname_handle],y - sta ]segname_ptr+2 - - clc - lda ]segname_ptr - adc #2 - tax - lda ]segname_ptr+2 - adc #0 - tay - lda :lablen - jsr GSOSread - lda :lablen ;length of segment name - sta []segname_ptr] - rts - -:tmp ds 4 ;temp location -:lablen ds 2 ;length of name or record in segment - - -************************************************** -* parse segment for +hex option. * -************************************************** -parse_segment_hex ent -]end_offset = $20 ;offset to end hex disassembly -]num_read = $24 ;number of bytes read - - ldx @omf+`offset ;make duplicate of offset - ldy @omf+`offset+2 - stx ]end_offset - sty ]end_offset+2 - - lda @omf+`version - cmp #1 - bne :0 - lda @omf+`library - bne :0 - lda @omf+`bytecnt - asl ;each block is 512 bytes - asl - asl - asl - asl - asl - asl - asl - asl - clc - adc ]end_offset - sta ]end_offset - tya - adc #0 - sta ]end_offset+2 - bra :loop -:0 clc - txa - adc @omf+`bytecnt - sta ]end_offset - tya - adc @omf+`bytecnt+2 - sta ]end_offset+2 - -:loop lda @omf+`displacement+2 - cmp ]end_offset+2 - blt :1 - lda @omf+`displacement - cmp ]end_offset - blt :1 - beq :1 - brl :end -:1 lda #15 - ldx #:hex - ldy #^:hex - jsr GSOSread - stx ]num_read - bcc :2 - brl :end -:2 bne :3 - brl :end -:3 lda #6 - ldx @omf+`displacement - ldy @omf+`displacement+2 - jsr print_fix_long_hex - pea #^vert_separator+1 - pea #vert_separator+1 - _WriteCString - incr ]num_read;@omf+`displacement - - ldx #0 ;output bytes just read -:print_byte phx - lda :hex,x ;word - char to convert - and #$ff - tax - jsr print_fix_char_hex - pea #' ' - _WriteChar - plx - inx - cpx ]num_read - blt :print_byte - - pea #^blank_str ;long - pointer to string - pea #blank_str - pea #0 ;word - offset into text - sec ;word - number of characters to print - lda #15 ;3 * (15 - ]num_read) - sbc ]num_read - tax - asl - pha - clc - txa - adc 1,s - sta 1,s - _TextWriteBlock - pea #^:dash_separator - pea #:dash_separator - _WriteCString - - ldx #0 -:print_char phx - lda :hex,x - and #$ff - jsr isprint - bcs :print_period - pha - _WriteChar - bra :end_loop -:print_period pea #'.' - _WriteChar -:end_loop plx - inx - cpx ]num_read - blt :print_char - put_cr - brl :loop - -:end put_cr - rts - -:hex ds 16 ;read 15 bytes at a time -:dash_separator cStr '- ' ;separate bytes/ascii - - -************************************************** -* parse current OMF segment. * -************************************************** -parse_segment ent -]record = $20 ;record to parse -]offset = $22 - - ldx #TRUE_OFFSET - stx ]offset - stz ]record - lda }assembly ;display header for assembly parsing - beq :0 - jsr display_header_asm -:0 ldx @omf+`displacement+2 - ldy @omf+`displacement - jsr GSOSset_mark - -:loop read_char ]record - lda ]record - cmp #END - beq :4 - cmp #cRELOC - beq :1 - cmp #RELOC - beq :1 - cmp #SUPER - bne :2 -:1 lda }assembly - bne :3 - -:2 lda }nooffset - bne :3 - ldx ]offset - cpx #TRUE_OFFSET - bne :3 - jsr print_offset - -:3 incr @omf+`displacement - lda ]record - ldx #0 - ldy #TRUE - jsr parse_record - stx ]offset - cpx #FALSE_OFFSET - beq :loop - ldx #TRUE_OFFSET - stx ]offset - bra :loop - -:4 lda }assembly - beq :6 - lda @omf+`resspc ;append DS to end of assembly listing - ora @omf+`resspc+2 ;if resspc not zero - beq :5 - jsr print_offset - pea #^space_12 - pea #space_12 - _WriteCString - pea #^DS_asm - pea #DS_asm - _WriteCString - ldx @omf+`resspc - ldy @omf+`resspc+2 - jsr print_long_dec - put_cr -:5 lda ~assembler - cmp #MERLIN - beq :end - jsr print_offset - pea #^space_12 - pea #space_12 - _WriteCString - pea #^:end_str - pea #:end_str - _WriteCString - bra :cr -:6 jsr print_offset - pea #^:END_str - pea #:END_str - _WriteCString - -:cr put_cr -:end put_cr - lda #LOCAL ;remove local labels - jsr delete_labels - rts - -:END_str cStr 'END (00)' ;END record name -:end_str cStr 'end' - - -************************************************** -* parse current OMF record. * -* ---------------------------------------------- * -* (input) * -* a - record to parse. * -* x - offset into current line. * -* y - prepend spaces to output? * -* (output) * -* x - offset into current line. * -************************************************** -parse_record ent -]record = $40 ;record to parse -]space = $42 ;prepend spaces to output? -]offset = $44 -]truncate_size = $46 ;truncate expression to x bytes - - sta ]record - stx ]offset - sty ]space - stz ]truncate_size - - cmp #END - bne :align - brl :end - -:align cmp #ALIGN - bne :org - ldx ]record - jsr parse_ALIGN - brl :end - -:org cmp #ORG - bne :entry - ldx ]record - jsr parse_ORG - brl :end - -:entry cmp #ENTRY - bne :general - ldx ]record - jsr parse_ENTRY - brl :end - -:general cmp #GENERAL - bne :using - ldx ]record - jsr parse_GENERAL - brl :end - -:using cmp #USING - bne :strong - jsr parse_USING - brl :end - -:strong cmp #STRONG - bne :global - lda }assembly - beq :parse - lda ]space - beq :parse - pea #^space_12 - pea #space_12 - _WriteCString -:parse jsr parse_STRONG - brl :end - -:global cmp #GLOBAL - bne :local - jsr parse_GLOBAL_LOCAL - brl :end - -:local cmp #LOCAL - bne :gequ - jsr parse_GLOBAL_LOCAL - brl :end - -:gequ cmp #GEQU - bne :equ - ldx ]offset - jsr parse_GEQU_EQU - stx ]offset - brl :end - -:equ cmp #EQU - bne :mem - ldx ]offset - jsr parse_GEQU_EQU - stx ]offset - brl :end - -:mem cmp #MEM - bne :expr - ldx ]offset - jsr parse_MEM - stx ]offset - brl :end - -:expr cmp #EXPR - beq :parse_expr -:bexpr cmp #BEXPR - beq :parse_expr -:lexpr cmp #LEXPR - beq :parse_expr -:relexpr cmp #RELEXPR - bne :ds -:parse_expr ldy ]space - ldx ]offset - jsr parse_expression - stx ]offset - brl :end - -:ds cmp #DS - bne :lconst - lda }assembly - beq :ds_0 - pea #^space_12 - pea #space_12 - _WriteCString -:ds_0 lda ]record - jsr parse_DS - bra :end -:lconst cmp #LCONST - bne :creloc - ldx }assembly - beq :lconst_0 - jsr parse_CONST_asm - bra :end -:lconst_0 jsr parse_CONST - bra :end -:creloc cmp #cRELOC - bne :reloc - jsr parse_cRELOC - stx ]offset - bra :end -:reloc cmp #RELOC - bne :interseg - jsr parse_RELOC - stx ]offset - bra :end -:interseg cmp #INTERSEG - bne :cinterseg - jsr parse_INTERSEG - stx ]offset - bra :end -:cinterseg cmp #cINTERSEG - bne :super - jsr parse_cINTERSEG - stx ]offset - bra :end -:super cmp #SUPER - bne :default - jsr parse_SUPER - stx ]offset - bra :end -:default lda }assembly - beq :10 - lda ]record - jsr parse_CONST_asm - bra :end -:10 lda ]record - jsr parse_CONST - -:end ldx ]offset - rts - - -************************************************** -* parse CONST record. * -* ---------------------------------------------- * -* (input) * -* a - record number. * -************************************************** -parse_CONST equ * -]count = $50 ;number of bytes to read -]edge = $54 ;right margin for output -]record = $56 ;record number -]num_read = $58 ;number of bytes read - - sta ]record - sta ]count - stz ]count+2 - cmp #LCONST - bne :const - - pea #^:LCONST_str - pea #:LCONST_str - _WriteCString - read_long ]count - clc - lda @omf+`displacement - adc #4 - sta @omf+`displacement - bcc :0 - inc @omf+`displacement+2 - bra :0 -:const pea #^:CONST_str - pea #:CONST_str - _WriteCString - lda ]record - sta ]count - stz ]count+2 - -:0 ldx ]record - jsr print_fix_char_hex - pea #^vert_separator - pea #vert_separator - _WriteCString - - pea #^:length_str - pea #:length_str - _WriteCString - ldx ]count - ldy ]count+2 - jsr print_long_dec - pea #^:hex_length_str - pea #:hex_length_str - _WriteCString - ldx ]count - ldy ]count+2 - jsr print_long_hex - pea #')' - _WriteChar - pea #^:byte_str - pea #:byte_str - _WriteCString - lda ]count - ora ]count+2 - cmp #1 - beq :1 - pea #'s' - _WriteChar -:1 put_cr - lda }compress - beq :parse_CONST - clc - lda @omf+`counter - adc ]count - sta @omf+`counter - lda @omf+`counter+2 - adc ]count+2 - sta @omf+`counter+2 - clc - lda @omf+`displacement - adc ]count - sta @omf+`displacement - lda @omf+`displacement+2 - adc ]count+2 - sta @omf+`displacement+2 - ldx ]count - ldy ]count+2 - jsr GSOSset_mark_plus - rts - -:parse_CONST jsr print_offset - pea #^space_vert_bar - pea #space_vert_bar - _WriteCString - - lda #0 - ldx }nooffset - beq :2 - lda #5 -:2 clc - adc #CONST_EDGE - sta ]edge - -:loop lda ]count+2 ;if number of bytes to read is less - bne :3 ;than the default, output only - lda ]count ;default many bytes - cmp ]edge - blt :4 -:3 lda ]edge ;read in default number of characters -:4 ldx #:hex - ldy #^:hex - jsr GSOSread - stx ]num_read - - ldx #0 ;output bytes just read -:print_byte phx - lda :hex,x - and #$ff - tax - jsr print_fix_char_hex - pea #' ' - _WriteChar - plx - inx - cpx ]num_read - blt :print_byte - - pea #^blank_str ;long - pointer to string - pea #blank_str - pea #0 ;word - offset into text - sec ;word - number of characters to print - lda ]edge ;3 * (]edge - ]num_read) - sbc ]num_read - tax - asl - pha - clc - txa - adc 1,s - sta 1,s - _TextWriteBlock - pea #^:dash_separator - pea #:dash_separator - _WriteCString - - ldx #0 -:print_char phx - lda :hex,x - and #$ff - jsr isprint - bcs :print_period - pha - _WriteChar - bra :end_loop -:print_period pea #'.' - _WriteChar -:end_loop plx - inx - cpx ]num_read - blt :print_char - put_cr - - decr ]num_read;]count - incr ]num_read;@omf+`counter ;update counter - incr ]num_read;@omf+`displacement ;update offse into OMF file - - lda ]count - ora ]count+2 - beq :end - lda }nooffset - bne :5 - jsr print_offset -:5 pea #^space_vert_bar - pea #space_vert_bar - _WriteCString - brl :loop -:end rts - -:hex ds CONST_EDGE+6 ;space for input string -:CONST_str cStr 'CONST (' ;CONST record name -:LCONST_str cStr 'LCONST (' ;LCONST record name -:dash_separator cStr '- ' ;separate bytes/ascii -:length_str cStr 'Length: ' ;length of LCONST record -:hex_length_str cStr ' (