FreeCalypso > hg > freecalypso-tools
diff miscutil/srec-regions.c @ 622:89e9e79a7f55
srec-regions utility written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 27 Feb 2020 07:59:47 +0000 |
parents | |
children | 7485e75d9477 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/miscutil/srec-regions.c Thu Feb 27 07:59:47 2020 +0000 @@ -0,0 +1,179 @@ +/* + * This program parses an S-record file (TI's *.m0 or otherwise), identifies + * the set of discontiguous regions into which this SREC image deposits bits, + * and lists these identified regions. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> + +char *infname; +FILE *inf; +char srecbuf[1024]; +u_char srecbin[256]; +int lineno, state; +u_long region_start, region_end; + +decode_hex_byte(s) + char *s; +{ + register int u, l; + + if (!isxdigit(s[0]) || !isxdigit(s[1])) + return(-1); + if (isdigit(s[0])) + u = s[0] - '0'; + else if (isupper(s[0])) + u = s[0] - 'A' + 10; + else + u = s[0] - 'a' + 10; + if (isdigit(s[1])) + l = s[1] - '0'; + else if (isupper(s[1])) + l = s[1] - 'A' + 10; + else + l = s[1] - 'a' + 10; + return((u << 4) | l); +} + +srec2bin() +{ + register int i, l, b; + + l = decode_hex_byte(srecbuf + 2); + if (l < 1) { + fprintf(stderr, "%s line %d: S-record length octet is bad\n", + infname, lineno); + exit(1); + } + srecbin[0] = l; + for (i = 1; i <= l; i++) { + b = decode_hex_byte(srecbuf + i*2 + 2); + if (b < 0) { + fprintf(stderr, "%s line %d: hex decode error\n", + infname, lineno); + exit(1); + } + srecbin[i] = b; + } + return(0); +} + +srec_cksum() +{ + u_char accum; + register int i, len; + + len = srecbin[0] + 1; + accum = 0; + for (i = 0; i < len; i++) + accum += srecbin[i]; + if (accum != 0xFF) { + fprintf(stderr, "%s line %d: bad checksum\n", infname, lineno); + exit(1); + } + return(0); +} + +main(argc, argv) + char **argv; +{ + register int i; + u_long curaddr; + int datalen; + + if (argc != 2) { + fprintf(stderr, "usage: %s image.m0\n", argv[0]); + exit(1); + } + infname = argv[1]; + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + + state = 0; + for (lineno = 1; ; lineno++) { + if (!fgets(srecbuf, sizeof srecbuf, inf)) { + fprintf(stderr, "%s: premature EOF\n", infname); + exit(1); + } + if (srecbuf[0] != 'S') { + fprintf(stderr, "%s line %d: not an S-record\n", + infname, lineno); + exit(1); + } + switch (srecbuf[1]) { + case '0': + if (state == 0) + break; + else + goto badtype; + case '3': + if (state == 0) + goto badtype; + else + break; + case '7': + if (state == 2) + break; + else + goto badtype; + default: + badtype: + fprintf(stderr, + "%s line %d: S-record type unexpected\n", + infname, lineno); + exit(1); + } + srec2bin(); + srec_cksum(); + switch (srecbuf[1]) { + case '0': + state = 1; + continue; + case '3': + if (srecbin[0] < 6) { + fprintf(stderr, + "%s line %d: S3 record is too short\n", + infname, lineno); + exit(1); + } + curaddr = (srecbin[1] << 24) | (srecbin[2] << 16) | + (srecbin[3] << 8) | srecbin[4]; + datalen = srecbin[0] - 5; + if (state < 2) { + region_start = curaddr; + region_end = curaddr + datalen; + state = 2; + continue; + } + if (curaddr < region_end) { + fprintf(stderr, + "%s line %d: address going backwards\n", + infname, lineno); + exit(1); + } + if (curaddr > region_end) { + printf("0x%08lX to 0x%08lX (%lu bytes)\n", + region_start, region_end, + region_end - region_start); + region_start = curaddr; + } + region_end = curaddr + datalen; + continue; + case '7': + printf("0x%08lX to 0x%08lX (%lu bytes)\n", + region_start, region_end, + region_end - region_start); + exit(0); + default: + abort(); + } + } +}