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/>. */
25 * The module lkihx.c contains the function to
26 * output the relocated object code in the
29 * lkihx.c contains the following functions:
30 * VOID hexRecord(addr, rtvalIndex)
32 * VOID ihxExtendedLinearAddress(a)
34 * local variables: hexPageOverrun, lastHexAddr
38 * Record Mark Field - This field signifies the start of a
39 * record, and consists of an ascii colon
42 * Record Length Field - This field consists of two ascii
43 * characters which indicate the number of
44 * data bytes in this record. The
45 * characters are the result of converting
46 * the number of bytes in binary to two
47 * ascii characters, high digit first. An
48 * End of File record contains two ascii
49 * zeros in this field.
51 * Load Address Field - This field consists of the four ascii
52 * characters which result from converting
53 * the the binary value of the address in
54 * which to begin loading this record. The
55 * order is as follows:
57 * High digit of high byte of address.
58 * Low digit of high byte of address.
59 * High digit of low byte of address.
60 * Low digit of low byte of address.
62 * In an End of File record this field con-
63 * sists of either four ascii zeros or the
64 * program entry address. Currently the
65 * entry address option is not supported.
67 * Record Type Field - This field identifies the record type,
68 * which is either 0 for data records or 1
69 * for an End of File record. It consists
70 * of two ascii characters, with the high
71 * digit of the record type first, followed
72 * by the low digit of the record type.
74 * Data Field - This field consists of the actual data,
75 * converted to two ascii characters, high
76 * digit first. There are no data bytes in
77 * the End of File record.
79 * Checksum Field - The checksum field is the 8 bit binary
80 * sum of the record length field, the load
81 * address field, the record type field,
82 * and the data field. This sum is then
83 * negated (2's complement) and converted
84 * to two ascii characters, high digit
88 /* Static variable which holds the count of hex page overruns
89 * (crossings of the 64kB boundary). Cleared at explicit extended
92 static int hexPageOverrun = 0;
94 /* Global which holds the last (16 bit) address of hex record.
95 * Cleared at begin of new area or when the extended address is output.
97 unsigned int lastHexAddr = 0;
100 /*)Function hexRecord(addr, rtvalIndex)
102 * unsigned addr starting address of hex record
103 * int rtvalIndex starting index into the rtval[] array
105 * The function hexRecord() outputs the relocated data
106 * in the standard Intel Hex format (with inserting
107 * the extended address record if necessary).
110 * Addr_T chksum byte checksum
111 * int i index for loops
112 * int overrun temporary storage for hexPageOverrun
113 * int bytes counter for bytes written
116 * FILE * ofp output file handle
117 * int rtcnt count of data words
118 * int rtflg[] output the data flag
119 * Addr_T rtval[] relocated data
122 * int fprintf() c_library
123 * ihxExtendedLinearAddress() lkihx.c
124 * hexRecord() lkihx.c (recursion)
127 * hexPageOverrun is eventually incremented,
128 * lastHexAddr is updated
132 hexRecord(unsigned addr, int rtvalIndex)
135 int i, overrun, bytes;
137 for (i = rtvalIndex, chksum = 0; i < rtcnt; i++) {
139 if (addr + ++chksum > 0xffff)
144 return; // nothing to output
146 if (lastHexAddr > addr) {
147 overrun = hexPageOverrun + 1;
148 ihxExtendedLinearAddress(lastExtendedAddress + overrun);
149 hexPageOverrun = overrun;
150 hexRecord(addr, rtvalIndex);
155 fprintf(ofp, ":%02X%04X00", chksum, addr);
156 chksum += (addr >> 8) + (addr & 0xff);
157 for (i = rtvalIndex, bytes = 0; i < rtcnt; i++) {
159 fprintf(ofp, "%02X", rtval[i]);
162 if (addr + ++bytes > 0xffff) {
164 fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
165 overrun = hexPageOverrun + 1;
166 ihxExtendedLinearAddress(lastExtendedAddress + overrun);
167 hexPageOverrun = overrun;
172 "warning: extended linear address encountered; "
173 "you probably want the -r flag.\n");
179 fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
184 * int i 0 - process data
187 * The function ihx() calls the hexRecord() function for processing data
188 * or writes the End of Data record to the file defined by ofp.
191 * Addr_T n auxiliary variable
194 * int hilo byte order
195 * FILE * ofp output file handle
196 * Addr_T rtval[] relocated data
199 * VOID hexRecord() lkihx.c
200 * int fprintf() c_library
203 * The sequence of rtval[0], rtval[1] is eventually changed.
211 if (ap->a_flag & A_NOLOAD)
218 hexRecord((rtval[0]<<8) + rtval[1], 2);
220 fprintf(ofp, ":00000001FF\n");
224 /*)Function ihxNewArea(i)
225 * The function ihxNewArea() is called when processing of new area is started.
226 * It resets the value of lastHexAddr.
235 /*)Function ihxExtendedLinearAddress(i)
237 * Addr_T i 16 bit extended linear address.
239 * The function ihxExtendedLinearAddress() writes an extended
240 * linear address record (type 04) to the output file.
243 * Addr_T chksum byte checksum
246 * FILE * ofp output file handle
249 * int fprintf() c_library
252 * The data is output to the file defined by ofp.
253 * hexPageOverrun and lastHexAddr is cleared
256 ihxExtendedLinearAddress(Addr_T a)
260 /* The checksum is the complement of the bytes in the
261 * record: the 2 is record length, 4 is the extended linear
262 * address record type, plus the two address bytes.
264 chksum = 2 + 4 + (a & 0xff) + ((a >> 8) & 0xff);
266 fprintf(ofp, ":02000004%04X%02X\n", a & 0xffff, (0-chksum) & 0xff);