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 /* Is this record in the same bank as previous? */
147 if ( ((lastHexAddr>>16) != (addr>>16)) && (rflag) ) {
148 overrun = hexPageOverrun + 1;
149 ihxExtendedLinearAddress(lastExtendedAddress + overrun);
150 hexPageOverrun = overrun;
151 hexRecord(addr, rtvalIndex);
156 fprintf(ofp, ":%02X%04X00", chksum, addr);
157 chksum += (addr >> 8) + (addr & 0xff);
158 for (i = rtvalIndex, bytes = 0; i < rtcnt; i++) {
160 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");
178 fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
183 * int i 0 - process data
186 * The function ihx() calls the hexRecord() function for processing data
187 * or writes the End of Data record to the file defined by ofp.
190 * Addr_T n auxiliary variable
193 * int hilo byte order
194 * FILE * ofp output file handle
195 * Addr_T rtval[] relocated data
198 * VOID hexRecord() lkihx.c
199 * int fprintf() c_library
202 * The sequence of rtval[0], rtval[1] is eventually changed.
215 hexRecord((rtval[0]<<8) + rtval[1], 2);
217 if (rflag) /* linear start address, hardcoded as reset vector (0x0000) */
218 fprintf(ofp, ":0400000500000000F7\n");
219 fprintf(ofp, ":00000001FF\n");
223 /*)Function ihxNewArea(i)
224 * The function ihxNewArea() is called when processing of new area is started.
225 * It resets the value of lastHexAddr.
234 /*)Function ihxExtendedLinearAddress(i)
236 * Addr_T i 16 bit extended linear address.
238 * The function ihxExtendedLinearAddress() writes an extended
239 * linear address record (type 04) to the output file.
242 * Addr_T chksum byte checksum
245 * FILE * ofp output file handle
248 * int fprintf() c_library
251 * The data is output to the file defined by ofp.
252 * hexPageOverrun and lastHexAddr is cleared
255 ihxExtendedLinearAddress(Addr_T a)
259 /* The checksum is the complement of the bytes in the
260 * record: the 2 is record length, 4 is the extended linear
261 * address record type, plus the two address bytes.
263 chksum = 2 + 4 + (a & 0xff) + ((a >> 8) & 0xff);
265 fprintf(ofp, ":02000004%04X%02X\n", a & 0xffff, (0-chksum) & 0xff);