sdcc-cpm-diskdump/lsrc/binpak.c
Fabio Battaglia 6a6a01a581 Fix binpak
2014-07-09 19:49:19 +02:00

69 lines
1.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <libgen.h>
void print_usage(const char *p_name);
int main(int argc, char *argv[]) {
int opt, user_no = 0;
unsigned int checksum = 0;
long f_size = 0;
FILE *in_file;
unsigned char r_data;
opterr = 0;
while ((opt = getopt(argc, argv, "u:")) != -1) {
switch(opt) {
case 'u':
user_no = atoi(optarg);
break;
default:
print_usage(argv[0]);
break;
}
}
if (optind >= argc) {
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
in_file = fopen(argv[optind], "rb");
if (!in_file) {
perror(argv[optind]);
exit(EXIT_FAILURE);
}
// Get size
fseek(in_file, 0L, SEEK_END);
f_size = ftell(in_file);
fseek(in_file, 0L, SEEK_SET);
// The checksum is two pairs of HEX values:
// The first one is the low-byte of the length of the file being uploaded.
// Because CP/M files are normally saved in blocks of 128, this is normally
// "80" or "00", but doesn't need to be.
// The second one is the low-byte of the SUM of each byte being uploaded.
// The checksum is very simple, but more than adequate for confirming a simple
// data transfer, as it can detect missing, extra or changed characters.
fprintf(stdout, "A:DOWNLOAD %s\r\nU%u\r\n:", basename(argv[optind]), user_no);
while (fread(&r_data, 1, 1, in_file) == 1) {
fprintf(stdout, "%.02X", r_data);
checksum += r_data;
}
fprintf(stdout, ">%.04X\r\n", (unsigned short)((checksum & 0xFF) | ((f_size & 0xFF) << 8)));
fclose(in_file);
return 0;
}
void print_usage(const char *p_name) {
fprintf(stderr, "Usage: %s [-u user_no] file\n", p_name);
}