# HG changeset patch # User William Astle # Date 1679007590 21600 # Node ID cde1a5a48636634b78e0ff1648519139c94c7697 # Parent 33e37b3d98cfa8cdd6db764188f7283eba933476 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. diff -r 33e37b3d98cf -r cde1a5a48636 lwlink/lwlink.h --- 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 diff -r 33e37b3d98cf -r cde1a5a48636 lwlink/main.c --- 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, diff -r 33e37b3d98cf -r cde1a5a48636 lwlink/output.c --- 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