# HG changeset patch # User William Astle # Date 1428604053 21600 # Node ID 55c1f9a321e9357b7b65af59c836d803b1ec5029 # Parent 98f3e016cfd845569473195de90480af437d9115 Add S-record output support to lwlink Thanks to a patch from Joachim Ga?ler , lwlink now has output support for S-records. This is output only - it does not add input support for S-record files. diff -r 98f3e016cfd8 -r 55c1f9a321e9 lwlink/lwlink.h --- a/lwlink/lwlink.h Mon Mar 16 09:27:20 2015 -0600 +++ b/lwlink/lwlink.h Thu Apr 09 12:27:33 2015 -0600 @@ -30,6 +30,7 @@ #define OUTPUT_RAW 1 // raw sequence of bytes #define OUTPUT_LWEX0 2 // LWOS LWEX binary version 0 #define OUTPUT_OS9 3 // OS9 object code module +#define OUTPUT_SREC 4 // motorola SREC format typedef struct symtab_s symtab_t; struct symtab_s diff -r 98f3e016cfd8 -r 55c1f9a321e9 lwlink/main.c --- a/lwlink/main.c Mon Mar 16 09:27:20 2015 -0600 +++ b/lwlink/main.c Thu Apr 09 12:27:33 2015 -0600 @@ -81,6 +81,8 @@ outformat = OUTPUT_LWEX0; else if (!strcasecmp(arg, "os9")) outformat = OUTPUT_OS9; + else if (!strcasecmp(arg, "srec")) + outformat = OUTPUT_SREC; else { fprintf(stderr, "Invalid output format: %s\n", arg); @@ -130,7 +132,7 @@ { "debug", 'd', 0, 0, "Set debug mode"}, { "format", 'f', "TYPE", 0, - "Select output format: decb, raw, lwex, os9"}, + "Select output format: decb, raw, lwex, os9, srec"}, { "decb", 'b', 0, 0, "Generate DECB .bin format output, equivalent of --format=decb"}, { "raw", 'r', 0, 0, diff -r 98f3e016cfd8 -r 55c1f9a321e9 lwlink/output.c --- a/lwlink/output.c Mon Mar 16 09:27:20 2015 -0600 +++ b/lwlink/output.c Thu Apr 09 12:27:33 2015 -0600 @@ -37,6 +37,7 @@ void do_output_decb(FILE *of); void do_output_raw(FILE *of); void do_output_lwex0(FILE *of); +void do_output_srec(FILE *of); void do_output(void) { @@ -68,6 +69,10 @@ do_output_os9(of); break; + case OUTPUT_SREC: + do_output_srec(of); + break; + default: fprintf(stderr, "Unknown output format doing output!\n"); exit(111); @@ -161,6 +166,59 @@ } } +void do_output_srec(FILE *of) +{ + const int SRECLEN = 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 = (SRECLEN>remainingcodebytes)?remainingcodebytes:SRECLEN; + recsum = recdlen + 3; + codeaddr = recaddr - sectlist[sn].ptr -> loadaddress; + fprintf(of, "S1%02X%04X", recdlen + 3, recaddr); + 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)(~recsum)); + reccnt += 1; + remainingcodebytes -= recdlen; + recaddr += recdlen; + } + } + // S9 record as a footer to inform about start addr + recsum = 3; + recsum += (linkscript.execaddr >> 8) & 0xFF; + recsum += linkscript.execaddr & 0xFF; + fprintf(of,"S903%04X%02X\r\n",linkscript.execaddr,(unsigned char)(~recsum)); +} + void do_output_lwex0(FILE *of) { int nskips = 0; // used to output blanks for BSS inline diff -r 98f3e016cfd8 -r 55c1f9a321e9 lwlink/script.c --- a/lwlink/script.c Mon Mar 16 09:27:20 2015 -0600 +++ b/lwlink/script.c Thu Apr 09 12:27:33 2015 -0600 @@ -58,6 +58,17 @@ "entry 2000\n" ; +// the built-in SREC target linker script +static char *srec_script = + "define basesympat s_%s\n" + "define lensympat l_%s\n" + "section init load 0400\n" + "section code\n" + "section *,!bss\n" + "section *,bss\n" + "entry __start\n" + ; + // the built-in RAW target linker script static char *raw_script = "define basesympat s_%s\n" @@ -147,6 +158,10 @@ script = decb_script; break; + case OUTPUT_SREC: + script = srec_script; + break; + case OUTPUT_LWEX0: script = lwex0_script; break;