2 * Copyright (c) 2005 Chris Kuethe <chris.kuethe@gmail.com>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #include <sys/types.h>
23 * See srec(5) for a description of this format.
24 * We read and write 4-byte addresses.
26 * S3: Memory Loadable Data, 4byte address
27 * S5: Count of S1, S2 and S3 Records
28 * S7: starting execution address interpreted as a 4-byte address
30 #define MAX_BYTES_PER_RECORD 16
33 * bin2srec: turn a chunk of binary into an S-record
34 * offset: used to specify load address
35 * num: up to MAX_BYTES_PER_RECORD bytes can be encoded at one time
36 * bytes are read from bbuf and a ready-to-go srecord is placed in sbuf
39 bin2srec(unsigned int type, unsigned int offset, unsigned int num,
40 unsigned char *bbuf, unsigned char *sbuf)
42 unsigned char abuf[MAX_BYTES_PER_RECORD * 2 + 2], sum;
45 if ((num < 1) || (num > MAX_BYTES_PER_RECORD))
48 len = (size_t) (4 + num + 1);
49 memset(abuf, 0, sizeof(abuf));
50 hexdump((size_t) num, bbuf, abuf);
51 sum = sr_sum((unsigned int)len, offset, bbuf);
52 (void)snprintf((char *)sbuf, MAX_BYTES_PER_RECORD * 2 + 17,
53 "S%u%02X%08X%s%02X\r\n",
54 type, (unsigned)len, offset, (char *)abuf, (unsigned)sum);
58 int srec_hdr(unsigned int num, unsigned char *bbuf, unsigned char *sbuf)
60 return bin2srec(0, 0, num, bbuf, sbuf);
63 int srec_fin(unsigned int num, unsigned char *sbuf)
65 unsigned char bbuf[4], sum;
69 bbuf[0] = (unsigned char)(num & 0xff);
70 bbuf[1] = (unsigned char)((num >> 8) & 0xff);
71 sum = sr_sum(3, 0, bbuf);
72 (void)snprintf((char *)sbuf, 13, "S503%04X%02X\r\n", num, (unsigned)sum);
77 void hexdump(size_t len, unsigned char *bbuf, unsigned char *abuf)
81 memset(abuf, 0, MAX_BYTES_PER_RECORD * 2 + 2);
82 if (len > MAX_BYTES_PER_RECORD * 2)
83 len = MAX_BYTES_PER_RECORD * 2;
85 for (i = 0; i < len; i++) {
86 abuf[i * 2] = hc((bbuf[i] & 0xf0) >> 4);
87 abuf[i * 2 + 1] = hc(bbuf[i] & 0x0f);
92 unsigned char hc(unsigned char x)
101 return ('A' + x - 10);
122 sr_sum(unsigned int count, unsigned int addr, unsigned char *bbuf)
125 unsigned char k, sum = 0;
127 sum = (count & 0xff);
128 sum += ((addr & 0x000000ff));
129 sum += ((addr & 0x0000ff00) >> 8);
130 sum += ((addr & 0x00ff0000) >> 16);
131 sum += ((addr & 0xff000000) >> 24);
133 for (i = 0; i < j; i++) {