TAPE: Add support for FIXED record size unlabeled tape of binary and text files
This commit is contained in:
parent
e49617cd0c
commit
6908c1e46c
2 changed files with 236 additions and 90 deletions
259
sim_tape.c
259
sim_tape.c
|
@ -113,6 +113,7 @@ static struct sim_tape_fmt {
|
|||
{ "AWS", 0, 0, 0 },
|
||||
{ "TAR", UNIT_RO, 0, 0 },
|
||||
{ "ANSI", UNIT_RO, 0, 0 },
|
||||
{ "FIXED", UNIT_RO, 0, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -441,7 +442,7 @@ typedef struct TAPE_RECORD {
|
|||
uint8 data[1];
|
||||
} TAPE_RECORD;
|
||||
|
||||
typedef struct ANSI_TAPE {
|
||||
typedef struct MEMORY_TAPE {
|
||||
uint32 ansi_type; /* ANSI-VMS, ANSI-RT11, ANSI-RSTS, ANSI-RSX11 */
|
||||
uint32 file_count; /* number of labeled files */
|
||||
uint32 record_count; /* number of entries in the record array */
|
||||
|
@ -449,7 +450,7 @@ typedef struct ANSI_TAPE {
|
|||
uint32 block_size; /* tape block size */
|
||||
TAPE_RECORD **records;
|
||||
VOL1 vol1;
|
||||
} ANSI_TAPE;
|
||||
} MEMORY_TAPE;
|
||||
|
||||
const char HDR3_RMS_STREAM[] = "HDR3020002040000"
|
||||
"0000000100000000"
|
||||
|
@ -507,15 +508,17 @@ static struct ansi_tape_parameters {
|
|||
};
|
||||
|
||||
|
||||
static ANSI_TAPE *ansi_create_tape (const char *label, uint32 block_size, uint32 ansi_type);
|
||||
static int ansi_free_tape (void *vtape);
|
||||
static MEMORY_TAPE *ansi_create_tape (const char *label, uint32 block_size, uint32 ansi_type);
|
||||
static MEMORY_TAPE *memory_create_tape (void);
|
||||
static void memory_free_tape (void *vtape);
|
||||
static void sim_tape_add_ansi_entry (const char *directory,
|
||||
const char *filename,
|
||||
t_offset FileSize,
|
||||
const struct stat *filestat,
|
||||
void *context);
|
||||
static t_bool ansi_tape_add_block (ANSI_TAPE *tape, uint8 *block, uint32 size);
|
||||
static t_bool memory_tape_add_block (MEMORY_TAPE *tape, uint8 *block, uint32 size);
|
||||
static t_stat sim_export_tape (UNIT *uptr, const char *export_file);
|
||||
static int tape_classify_file_contents (FILE *f, size_t *max_record_size, t_bool *lf_line_endings, t_bool *crlf_line_endings);
|
||||
|
||||
|
||||
/* Enable asynchronous operation */
|
||||
|
@ -618,6 +621,7 @@ t_bool auto_format = FALSE;
|
|||
t_bool had_debug = (sim_deb != NULL);
|
||||
uint32 starting_dctrl = uptr->dctrl;
|
||||
int32 saved_switches = sim_switches;
|
||||
MEMORY_TAPE *tape = NULL;
|
||||
|
||||
if ((dptr = find_dev_from_unit (uptr)) == NULL)
|
||||
return SCPE_NOATT;
|
||||
|
@ -644,16 +648,19 @@ else {
|
|||
if ((MT_GET_FMT (uptr) == MTUF_F_TAR) && (uptr->recsize == 0))
|
||||
uptr->recsize = TAR_DFLT_RECSIZE;
|
||||
}
|
||||
if (sim_switches & SWMASK ('X'))
|
||||
cptr = get_glyph_nc (cptr, export_file, 0); /* get spec */
|
||||
if ((MT_GET_FMT (uptr) == MTUF_F_TPC) ||
|
||||
(MT_GET_FMT (uptr) == MTUF_F_TAR) ||
|
||||
(MT_GET_FMT (uptr) == MTUF_F_ANSI))
|
||||
(MT_GET_FMT (uptr) >= MTUF_F_ANSI))
|
||||
sim_switches |= SWMASK ('R'); /* Force ReadOnly attach for TPC, TAR and ANSI tapes */
|
||||
if (sim_switches & SWMASK ('X'))
|
||||
cptr = get_glyph_nc (cptr, export_file, 0); /* get export file spec */
|
||||
if (MT_GET_FMT (uptr) == MTUF_F_ANSI) {
|
||||
switch (MT_GET_FMT (uptr)) {
|
||||
case MTUF_F_ANSI:
|
||||
if (1) {
|
||||
const char *ocptr = cptr;
|
||||
char label[CBUFSIZE] = "simh";
|
||||
ANSI_TAPE *tape;
|
||||
|
||||
if ((MT_GET_ANSI_TYP (uptr) == MTAT_F_RT11) ||
|
||||
(MT_GET_ANSI_TYP (uptr) == MTAT_F_RSX11) ||
|
||||
|
@ -675,7 +682,7 @@ if (MT_GET_FMT (uptr) == MTUF_F_ANSI) {
|
|||
}
|
||||
if (tape->file_count > 0) {
|
||||
r = SCPE_OK;
|
||||
ansi_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
memory_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
uptr->flags |= UNIT_ATT;
|
||||
uptr->filename = (char *)malloc (strlen (ocptr) + 1);
|
||||
strcpy (uptr->filename, ocptr);
|
||||
|
@ -683,14 +690,119 @@ if (MT_GET_FMT (uptr) == MTUF_F_ANSI) {
|
|||
}
|
||||
else {
|
||||
r = SCPE_ARG;
|
||||
ansi_free_tape (uptr->fileref);
|
||||
memory_free_tape (uptr->fileref);
|
||||
uptr->fileref = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MTUF_F_FIXED:
|
||||
if (1) {
|
||||
FILE *f;
|
||||
size_t max_record_size;
|
||||
t_bool lf_line_endings;
|
||||
t_bool crlf_line_endings;
|
||||
uint8 *block = NULL;
|
||||
int error = FALSE;
|
||||
static const uint8 ascii2ebcdic[128] = {
|
||||
0000,0001,0002,0003,0067,0055,0056,0057,
|
||||
0026,0005,0045,0013,0014,0015,0016,0017,
|
||||
0020,0021,0022,0023,0074,0075,0062,0046,
|
||||
0030,0031,0077,0047,0034,0035,0036,0037,
|
||||
0100,0117,0177,0173,0133,0154,0120,0175,
|
||||
0115,0135,0134,0116,0153,0140,0113,0141,
|
||||
0360,0361,0362,0363,0364,0365,0366,0367,
|
||||
0370,0371,0172,0136,0114,0176,0156,0157,
|
||||
0174,0301,0302,0303,0304,0305,0306,0307,
|
||||
0310,0311,0321,0322,0323,0324,0325,0326,
|
||||
0327,0330,0331,0342,0343,0344,0345,0346,
|
||||
0347,0350,0351,0112,0340,0132,0137,0155,
|
||||
0171,0201,0202,0203,0204,0205,0206,0207,
|
||||
0210,0211,0221,0222,0223,0224,0225,0226,
|
||||
0227,0230,0231,0242,0243,0244,0245,0246,
|
||||
0247,0250,0251,0300,0152,0320,0241,0007};
|
||||
|
||||
tape = memory_create_tape ();
|
||||
uptr->fileref = (FILE *)tape;
|
||||
if (!uptr->fileref)
|
||||
return SCPE_MEM;
|
||||
f = fopen (cptr, "rb");
|
||||
if (f == NULL) {
|
||||
r = sim_messagef (SCPE_OPENERR, "Can't open: %s - %s\n", cptr, strerror (errno));
|
||||
break;
|
||||
}
|
||||
tape_classify_file_contents (f, &max_record_size, &lf_line_endings, &crlf_line_endings);
|
||||
if ((!lf_line_endings) && (!crlf_line_endings)) { /* binary file? */
|
||||
if (uptr->recsize == 0) {
|
||||
r = sim_messagef (SCPE_ARG, "Binary file %s must specify a record size with -B\n", cptr);
|
||||
fclose (f);
|
||||
break;
|
||||
}
|
||||
block = (uint8 *)malloc (uptr->recsize);
|
||||
tape->block_size = uptr->recsize;
|
||||
while (!feof(f) && !error) {
|
||||
size_t data_read = fread (block, 1, tape->block_size, f);
|
||||
if (data_read > 0)
|
||||
error = memory_tape_add_block (tape, block, data_read);
|
||||
}
|
||||
}
|
||||
else { /* text file */
|
||||
if (uptr->recsize == 0)
|
||||
uptr->recsize = max_record_size;
|
||||
if (uptr->recsize < max_record_size) {
|
||||
r = sim_messagef (SCPE_ARG, "Text file: %s has lines longer than %d\n", cptr, (int)uptr->recsize);
|
||||
fclose (f);
|
||||
break;
|
||||
}
|
||||
tape->block_size = uptr->recsize;
|
||||
block = (uint8 *)calloc (1, uptr->recsize + 3);
|
||||
while (!feof(f) && !error) {
|
||||
if (fgets ((char *)block, uptr->recsize + 3, f)) {
|
||||
size_t len = strlen ((char *)block);
|
||||
|
||||
while ((len > 0) &&
|
||||
((block[len - 1] == '\r') || (block[len - 1] == '\n')))
|
||||
--len;
|
||||
memset (block + len, ' ', uptr->recsize - len);
|
||||
if (sim_switches & SWMASK ('C')) {
|
||||
uint32 i;
|
||||
|
||||
for (i=0; i<uptr->recsize; i++)
|
||||
block[i] = ascii2ebcdic[block[i]];
|
||||
}
|
||||
error = memory_tape_add_block (tape, block, uptr->recsize);
|
||||
}
|
||||
else
|
||||
error = ferror (f);
|
||||
}
|
||||
}
|
||||
free (block);
|
||||
fclose (f);
|
||||
r = SCPE_OK;
|
||||
memory_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
memory_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
uptr->flags |= UNIT_ATT;
|
||||
uptr->filename = (char *)malloc (strlen (cptr) + 1);
|
||||
strcpy (uptr->filename, cptr);
|
||||
uptr->tape_eom = tape->record_count;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTUF_F_TAR:
|
||||
if (uptr->recsize == 0)
|
||||
uptr->recsize = TAR_DFLT_RECSIZE; /* Apply default block size */
|
||||
/* fall through */
|
||||
default:
|
||||
r = attach_unit (uptr, (CONST char *)cptr); /* attach unit */
|
||||
if (r != SCPE_OK) /* error? */
|
||||
break;
|
||||
}
|
||||
if (r != SCPE_OK) { /* error? */
|
||||
if (auto_format) /* format was specified at attach time? */
|
||||
sim_tape_set_fmt (uptr, 0, "SIMH", NULL); /* restore default format */
|
||||
uptr->recsize = 0;
|
||||
uptr->tape_eom = 0;
|
||||
return sim_messagef (r, "Can't open tape image: %s\n", cptr);
|
||||
}
|
||||
|
||||
if ((sim_switches & SWMASK ('D')) && !had_debug) {
|
||||
sim_switches |= SWMASK ('E');
|
||||
|
@ -777,10 +889,11 @@ if (ctx)
|
|||
sim_tape_clr_async (uptr);
|
||||
|
||||
MT_CLR_INMRK (uptr); /* Not within a TAR tapemark */
|
||||
if (MT_GET_FMT (uptr) == MTUF_F_ANSI) {
|
||||
r = ansi_free_tape ((void *)uptr->fileref);
|
||||
if (MT_GET_FMT (uptr) >= MTUF_F_ANSI) {
|
||||
memory_free_tape ((void *)uptr->fileref);
|
||||
uptr->fileref = NULL;
|
||||
uptr->flags &= ~UNIT_ATT;
|
||||
r = SCPE_OK;
|
||||
}
|
||||
else
|
||||
r = detach_unit (uptr); /* detach unit */
|
||||
|
@ -833,11 +946,13 @@ fprintf (st, " -E Must Exist (if not specified an attempt to create
|
|||
fprintf (st, " virtual tape will be attempted).\n");
|
||||
fprintf (st, " -F Open the indicated tape container in a specific format (default\n");
|
||||
fprintf (st, " is SIMH, alternatives are E11, TPC, P7B, AWS, TAR, ANSI-VMS,\n");
|
||||
fprintf (st, " ANSI-RT11, ANSI-RSX11 or ANSI-RSTS)\n");
|
||||
fprintf (st, " ANSI-RT11, ANSI-RSX11, ANSI-RSTS, FIXED)\n");
|
||||
fprintf (st, " -B For TAR format tapes, the record size for data read from the \n");
|
||||
fprintf (st, " specified file. This record size will be used for all but \n");
|
||||
fprintf (st, " possibly the last record which will be what remains unread.\n");
|
||||
fprintf (st, " The default TAR record size is 10240.\n");
|
||||
fprintf (st, " The default TAR record size is 10240. For FIXED format tapes\n");
|
||||
fprintf (st, " -B specifies the record size for binary data or the maximum \n");
|
||||
fprintf (st, " record size for text data\n");
|
||||
fprintf (st, " -V Display some summary information about the record structure\n");
|
||||
fprintf (st, " contained in the tape image scan performed when it is attached.\n");
|
||||
fprintf (st, " -L Display detailed record size counts observed during attach\n");
|
||||
|
@ -845,6 +960,8 @@ fprintf (st, " validation pass\n");
|
|||
fprintf (st, " contained in the tape image scan performed when it is attached.\n");
|
||||
fprintf (st, " -D Causes the internal tape structure information to be displayed\n");
|
||||
fprintf (st, " while the tape image is scanned.\n");
|
||||
fprintf (st, " -C Causes FIXED format tape data sets derived from text files to be\n");
|
||||
fprintf (st, " converted from ASCII to EBCDIC.\n");
|
||||
fprintf (st, " -X Extract a copy of the attached tape and convert it to a SIMH\n");
|
||||
fprintf (st, " format tape image.\n\n");
|
||||
fprintf (st, "Notes: ANSI-VMS, ANSI-RT11, ANSI-RSTS, ANSI-RSX11 formats allows one or several\n");
|
||||
|
@ -1271,8 +1388,9 @@ switch (f) { /* otherwise the read method
|
|||
break;
|
||||
|
||||
case MTUF_F_ANSI:
|
||||
case MTUF_F_FIXED:
|
||||
if (1) {
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)uptr->fileref;
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)uptr->fileref;
|
||||
|
||||
if (uptr->pos >= tape->record_count)
|
||||
status = MTSE_EOM;
|
||||
|
@ -1605,8 +1723,9 @@ switch (f) { /* otherwise the read me
|
|||
break;
|
||||
|
||||
case MTUF_F_ANSI:
|
||||
case MTUF_F_FIXED:
|
||||
if (1) {
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)uptr->fileref;
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)uptr->fileref;
|
||||
|
||||
--uptr->pos;
|
||||
if (tape->records[uptr->pos]->size == 0)
|
||||
|
@ -1692,7 +1811,7 @@ if (f < MTUF_F_ANSI) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)uptr->fileref;
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)uptr->fileref;
|
||||
|
||||
memcpy (buf, tape->records[uptr->pos - 1]->data, rbc);
|
||||
i = rbc;
|
||||
|
@ -1762,7 +1881,7 @@ if (f < MTUF_F_ANSI) {
|
|||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
else {
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)uptr->fileref;
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)uptr->fileref;
|
||||
|
||||
memcpy (buf, tape->records[uptr->pos]->data, rbc);
|
||||
i = rbc;
|
||||
|
@ -3216,6 +3335,10 @@ sprintf(msgbuf, "Error %d", stat);
|
|||
return msgbuf;
|
||||
}
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
static t_stat sim_tape_validate_tape (UNIT *uptr)
|
||||
{
|
||||
t_addr saved_pos = uptr->pos;
|
||||
|
@ -3285,30 +3408,36 @@ while (r == SCPE_OK) {
|
|||
pos_r = uptr->pos;
|
||||
if (r_r != r_f) {
|
||||
sim_printf ("Forward Record Read returned: %s, Reverse read returned: %s\n", sim_tape_error_text (r_f), sim_tape_error_text (r_r));
|
||||
r = MAX(r_f, r_r);
|
||||
break;
|
||||
}
|
||||
if (bc_f != bc_r) {
|
||||
sim_printf ("Forward Record Read record length: %d, Reverse read record length: %d\n", bc_f, bc_r);
|
||||
r = MTSE_RECE;
|
||||
break;
|
||||
}
|
||||
if (0 != memcmp (buf_f, buf_r, bc_f)) {
|
||||
sim_printf ("%d byte record contents differ when read forward amd backwards start from position %" T_ADDR_FMT "u\n", bc_f, pos_f);
|
||||
r = MTSE_RECE;
|
||||
break;
|
||||
}
|
||||
memset (buf_f, 0, bc_f);
|
||||
memset (buf_r, 0, bc_r);
|
||||
if (pos_f != pos_r) {
|
||||
sim_printf ("Unexpected tape file position between forward and reverse record read: (%" T_ADDR_FMT "u, %" T_ADDR_FMT "u)\n", pos_f, pos_r);
|
||||
r = MTSE_RECE;
|
||||
break;
|
||||
}
|
||||
r_s = sim_tape_sprecf (uptr, &bc_s);
|
||||
pos_sa = uptr->pos;
|
||||
if (r_s != r_f) {
|
||||
sim_printf ("Unexpected Space Record Status: %s vs %s\n", sim_tape_error_text (r_s), sim_tape_error_text (r_f));
|
||||
r = MAX(r_s, r_f);
|
||||
break;
|
||||
}
|
||||
if (bc_s != bc_f) {
|
||||
sim_printf ("Unexpected Space Record Length: %d vs %d\n", bc_s, bc_f);
|
||||
r = MTSE_RECE;
|
||||
break;
|
||||
}
|
||||
if (pos_fa != pos_sa) {
|
||||
|
@ -3789,12 +3918,17 @@ sim_switches = saved_switches;
|
|||
return stat;
|
||||
}
|
||||
|
||||
static t_stat sim_tape_test_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, t_awslnt recsize)
|
||||
{
|
||||
char args[256];
|
||||
char str_recsize[16] = "";
|
||||
t_stat stat;
|
||||
|
||||
sprintf (args, "%s %s.%s", format, filename, format);
|
||||
if (recsize) {
|
||||
sim_switches |= SWMASK ('B');
|
||||
sprintf (str_recsize, " %d", (int)recsize);
|
||||
}
|
||||
sprintf (args, "%s%s %s.%s", format, str_recsize, filename, format);
|
||||
sim_tape_detach (uptr);
|
||||
sim_switches |= SWMASK ('F') | SWMASK ('L'); /* specific-format and detailed record report */
|
||||
stat = sim_tape_attach_ex (uptr, args, 0, 0);
|
||||
|
@ -3888,34 +4022,36 @@ 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_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "aws"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tar", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.3", "aws"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "aws", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.2", "aws"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.3", "aws", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tar"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.2", "aws", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.2", "tar"));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "aws"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1.2", "tar", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "p7b"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "aws", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tpc"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "p7b", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "e11"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "tpc", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "simh"));
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "e11", 0));
|
||||
|
||||
sim_switches = saved_switches;
|
||||
SIM_TEST(sim_tape_test_process_tape_file (dptr->units, "TapeTestFile1", "simh", 0));
|
||||
|
||||
SIM_TEST(sim_tape_test_remove_tape_files (dptr->units, "TapeTestFile1"));
|
||||
|
||||
|
@ -4097,7 +4233,7 @@ static void ansi_fill_text_buffer (FILE *f, char *buf, size_t buf_size, size_t r
|
|||
free (tmp);
|
||||
}
|
||||
|
||||
static t_bool ansi_tape_add_block (ANSI_TAPE *tape, uint8 *block, uint32 size)
|
||||
static t_bool memory_tape_add_block (MEMORY_TAPE *tape, uint8 *block, uint32 size)
|
||||
{
|
||||
TAPE_RECORD *rec;
|
||||
|
||||
|
@ -4119,10 +4255,10 @@ tape->records[tape->record_count++] = rec;
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static int ansi_free_tape (void *vtape)
|
||||
static void memory_free_tape (void *vtape)
|
||||
{
|
||||
uint32 i;
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)vtape;
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)vtape;
|
||||
|
||||
for (i=0; i<tape->record_count; i++) {
|
||||
free (tape->records[i]);
|
||||
|
@ -4130,23 +4266,19 @@ for (i=0; i<tape->record_count; i++) {
|
|||
}
|
||||
free (tape->records);
|
||||
free (tape);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ANSI_TAPE *ansi_create_tape (const char *label, uint32 block_size, uint32 ansi_type)
|
||||
MEMORY_TAPE *memory_create_tape (void)
|
||||
{
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)calloc (1, sizeof (*tape));
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)calloc (1, sizeof (*tape));
|
||||
|
||||
if (NULL == tape)
|
||||
return tape;
|
||||
tape->block_size = block_size;
|
||||
tape->ansi_type = ansi_type;
|
||||
ansi_make_VOL1 (&tape->vol1, label, ansi_type);
|
||||
ansi_tape_add_block (tape, (uint8 *)&tape->vol1, sizeof (tape->vol1));
|
||||
tape->ansi_type = -1;
|
||||
return tape;
|
||||
}
|
||||
|
||||
static int ansi_classify_file_contents (FILE *f, size_t *max_record_size, t_bool *lf_line_endings, t_bool *crlf_line_endings)
|
||||
static int tape_classify_file_contents (FILE *f, size_t *max_record_size, t_bool *lf_line_endings, t_bool *crlf_line_endings)
|
||||
{
|
||||
long pos = -1;
|
||||
long last_cr = -1;
|
||||
|
@ -4202,7 +4334,20 @@ else {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ansi_add_file_to_tape (ANSI_TAPE *tape, const char *filename)
|
||||
MEMORY_TAPE *ansi_create_tape (const char *label, uint32 block_size, uint32 ansi_type)
|
||||
{
|
||||
MEMORY_TAPE *tape = memory_create_tape ();
|
||||
|
||||
if (NULL == tape)
|
||||
return tape;
|
||||
tape->block_size = block_size;
|
||||
tape->ansi_type = ansi_type;
|
||||
ansi_make_VOL1 (&tape->vol1, label, ansi_type);
|
||||
memory_tape_add_block (tape, (uint8 *)&tape->vol1, sizeof (tape->vol1));
|
||||
return tape;
|
||||
}
|
||||
|
||||
static int ansi_add_file_to_tape (MEMORY_TAPE *tape, const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
struct ansi_tape_parameters *ansi = &ansi_args[tape->ansi_type];
|
||||
|
@ -4224,7 +4369,7 @@ if (f == NULL) {
|
|||
fprintf (stderr, "Can't open: %s - %s\n", filename, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
ansi_classify_file_contents (f, &max_record_size, &lf_line_endings, &crlf_line_endings);
|
||||
tape_classify_file_contents (f, &max_record_size, &lf_line_endings, &crlf_line_endings);
|
||||
ansi_make_HDR1 (&hdr1, &tape->vol1, &hdr4, filename, tape->ansi_type);
|
||||
sprintf (file_sequence, "%04d", 1 + tape->file_count);
|
||||
memcpy (hdr1.file_sequence, file_sequence, sizeof (hdr1.file_sequence));
|
||||
|
@ -4242,14 +4387,14 @@ if (!ansi->nohdr3) { /* Need HDR3? */
|
|||
memcpy (&hdr3, ansi->hdr3_crlf_line_endings, sizeof (hdr3));
|
||||
}
|
||||
}
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr1, sizeof (hdr1));
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr1, sizeof (hdr1));
|
||||
if (!ansi->nohdr2)
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr2, sizeof (hdr2));
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr2, sizeof (hdr2));
|
||||
if (!ansi->nohdr3)
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr3, sizeof (hdr3));
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr3, sizeof (hdr3));
|
||||
if ((0 != memcmp (hdr4.extra_name_used, "00", 2)) && !ansi->nohdr3 && !ansi->nohdr2)
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr4, sizeof (hdr4));
|
||||
ansi_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr4, sizeof (hdr4));
|
||||
memory_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
rewind (f);
|
||||
block = (uint8 *)calloc (tape->block_size, 1);
|
||||
while (!feof(f) && !error) {
|
||||
|
@ -4262,27 +4407,27 @@ while (!feof(f) && !error) {
|
|||
else
|
||||
data_read = fread (block, 1, tape->block_size, f);
|
||||
if (data_read > 0)
|
||||
error = ansi_tape_add_block (tape, block, data_read);
|
||||
error = memory_tape_add_block (tape, block, data_read);
|
||||
if (!error)
|
||||
++block_count;
|
||||
}
|
||||
fclose (f);
|
||||
free (block);
|
||||
ansi_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
memory_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
memcpy (hdr1.type, "EOF", sizeof (hdr1.type));
|
||||
memcpy (hdr2.type, "EOF", sizeof (hdr2.type));
|
||||
memcpy (hdr3.type, "EOF", sizeof (hdr3.type));
|
||||
memcpy (hdr4.type, "EOF", sizeof (hdr4.type));
|
||||
sprintf (block_count_string, "%06d", block_count);
|
||||
memcpy (hdr1.block_count, block_count_string, sizeof (hdr1.block_count));
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr1, sizeof (hdr1));
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr1, sizeof (hdr1));
|
||||
if (!ansi->nohdr2)
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr2, sizeof (hdr2));
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr2, sizeof (hdr2));
|
||||
if (!ansi->nohdr3)
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr3, sizeof (hdr3));
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr3, sizeof (hdr3));
|
||||
if ((0 != memcmp (hdr4.extra_name_used, "00", 2)) && !ansi->nohdr3 && !ansi->nohdr2)
|
||||
ansi_tape_add_block (tape, (uint8 *)&hdr4, sizeof (hdr4));
|
||||
ansi_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
memory_tape_add_block (tape, (uint8 *)&hdr4, sizeof (hdr4));
|
||||
memory_tape_add_block (tape, NULL, 0); /* Tape Mark */
|
||||
if (sim_switches & SWMASK ('V'))
|
||||
sim_messagef (SCPE_OK, "%17.17s%62.62s\n\t%d blocks of data\n", hdr1.file_ident, hdr4.extra_name, block_count);
|
||||
++tape->file_count;
|
||||
|
@ -4295,7 +4440,7 @@ static void sim_tape_add_ansi_entry (const char *directory,
|
|||
const struct stat *filestat,
|
||||
void *context)
|
||||
{
|
||||
ANSI_TAPE *tape = (ANSI_TAPE *)context;
|
||||
MEMORY_TAPE *tape = (MEMORY_TAPE *)context;
|
||||
char FullPath[PATH_MAX + 1];
|
||||
|
||||
sprintf (FullPath, "%s%s", directory, filename);
|
||||
|
|
|
@ -99,6 +99,7 @@ typedef struct {
|
|||
#define MTUF_F_AWS 4 /* AWS format */
|
||||
#define MTUF_F_TAR 5 /* TAR format */
|
||||
#define MTUF_F_ANSI 6 /* ANSI format */
|
||||
#define MTUF_F_FIXED 7 /* FIXED format */
|
||||
|
||||
#define MTAT_F_VMS 0 /* VMS ANSI type */
|
||||
#define MTAT_F_RSX11 1 /* RSX-11 ANSI type */
|
||||
|
|
Loading…
Add table
Reference in a new issue