Adding upstream version 6.02~pre8+dfsg.
[syslinux-debian/hramrach.git] / com32 / libupload / upload_srec.c
blobc1907131bc65b07a89c077cfd16d26659771216d
1 /*
2 * S-records dump routine -- dumps S-records on the console
3 */
5 #include <string.h>
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include <minmax.h>
9 #include "upload_backend.h"
11 /* Write a single S-record */
12 static int write_srecord(unsigned int len, unsigned int alen,
13 uint32_t addr, uint8_t type, const void *data)
15 char buf[2+2+8+255*2+2+2];
16 char *p = buf;
17 uint8_t csum;
18 const uint8_t *dptr = data;
19 unsigned int i;
21 switch (alen) {
22 case 2:
23 addr &= 0xffff;
24 break;
25 case 3:
26 addr &= 0xffffff;
27 break;
28 case 4:
29 break;
32 csum = (len+alen+1) + addr + (addr >> 8) + (addr >> 16) + (addr >> 24);
33 for (i = 0; i < len; i++)
34 csum += dptr[i];
35 csum = 0xff-csum;
37 p += sprintf(p, "S%c%02X%0*X", type, len+alen+1, alen*2, addr);
38 for (i = 0; i < len; i++)
39 p += sprintf(p, "%02X", dptr[i]);
40 p += sprintf(p, "%02X\n", csum);
42 fputs(buf, stdout);
43 return 0;
46 static int upload_srec_write(struct upload_backend *be)
48 char name[33];
49 const char *buf;
50 size_t len, chunk, offset, hdrlen;
52 buf = be->outbuf;
53 len = be->zbytes;
55 putchar('\n');
57 hdrlen = snprintf(name, sizeof name, "%.32s",
58 be->argv[0] ? be->argv[0] : "");
60 /* Write head record */
61 write_srecord(hdrlen, 2, 0, '0', name);
63 /* Write data records */
64 offset = 0;
65 while (len) {
66 chunk = min(len, (size_t)32);
68 write_srecord(chunk, 4, offset, '3', buf);
69 buf += chunk;
70 len -= chunk;
71 offset += chunk;
74 /* Write termination record */
75 write_srecord(0, 4, 0, '7', NULL);
77 return 0;
80 struct upload_backend upload_srec = {
81 .name = "srec",
82 .helpmsg = "[filename]",
83 .minargs = 0,
84 .write = upload_srec_write,