commit ada3e18cd35ee6df52f76497d480e783dacebed1 Author: Wen-chien Jesse Sung Date: Fri Jul 6 18:16:09 2012 +0800 Initial import diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b914bfa --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +TARGET = hex2hcd +CFLAGS = -O2 -march=native +CC = gcc + +all: $(TARGET) + +$(TARGET): $(TARGET).c + +clean: + -rm $(TARGET) + diff --git a/hex2hcd.c b/hex2hcd.c new file mode 100644 index 0000000..e693676 --- /dev/null +++ b/hex2hcd.c @@ -0,0 +1,116 @@ +#include +#include +#include + +#define RBUF_SIZE 640 + +static unsigned int asc_to_int(char a) +{ + if (a >= 'A') + return (a - 'A') + 10; + else + return a - '0'; +} + +static unsigned int hex_to_int(const char *h) +{ + return asc_to_int(*h) * 0x10 + asc_to_int(*(h + 1)); +} + +static unsigned int lhex_to_int(const char *h) +{ + return hex_to_int(h) * 0x100 + hex_to_int(h + 2); +} + +static int check_sum(const char *str, int len) +{ + unsigned int sum, cal; + int i; + sum = hex_to_int(str + len - 2); + for (cal = 0, i = 1; i < len - 2; i += 2) + cal += hex_to_int(str + i); + cal = 0x100 - cal & 0xFF; + return sum == cal; +} + +static int check_hex_line(const char *str, int len) +{ + if ((str[0] != ':') || (len < 11) || !check_sum(str, len) || + (hex_to_int(str + 1) * 2 + 11 != len)) + return 0; + return 1; +} + +int main(int argc, char *argv[]) +{ + unsigned int addr = 0; + FILE *ifp, *ofp; + char *rbuf; + ssize_t len, i; + size_t buflen; + + if (argc != 3) { + printf("Usage: %s \n", argv[0]); + return 0; + } + + ifp = fopen(argv[1], "r"); + ofp = fopen(argv[2], "w"); + if ((ifp == NULL) || (ofp == NULL)) { + puts("failed to open file."); + return -EIO; + } + + rbuf = NULL; + while ((len = getline(&rbuf, &buflen, ifp)) > 0) { + int type; + char obuf[7]; + unsigned int dest_addr; + while ((rbuf[len - 1] == '\r') || (rbuf[len - 1] == '\n')) + len--; + printf("%d, %s\n", (int)len, rbuf); + if (!check_hex_line(rbuf, len)) + break; + type = hex_to_int(rbuf + 7); + switch (type) { + case 4: + addr = lhex_to_int(rbuf + 9) * 0x10000; + printf("bump addr to 0x%08X\n", addr); + break; + case 0: + dest_addr = addr + lhex_to_int(rbuf + 3); + obuf[0] = 0x4c; + obuf[1] = 0xfc; + obuf[2] = hex_to_int(rbuf + 1) + 4; + obuf[3] = dest_addr; + obuf[4] = dest_addr >> 8; + obuf[5] = dest_addr >> 16; + obuf[6] = dest_addr >> 24; + if (fwrite(obuf, 7, 1, ofp) != 1) + goto output_err; + for (i = 0; i < hex_to_int(rbuf + 1); i++) { + obuf[0] = hex_to_int(rbuf + 9 + i * 2); + if (fwrite(obuf, 1, 1, ofp) != 1) + goto output_err; + } + break; + case 1: + if (fwrite("\x4e\xfc\x04\xff\xff\xff\xff", 7, 1, ofp) != 1) + goto output_err; + goto end; + default: + return -EINVAL; + } + } + + puts("hex file formatting error"); + return -EINVAL; + +output_err: + puts("error on writing output file"); + return -EIO; + +end: + return 0; +} +