From: Keith Packard Date: Sun, 24 Mar 2013 22:30:24 +0000 (-0700) Subject: ao-tools/lib: Add loading support for 32-bit ihx files X-Git-Tag: 1.2.1~44 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=1f30b1f14dbab6e6ea94177e459c80732e31e433 ao-tools/lib: Add loading support for 32-bit ihx files These place the upper 16 bits of the address in a special record. That requires handling records in file order, so don't sort them in address order anymore, instead find the bounds of the loaded data by scanning them all. Signed-off-by: Keith Packard --- diff --git a/ao-tools/lib/ccdbg-hex.c b/ao-tools/lib/ccdbg-hex.c index dfea9156..184b4e3b 100644 --- a/ao-tools/lib/ccdbg-hex.c +++ b/ao-tools/lib/ccdbg-hex.c @@ -233,15 +233,6 @@ ccdbg_hex_file_free(struct hex_file *hex) free(hex); } -static int -ccdbg_hex_record_compar(const void *av, const void *bv) -{ - const struct hex_record *a = *(struct hex_record **) av; - const struct hex_record *b = *(struct hex_record **) bv; - - return (int) a->address - (int) b->address; -} - struct hex_file * ccdbg_hex_file_read(FILE *file, char *name) { @@ -272,11 +263,6 @@ ccdbg_hex_file_read(FILE *file, char *name) if (record->type == HEX_RECORD_EOF) done = 1; } - /* - * Sort them into increasing addresses, except for EOF - */ - qsort(hex->records, hex->nrecord - 1, sizeof (struct hex_record *), - ccdbg_hex_record_compar); return hex; bail: @@ -288,16 +274,45 @@ struct hex_image * ccdbg_hex_image_create(struct hex_file *hex) { struct hex_image *image; - struct hex_record *first, *last, *record; + struct hex_record *record; int i; + uint32_t addr; uint32_t base, bound; uint32_t offset; + uint32_t extended_addr; + int length; - first = hex->records[0]; - last = hex->records[hex->nrecord - 2]; /* skip EOF */ - base = (uint32_t) first->address; - bound = (uint32_t) last->address + (uint32_t) last->length; + base = 0xffffffff; + bound = 0x0; + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { + uint32_t r_bound; + record = hex->records[i]; + switch (record->type) { + case 0: + addr = extended_addr + record->address; + r_bound = addr + record->length; + if (addr < base) + base = addr; + if (r_bound > bound) + bound = r_bound; + break; + case 1: + break; + case 2: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + if (record->length != 2) + return NULL; + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } + + } length = bound - base; image = calloc(sizeof(struct hex_image) + length, 1); if (!image) @@ -305,10 +320,24 @@ ccdbg_hex_image_create(struct hex_file *hex) image->address = base; image->length = length; memset(image->data, 0xff, length); - for (i = 0; i < hex->nrecord - 1; i++) { + extended_addr = 0; + for (i = 0; i < hex->nrecord; i++) { record = hex->records[i]; - offset = record->address - base; - memcpy(image->data + offset, record->data, record->length); + switch (record->type) { + case 0: + addr = extended_addr + record->address; + offset = addr - base; + memcpy(image->data + offset, record->data, record->length); + break; + case 1: + break; + case 2: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 4; + break; + case 4: + extended_addr = ((record->data[0] << 8) | record->data[1]) << 16; + break; + } } return image; } @@ -328,3 +357,25 @@ ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b) return 0; return 1; } + +struct hex_image * +ccdbg_hex_load(char *filename) +{ + FILE *file; + struct hex_file *hex_file; + struct hex_image *hex_image; + + file = fopen (filename, "r"); + if (!file) + return 0; + + hex_file = ccdbg_hex_file_read(file, filename); + fclose(file); + if (!hex_file) + return 0; + hex_image = ccdbg_hex_image_create(hex_file); + if (!hex_image) + return 0; + ccdbg_hex_file_free(hex_file); + return hex_image; +} diff --git a/ao-tools/lib/ccdbg.h b/ao-tools/lib/ccdbg.h index ca596143..a27ff5d1 100644 --- a/ao-tools/lib/ccdbg.h +++ b/ao-tools/lib/ccdbg.h @@ -122,8 +122,8 @@ struct hex_file { }; struct hex_image { - uint16_t address; - uint16_t length; + uint32_t address; + uint32_t length; uint8_t data[0]; }; @@ -253,6 +253,9 @@ ccdbg_hex_image_create(struct hex_file *hex); void ccdbg_hex_image_free(struct hex_image *image); +struct hex_image * +ccdbg_hex_load(char *filename); + int ccdbg_hex_image_equal(struct hex_image *a, struct hex_image *b);