URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/eco32/tags/eco32-0.24/tools/bin2exo
- from Rev 66 to Rev 211
- ↔ Reverse comparison
Rev 66 → Rev 211
/bin2exo.c
0,0 → 1,163
/* |
* bin2exo.c -- convert binary data to Motorola S-records |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <stdarg.h> |
|
|
#define S1 1 |
#define S2 2 |
#define S3 3 |
|
|
void error(char *fmt, ...) { |
va_list ap; |
|
va_start(ap, fmt); |
printf("Error: "); |
vprintf(fmt, ap); |
printf("\n"); |
va_end(ap); |
exit(1); |
} |
|
|
int main(int argc, char *argv[]) { |
int type; |
unsigned int loadAddrMsk; |
char *loadAddrStr; |
char *infileStr; |
char *outfileStr; |
char *endptr; |
unsigned int loadAddr; |
unsigned int startAddr; |
FILE *infile; |
FILE *outfile; |
int numBytes, i; |
int c; |
unsigned char lineData[16]; |
unsigned int chksum; |
|
if (argc != 5) { |
printf("Usage: %s -S1|-S2|-S3 <load addr, hex> ", argv[0]); |
printf("<input file> <output file>\n"); |
exit(1); |
} |
if (strcmp(argv[1], "-S1") == 0) { |
type = S1; |
loadAddrMsk = 0x0000FFFF; |
} else |
if (strcmp(argv[1], "-S2") == 0) { |
type = S2; |
loadAddrMsk = 0x00FFFFFF; |
} else |
if (strcmp(argv[1], "-S3") == 0) { |
type = S3; |
loadAddrMsk = 0xFFFFFFFF; |
} else { |
error("exactly one of -S1, -S2, or -S3 must be specified"); |
} |
loadAddrStr = argv[2]; |
infileStr = argv[3]; |
outfileStr = argv[4]; |
loadAddr = strtoul(loadAddrStr, &endptr, 16); |
if (*endptr != '\0') { |
error("illegal load address %s", loadAddrStr); |
} |
if (loadAddr & ~loadAddrMsk) { |
error("load address too big"); |
} |
startAddr = loadAddr; |
infile = fopen(infileStr, "rb"); |
if (infile == NULL) { |
error("cannot open input file %s", infileStr); |
} |
outfile = fopen(outfileStr, "wt"); |
if (outfile == NULL) { |
error("cannot open output file %s", outfileStr); |
} |
while (1) { |
chksum = 0; |
for (numBytes = 0; numBytes < 16; numBytes++) { |
c = fgetc(infile); |
if (c == EOF) { |
break; |
} |
lineData[numBytes] = c; |
chksum += c; |
} |
if (numBytes == 0) { |
break; |
} |
switch (type) { |
case S1: |
fprintf(outfile, "S1%02X%04X", numBytes + 3, loadAddr); |
break; |
case S2: |
fprintf(outfile, "S2%02X%06X", numBytes + 4, loadAddr); |
break; |
case S3: |
fprintf(outfile, "S3%02X%08X", numBytes + 5, loadAddr); |
break; |
} |
for (i = 0; i < numBytes; i++) { |
fprintf(outfile, "%02X", lineData[i]); |
} |
switch (type) { |
case S1: |
chksum += numBytes + 3 + |
((loadAddr >> 0) & 0xFF) + |
((loadAddr >> 8) & 0xFF); |
break; |
case S2: |
chksum += numBytes + 4 + |
((loadAddr >> 0) & 0xFF) + |
((loadAddr >> 8) & 0xFF) + |
((loadAddr >> 16) & 0xFF); |
break; |
case S3: |
chksum += numBytes + 5 + |
((loadAddr >> 0) & 0xFF) + |
((loadAddr >> 8) & 0xFF) + |
((loadAddr >> 16) & 0xFF) + |
((loadAddr >> 24) & 0xFF); |
break; |
} |
fprintf(outfile, "%02X\n", 0xFF - (chksum & 0xFF)); |
loadAddr += numBytes; |
if (c == EOF) { |
break; |
} |
} |
switch (type) { |
case S1: |
fprintf(outfile, "S903%04X", startAddr); |
chksum = 3 + |
((startAddr >> 0) & 0xFF) + |
((startAddr >> 8) & 0xFF); |
break; |
case S2: |
fprintf(outfile, "S804%06X", startAddr); |
chksum = 4 + |
((startAddr >> 0) & 0xFF) + |
((startAddr >> 8) & 0xFF) + |
((startAddr >> 16) & 0xFF); |
break; |
case S3: |
fprintf(outfile, "S705%08X", startAddr); |
chksum = 5 + |
((startAddr >> 0) & 0xFF) + |
((startAddr >> 8) & 0xFF) + |
((startAddr >> 16) & 0xFF) + |
((startAddr >> 24) & 0xFF); |
break; |
} |
fprintf(outfile, "%02X\n", 0xFF - (chksum & 0xFF)); |
fclose(infile); |
fclose(outfile); |
return 0; |
} |
/srecord.html
0,0 → 1,205
<!DOCTYPE doctype PUBLIC "-//IETF//DTD HTML//EN"> |
<html><head> |
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> |
<meta name="GENERATOR" content="Internet Assistant for Word 1.0Z"> |
<meta name="SUBJECT" content="EE/CS 373"> |
<meta name="AUTHOR" content="Val Tareski"><title>Motorola S-record description</title></head><body> |
<h1> |
<a name="top">Motorola S-records</a> |
</h1> |
|
The following fairly complete description of Motorola S-records was found |
a number of years ago on the man pages of a UNIX system. |
|
<hr> |
|
NAME |
<blockquote> |
srec - S-record file and record format |
</blockquote> |
<p> |
DESCRIPTION |
</p><blockquote> |
An S-record file consists of a sequence of specially formatted ASCII character |
strings. An S-record will be less than or equal to 78 bytes in length. |
<p> |
The order of S-records within a file is of no significance and no particular |
order may be assumed. |
</p><p> |
The general format of an S-record follows: |
</p></blockquote> |
<pre><tt>+-------------------//------------------//-----------------------+ |
| type | count | address | data | checksum | |
+-------------------//------------------//-----------------------+</tt> |
</pre> |
<blockquote> |
type -- A char[2] field. These characters describe the type of record (S0, |
S1, S2, S3, S5, S7, S8, or S9). |
<p> |
count -- A char[2] field. These characters when paired and interpreted as |
a hexadecimal value, display the count of remaining character pairs in the |
record. |
</p><p> |
address -- A char[4,6, or 8] field. These characters grouped and interpreted |
as a hexadecimal value, display the address at which the data field is to |
be loaded into memory. The length of the field depends on the number of bytes |
necessary to hold the address. A 2-byte address uses 4 characters, a 3-byte |
address uses 6 characters, and a 4-byte address uses 8 characters. |
</p><p> |
data -- A char [0-64] field. These characters when paired and interpreted |
as hexadecimal values represent the memory loadable data or descriptive |
information. |
</p><p> |
checksum -- A char[2] field. These characters when paired and interpreted |
as a hexadecimal value display the least significant byte of the ones complement |
of the sum of the byte values represented by the pairs of characters making |
up the count, the address, and the data fields. |
</p><p> |
Each record is terminated with a line feed. If any additional or different |
record terminator(s) or delay characters are needed during transmission to |
the target system it is the responsibility of the transmitting program to |
provide them. |
</p><p> |
S0 Record. The type of record is 'S0' (0x5330). The address field is unused |
and will be filled with zeros (0x0000). The header information within the |
data field is divided into the following subfields. |
</p><p> |
</p><blockquote> |
<blockquote> |
mname is char[20] and is the module name.<br> |
ver is char[2] and is the version number.<br> |
rev is char[2] and is the revision number.<br> |
description is char[0-36] and is a text comment. |
<p> |
</p></blockquote> |
Each of the subfields is composed of ASCII bytes whose associated characters, |
when paired, represent one byte hexadecimal values in the case of the version |
and revision numbers, or represent the hexadecimal values of the ASCII characters |
comprising the module name and description. |
</blockquote> |
<p> |
S1 Record. The type of record field is 'S1' (0x5331). The address field is |
intrepreted as a 2-byte address. The data field is composed of memory loadable |
data. |
</p><p> |
S2 Record. The type of record field is 'S2' (0x5332). The address field is |
intrepreted as a 3-byte address. The data field is composed of memory loadable |
data. |
</p><p> |
S3 Record. The type of record field is 'S3' (0x5333). The address field is |
intrepreted as a 4-byte address. The data field is composed of memory loadable |
data. |
</p><p> |
S5 Record. The type of record field is 'S5' (0x5335). The address field is |
intrepreted as a 2-byte value and contains the count of S1, S2, and S3 records |
previously transmitted. There is no data field. |
</p><p> |
S7 Record. The type of record field is 'S7' (0x5337). The address field contains |
the starting execution address and is intrepreted as 4-byte address. There |
is no data field. |
</p><p> |
S8 Record. The type of record field is 'S8' (0x5338). The address field contains |
the starting execution address and is intrepreted as 3-byte address. There |
is no data field. |
</p><p> |
S9 Record. The type of record field is 'S9' (0x5339). The address field contains |
the starting execution address and is intrepreted as 2-byte address. There |
is no data field. |
</p></blockquote> |
<p> |
EXAMPLE |
</p><blockquote> |
Shown below is a typical S-record format file. |
<p> |
|
</p><blockquote> |
<tt>S00600004844521B<br> |
S1130000285F245F2212226A000424290008237C2A<br> |
S11300100002000800082629001853812341001813<br> |
S113002041E900084E42234300182342000824A952<br> |
S107003000144ED492<br> |
S5030004F8<br> |
S9030000FC</tt> |
</blockquote> |
<p> |
The file consists of one S0 record, four S1 records, one S5 record and an |
S9 record. |
</p><p> |
The S0 record is comprised as follows: |
</p><ul> |
<li>S0 S-record type S0, indicating it is a header record. |
</li><li>06 Hexadecimal 06 (decimal 6), indicating that six character pairs (or ASCII |
bytes) follow. |
</li><li>00 00 Four character 2-byte address field, zeroes in this example.<br> |
</li><li>48 44 52 ASCII H, D, and R - "HDR". |
</li><li>1B The checksum. |
|
</li></ul> |
The first S1 record is comprised as follows: |
<ul> |
<li>S1 S-record type S1, indicating it is a data record to be loaded at a 2-byte |
address. |
</li><li>13 Hexadecimal 13 (decimal 19), indicating that nineteen character pairs, |
representing a 2 byte address, 16 bytes of binary data, and a 1 byte checksum, |
follow. |
</li><li>00 00 Four character 2-byte address field; hexidecimal address 0x0000, where |
the data which follows is to be loaded. |
</li><li>28 5F 24 5F 22 12 22 6A 00 04 24 29 00 08 23 7C Sixteen character pairs |
representing the actual binary data. |
</li><li>2A The checksum. |
</li></ul> |
<p> |
The second and third S1 records each contain 0x13 (19) character pairs and |
are ended with checksums of 13 and 52, respectively. The fourth S1 record |
contains 07 character pairs and has a checksum of 92. |
</p><p> |
The S5 record is comprised as follows: |
</p><ul> |
<li>S5 S-record type S5, indicating it is a count record indicating the number |
of S1 records |
</li><li>03 Hexadecimal 03 (decimal 3), indicating that three character pairs |
follow. |
</li><li>00 04 Hexadecimal 0004 (decimal 4), indicating that there are four data records |
previous to this record. |
</li><li>F8 The checksum. |
</li></ul> |
<p> |
The S9 record is comprised as follows: |
</p><ul> |
<li>S9 S-record type S9, indicating it is a termination record. |
</li><li>03 Hexadecimal 03 (decimal 3), indicating that three character pairs |
follow. |
</li><li>00 00 The address field, hexadecimal 0 (decimal 0) indicating the starting |
execution address. |
</li><li>FC The checksum. |
</li></ul> |
</blockquote> |
<p> |
</p><hr> |
<h2> |
Instructor Notes |
</h2> |
<ul> |
<li> |
There isn't any evidence that Motorola ever has made use of the header |
information within the data field of the S0 record, as described above. This |
must have been used by some third party vendors. |
</li><li> |
This is the only place that a 78-byte limit on total record length or 64-byte |
limit on data length is documented. These values shouldn't be trusted for |
the general case. |
</li><li> |
The count field can have values in the range of 0x3 (2 bytes of address + |
1 byte checksum = 3, a not very useful record) to 0xff; this is the count |
of remaining character <big><b>pairs</b></big>, including checksum. |
</li><li> |
If you write code to convert S-Records, you should always assume that a record |
can be as long as 514 (decimal) characters in length (255 * 2 = 510, plus |
4 characters for the type and count fields), plus any terminating character(s). |
That is, in establishing an input buffer in C, you would declare it to be |
an array of 515 chars, thus leaving room for the terminating null character. |
</li></ul> |
<p> |
</p><hr> |
<a href="#top">Beginning of document</a><br> |
</body></html> |
/Makefile
0,0 → 1,19
# |
# Makefile for binary to S-record converter |
# |
|
BUILD = ../../build |
|
.PHONY: all install clean |
|
all: bin2exo |
|
install: bin2exo |
mkdir -p $(BUILD)/bin |
cp bin2exo $(BUILD)/bin |
|
bin2exo: bin2exo.c |
gcc -m32 -g -Wall -o bin2exo bin2exo.c |
|
clean: |
rm -f *~ bin2exo |