3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 * The module lkihx.c contains the function to
27 * output the relocated object code in the
30 * lkihx.c contains the following functions:
31 * VOID hexRecord(addr, rtvalIndex)
33 * VOID ihxExtendedLinearAddress(a)
35 * local variables: hexPageOverrun, lastHexAddr
39 * Record Mark Field - This field signifies the start of a
40 * record, and consists of an ascii colon
43 * Record Length Field - This field consists of two ascii
44 * characters which indicate the number of
45 * data bytes in this record. The
46 * characters are the result of converting
47 * the number of bytes in binary to two
48 * ascii characters, high digit first. An
49 * End of File record contains two ascii
50 * zeros in this field.
52 * Load Address Field - This field consists of the four ascii
53 * characters which result from converting
54 * the the binary value of the address in
55 * which to begin loading this record. The
56 * order is as follows:
58 * High digit of high byte of address.
59 * Low digit of high byte of address.
60 * High digit of low byte of address.
61 * Low digit of low byte of address.
63 * In an End of File record this field con-
64 * sists of four ascii zeros, in a start
65 * address record this is the program entry
66 * address (low), or in a segment record
67 * this is the high order address.
69 * Record Type Field - This field identifies the record type,
70 * which is either 0 for data records, 1
71 * for an End of File record, 3 for a
72 * start address, or 4 for a
73 * segment record. It consists
74 * of two ascii characters, with the high
75 * digit of the record type first, followed
76 * by the low digit of the record type.
78 * Data Field - This field consists of the actual data,
79 * converted to two ascii characters, high
80 * digit first. There are no data bytes in
81 * the End of File record.
83 * Checksum Field - The checksum field is the 8 bit binary
84 * sum of the record length field, the load
85 * address field, the record type field,
86 * and the data field. This sum is then
87 * negated (2's complement) and converted
88 * to two ascii characters, high digit
92 /* Static variable which holds the count of hex page overruns
93 * (crossings of the 64kB boundary). Cleared at explicit extended
96 static int hexPageOverrun
= 0;
98 /* Global which holds the last (16 bit) address of hex record.
99 * Cleared at begin of new area or when the extended address is output.
101 unsigned int lastHexAddr
= 0;
104 /*)Function hexRecord(addr, rtvalIndex)
106 * unsigned addr starting address of hex record
107 * int rtvalIndex starting index into the rtval[] array
109 * The function hexRecord() outputs the relocated data
110 * in the standard Intel Hex format (with inserting
111 * the extended address record if necessary).
114 * a_uint chksum byte checksum
115 * int i index for loops
116 * int overrun temporary storage for hexPageOverrun
117 * int bytes counter for bytes written
120 * FILE * ofp output file handle
121 * int rtcnt count of data words
122 * int rtflg[] output the data flag
123 * a_uint rtval[] relocated data
126 * int fprintf() c_library
127 * ihxExtendedLinearAddress() lkihx.c
128 * hexRecord() lkihx.c (recursion)
131 * hexPageOverrun is eventually incremented,
132 * lastHexAddr is updated
136 hexRecord(unsigned addr
, int rtvalIndex
)
139 int i
, overrun
, bytes
;
141 for (i
= rtvalIndex
, chksum
= 0; i
< rtcnt
; i
++) {
143 if (addr
+ ++chksum
> 0xffff)
148 return; // nothing to output
150 /* Is this record in the same bank as previous? */
151 if ((TARGET_IS_8051
&& ((lastHexAddr
>>16) != (addr
>>16)) && (rflag
)) ||
152 (TARGET_IS_6808
&& lastHexAddr
> addr
)) {
153 overrun
= hexPageOverrun
+ 1;
154 ihxExtendedLinearAddress(lastExtendedAddress
+ overrun
);
155 hexPageOverrun
= overrun
;
156 hexRecord(addr
, rtvalIndex
);
161 fprintf(ofp
, ":%02X%04X00", chksum
, addr
);
162 chksum
+= (addr
>> 8) + (addr
& 0xff);
163 for (i
= rtvalIndex
, bytes
= 0; i
< rtcnt
; i
++) {
165 fprintf(ofp
, "%02X", rtval
[i
]);
167 if (TARGET_IS_8051
) {
168 if (addr
+ ++bytes
> 0xffff) {
170 fprintf(ofp
, "%02X\n", (0-chksum
) & 0xff);
171 overrun
= hexPageOverrun
+ 1;
172 ihxExtendedLinearAddress(lastExtendedAddress
+ overrun
);
173 hexPageOverrun
= overrun
;
178 "warning: extended linear address encountered; "
179 "you probably want the -r flag.\n");
185 fprintf(ofp
, "%02X\n", (0-chksum
) & 0xff);
190 * int i 0 - process data
193 * The function ihx() calls the hexRecord() function for processing data
194 * or writes the End of Data record to the file defined by ofp.
197 * a_uint n auxiliary variable
200 * int hilo byte order
201 * FILE * ofp output file handle
202 * a_uint rtval[] relocated data
205 * VOID hexRecord() lkihx.c
206 * int fprintf() c_library
209 * The sequence of rtval[0], rtval[1] is eventually changed.
217 if (TARGET_IS_6808
&& ap
->a_flag
& A_NOLOAD
)
225 hexRecord((rtval
[0]<<8) + rtval
[1], 2);
227 if (TARGET_IS_8051
&& rflag
) /* linear start address, hardcoded as reset vector (0x0000) */
228 fprintf(ofp
, ":0400000500000000F7\n");
229 fprintf(ofp
, ":00000001FF\n");
233 /*)Function ihxNewArea(i)
234 * The function ihxNewArea() is called when processing of new area is started.
235 * It resets the value of lastHexAddr.
244 /*)Function ihxExtendedLinearAddress(i)
246 * a_uint i 16 bit extended linear address.
248 * The function ihxExtendedLinearAddress() writes an extended
249 * linear address record (type 04) to the output file.
252 * a_uint chksum byte checksum
255 * FILE * ofp output file handle
258 * int fprintf() c_library
261 * The data is output to the file defined by ofp.
262 * hexPageOverrun and lastHexAddr is cleared
265 ihxExtendedLinearAddress(a_uint a
)
269 /* The checksum is the complement of the bytes in the
270 * record: the 2 is record length, 4 is the extended linear
271 * address record type, plus the two address bytes.
273 chksum
= 2 + 4 + (a
& 0xff) + ((a
>> 8) & 0xff);
275 fprintf(ofp
, ":02000004%04X%02X\n", a
& 0xffff, (0-chksum
) & 0xff);