2 * rdf2ihx.c - convert an RDOFF object file to Intel Hex format.
3 * This is based on rdf2bin.
4 * Note that this program only writes 16-bit HEX.
18 /* This function writes a single n-byte data record to of. Maximum value
20 static int write_data_record(FILE *of
, int ofs
, int nbytes
,
24 unsigned int checksum
;
27 fprintf(of
, ":%02X%04X00", nbytes
, ofs
);
29 for (i
=0; i
<nbytes
; i
++) {
30 fprintf(of
, "%02X", data
[i
]);
34 checksum
= checksum
+ /* current checksum */
35 nbytes
+ /* RECLEN (one byte) */
36 ((iofs
>> 8) & 0xff) + /* high byte of load offset */
37 (iofs
& 0xff); /* low byte of load offset */
38 checksum
= ~checksum
+ 1;
39 fprintf(of
, "%02X\n", checksum
&0xff);
43 int main(int argc
, char **argv
)
49 unsigned char *segbin
[2];
50 int pad
[2], segn
, ofs
, i
;
52 unsigned int checksum
;
56 puts("Usage: rdf2ihx [-o relocation-origin] [-p segment-alignment] "
57 "input-file output-file");
64 if (strcmp(*argv
,"-o") == 0) {
66 origin
= readnum(*argv
, &tmp
);
68 fprintf(stderr
,"rdf2ihx: invalid parameter: %s\n",*argv
);
71 } else if (strcmp(*argv
,"-p") == 0) {
73 align
= readnum(*argv
, &tmp
);
75 fprintf(stderr
,"rdf2ihx: invalid parameter: %s\n",*argv
);
83 puts("rdf2ihx: required parameter missing");
89 rdfperror("rdf2ihx",*argv
);
92 printf("relocating %s: origin=%lx, align=%d\n",*argv
, origin
, align
);
95 m
->datarel
= origin
+ m
->f
.seg
[0].length
;
96 if (m
->datarel
% align
!= 0) {
97 pad
[0] = align
- (m
->datarel
% align
);
103 m
->bssrel
= m
->datarel
+ m
->f
.seg
[1].length
;
104 if (m
->bssrel
% align
!= 0) {
105 pad
[1] = align
- (m
->bssrel
% align
);
111 printf("code: %08lx\ndata: %08lx\nbss: %08lx\n",
112 m
->textrel
, m
->datarel
, m
->bssrel
);
118 of
= fopen(*argv
,"w");
120 fprintf(stderr
,"rdf2ihx: could not open output file %s\n",*argv
);
124 padding
= malloc(align
);
126 fprintf(stderr
,"rdf2ihx: out of memory\n");
130 /* write extended segment address record */
131 fprintf(of
, ":02000002"); /* Record mark, reclen, load offset & rectyp
132 fields for ext. seg. address record */
133 segaddr
= ((origin
>> 16) & 0xffff); /* segment address */
134 fprintf(of
, "%04X", (unsigned int)(segaddr
& 0xffff));
135 checksum
= 0x02 + /* reclen */
136 0x0000 + /* Load Offset */
138 (segaddr
& 0xff) + /* USBA low */
139 ((segaddr
>> 8) & 0xff); /* USBA high */
140 checksum
= ~checksum
+ 1; /* two's-complement the checksum */
141 fprintf(of
, "%02X\n", checksum
& 0xff);
143 /* See if there's a '_main' symbol in the symbol table */
144 if ((s
=symtabFind(m
->symtab
, "_main")) == NULL
) {
145 printf("No _main symbol found, no start segment address record added\n");
147 printf("_main symbol found at %04x:%04x\n", s
->segment
,
148 (unsigned int)(s
->offset
& 0xffff));
149 /* Create a start segment address record for the _main symbol. */
150 segaddr
= ((s
->segment
& 0xffff) << 16) + ((s
->offset
) & 0xffff);
151 fprintf(of
, ":04000003"); /* Record mark, reclen, load offset & rectyp
152 fields for start seg. addr. record */
153 fprintf(of
, "%08lX", segaddr
); /* CS/IP field */
154 checksum
= 0x04 + /* reclen */
155 0x0000 + /* load offset */
157 (segaddr
& 0xff) + /* low-low byte of segaddr */
158 ((segaddr
>> 8) & 0xff) + /* low-high byte of segaddr */
159 ((segaddr
>> 16) & 0xff) + /* high-low byte of segaddr */
160 ((segaddr
>> 24) & 0xff); /* high-high byte of segaddr */
161 checksum
= ~checksum
+ 1; /* two's complement */
162 fprintf(of
, "%02X\n", checksum
& 0xff);
165 /* Now it's time to write data records from the code and data segments in.
166 This current version doesn't check for segment overflow; proper behavior
167 should be to output a segment address record for the code and data
168 segments. Something to do. */
172 for (segn
=0; segn
<2; segn
++) {
175 if (m
->f
.seg
[segn
].length
== 0)
177 for (i
=0; i
+15<m
->f
.seg
[segn
].length
; i
+=16) {
178 ofs
= write_data_record(of
, ofs
, 16, &segbin
[segn
][i
]);
180 if ((mod
=m
->f
.seg
[segn
].length
& 0x000f) != 0) {
181 adr
= m
->f
.seg
[segn
].length
& 0xfff0;
182 ofs
= write_data_record(of
, ofs
, mod
, &segbin
[segn
][adr
]);
185 /* output an end of file record */
186 fprintf(of
, ":00000001FF\n");