FreeCalypso > hg > freecalypso-tools
changeset 622:89e9e79a7f55
srec-regions utility written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 27 Feb 2020 07:59:47 +0000 |
parents | f44770a652eb |
children | 46d17c346511 |
files | .hgignore miscutil/Makefile miscutil/srec-regions.c |
diffstat | 3 files changed, 184 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Feb 27 04:27:18 2020 +0000 +++ b/.hgignore Thu Feb 27 07:59:47 2020 +0000 @@ -34,6 +34,7 @@ ^miscutil/fc-vm2hex$ ^miscutil/imei-luhn$ ^miscutil/mokosrec2bin$ +^miscutil/srec-regions$ ^ringtools/fc-e1decode$ ^ringtools/fc-e1gen$
--- a/miscutil/Makefile Thu Feb 27 04:27:18 2020 +0000 +++ b/miscutil/Makefile Thu Feb 27 07:59:47 2020 +0000 @@ -1,7 +1,7 @@ CC= gcc CFLAGS= -O2 PROGS= fc-fr2tch fc-gsm2vm fc-rgbconv fc-serterm fc-tch2fr fc-vm2hex imei-luhn\ - mokosrec2bin + mokosrec2bin srec-regions SCRIPTS=c139explore pirexplore INSTALL_PREFIX= /opt/freecalypso @@ -42,6 +42,9 @@ mokosrec2bin: mokosrec2bin.c ${CC} ${CFLAGS} -o $@ $@.c +srec-regions: srec-regions.c + ${CC} ${CFLAGS} -o $@ $@.c + install: mkdir -p ${INSTBIN} install -c ${PROGS} ${SCRIPTS} ${INSTBIN}
--- /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(); + } + } +}