#include #include #include #include #include #include #include #include extern const char *__progname; static FILE *sf; static const char *sfn; static unsigned char ibuf[512]; static int ibfill; static int ibptr; static unsigned char *srd = 0; static int sra = 0; static int srn; static unsigned int sr_len; static char sr_kind; static unsigned char sr_data[512]; static int have_ep; static unsigned int ep; static int ataddr; static unsigned int curaddr; static void openfile(const char *fn) { sfn = fn; sf = fopen(fn,"r"); if (! sf) { fprintf(stderr,"%s: open %s: %s\r\n",__progname,fn,strerror(errno)); exit(1); } } static void nonblocking(int fd) { fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NONBLOCK); } static int get1(int tmo) { struct pollfd pfd; int i; if (ibptr >= ibfill) { fflush(0); while (1) { ibfill = read(0,&ibuf[0],sizeof(ibuf)); if (ibfill > 0) { ibptr = 0; break; } if (ibfill < 0) { switch (errno) { case EINTR: continue; break; case EWOULDBLOCK: pfd.fd = 0; pfd.events = POLLIN | POLLRDNORM; i = poll(&pfd,1,tmo); if (i == 0) return(-1); continue; break; } fprintf(stderr,"%s: input read: %s\r\n",__progname,strerror(errno)); exit(1); } fprintf(stderr,"%s: input EOF\r\n",__progname); exit(1); } } return(ibuf[ibptr++]); } static void require(const char *s) { int c; const char *sp; sp = s; while (*sp) { c = get1(1000); if (c < 0) { fprintf(stderr,"%s: read timeout at\r\n%.*s <<>> %s\r\n", __progname, (int)(sp-s), s, sp); exit(1); } if (c != (unsigned char)*sp) { fprintf(stderr,"%s: unexpected character %02x at\r\n%.*s <<>> %s\r\n", __progname, c, (int)(sp-s), s, sp); exit(1); } sp ++; } } static void drain(int tmo) { do ibptr = ibfill; while (get1(tmo) >= 0); } static int xval(unsigned char c) { switch (c) { case '0': return(0); break; case '1': return(1); break; case '2': return(2); break; case '3': return(3); break; case '4': return(4); break; case '5': return(5); break; case '6': return(6); break; case '7': return(7); break; case '8': return(8); break; case '9': return(9); break; case 'a': case 'A': return(10); break; case 'b': case 'B': return(11); break; case 'c': case 'C': return(12); break; case 'd': case 'D': return(13); break; case 'e': case 'E': return(14); break; case 'f': case 'F': return(15); break; } return(-1); } #if 0 static void getrom(void) { int a; int c1; int c2; int v1; int v2; for (a=0;a= sra) srd = realloc(srd,sra=srn+8); srd[srn++] = ch; } srn = 0; while (1) { c = getc(sf); if (c == EOF) { if (srn > 0) { fprintf(stderr,"%s: %s: warning: ignoring partial line at EOF\n",__progname,sfn); have_ep = -1; } return(0); } if (c == '\n') break; savec(c); } savec('\0'); srn --; sr_kind = '\0'; if (srn < 1) return(1); if ((srd[0] != 'S') || (srn < 6) || (srn & 1)) { fprintf(stderr,"%s: %s: ignoring non-S-record line: %.*s\n",__progname,sfn,srn,srd); have_ep = -1; return(1); } switch (srd[1]) { case '3': case '7': break; default: fprintf(stderr,"%s: %s: ignoring unrecognized S-record line: %.*s\n",__progname,sfn,srn,srd); have_ep = -1; return(1); } for (ii=2,oi=0;ii=0;x--) ck += sr_data[x]; if ((ck & 0xff) != 0xff) { fprintf(stderr,"%s: %s: ignoring line with bad checksum: %.*s\n",__progname,sfn,srn,srd); have_ep = -1; return(1); } sr_len -= 2; if (sr_len > 0) bcopy(&sr_data[1],&sr_data[0],sr_len); sr_kind = srd[1]; return(1); } static void handlesrec(void) { unsigned int addr; int i; switch (sr_kind) { case '3': if (sr_len < 4) { fprintf(stderr,"%s: %s: ignoring too-short S3 line: %.*s\n",__progname,sfn,srn,srd); have_ep = -1; return; } addr = (sr_data[0] * 0x01000000U) | (sr_data[1] * 0x00010000U) | (sr_data[2] * 0x00000100U) | (sr_data[3] * 0x00000001U); if (!ataddr || (addr != curaddr)) { printf("%08x",addr); ataddr = 1; curaddr = addr; } for (i=4;i 0) { fprintf(stderr,"%s: %s: warning: overriding earlier S7 line: %.*s\n",__progname,sfn,srn,srd); } if (have_ep >= 0) { ep = addr; have_ep = 1; } break; default: abort(); break; } } static void sendep(void) { if (have_ep != 1) return; printf("%08xJ",ep); } int main(int, const char **); int main(int ac, const char **av) { if (ac != 2) { fprintf(stderr,"Usage: %s filename\n",__progname); exit(1); } openfile(av[1]); ibfill = 0; ibptr = 0; nonblocking(0); drain(1000); printf("B123456789a?"); require("addr = 3456789a value = 12"); drain(1000); have_ep = 0; ataddr = 0; while (readsrec()) { handlesrec(); fprintf(stderr,"."); } fprintf(stderr,"\n"); sendep(); fflush(0); return(0); }