-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathihex.c
99 lines (80 loc) · 2.08 KB
/
ihex.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "ihex.h"
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
// return true if failed
static bool hexdigitValue(int ch, int *v)
{
if ('0' <= ch && ch <= '9')
*v = ch - '0';
else if ('A' <= ch && ch <= 'F')
*v = ch - 'A' + 10;
else if ('a' <= ch && ch <= 'f')
*v = ch - 'a' + 10;
else
return true;
return false;
}
static bool read_hex(FILE *f, int n, int *v)
{
*v = 0;
while (n-- > 0) {
int dv, ch = fgetc(f);
if (hexdigitValue(ch, &dv)) {
fprintf(stderr, "Expected hexdigit at pos %ld, got %d",
ftell(f) - 1, ch);
return true;
}
*v = 16* *v + dv;
}
return false;
}
static bool read_ihex_line(FILE *f, unsigned char *memory, unsigned *start_addr)
{
/*
Expect lines like this:
:10010000214601360121470136007EFE09D2190140
That is (without spaces)
CC AAAAA TT DD DD DD .. DD KK
CC is the byte count (# of DD pairs)
AA is the 16-bit address (offset) from base
TT is the type
KK checksum (twos compliment of sum of all bytes)
*/
int ch, count, addr, type, v, chk;
do {
ch = fgetc(f);
if (ch < 0)
return false;
} while (ch == '\n' || ch == '\r');
if (ch != ':') {
fprintf(stderr, "Expected ':' at pos %ld, got %d",
ftell(f) - 1, ch);
return true;
}
if (read_hex(f, 2, &count) ||
read_hex(f, 4, &addr) ||
read_hex(f, 2, &type))
return true;
if (type == 5)
*start_addr = addr;
while (count-- > 0) {
if (read_hex(f, 2, &v))
return true;
if (2048 <= addr && addr < 65536)
memory[addr++] = v;
}
if (read_hex(f, 2, &chk))
return true;
return false;
}
void load_ihex(const char *file, unsigned char *memory)
{
FILE *f = fopen(file, "r");
unsigned start_addr = -1;
while (!feof(f))
if (read_ihex_line(f, memory, &start_addr)) {
printf("Couldn't load %s as ihex\n", file);
break;
}
}