X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=as%2Fmcs51%2Flkihx.c;h=8a5aa3effab2651908551ed6bf8b27cbeaa0d74c;hb=2ba563b3151e76ab0652dbf07d9185ecb5d9bef6;hp=d849c1651b61063111d747f4f241d73fc43ed316;hpb=b09af35f2f1cde7649d3ac4a6f5d2af6d97895a0;p=fw%2Fsdcc diff --git a/as/mcs51/lkihx.c b/as/mcs51/lkihx.c index d849c165..8a5aa3ef 100644 --- a/as/mcs51/lkihx.c +++ b/as/mcs51/lkihx.c @@ -11,7 +11,6 @@ #include #include -#include #include "aslink.h" /*)Module lkihx.c @@ -20,10 +19,12 @@ * output the relocated object code in the * Intel Hex format. * - * lkihx.c contains the following function: + * lkihx.c contains the following functions: + * VOID hexRecord(addr, rtvalIndex) * VOID ihx(i) + * VOID ihxEntendedLinearAddress(a) * - * lkihx.c contains no local variables. + * local variables: hexPageOverrun, lastHexAddr */ /*Intel Hex Format @@ -77,58 +78,181 @@ * first. */ +/* Static variable which holds the count of hex page overruns + * (crossings of the 64kB boundary). Cleared at explicit extended + * address output. + */ +static int hexPageOverrun = 0; + +/* Global which holds the last (16 bit) address of hex record. + * Cleared at begin of new area or when the extended address is output. + */ +unsigned int lastHexAddr = 0; + + +/*)Function hexRecord(addr, rtvalIndex) + * + * unsigned addr starting address of hex record + * int rtvalIndex starting index into the rtval[] array + * + * The function hexRecord() outputs the relocated data + * in the standard Intel Hex format (with inserting + * the extended address record if necessary). + * + * local variables: + * Addr_T chksum byte checksum + * int i index for loops + * int overrun temporary storage for hexPageOverrun + * int bytes counter for bytes written + * + * global variables: + * FILE * ofp output file handle + * int rtcnt count of data words + * int rtflg[] output the data flag + * Addr_T rtval[] relocated data + * + * functions called: + * int fprintf() c_library + * ihxEntendedLinearAddress() lkihx.c + * hexRecord() lkihx.c (recursion) + * + * side effects: + * hexPageOverrun is eventually incremented, + * lastHexAddr is updated + */ + +VOID +hexRecord(unsigned addr, int rtvalIndex) +{ + Addr_T chksum; + int i, overrun, bytes; + + for (i = rtvalIndex, chksum = 0; i < rtcnt; i++) { + if (rtflg[i]) { + if (addr + ++chksum > 0xffff) + break; + } + } + if (chksum == 0) + return; // nothing to output + + if ( (lastHexAddr > addr) && (rflag) ) { + overrun = hexPageOverrun + 1; + ihxEntendedLinearAddress(lastExtendedAddress + overrun); + hexPageOverrun = overrun; + hexRecord(addr, rtvalIndex); + return; + } + + lastHexAddr = addr; + fprintf(ofp, ":%02X%04X00", chksum, addr); + chksum += (addr >> 8) + (addr & 0xff); + for (i = rtvalIndex, bytes = 0; i < rtcnt; i++) { + if (rtflg[i]) { + fprintf(ofp, "%02X", rtval[i]); + chksum += rtval[i]; + if (addr + ++bytes > 0xffff) { + if (rflag) { + fprintf(ofp, "%02X\n", (0-chksum) & 0xff); + overrun = hexPageOverrun + 1; + ihxEntendedLinearAddress(lastExtendedAddress + overrun); + hexPageOverrun = overrun; + hexRecord(0, i + 1); + return; + } else { + fprintf(stderr, + "warning: extended linear address encountered; " + "you probably want the -r flag.\n"); + } + } + } + } + fprintf(ofp, "%02X\n", (0-chksum) & 0xff); +} + /*)Function ihx(i) * * int i 0 - process data * 1 - end of data * - * The function ihx() outputs the relocated data - * in the standard Intel Hex format. + * The function ihx() calls the hexRecord() function for processing data + * or writes the End of Data record to the file defined by ofp. * * local variables: - * addr_t chksum byte checksum + * Addr_T n auxiliary variable * * global variables: * int hilo byte order * FILE * ofp output file handle - * int rtcnt count of data words - * int rtflg[] output the data flag - * addr_t rtval[] relocated data + * Addr_T rtval[] relocated data * * functions called: - * int fprintf() c_library + * VOID hexRecord() lkihx.c + * int fprintf() c_library * * side effects: - * The data is output to the file defined by ofp. + * The sequence of rtval[0], rtval[1] is eventually changed. */ VOID ihx(i) { - register addr_t chksum; - + Addr_T n; if (i) { if (hilo == 0) { - chksum = rtval[0]; + n = rtval[0]; rtval[0] = rtval[1]; - rtval[1] = chksum; - } - for (i = 0, chksum = -2; i < rtcnt; i++) { - if (rtflg[i]) - chksum++; + rtval[1] = n; } - fprintf(ofp, ":%02X", chksum); - for (i = 0; i < rtcnt ; i++) { - if (rtflg[i]) { - fprintf(ofp, "%02X", rtval[i]); - chksum += rtval[i]; - } - if (i == 1) { - fprintf(ofp, "00"); - } - } - fprintf(ofp, "%02X\n", (-chksum) & 0xff); + hexRecord((rtval[0]<<8) + rtval[1], 2); } else { fprintf(ofp, ":00000001FF\n"); } } + +/*)Function newArea(i) + * The function newArea() is called when processing of new area is started. + * It resets the value of lastHexAddr. + */ + +VOID +newArea() +{ + lastHexAddr = 0; +} + +/*)Function ihxEntendedLinearAddress(i) + * + * Addr_T i 16 bit extended linear address. + * + * The function ihxEntendedLinearAddress() writes an extended + * linear address record (type 04) to the output file. + * + * local variables: + * Addr_T chksum byte checksum + * + * global variables: + * FILE * ofp output file handle + * + * functions called: + * int fprintf() c_library + * + * side effects: + * The data is output to the file defined by ofp. + * hexPageOverrun and lastHexAddr is cleared + */ +VOID +ihxEntendedLinearAddress(Addr_T a) +{ + Addr_T chksum; + + /* The checksum is the complement of the bytes in the + * record: the 2 is record length, 4 is the extended linear + * address record type, plus the two address bytes. + */ + chksum = 2 + 4 + (a & 0xff) + ((a >> 8) & 0xff); + + fprintf(ofp, ":02000004%04X%02X\n", a & 0xffff, (0-chksum) & 0xff); + hexPageOverrun = 0; + lastHexAddr = 0; +}