Mercurial > hg > index.cgi
changeset 548:cde1a5a48636
Add IHEX output format to lwlink
At the request of Craig Iannello who provided a small bribe, IHEX output
format is now available in lwlink. At least a first pass version of it.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 16 Mar 2023 16:59:50 -0600 |
parents | 33e37b3d98cf |
children | ee3e52ab2288 |
files | lwlink/lwlink.h lwlink/main.c lwlink/output.c |
diffstat | 3 files changed, 61 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/lwlink/lwlink.h Thu Mar 16 16:18:13 2023 -0600 +++ b/lwlink/lwlink.h Thu Mar 16 16:59:50 2023 -0600 @@ -32,6 +32,7 @@ #define OUTPUT_OS9 3 // OS9 object code module #define OUTPUT_SREC 4 // motorola SREC format #define OUTPUT_RAW2 5 // raw sequence of bytes, BSS converted to NULs +#define OUTPUT_IHEX 6 // IHEX output format typedef struct symtab_s symtab_t; struct symtab_s
--- a/lwlink/main.c Thu Mar 16 16:18:13 2023 -0600 +++ b/lwlink/main.c Thu Mar 16 16:59:50 2023 -0600 @@ -92,6 +92,8 @@ outformat = OUTPUT_OS9; else if (!strcasecmp(arg, "srec")) outformat = OUTPUT_SREC; + else if (!strcasecmp(arg, "ihex")) + outformat = OUTPUT_IHEX; else { fprintf(stderr, "Invalid output format: %s\n", arg); @@ -141,7 +143,7 @@ { "debug", 'd', 0, 0, "Set debug mode"}, { "format", 'f', "TYPE", 0, - "Select output format: decb, raw, lwex, os9, srec"}, + "Select output format: decb, raw, lwex, os9, srec, ihex"}, { "decb", 'b', 0, 0, "Generate DECB .bin format output, equivalent of --format=decb"}, { "raw", 'r', 0, 0,
--- a/lwlink/output.c Thu Mar 16 16:18:13 2023 -0600 +++ b/lwlink/output.c Thu Mar 16 16:59:50 2023 -0600 @@ -39,6 +39,7 @@ void do_output_raw2(FILE *of); void do_output_lwex0(FILE *of); void do_output_srec(FILE *of); +void do_output_ihex(FILE *of); void do_output(void) { @@ -77,6 +78,10 @@ case OUTPUT_SREC: do_output_srec(of); break; + + case OUTPUT_IHEX: + do_output_ihex(of); + break; default: fprintf(stderr, "Unknown output format doing output!\n"); @@ -241,6 +246,58 @@ fprintf(of,"S903%04X%02X\r\n",linkscript.execaddr,(unsigned char)(~recsum)); } +void do_output_ihex(FILE *of) +{ + const int IRECLEN = 16; + + int sn; + int remainingcodebytes; + + int codeaddr; + int i; + int recaddr = 0; + int recdlen = 0; + int recsum; + int reccnt = -1; + unsigned char* sectcode; + // no header yet; unnecessary + + for (sn = 0; sn < nsects; sn++) // check all sections + { + if (sectlist[sn].ptr -> flags & SECTION_BSS) // ignore BSS sections + continue; + if (sectlist[sn].ptr -> codesize == 0) // ignore empty sections + continue; + + recaddr = sectlist[sn].ptr -> loadaddress; + remainingcodebytes = sectlist[sn].ptr -> codesize; + sectcode = sectlist[sn].ptr -> code; + + while (remainingcodebytes) + { + recdlen = (IRECLEN>remainingcodebytes)?remainingcodebytes:IRECLEN; + recsum = recdlen; + codeaddr = recaddr - sectlist[sn].ptr -> loadaddress; + fprintf(of, ":%02X%04X00", recdlen, recaddr & 0xffff); + for (i = 0; i < recdlen; i++) + { + fprintf(of, "%02X", sectcode[codeaddr+i]); + recsum += sectcode[codeaddr+i]; + } + recsum += (recaddr >> 8) & 0xFF; + recsum += recaddr & 0xFF; + fprintf(of, "%02X\r\n", (unsigned char)(256 - recsum)); + reccnt += 1; + remainingcodebytes -= recdlen; + recaddr += recdlen; + } + } + if (reccnt > 0) + { + fprintf(of, ":00%04X01FF\r\n", linkscript.execaddr); + } +} + void do_output_lwex0(FILE *of) { int nskips = 0; // used to output blanks for BSS inline