Files
open-simh.simtools/extracters/tpdump/tpdump.c
Timothe Litt 2d7f74e9ff Add Makefiles, fix some compile errors
There are more compile errors, especially in the cross-assemblers.
But I'm leaving those for someone else.
2015-05-26 17:42:36 -04:00

185 lines
6.4 KiB
C

/* Dump tapes in the format of the simh 1401 simulator.
See "usage" function below.
*/
#include <stdio.h>
/* From i1401_dat.h: */
char bcd_to_ascii_old[64] = {
' ', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', '#', '@', ':', '>', '(',
'^', '/', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '\'', ',', '%', '=', '\\', '+',
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', '!', '$', '*', ']', ';', '_',
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', '?', '.', ')', '[', '<', '"'
};
char bcd_to_ascii_a[64] = {
' ', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', '#', '@', ':', '>', '{',
'^', '/', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '|', ',', '%', '~', '\\', '"',
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', '!', '$', '*', ']', ';', '_',
'&', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', '?', '.', ')', '[', '<', '}'
};
char bcd_to_ascii_h[64] = {
' ', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '0', '=', '\'', ':', '>', '{',
'^', '/', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '|', ',', '(', '~', '\\', '"',
'-', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', '!', '$', '*', ']', ';', '_',
'+', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', '?', '.', ')', '[', '<', '}'
};
/* Interesting BCD characters, from i1401_defs.h */
#define BCD_BLANK 000
#define BCD_ALT 020
#define BCD_WM 035
size_t read_len ( FILE* fi )
/* Read a little-endian four-byte number */
{ unsigned char c; /* A Character from the file */
size_t i;
size_t n; /* the number */
if ( fread ( &c, 1, 1, fi ) == 0 )
return (0);
n = c; i = 256;
if ( fread ( &c, 1, 1, fi ) == 0 )
return (0);
n += i*c;
i *= 256;
if ( fread ( &c, 1, 1, fi ) == 0 )
return (0);
n += i*c;
i *= 256;
if ( fread ( &c, 1, 1, fi ) == 0 )
return (0);
n += i*c;
i *= 256;
return (n);
}
void usage ( char* argv[] )
{ printf ( "Usage: %s [options] <input_file>\n", argv[0] );
printf ( " Options: -w to print word marks on a separate line)\n" );
printf ( " -# number of 'files' to print (default 1)\n");
printf ( " -a print all of each record, including blank lines,\n");
printf ( " which are otherwise suppressed (except for the last one)\n");
printf ( " -e E11 format, i.e., don't require even-length records\n" );
printf ( " -h Use the H (Fortran) print arrangement\n");
printf ( " -o Use the 'old simh' print arrangement\n");
}
int main ( int argc, char* argv[] )
{ FILE* fi;
int all; /* "print all of a record, even blank lines" */
char* bcd_to_ascii; /* Translation table, ..._a or ..._h */
int cl; /* Command line argument index */
int dowm; /* "do word marks" */
int even; /* Require even-length records */
int i, j; /* Subscript, loop inductor */
int nb; /* Number of characters in print buffer so far */
int nf, nft; /* Number of "files" */
int np; /* Number of characters processed so far */
int nr; /* Number of records dumped so far */
char pr[101]; /* Buffer to print tape contents */
size_t recsiz, recsiz2; /* Record size before, after */
char wm[101]; /* Buffer to print word marks */
if ( argc < 2 )
{ usage( argv );
return(1);
}
all = 0;
bcd_to_ascii = bcd_to_ascii_a;
dowm = 0;
even = 1;
nf = 1;
for ( cl=1; cl<=argc; cl++ )
{ if ( argv[cl][0] != '-' ) break;
if ( argv[cl][1] == 'w' ) dowm = 1;
else if ( argv[cl][1] == 'a' ) all = 1;
else if ( argv[cl][1] == 'e' ) even = 0;
else if ( argv[cl][1] == 'h' ) bcd_to_ascii = bcd_to_ascii_h;
else if ( argv[cl][1] == 'o' ) bcd_to_ascii = bcd_to_ascii_old;
else if ( sscanf(argv[cl], "%d", &nft ) ) nf = -nft;
else
{ usage ( argv );
return(1);
}
}
fi = fopen ( argv[cl], "r" );
if ( fi == NULL )
{ printf ( "Unable to open %s\n", argv[cl] );
return(2);
}
bcd_to_ascii[BCD_BLANK] = bcd_to_ascii[BCD_ALT]; /* use '^' for blank */
nft = 1;
if ( nf > 1 ) printf ( "File %d\n", nft );
while ( nf > 0 )
{ nf--;
for ( np=0; np<100; pr[np++]='.' );
pr[100] = '\0';
for ( np=5; np<=100; np+=5 ) /* Print a row of dots and column numbers */
for ( nb=1, i=np; i>0; i/=10, nb++ ) pr[np-nb] = '0' + ( i%10 );
printf ( " %s\n", pr );
nr = 0;
while ( (recsiz = read_len ( fi )) )
{ nb = 1;
nr++;
i = recsiz;
while ( i )
{ for ( np=0; np<101; pr[np]='^',wm[np++]=' ') ; /* Clear buffers */
for ( np=0; i>0 && np<100; np++ )
{ if ( fread ( &pr[np], 1, 1, fi ) <= 0 )
{ printf ( "Error reading %s\n", argv[cl] );
return(3);
}
i--;
pr[np] = bcd_to_ascii[(unsigned int)pr[np]];
if ( dowm )
if ( pr[np] == bcd_to_ascii[BCD_WM] ) wm[np--] = '1';
}
for ( j=np--; j>=0 && pr[j] == bcd_to_ascii[BCD_ALT] &&
wm[j] == ' '; j-- ) ;
if ( ( j >= 0 ) || ( nb == 1 ) || all || ( i == 0 ) )
{ printf ( "%5d: ", nb );
pr[np+1] = '\0';
printf ( "%s", pr );
if ( nb == 1 )
{ for ( j=np ; j++<100 ; printf ( " " ) ) ;
printf ( " Record %d", nr );
}
printf ( "\n" );
if ( dowm )
{ for ( ; np >= 0 && wm[np] == ' '; np-- );
wm[++np] = '\0';
printf ( " %s\n", wm );
}
}
nb += 100;
}
if ( (recsiz & 1) && even ) fread ( pr, 1, 1, fi );
recsiz2 = read_len ( fi );
if ( recsiz2 != recsiz )
{ printf("Unequal starting and ending record sizes: %d != %d\n",
recsiz, recsiz2);
return(4);
}
}
if ( nf > 0 ) printf ( "File %d\n", ++nft );
}
return(0);
}