4 * (C) Copyright 1989-1995
18 * The module lkihx.c contains the function to
19 * output the relocated object code in the
22 * lkihx.c contains the following functions:
23 * VOID hexRecord(addr, rtvalIndex)
25 * VOID ihxExtendedLinearAddress(a)
27 * local variables: hexPageOverrun, lastHexAddr
31 * Record Mark Field - This field signifies the start of a
32 * record, and consists of an ascii colon
35 * Record Length Field - This field consists of two ascii
36 * characters which indicate the number of
37 * data bytes in this record. The
38 * characters are the result of converting
39 * the number of bytes in binary to two
40 * ascii characters, high digit first. An
41 * End of File record contains two ascii
42 * zeros in this field.
44 * Load Address Field - This field consists of the four ascii
45 * characters which result from converting
46 * the the binary value of the address in
47 * which to begin loading this record. The
48 * order is as follows:
50 * High digit of high byte of address.
51 * Low digit of high byte of address.
52 * High digit of low byte of address.
53 * Low digit of low byte of address.
55 * In an End of File record this field con-
56 * sists of either four ascii zeros or the
57 * program entry address. Currently the
58 * entry address option is not supported.
60 * Record Type Field - This field identifies the record type,
61 * which is either 0 for data records or 1
62 * for an End of File record. It consists
63 * of two ascii characters, with the high
64 * digit of the record type first, followed
65 * by the low digit of the record type.
67 * Data Field - This field consists of the actual data,
68 * converted to two ascii characters, high
69 * digit first. There are no data bytes in
70 * the End of File record.
72 * Checksum Field - The checksum field is the 8 bit binary
73 * sum of the record length field, the load
74 * address field, the record type field,
75 * and the data field. This sum is then
76 * negated (2's complement) and converted
77 * to two ascii characters, high digit
81 /* Static variable which holds the count of hex page overruns
82 * (crossings of the 64kB boundary). Cleared at explicit extended
85 static int hexPageOverrun = 0;
87 /* Global which holds the last (16 bit) address of hex record.
88 * Cleared at begin of new area or when the extended address is output.
90 unsigned int lastHexAddr = 0;
93 /*)Function hexRecord(addr, rtvalIndex)
95 * unsigned addr starting address of hex record
96 * int rtvalIndex starting index into the rtval[] array
98 * The function hexRecord() outputs the relocated data
99 * in the standard Intel Hex format (with inserting
100 * the extended address record if necessary).
103 * Addr_T chksum byte checksum
104 * int i index for loops
105 * int overrun temporary storage for hexPageOverrun
106 * int bytes counter for bytes written
109 * FILE * ofp output file handle
110 * int rtcnt count of data words
111 * int rtflg[] output the data flag
112 * Addr_T rtval[] relocated data
115 * int fprintf() c_library
116 * ihxExtendedLinearAddress() lkihx.c
117 * hexRecord() lkihx.c (recursion)
120 * hexPageOverrun is eventually incremented,
121 * lastHexAddr is updated
125 hexRecord(unsigned addr, int rtvalIndex)
128 int i, overrun, bytes;
130 for (i = rtvalIndex, chksum = 0; i < rtcnt; i++) {
132 if (addr + ++chksum > 0xffff)
137 return; // nothing to output
139 if (lastHexAddr > addr) {
140 overrun = hexPageOverrun + 1;
141 ihxExtendedLinearAddress(lastExtendedAddress + overrun);
142 hexPageOverrun = overrun;
143 hexRecord(addr, rtvalIndex);
148 fprintf(ofp, ":%02X%04X00", chksum, addr);
149 chksum += (addr >> 8) + (addr & 0xff);
150 for (i = rtvalIndex, bytes = 0; i < rtcnt; i++) {
152 fprintf(ofp, "%02X", rtval[i]);
155 if (addr + ++bytes > 0xffff) {
157 fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
158 overrun = hexPageOverrun + 1;
159 ihxExtendedLinearAddress(lastExtendedAddress + overrun);
160 hexPageOverrun = overrun;
165 "warning: extended linear address encountered; "
166 "you probably want the -r flag.\n");
172 fprintf(ofp, "%02X\n", (0-chksum) & 0xff);
177 * int i 0 - process data
180 * The function ihx() calls the hexRecord() function for processing data
181 * or writes the End of Data record to the file defined by ofp.
184 * Addr_T n auxiliary variable
187 * int hilo byte order
188 * FILE * ofp output file handle
189 * Addr_T rtval[] relocated data
192 * VOID hexRecord() lkihx.c
193 * int fprintf() c_library
196 * The sequence of rtval[0], rtval[1] is eventually changed.
204 if (ap->a_flag & A_NOLOAD)
211 hexRecord((rtval[0]<<8) + rtval[1], 2);
213 fprintf(ofp, ":00000001FF\n");
217 /*)Function ihxNewArea(i)
218 * The function ihxNewArea() is called when processing of new area is started.
219 * It resets the value of lastHexAddr.
228 /*)Function ihxExtendedLinearAddress(i)
230 * Addr_T i 16 bit extended linear address.
232 * The function ihxExtendedLinearAddress() writes an extended
233 * linear address record (type 04) to the output file.
236 * Addr_T chksum byte checksum
239 * FILE * ofp output file handle
242 * int fprintf() c_library
245 * The data is output to the file defined by ofp.
246 * hexPageOverrun and lastHexAddr is cleared
249 ihxExtendedLinearAddress(Addr_T a)
253 /* The checksum is the complement of the bytes in the
254 * record: the 2 is record length, 4 is the extended linear
255 * address record type, plus the two address bytes.
257 chksum = 2 + 4 + (a & 0xff) + ((a >> 8) & 0xff);
259 fprintf(ofp, ":02000004%04X%02X\n", a & 0xffff, (0-chksum) & 0xff);