OMF Analyzer
(C) 2013-2014 by Antoine VIGNAU and Olivier ZARDINI
> What is OMF
Analyzer ?
OMFAnalyzer
is a command-line tool for Windows
to analyze OMF
Files
we
can found on 16 bits Apple
IIgs
operating systems like Prodos
16 or
GS/OS.
Because OMF files
are the core of any executable code on the Apple IIgs system
(S16,
Exe, CDA, NDA, FST, PIF, Library, Tool...),
OMF Analyzer
will be helpful for anyone wanting to write an Assembler, a Compiler, a
Linker or a Disasembler...
OMF Analyzer is
part of the Brutal
Deluxe's Cross
Development Tools Project, a full set of utilities available on Windows
(and other) platforms to enable the creation of new Apple IIgs software
: 65c816 Assembler, 65c816 Disassembler, 65c816 Simulator, Graphic File
Converter, Resource Catcher...
> Relocating
Code anywhere in memory / Dynamic loading
If
the object code is supposed to be executed from a pre-defined address
in the Apple IIgs memory space, you can assemble your source code using
the ORG
directive (Merlin 16+
syntax) to define the starting address, including the Bank number. In the
following example, the source code is assembled to run from $03/8000 :
+--------+-----------------------+----------------------------------------------------------
|
|
|
ORG $038000
| |
|
|
| 03/8000 :
18
|
CLC ;
8
bit
|
| 03/8001 :
FB
|
XCE
|
| 03/8002 : E2
30
|
SEP
#$30
|
|
|
|
1 | 03/8004
: A9 2E
|
LDA #VAR1 ; 1 byte address :
LL
| 1 >>
8 | 03/8006 : A9 80
|
LDA #>VAR1 ; 1 byte address :
HH
|
1 | 03/8008
: A9 2E
|
LDA #<VAR1 ; 1 byte address :
LL
| 1
>>16 | 03/800A : A9 03
|
LDA #^VAR1 ; 1 byte address :
BB
|
|
|
|
| 03/800C :
18
|
CLC ;
16
bit
|
| 03/800D :
FB
|
XCE
|
| 03/800E : C2
30
|
REP
#$30
|
|
|
|
2 | 03/8010
: A9 2E
80
|
LDA #VAR1 ; 2 bytes address :
HHLL
| 2 >>
8 | 03/8013 : A9 80 03
|
LDA #>VAR1 ; 2 bytes address :
BBHH
|
2 | 03/8016
: A9 2E
80
|
LDA #<VAR1 ; 2 bytes address :
HHLL
| 1
>>16 | 03/8019 : A9 03 00
|
LDA #^VAR1 ; 2 bytes address : 00BB
|
|
|
|
2 | 03/801C
: AD 2E
80
|
LDA VAR1 ; 2 bytes
address :
HHLL
|
3 | 03/801F
: AF 2E
80 03
|
LDAL VAR1 ; 3 bytes address :
BBHHLL
| 2 >>
8 | 03/8023 : AF 80 03 00
|
LDA >VAR1 ; 3 bytes
address : 00BBHH
|
2 | 03/8027
: AD 2E
80
|
LDA <VAR1 ; 2 bytes
address :
HHLL
| 1
>>16 | 03/802A : F4 03 00
|
PEA
^VAR1 ; 2 bytes address :
00BB
|
|
|
|
| 03/802D :
60
|
RTS
|
|
|
|
| 03/802E
: 00 00 |
VAR1
HEX 0000
; Address is 00BB/HHLL=0003/802E
|
|
|
|
2 | 03/8030
: 2E
80
| TABLE2
DA
VAR1 ; 2 bytes address : HHLL
|
3 | 03/8032
: 2E
80 03
| TABLE3
ADR
VAR1 ; 3 bytes address : BBHHLL
|
3 | 03/8035
: 2E
80 03 00 |
TABLE4 ADRL
VAR1 ; 4 bytes address : 00BBHHLL
+--------+-----------------------+----------------------------------------------------------
A
16 bit variable named VAR1
is embedded in the source code. Its address is $03/802E
if the ORG value is $03/8000.
There are many ways to manipulate the variable address, depending on
the addressing modes and the Registers size. An address can go from 1
byte to 4 bytes. Because the 65c816 uses 24 bits address, the higher
byte of the 32 bit address will be always 0x00. We define a 32 bit
generic address as 00BBHHLL,
with 00 for
the highest byte, BB
for the Bank
byte, HH
for the High
Byte of the address (within the Bank) and LL for the Low Byte. The
previous example shows how the assembler encode the variable address
($03/802E) on various modes (Merlin
16+ syntax). Beware about the ^VAR1
address mode (00BB), it is valid only
with PEA
opcode (mostly used for Tool calls). See comment area for explanations.
If
we want the same code to be used anywhere in the Apple IIgs memory, we
have to use the REL
(RELocatable code) directive at the beginning of the source code. This
time, the ORG is virtually set to $00/0000
and the address of VAR1
is now $00/002E.
Because the Bank
Byte is 00, like the HH
Byte or the higher Byte of the 32 bit address, the result of the
assembly process is harder to read than previous one (check comment
area to properly identify each byte), but the logic is the same :
+--------+-----------------------+----------------------------------------------------------
|
|
|
REL
; Relocatable
Code
|
|
|
|
| 00/0000 :
18
|
CLC ;
8
bit
|
| 00/0001 :
FB
|
XCE
|
| 00/0002 : E2
30
|
SEP
#$30
|
|
|
|
1 | 00/0004
: A9 2E
|
LDA #VAR1 ; 1 byte address :
LL
| 1 >>
8 | 00/0006 : A9 00
|
LDA #>VAR1 ; 1 byte address :
HH
|
1 | 00/0008
: A9 2E
|
LDA #<VAR1 ; 1 byte address :
LL
| 1
>>16 | 00/000A : A9 00
|
LDA #^VAR1 ; 1 byte address :
BB
|
|
|
|
| 00/000C :
18
|
CLC ;
16
bit
|
| 00/000D :
FB
|
XCE
|
| 00/000E : C2
30
|
REP
#$30
|
|
|
|
2 | 00/0010
: A9 2E
00
|
LDA #VAR1 ; 2 bytes address :
HHLL
| 2 >>
8 | 00/0013 : A9 00 00
|
LDA #>VAR1 ; 2 bytes address :
BBHH
|
2 | 00/0016
: A9 2E
00
|
LDA #<VAR1 ; 2 bytes address :
HHLL
| 1
>>16 | 00/0019 : A9 00 00
|
LDA #^VAR1 ; 2 bytes address : 00BB
|
|
|
|
2 | 00/001C
: AD 2E
00
|
LDA VAR1 ; 2 bytes
address :
HHLL
|
3 | 00/001F
: AF 2E
00 00
|
LDAL VAR1 ; 3 bytes address :
BBHHLL
| 2 >>
8 | 00/0023 : AF 2E 00 00
|
LDA >VAR1 ; 3 bytes
address : 00BBHH
|
2 | 00/0027
: AD 2E
00
|
LDA <VAR1 ; 2 bytes
address :
HHLL
| 1
>>16 | 00/002A : F4 00 00
|
PEA ^VAR1 ; 2 bytes address :
00BB
|
|
|
|
| 00/002D :
60
|
RTS
|
|
|
|
| 00/002E
: 00 00 |
VAR1
HEX 0000
; Address is 00BB/HHLL=0003/802E
|
|
|
|
2 | 00/0030
: 2E
00
| TABLE2
DA
VAR1 ; 2 bytes address : HHLL
|
3 | 00/0032
: 2E
00 00 |
TABLE3
ADR VAR1 ; 3 bytes
address : BBHHLL
|
3 | 00/0035
: 2E
00 00 00 |
TABLE4 ADRL
VAR1 ; 4 bytes address : 00BBHHLL
+--------+-----------------------+----------------------------------------------------------
In
addition to the relocatable
object code, we have to provide a Relocation Dictionary
used to remap all the address located in the object code :
+-----------+-------------+----------+-------------+
| #
Bytes | Bit Shift |
Offset | Reference |
+-----------+-------------+----------+-------------+
|
01
|
| 0005
|
002E |
|
01
| >>
8 |
0007
|
002E |
|
01
|
| 0009
|
002E |
|
01
| >>
16 |
000B |
002E |
+-----------+-------------+----------+-------------+
|
02
|
| 0011
|
002E |
|
02
| >>
8 |
0014
|
002E |
|
02
|
| 0017
|
002E |
|
01
| >>
16 |
001A |
002E |
+-----------+-------------+----------+-------------+
|
02
|
| 001D
|
002E |
|
03
|
>>
8 |
0020 |
002E |
|
02
|
| 0024
|
002E |
|
02
|
| 0028
|
002E |
|
01
|
>>
16 |
002B |
002E |
+-----------+-------------+----------+-------------+
|
02
|
| 0030
|
002E |
|
03
|
| 0032
|
002E |
|
03
|
| 0035
|
002E |
+-----------+-------------+----------+-------------+
Each
Directory Entry
contains 4 information :
- Number of bytes to
relocate (from 1 to 3)
- Bit Shift
: logical operation to peform on the 32 bit address. We use here a C
Language syntax (>> 8 = shift the address 8 times on the
right)
- Offset, in the
object code, of the bytes to relocate. Because the code is divided into
64 KB segments, the offset is a 16 bit value.
- Reference : Address
value (lower 16 bits value of the 32 bit address).
In
our previous example, the only address we used if the VAR1
variable address, to all the Reference
are set to 002E,
the address of the VAR1
variable in the relocatable object code. We use this address 16 times in the
source code, so the number of entries in the dictionary is 16. The Offset column
contains the offset of each usage of the VAR1
address in the relocatable object code (0005, 0007 , 0009...), shown in
blue
in the object code. The number of bytes to relocate depends on the
address mode (1 byte / 2 bytes or 3 bytes). Because the highest Byte of
the 32 bit address is always 00, we never have to modify / relocate it,
so the
maximum number of bytes to relocate is 3. With a Register size equal to
8 or 16 bit, we have to manipulate the 32 bits address to define which
part if the address we want to get in the Register (Lower part, higher
part, middle one...). We use the Bit Shift information
to encode the operation performed on the 32 bits address :
| 1
>>16 | 00/002A : F4 00 00
|
PEA ^VAR1 ; 2 bytes address :
00BB
The
address mode used with PEA
is ^VAR1.
We want to get a 16 bit value of the 2 highest bytes of the 32 bit
address. We have 00 00 in the object code because the Bank number is 00
and another 00 because the highest byte of a 32 bit address is always
00. In the dictionary, we have to indicate than 1 byte has to be
relocated (and not 2 because the highest byte of a 32 bit address is
always 00). For the byte to relocate (the Bank byte), we have to shift
the 32 bit address (00BBHHLL) for 16 positions to the right (00BBHHLL
>> 16 = 000000BB). We get 1 one byte from this value (the
lowest
one). The first column of the source code 1 >>16
describes this (1
byte to relocate, >>16
bits shift to the right).
The
main job of the Prodos 16 or GS/OS loader is to find a free area in
memory to copy the relocatable object code and to patch all the address
defined in the Relocation Dictionary. The code is now ready to be
executed.
> Commands
List
If
you do not provide any parameter on the command line, OMFAnalyzer
displays a quick reminder of existing commands :
C:\AppleIIgs>OMFAnalyzer.exe
OMFAnalyzer.exe v 1.0 (c) Brutal Deluxe 2013-2014
Usage : OMFAnalyzer.exe DUMP
<omf_file_path>
<output_file_path>.
OMFAnalyzer.exe EXTRACT
<omf_file_path>
<segment_number> <output_file_path>.
OMFAnalyzer.exe COMPARE
<omf_file1_path>
<omf_file2_path> <diff_file_path>.
OMFAnalyzer.exe COMPAREBIN <binary_file1_path>
<binary_file2_path>
<diff_file_path>.
Few
remarks about the Parameters required on the Command Line and the
sotware behavior :
- If the Windows File or
folder paths contains Space
characters, quote
the path to avoid conflicts (OMFAnalyzer.exe DUMP
"c:\Users
and Settings\AppleIIgs\Finder"
c:\Temp\Finder_omf.txt).
- Any
error occuring during the
execution of a
command is immediately displayed on the Screen.
- If
your are transfering OMF Files from a disk image or FTP server, make
sure you transfer the file as a binary file.
DUMP
Dump the content of an OMF
File into a text file. Refer to the Apple
IIgs GS/OS Reference
book (Appendix
F : Object Module Format)
for
full details about data structure definitions and naming convention.
The output file contains several sections :
- File Information
- Segments Summary
- Segment #1
...
- Segment #n
Most of the numeric data (size, offset, numbers...) are
displayed using hexadecimal
representation and padded with the right number of 0 to fit into its
data type (Byte, Word, 3 bytes or Long). You may sometimes
find
the decimal
value between parenthesis.
File Information
***************************
**
File Information **
***************************
- File Name
: 'Finder'
-
Length
: 023DEC (146924)
- Segment Number : 0E (14)
The File
Information part contains the file Name (here we are
analyzing the System 6.01's Finder
file), the Length of the file and the Number of segments of the OMF file.
Segment Summary
An OMF File contains one or more Segments. Each segment consists of one Segment Header and one Segment Body. The Segment Body is a set of Records that contains Code (or Data) and Relocation information.
*************************** **
Segments Summary ** ***************************
+----------+----------+-----------------+----------------+----------------+-------------+------------+--------------
| Offset | SegNum
|
SegType
|
SegName |
LoadName | SegLength
| #
Record | RecordList
+----------+----------+-----------------+----------------+----------------+-------------+------------+--------------
| 000000 |
01 |
Data
| ~ExpressLoad |
Finder
|
00041C |
0002 |
LCONST + END
| 00041C |
02 |
Code
|
FINDER
|
| 01033E
|
0029 | LCONST + cINTERSEG (21)
+ RELOC (2) +
SUPER (16) + END
| 01075A |
03 |
Code
|
BUFFERS
|
| 00229B
|
0003 | LCONST + SUPER + END
| 0129F5 |
04 |
Code
|
VERIFY
|
| 001280
|
0011 | LCONST + cINTERSEG (2) +
RELOC (4) +
SUPER (9) + END
| 013C75 |
05 |
Code
|
INFO
|
| 0038F0
|
0032 | LCONST + cINTERSEG (38)
+ RELOC + SUPER
(9) + END
| 017565 |
06 |
Code
|
CONTROL
|
| 000D2C
|
0005 | LCONST + SUPER (3) + END
| 018291 |
07 |
Code
|
MATCH
|
| 002313
|
000D | LCONST + cINTERSEG (2) +
SUPER (9) + END
| 01A5A4 |
08 |
Code
|
ALERT
|
| 000D8B
|
0017 | LCONST + cINTERSEG (14)
+ SUPER (7) + END
| 01B32F |
09 |
Code
|
CODE
|
| 006EB2
|
0026 | LCONST + RELOC (8) +
cINTERSEG (17) +
SUPER (11) + END
| 0221E1 |
0A |
Code
|
DATA
|
| 000AE1
|
0003 | LCONST + SUPER + END
| 022CC2 |
0B | Jump
Table |
~JumpTable
|
| 0000DF
|
0002 | LCONST + END
| 022DA1 |
0C |
Code
|
ABOUT
|
| 0009A1
|
0020 | LCONST + RELOC (24) +
SUPER (6) + END
| 023742 |
0D |
Code
|
Help
|
| 000221
|
0008 | LCONST + RELOC (2) +
SUPER (4) + END
| 023963 |
0E |
Code
| FIFIFIONE
|
| 000489
|
0005 | LCONST + SUPER (3) + END
+----------+----------+-----------------+----------------+----------------+-------------+------------+--------------
|
The Segment
Summary part gives an overview of the OMF file content. We list here all the Segment information including the Number (SegNum, from 1 to N), the Location in the OMF File (Offset, in bytes from the begining of the file), the Length (SegLength in bytes), the Name (SegName) and the Type (SegType : Data, Code, Jump Table...). If available, we may also find the name of the load segment that will contain the code generated by the linker for this segment (LoadName).
The last two columns indicate the Number of Records found in the Body part of the Segment (# Record) and the List of Records (RecordList : LCONST, END, SUPER, RELOC, cINTERSEG...). We always find at least one LCONST and one END record in the Segment Body. The LCONST record contains the Code or the Data and the END record indicates the end of the Segment. The other records (SUPER, cINTERSEG, RELOC...)
provide code relocation information. Between parenthesis, we indicate
the number (in decimal) of each record type found in the Segment, if
they appear more than once in the Segment Body. So the line
LCONST + RELOC (2) +
SUPER (4) + END
must be understood as : One LCONST record, Two RELOC records, Four SUPER records and One END record. Notice that the order used to display the record list do not reflect necessarily the Segment Body organization (SUPER records may appear before RELOC records).
Segment #n
*************************** **
Segment 02
** ***************************
*** Header ***
- Segment Header size + Segment Body
size
: 01033E 66366
- Number of 0x00 to add at the end of the Segment Body
: 000000 0
- Size of the Segment once loaded in
Memory
: 00F9BF 63935
- Undefined Byte #1
(usually set to 0x00)
: 00
- Label Length
(usually set to 0x00 or 0x0A)
: 00
- Number Length
(usually set to 4 bytes)
: 04
- Segment OMF Version
(should be 0x02 for 2.1)
: 02
- Bank Size (64 KB
for Code, 0-64 KB for Data)
: 010000 65536
- Segment Type + Segment
Attributes
: 1100 = Code (Static +
Bank Relative)
- Undefined Byte #2
(usually set to 0x00)
: 00
- Undefined Byte #3
(usually set to 0x00)
: 00
- Org Address to load the Segment
(0x0000 = anywhere) : 000000
- Boundary for Segment Alignment
(0, 0x100 or 0x010000) : 000000 = No alignment needed
- Order of the bytes in a Number
(0x00 for the IIgs)
: 00
- Undefined Byte #4
(usually set to 0x00)
: 00
- Segment Number (1
to N)
: 0002 2
- Entry Point in the
Segment
: 000000 0
- Load
Name
: ''
- Segment
Name
: 'FINDER'
|
The Segment Header contains general information about the Segment such as Name, Length, Number, Type, OMF Version... It contains also technical information about the Code part (alignment, entry point, org address, order of bytes in a number...). In red,
we provide extra information regarding the value found there. When
needed, the decimal representation of the numbers are following the
hexadecimal one. For exhaustive explanation about the Segment Header
structure, please refer to the Apple IIgs GS/OS Reference book, Appendix F, page 446.
***
Data or Code ***
-
Length
: 00F9BF (63935)
000000 4B AB 09 00 01 8D B3 E0 22 12 00 0B 90 10 A9
00.00
A2 4E 09 A0 4E 09 22 40 0A 08 82 DD 01 22 20
000020 00 0B 20 31 00 20 A4 06 20 DA 07 20 66 04 4C
81.06
A2 70 00 BD 2F F0 9D 0C EF CA CA 10 F6 AD 2F
000040 F0 8D 0C EF A2 23 06 9E C1 E0 CA CA 10 F9 9C
C1.E0
A2 FE 00 74 00 CA CA 10 FA 7B 8D B5 E0 18 69
000060 50 00 8D B7 E0 9C 2C 09 9C 2E 09 9C 30 09 9C
32.09
A9 02 04 8F E8 EA 00 8F 49 0D 03 8F E6 E6 00
000080 A9 80 00 8F 4B 11 03 8F CD 11 03 A2 01 02 22
00.00
E1 48 A2 02 02 22 00 00 E1 68 85 AA 22 A8 00
0000A0 E1 2A 20 07 02 00 00 AD 09 02 0A 4A C9 02 04
B0.10
A9 00 00 A2 E4 07 A0 E4 07 22 40 0A 08 82 37
...
00F940 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00.00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00F960 00 00 00 00 00 00 00 47 F9 00 00 00 00 00 00
00.00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00F980 00 00 00 00 00 00 00 47 F9 00 00 00 00 00 00
A2.00
00 48 48 F4 00 00 48 D4 00 DA 48 48 A2 02 09
00F9A0 22 00 00 E1 8D 1D F1 68 FA 60 A9 1E 00 80 03
A9.14
00 FA F4 00 00 48 7B 18 63 01 83 01 DA 60
|
We dump here the LCONST record data of the Segment, in hexadecimal (32 bytes / row). This can be 65c816 Code (most of the time) or any kind of Data used by the GS/OS Loader (ExpressLoad, Direct-page / Stack...) or other Segments code. If you want to work with such data (disassemble...), use the EXTRACT command to get them outside of the OMF file as a ready-to-use binay file.
***
Relocation Dictionary ***
- # Address to be
patched : 0101 (257)
+--------+-----------+-------------+----------+-------------+
| #
| # Bytes | Bit Shift
| Offset
| Reference |
+--------+-----------+-------------+----------+-------------+
| 0000
|
03
|
| 0075
|
EAE8 |
| 0001
|
03
|
| 007D
|
E6E6 |
...
| 00FD
|
03
|
| F8D4
|
F98D |
| 00FE
|
03
|
| F8D9
|
F98B |
| 00FF
|
03
|
| F967
|
F947 |
| 0100
|
03
|
| F987
|
F947 |
+--------+-----------+-------------+----------+-------------+
- # Address to be
patched : 0469 (1129)
+--------+-----------+-------------+----------+-------------+------------+-----------+
| #
| # Bytes | Bit Shift
| Offset
| Reference | File Num
| Seg Num |
+--------+-----------+-------------+----------+-------------+------------+-----------+
| 0000
|
03
|
| 0009
|
0012
| 0001
| 000B |
| 0001
|
02
|
| 0012
|
094E
| 0001
| 000A |
| 0002
|
02
|
0F
| 0015
|
094E
| 0001
| 000B |
| 0003
|
03
|
| 0018
|
0A40
| 0001
| 0008 |
...
| 0466
|
02
|
0F
| F91B
|
F967
| 0001
| 0003 |
| 0467
|
03
|
| F92C
|
26B1
| 0001
| 0009 |
| 0468
|
04
|
| F983
|
007C
| 0001
| 0008 |
+--------+-----------+-------------+----------+-------------+------------+-----------+
|
Instead of showing here the relocation records raw data (RELOC, INTERSEG, cRELOC, cINTERSEG, SUPER...), we have splited the relocation dictionary entries into two logical tables :
- one for the inner-segment addresses to be patched (we patch an address in a segment with a reference to another address in the same segment)
- one for the inter-segments addresses to be patched (we patch an address in a segment with a reference to another address in a different segment)
Both tables have the same mandatory information set :
- # Bytes : number of bytes to be relocated
- Bit Shift : bit shift operation to perform on the relocated address
- Offset : offset (relative to the start of the Segment) of the first byte to be relocated
- Reference : reference address (relative to the start of the Segment)
For relocation references located in another segment (target segment), we need two extra information :
- File Num : 1 if the target segment is part of the same OMF File, Jump Table segment number of the target segment is locateed in a run-time library
- Seg Num : target segment number (1 - N)
Syntax
OMFAnalyzer.exe DUMP <omf_file_path>
<output_file_path>
Example
OMFAnalyzer.exe DUMP
c:\AppleIIgs\Finder c:\AppleIIgs\Finder_OMF.txt
EXTRACT
Extract the LCONST part of a Segment to disk. This is useful to retrieve from a OMF file the Code or Data part. We need to provide the OMF file path, the segment number (1 to N) where the LCONST is located and so the path of the binary file where the data will be stored. If you want to get the Relocation Dictionary parts, use the DUMP command and get the RELOC and INTERSEG tables from the output file.
Syntax
OMFAnalyzer.exe EXTRACT
<omf_file_path>
<segment_number>
<output_file_path>
Example
OMFAnalyzer.exe EXTRACT c:\AppleIIgs\Merlin\Cogito
1
c:\AppleIIgs\Cogito_code.bin
COMPARE
Compare two OMF files and
create a text file as result with all differencies. This is useful
to compare the OMF files built by two differents compiler / assembler
(from the same source code) or to compare an original OMF file with a
new one rebuilt from the source code. Because each compiler /
assembler may organize the relocation dictionary as it wants (pick up
among all dfiiferent relocation entry structures), a binary comparison
of the OMF file is useless. If we want to check that two OMF files are
equivalent (but not necessarily equal in term of bytes organization) ,
we have to compare the Headers of each segment together and we have to compare Data / Code parts together and so the Relocation Dictionary entries together (for both RELOC and INTERSEG).
If the logical information are the same, they will be declared as
equivalent. If some parts are differents, we record them into a diff file. If we find more than 50 errors in one Segment part (Header, Data, Dictionary...) we record only the first 50 ones and we end up there.
Syntax
OMFAnalyzer.exe COMPARE
<omf_file1_path>
<omf_file2_path>
<diff_file_path>
Example
OMFAnalyzer.exe COMPARE c:\AppleIIgs\Merlin\Cogito
c:\AppleIIgs\Orca\Cogito
c:\AppleIIgs\Cogito_diff.txt
COMPAREBIN
Simply compare two files, byte per byte, and search for any difference. Unlike the COMPARE command, there is no intelligence here. This can be useful to compare two binary files (graphic, music...) but also to compare absolute memory image file like Prodos 8 loadable file format. If we find more than 50 differences, we end up there (the diff file will contain information about the the first 50 differences found).
Syntax
OMFAnalyzer.exe COMPAREBIN
<binary_file1_path>
<binary_file2_path>
<diff_file_path>
Example
OMFAnalyzer.exe COMPAREBIN c:\AppleIIgs\Merlin\Cogito
c:\AppleIIgs\Orca\Cogito
c:\AppleIIgs\Cogito_diff.txt
> F.A.Q
Is
the Source code available
somewhere ?
The
Source code is freely available in the Zip file (see download section).
It is currently pakaged as a Visual
Studio 2010 Project set
of files. The tool is only using C Language, so you
can recompile it with any other C ANSI compiler (GCC...).
What
about a Macintosh or Linux release ?
Everything
has be done to be as independant as possible from the Operating System.
The first release has been done using a Windows environment. The
Macintosh and Linux ports should be done in the next weeks, as soon as
someone is ready to handle it !
The source code is written in C
Ansi and the only Operating Systems calls have been isolated in a
specific file. So porting the project to Macintosh or Unix systems
should take maximum 4 hours to any C programmers having the knowledge
of the target platform.
>
References
Apple
IIgs GS/OS Reference, Appendix F : Object Module Format
version 2.1
Merlin 16+
documentation by Glen
Bredon,
Roger Wagner Publishing
ORCA / M 2.0
documentation by Mike Westerfield
>
Download
OMF
Analyzer
v1.0
for Windows
32 & 64 bits + Source Code
OMF
Analyzer
v1.1
for Windows
32 & 64 bits + Source Code
OMF
Analyzer
v1.3
for Windows
32 & 64 bits + Source Code