FreeCalypso > hg > freecalypso-tools
view miscutil/srec-regions.c @ 649:141372e0d28f
fc-loadtool module refactoring: tpinterfb.c split out
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 02 Mar 2020 02:45:35 +0000 |
parents | 7ef3343161d6 |
children |
line wrap: on
line source
/* * 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) { 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': if (srecbin[0] < 5) { fprintf(stderr, "%s line %d: S7 record is too short\n", infname, lineno); exit(1); } printf("0x%08lX to 0x%08lX (%lu bytes)\n", region_start, region_end, region_end - region_start); printf("S7 address 0x%02X%02X%02X%02X\n", srecbin[1], srecbin[2], srecbin[3], srecbin[4]); exit(0); default: abort(); } } }