Skip to content

Instantly share code, notes, and snippets.

@tomtor
Created March 19, 2016 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomtor/7da0d03f77b8633da9a3 to your computer and use it in GitHub Desktop.
Save tomtor/7da0d03f77b8633da9a3 to your computer and use it in GitHub Desktop.
Convert SIMH simulator tapes to normal files
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
* Convert SIMH simulator tapes to normal files
*
* Copyright 2016 Tom Vijlbrief
*
* tvijlbrief at gmail dot com
*
* Distributed under the GPL license
*/
void usage()
{
fprintf(stderr, "usage: rdtape [-v] [-s skip]\n");
exit(1);
}
int verbose;
/*
read longword in little endian order from file
*/
long rl(FILE *f)
{
unsigned char c[4];
long len;
static long prevlen, lencnt;
if (fread(c, 1, 4, f) != 4) {
fprintf(stderr, "Cannot read tape marker\n");
exit(1);
}
len =
((long)c[0]) |
((long)c[1] << 8) |
((long)c[2] << 16) |
((long)c[3] << 24);
if (verbose) {
if (len != prevlen) {
lencnt= 0;
} else {
lencnt++;
fprintf(stderr, "\r%05ldB %ld blocks", len, lencnt);
}
}
prevlen = len;
return len;
}
/*
read from file and write unblocked data to stdout
*/
void rblock(FILE *f, FILE *out)
{
size_t ret;
void *b;
long blen;
while (!feof(f)) {
blen = rl(f);
if (!blen) {
if (verbose)
fprintf(stderr, "\nend-of-file\n");
break;
}
b = malloc(blen);
if (b == NULL) {
perror("malloc:");
exit(1);
}
memset(b, 0, blen);
ret = fread(b, 1, blen, f);
if (ret != blen) {
fprintf(stderr, "short tape block\n");
exit(3);
}
if (fwrite(b, 1, blen, out) != blen) {
fprintf(stderr, "write failed\n");
exit(2);
}
if (rl(f) != blen) {
fprintf(stderr, "non matching end of block marker\n");
exit(3);
}
free(b);
}
}
int main(int argc, char **argv)
{
int i = 0;
int skip = 0;
int s;
FILE *out;
FILE *f;
while (++i < argc) {
f = 0;
skip = 0;
if (strcmp(argv[i], "-h") == 0){
usage();
exit(0);
}
if (strcmp(argv[i], "-v") == 0){
verbose = 1;
continue;
}
if (strcmp(argv[i], "-s") == 0){
if (++i == argc) {
usage();
exit(1);
}
skip = atoi(argv[i++]);
if (skip < 0) {
usage();
exit(1);
}
out = fopen("/dev/null", "w");
f = fopen(argv[i], "r");
if (f == NULL) {
perror(argv[i]);
exit(1);
}
for (s = 0; s < skip; s++)
rblock(f, out);
fclose(out);
}
if (!f) {
f = fopen(argv[i], "r");
if (f == NULL) {
perror(argv[i]);
exit(1);
}
}
rblock(f, stdout);
if (fclose(f) != 0) {
perror(argv[i]);
exit(1);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment