96 lines
2.1 KiB
C
96 lines
2.1 KiB
C
|
/* McPhail's Tip-Top TAP Top-Tailer
|
||
|
* Takes a raw code file as input
|
||
|
* Prepends data length and appends xor checksum
|
||
|
* Outputs to new file with .block suffix */
|
||
|
|
||
|
|
||
|
#include <fcntl.h>
|
||
|
#include <unistd.h>
|
||
|
#include <stdio.h>
|
||
|
#include <linux/limits.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
int fdin, fdout;
|
||
|
char outfilename[PATH_MAX];
|
||
|
unsigned int count = 0;
|
||
|
unsigned char flagopt = 0;
|
||
|
unsigned char tally = 0;
|
||
|
unsigned char next = 0;
|
||
|
if ((argc<2) || (argc>3)) {
|
||
|
printf("Please specify file to read.\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (3==argc) {
|
||
|
if (!strcmp(argv[2], "header")) flagopt = 1;
|
||
|
if (!strcmp(argv[2], "data")) flagopt = 2;
|
||
|
if (!flagopt) {
|
||
|
printf("Optional flags are \"header\" or \"data\"\n");
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (! flagopt) {
|
||
|
printf("*** WARNING ***\n");
|
||
|
printf("*** ttttt is running in RAW mode.\n");
|
||
|
printf("*** Have you manually included the format flag as the first byte of the block?\n");
|
||
|
printf("*** If not, run again passing 'header' or 'data' as the second parameter.\n");
|
||
|
printf("*** WARNING ***\n\n");
|
||
|
}
|
||
|
|
||
|
fdin = open(argv[1], O_RDONLY);
|
||
|
if (fdin<0) {
|
||
|
printf("Couldn't open %s. for reading\n", argv[1]);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
snprintf(outfilename, PATH_MAX, "%s.block", argv[1]);
|
||
|
outfilename[PATH_MAX - 1] = '\0';
|
||
|
if (! strcmp(argv[1], outfilename)) {
|
||
|
printf("Filename too long - would clobber existing.\n");
|
||
|
close(fdin);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
fdout = open(outfilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
|
||
|
if (fdout<0) {
|
||
|
printf("Couldn't open %s for writing.\n", outfilename);
|
||
|
close(fdin);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
while (read(fdin, &next, 1)) {
|
||
|
tally ^= next;
|
||
|
count ++;
|
||
|
};
|
||
|
lseek(fdin, 0, SEEK_SET);
|
||
|
|
||
|
if (flagopt) count++;
|
||
|
|
||
|
char lsb = (count+1)&255;
|
||
|
char msb = ((count+1)>>8)&255;
|
||
|
write(fdout, &lsb, 1);
|
||
|
write(fdout, &msb, 1);
|
||
|
next = 0;
|
||
|
if (flagopt == 2) next = 255;
|
||
|
if (flagopt) {
|
||
|
write(fdout, &next, 1);
|
||
|
tally ^= next;
|
||
|
}
|
||
|
while (read(fdin, &next, 1)) {
|
||
|
write(fdout, &next, 1);
|
||
|
}
|
||
|
write(fdout, &tally, 1);
|
||
|
|
||
|
close(fdout);
|
||
|
close(fdin);
|
||
|
|
||
|
printf("File %s written.\n", outfilename);
|
||
|
count--;
|
||
|
printf("Code length is %d (0x%.4X).\n", count, count);
|
||
|
|
||
|
return 0;
|
||
|
}
|