TAPE: Reworked reverse read of P7B tapes to avoid seeking on every byte
- Added string density support for MTAB generation
This commit is contained in:
parent
64fa357bf9
commit
436f1dbbbe
2 changed files with 125 additions and 34 deletions
158
sim_tape.c
158
sim_tape.c
|
@ -102,7 +102,7 @@
|
||||||
|
|
||||||
struct sim_tape_fmt {
|
struct sim_tape_fmt {
|
||||||
const char *name; /* name */
|
const char *name; /* name */
|
||||||
int32 uflags; /* unit flags */
|
int32 uflags; /* unit flags */
|
||||||
t_addr bot; /* bot test */
|
t_addr bot; /* bot test */
|
||||||
t_addr eom_remnant; /* potentially unprocessed data */
|
t_addr eom_remnant; /* potentially unprocessed data */
|
||||||
};
|
};
|
||||||
|
@ -1194,34 +1194,50 @@ else switch (f) { /* otherwise the read me
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MTUF_F_P7B:
|
case MTUF_F_P7B:
|
||||||
for (sbc = 1, all_eof = 1; (t_addr) sbc <= uptr->pos ; sbc++) {
|
if (1) {
|
||||||
(void)sim_fseek (uptr->fileref, uptr->pos - sbc, SEEK_SET);
|
#define BUF_SZ 512
|
||||||
(void)sim_fread (&c, sizeof (uint8), 1, uptr->fileref);
|
uint8 buf[BUF_SZ];
|
||||||
|
t_addr buf_offset;
|
||||||
|
size_t bytes_in_buf = 0;
|
||||||
|
size_t read_size;
|
||||||
|
|
||||||
if (ferror (uptr->fileref)) { /* error? */
|
for (sbc = 1, all_eof = 1; (t_addr) sbc <= uptr->pos ; sbc++) {
|
||||||
status = sim_tape_ioerr (uptr);
|
if (bytes_in_buf == 0) { /* Need to Fill Buffer */
|
||||||
break;
|
if (uptr->pos < BUF_SZ) {
|
||||||
}
|
buf_offset = 0;
|
||||||
else if (feof (uptr->fileref)) { /* eof? */
|
read_size = (size_t)uptr->pos;
|
||||||
status = MTSE_EOM;
|
}
|
||||||
break;
|
else {
|
||||||
}
|
buf_offset = uptr->pos - (sbc - 1 + BUF_SZ);
|
||||||
else {
|
read_size = BUF_SZ;
|
||||||
|
}
|
||||||
|
(void)sim_fseek (uptr->fileref, buf_offset, SEEK_SET);
|
||||||
|
bytes_in_buf = sim_fread (buf, sizeof (uint8), read_size, uptr->fileref);
|
||||||
|
if (ferror (uptr->fileref)) { /* error? */
|
||||||
|
status = sim_tape_ioerr (uptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (feof (uptr->fileref)) { /* eof? */
|
||||||
|
status = MTSE_EOM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = buf[--bytes_in_buf];
|
||||||
if ((c & P7B_DPAR) != P7B_EOF)
|
if ((c & P7B_DPAR) != P7B_EOF)
|
||||||
all_eof = 0;
|
all_eof = 0;
|
||||||
if (c & P7B_SOR) /* start of record? */
|
if (c & P7B_SOR) /* start of record? */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (status == MTSE_OK) {
|
if (status == MTSE_OK) {
|
||||||
uptr->pos = uptr->pos - sbc; /* update position */
|
uptr->pos = uptr->pos - sbc; /* update position */
|
||||||
*bc = sbc; /* save rec lnt */
|
*bc = sbc; /* save rec lnt */
|
||||||
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for next read */
|
(void)sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for next read */
|
||||||
if (all_eof) /* tape mark? */
|
if (all_eof) /* tape mark? */
|
||||||
status = MTSE_TMK;
|
status = MTSE_TMK;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case MTUF_F_AWS:
|
case MTUF_F_AWS:
|
||||||
*bc = sbc = 0;
|
*bc = sbc = 0;
|
||||||
|
@ -2883,6 +2899,7 @@ if (rec_sizes == NULL) {
|
||||||
r = sim_tape_rewind (uptr);
|
r = sim_tape_rewind (uptr);
|
||||||
while (r == SCPE_OK) {
|
while (r == SCPE_OK) {
|
||||||
pos_f = uptr->pos;
|
pos_f = uptr->pos;
|
||||||
|
memset (buf_f, 0, max);
|
||||||
r_f = sim_tape_rdrecf (uptr, buf_f, &bc_f, max);
|
r_f = sim_tape_rdrecf (uptr, buf_f, &bc_f, max);
|
||||||
switch (r_f) {
|
switch (r_f) {
|
||||||
case MTSE_OK: /* no error */
|
case MTSE_OK: /* no error */
|
||||||
|
@ -2897,6 +2914,7 @@ while (r == SCPE_OK) {
|
||||||
++unique_record_sizes;
|
++unique_record_sizes;
|
||||||
++rec_sizes[bc_f];
|
++rec_sizes[bc_f];
|
||||||
}
|
}
|
||||||
|
memset (buf_r, 0, max);
|
||||||
r_r = sim_tape_rdrecr (uptr, buf_r, &bc_r, max);
|
r_r = sim_tape_rdrecr (uptr, buf_r, &bc_r, max);
|
||||||
pos_r = uptr->pos;
|
pos_r = uptr->pos;
|
||||||
if (r_r != r_f) {
|
if (r_r != r_f) {
|
||||||
|
@ -2904,7 +2922,7 @@ while (r == SCPE_OK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bc_f != bc_r) {
|
if (bc_f != bc_r) {
|
||||||
sim_printf ("Forward Record Read record lemgtj: %d, Reverse read record length: %d\n", bc_f, bc_r);
|
sim_printf ("Forward Record Read record length: %d, Reverse read record length: %d\n", bc_f, bc_r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (0 != memcmp (buf_f, buf_r, bc_f)) {
|
if (0 != memcmp (buf_f, buf_r, bc_f)) {
|
||||||
|
@ -2965,7 +2983,6 @@ if ((r != MTSE_EOM) || (sim_switches & SWMASK ('V')) ||
|
||||||
if (remaining_data > fmts[MT_GET_FMT (uptr)].eom_remnant)
|
if (remaining_data > fmts[MT_GET_FMT (uptr)].eom_remnant)
|
||||||
sim_printf ("%u bytes of unexamined data remain in the tape image file\n", remaining_data);
|
sim_printf ("%u bytes of unexamined data remain in the tape image file\n", remaining_data);
|
||||||
}
|
}
|
||||||
/* Try again reading backwards */
|
|
||||||
if (unique_record_sizes > 2 * tapemark_total) {
|
if (unique_record_sizes > 2 * tapemark_total) {
|
||||||
sim_printf ("An unreasonable number of record sizes(%u) vs tape marks (%u) have been found\n", unique_record_sizes, tapemark_total);
|
sim_printf ("An unreasonable number of record sizes(%u) vs tape marks (%u) have been found\n", unique_record_sizes, tapemark_total);
|
||||||
sim_printf ("The tape format (%s) might not be correct for the '%s' tape image\n", fmts[MT_GET_FMT (uptr)].name, uptr->filename);
|
sim_printf ("The tape format (%s) might not be correct for the '%s' tape image\n", fmts[MT_GET_FMT (uptr)].name, uptr->filename);
|
||||||
|
@ -3116,6 +3133,45 @@ else { /* otherwise get the den
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* list supported densities
|
||||||
|
|
||||||
|
translates the mask of supported densities to a string list in the form:
|
||||||
|
|
||||||
|
"(800|1600|6250)"
|
||||||
|
|
||||||
|
this string may be useful to construct a MTAB help string for a
|
||||||
|
SET <unit> DENSITY= command.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
t_stat sim_tape_density_supported (char *string, size_t string_size, int32 valid_bits)
|
||||||
|
{
|
||||||
|
uint32 density;
|
||||||
|
int32 count;
|
||||||
|
|
||||||
|
strlcpy (string, "", string_size);
|
||||||
|
if ((!valid_bits) || (valid_bits >> BPI_COUNT))
|
||||||
|
return SCPE_ARG;
|
||||||
|
for (density = count = 0; density < BPI_COUNT; density++) {
|
||||||
|
if (valid_bits & (1 << density)) {
|
||||||
|
char density_str[20];
|
||||||
|
|
||||||
|
++count;
|
||||||
|
if (count == 1)
|
||||||
|
strlcat (string, "{", string_size);
|
||||||
|
else
|
||||||
|
strlcat (string, "|", string_size);
|
||||||
|
sprintf (density_str, "%d", bpi[density]);
|
||||||
|
strlcat (string, density_str, string_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((count == 1) && (string_size > 1))
|
||||||
|
memmove (string, string + 1, strlen (string));
|
||||||
|
else
|
||||||
|
strlcat (string, "}", string_size);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static DEBTAB tape_debug[] = {
|
static DEBTAB tape_debug[] = {
|
||||||
{"TRACE", MTSE_DBG_API, "API Trace"},
|
{"TRACE", MTSE_DBG_API, "API Trace"},
|
||||||
{"DATA", MTSE_DBG_DAT, "Tape Data"},
|
{"DATA", MTSE_DBG_DAT, "Tape Data"},
|
||||||
|
@ -3135,7 +3191,7 @@ static t_bool p7b_parity_inited = FALSE;
|
||||||
static uint8 p7b_odd_parity[64];
|
static uint8 p7b_odd_parity[64];
|
||||||
static uint8 p7b_even_parity[64];
|
static uint8 p7b_even_parity[64];
|
||||||
|
|
||||||
static t_stat create_tape_files (UNIT *uptr, const char *filename, int files, int records, int max_size)
|
static t_stat sim_tape_test_create_tape_files (UNIT *uptr, const char *filename, int files, int records, int max_size)
|
||||||
{
|
{
|
||||||
FILE *fSIMH = NULL;
|
FILE *fSIMH = NULL;
|
||||||
FILE *fE11 = NULL;
|
FILE *fE11 = NULL;
|
||||||
|
@ -3293,7 +3349,7 @@ sim_switches = saved_switches;
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat process_tape_file (UNIT *uptr, const char *filename, const char *format)
|
static t_stat sim_tape_test_process_tape_file (UNIT *uptr, const char *filename, const char *format)
|
||||||
{
|
{
|
||||||
char args[256];
|
char args[256];
|
||||||
t_stat stat;
|
t_stat stat;
|
||||||
|
@ -3309,7 +3365,7 @@ sim_switches = 0;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat remove_tape_files (UNIT *uptr, const char *filename)
|
static t_stat sim_tape_test_remove_tape_files (UNIT *uptr, const char *filename)
|
||||||
{
|
{
|
||||||
char name[256];
|
char name[256];
|
||||||
|
|
||||||
|
@ -3326,6 +3382,38 @@ sprintf (name, "%s.aws", filename);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static t_stat sim_tape_test_density_string (void)
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
int32 valid_bits = 0;
|
||||||
|
t_stat stat;
|
||||||
|
|
||||||
|
if ((SCPE_ARG != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||||
|
(strcmp (buf, "")))
|
||||||
|
return stat;
|
||||||
|
valid_bits = MT_556_VALID;
|
||||||
|
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||||
|
(strcmp (buf, "556")))
|
||||||
|
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||||
|
valid_bits = MT_800_VALID | MT_1600_VALID;
|
||||||
|
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||||
|
(strcmp (buf, "{800|1600}")))
|
||||||
|
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||||
|
valid_bits = MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
|
||||||
|
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||||
|
(strcmp (buf, "{800|1600|6250}")))
|
||||||
|
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||||
|
valid_bits = MT_200_VALID | MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
|
||||||
|
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||||
|
(strcmp (buf, "{200|800|1600|6250}")))
|
||||||
|
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||||
|
valid_bits = MT_NONE_VALID | MT_800_VALID | MT_1600_VALID | MT_6250_VALID;
|
||||||
|
if ((SCPE_OK != (stat = sim_tape_density_supported (buf, sizeof (buf), valid_bits))) ||
|
||||||
|
(strcmp (buf, "{0|800|1600|6250}")))
|
||||||
|
return sim_messagef (SCPE_ARG, "stat was: %s, got string: %s\n", sim_error_text (stat), buf);
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
t_stat sim_tape_test (DEVICE *dptr)
|
t_stat sim_tape_test (DEVICE *dptr)
|
||||||
|
@ -3335,26 +3423,28 @@ SIM_TEST_INIT;
|
||||||
|
|
||||||
sim_printf ("\nTesting %s device sim_tape APIs\n", sim_uname(dptr->units));
|
sim_printf ("\nTesting %s device sim_tape APIs\n", sim_uname(dptr->units));
|
||||||
|
|
||||||
SIM_TEST(remove_tape_files (dptr->units, "TapeTestFile1"));
|
SIM_TEST(sim_tape_test_density_string ());
|
||||||
|
|
||||||
SIM_TEST(create_tape_files (dptr->units, "TapeTestFile1", 2, 4, 4096));
|
SIM_TEST(sim_tape_test_remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||||
|
|
||||||
|
SIM_TEST(sim_tape_test_create_tape_files (dptr->units, "TapeTestFile1", 2, 5, 4096));
|
||||||
|
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "aws"));
|
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "aws"));
|
||||||
|
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "p7b"));
|
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "p7b"));
|
||||||
|
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "tpc"));
|
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tpc"));
|
||||||
|
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "e11"));
|
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "e11"));
|
||||||
|
|
||||||
sim_switches = saved_switches;
|
sim_switches = saved_switches;
|
||||||
SIM_TEST(process_tape_file (dptr->units, "TapeTestFile1", "simh"));
|
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "simh"));
|
||||||
|
|
||||||
SIM_TEST(remove_tape_files (dptr->units, "TapeTestFile1"));
|
SIM_TEST(sim_tape_test_remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||||
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,6 +224,7 @@ t_stat sim_tape_set_capac (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||||
t_stat sim_tape_show_capac (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
t_stat sim_tape_show_capac (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
t_stat sim_tape_set_dens (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
t_stat sim_tape_set_dens (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||||
t_stat sim_tape_show_dens (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
t_stat sim_tape_show_dens (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||||
|
t_stat sim_tape_density_supported (char *string, size_t string_size, int32 valid_bits);
|
||||||
t_stat sim_tape_set_asynch (UNIT *uptr, int latency);
|
t_stat sim_tape_set_asynch (UNIT *uptr, int latency);
|
||||||
t_stat sim_tape_clr_asynch (UNIT *uptr);
|
t_stat sim_tape_clr_asynch (UNIT *uptr);
|
||||||
t_stat sim_tape_test (DEVICE *dptr);
|
t_stat sim_tape_test (DEVICE *dptr);
|
||||||
|
|
Loading…
Add table
Reference in a new issue