Krupski
October 31st, 2009, 03:35 AM
Hi all,
I would appreciate if you could comment / critique the following simple program.
The main reason I am asking is that I have a "gut feeling" that I could be doing what I'm doing is a better manner.
I'm not a "programmer" and I only write little utilities, but I do wish to learn proper form and any tricks that there are to learn.
Please feel free to say anything you wish. If the code outright stinks, please say so! ;)
Here it is:
// motorola s-record to binary converter
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#undef BUFSIZ
#define BUFSIZ 1024
int readln(FILE *, char *);
int main(void)
{
char buffer[BUFSIZ]; // line input buffer
char rectype[2]; // record type (ascii S0, S1 or S9)
int bytes; // number of bytes in record (including the checksum)
int addrhi; // load address hi byte
int addrlo; // load address lo byte
int s_data; // binary data byte
int n; // counter
int x, y; // temporary hi and lo nybbles
int checksum; // s-record checksum accumulator
while(!feof(stdin)) {
readln(stdin, buffer); // read one line of text
if(strlen(buffer) >= 12) { // minimum length of s record line
// get recordtype (S1), number of bytes, load address hi, load address lo
sscanf(buffer, "%2s%02x%02x%02x", rectype, &bytes, &addrhi, &addrlo);
// only convert S1 (data) records
if(strcmp(rectype, "S1") == 0) {
// calculate checksum
checksum = (bytes + addrhi + addrlo + 1);
for(n = 0; n < (bytes - 2); n++) {
// get ascii values
x = buffer[8 + (n * 2) + 0] - '0';
y = buffer[8 + (n * 2) + 1] - '0';
// correct hex if A-F
if(x > 9) { x -= 7; }
if(y > 9) { y -= 7; }
// shift hi 4 bits up
x <<= 4;
// complete the data
s_data = x + y;
// add up checksum
checksum += s_data;
// output all but the checksum
if(n < (bytes - 3)) {
fputc(s_data, stdout);
}
}
}
// low order byte should be zero if checksum is good
if((checksum & 0xFF) != 0) {
fprintf(stderr, "Checksum error: %s\n", buffer);
break;
}
}
}
exit(0);
}
int readln(FILE * fp, char * str)
{
char buf[BUFSIZ];
int len, n;
buf[0] = 0;
fgets(buf, BUFSIZ, fp);
// strip any leading spaces
sscanf(buf, "%s", buf);
len = strlen(buf);
// strip any trailing cr, lf or other
while(len >= 0) {
if(buf[len] < 0x21) { buf[len] = 0; len--; }
else { break; }
}
// null terminat string
len++;
buf[len] = 0;
// uppercase buffer
for(n = 0; n < (int)strlen(buf); n++) {
buf[n] = toupper(buf[n]);
}
// copy string to output
strcpy(str, buf);
return len;
}
...and this is the type of data that the program is supposed to convert to raw binary:
S113E070005A2BDBD7A3BDE3E3BDE3E0BDE3E3201C
S113E080D1810D260A5D2702A700BDE3F4200E5CB2
S113E090C12824BED7A3A700BDE3A120B5CC0000AE
S113E0A0DD6BCE007BDFB2BDE2C2BDE2ADCE00A42B
S113E0B03ABDE10EA700810D2716BDE2CF2711BDA1
S113E0C0E2B45CC10823E3CEE55ABDE3FC7EE04341
S113E0D0D779CEE447DFB4DEB418CE00A4E6002A34
...and here's what each piece means:
S1 - indicates a "data record"
13 - hex 13 = decimal 19 (byte count)
E070 - load address of data
00 5A 2B DB D7 A3 BD E3 E3 BD E3 E0 BD E3 E3 20 - the actual data
1C - the checksum
Thanks in advance!
-- Roger
I would appreciate if you could comment / critique the following simple program.
The main reason I am asking is that I have a "gut feeling" that I could be doing what I'm doing is a better manner.
I'm not a "programmer" and I only write little utilities, but I do wish to learn proper form and any tricks that there are to learn.
Please feel free to say anything you wish. If the code outright stinks, please say so! ;)
Here it is:
// motorola s-record to binary converter
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#undef BUFSIZ
#define BUFSIZ 1024
int readln(FILE *, char *);
int main(void)
{
char buffer[BUFSIZ]; // line input buffer
char rectype[2]; // record type (ascii S0, S1 or S9)
int bytes; // number of bytes in record (including the checksum)
int addrhi; // load address hi byte
int addrlo; // load address lo byte
int s_data; // binary data byte
int n; // counter
int x, y; // temporary hi and lo nybbles
int checksum; // s-record checksum accumulator
while(!feof(stdin)) {
readln(stdin, buffer); // read one line of text
if(strlen(buffer) >= 12) { // minimum length of s record line
// get recordtype (S1), number of bytes, load address hi, load address lo
sscanf(buffer, "%2s%02x%02x%02x", rectype, &bytes, &addrhi, &addrlo);
// only convert S1 (data) records
if(strcmp(rectype, "S1") == 0) {
// calculate checksum
checksum = (bytes + addrhi + addrlo + 1);
for(n = 0; n < (bytes - 2); n++) {
// get ascii values
x = buffer[8 + (n * 2) + 0] - '0';
y = buffer[8 + (n * 2) + 1] - '0';
// correct hex if A-F
if(x > 9) { x -= 7; }
if(y > 9) { y -= 7; }
// shift hi 4 bits up
x <<= 4;
// complete the data
s_data = x + y;
// add up checksum
checksum += s_data;
// output all but the checksum
if(n < (bytes - 3)) {
fputc(s_data, stdout);
}
}
}
// low order byte should be zero if checksum is good
if((checksum & 0xFF) != 0) {
fprintf(stderr, "Checksum error: %s\n", buffer);
break;
}
}
}
exit(0);
}
int readln(FILE * fp, char * str)
{
char buf[BUFSIZ];
int len, n;
buf[0] = 0;
fgets(buf, BUFSIZ, fp);
// strip any leading spaces
sscanf(buf, "%s", buf);
len = strlen(buf);
// strip any trailing cr, lf or other
while(len >= 0) {
if(buf[len] < 0x21) { buf[len] = 0; len--; }
else { break; }
}
// null terminat string
len++;
buf[len] = 0;
// uppercase buffer
for(n = 0; n < (int)strlen(buf); n++) {
buf[n] = toupper(buf[n]);
}
// copy string to output
strcpy(str, buf);
return len;
}
...and this is the type of data that the program is supposed to convert to raw binary:
S113E070005A2BDBD7A3BDE3E3BDE3E0BDE3E3201C
S113E080D1810D260A5D2702A700BDE3F4200E5CB2
S113E090C12824BED7A3A700BDE3A120B5CC0000AE
S113E0A0DD6BCE007BDFB2BDE2C2BDE2ADCE00A42B
S113E0B03ABDE10EA700810D2716BDE2CF2711BDA1
S113E0C0E2B45CC10823E3CEE55ABDE3FC7EE04341
S113E0D0D779CEE447DFB4DEB418CE00A4E6002A34
...and here's what each piece means:
S1 - indicates a "data record"
13 - hex 13 = decimal 19 (byte count)
E070 - load address of data
00 5A 2B DB D7 A3 BD E3 E3 BD E3 E0 BD E3 E3 20 - the actual data
1C - the checksum
Thanks in advance!
-- Roger