mirror of
https://github.com/open-simh/simh.git
synced 2026-05-03 22:58:53 +00:00
Notes For V3.5-0
The source set has been extensively overhauled. For correct viewing, set Visual C++ or Emacs to have tab stops every 4 characters. 1. New Features in 3.4-1 1.1 All Ethernet devices - Added Windows user-defined adapter names (from Timothe Litt) 1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors - Added support for SET <unit>n DISCONNECT 1.3 VAX - Added latent QDSS support - Revised autoconfigure to handle QDSS 1.4 PDP-11 - Revised autoconfigure to handle more casees 2. Bugs Fixed in 3.4-1 2.1 SCP and libraries - Trim trailing spaces on all input (for example, attach file names) - Fixed sim_sock spurious SIGPIPE error in Unix/Linux - Fixed sim_tape misallocation of TPC map array for 64b simulators 2.2 1401 - Fixed bug, CPU reset was clearing SSB through SSG 2.3 PDP-11 - Fixed bug in VH vector display routine - Fixed XU runt packet processing (found by Tim Chapman) 2.4 Interdata - Fixed bug in SHOW PAS CONN/STATS - Fixed potential integer overflow exception in divide 2.5 SDS - Fixed bug in SHOW MUX CONN/STATS 2.6 HP - Fixed bug in SHOW MUX CONN/STATS 2.7 PDP-8 - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.8 PDP-18b - Fixed bug in SHOW TTIX CONN/STATS - Fixed bug in SET/SHOW TTOXn LOG 2.9 Nova, Eclipse - Fixed potential integer overflow exception in divide
This commit is contained in:
committed by
Mark Pizzolato
parent
ec60bbf329
commit
b7c1eae41f
547
sim_tape.c
547
sim_tape.c
@@ -1,6 +1,6 @@
|
||||
/* sim_tape.c: simulator tape support library
|
||||
|
||||
Copyright (c) 1993-2004, Robert M Supnik
|
||||
Copyright (c) 1993-2005, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -19,55 +19,58 @@
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
Ultimately, this will be a place to hide processing of various tape formats,
|
||||
as well as OS-specific direct hardware access.
|
||||
|
||||
28-Jul-04 RMS Fixed bug in writing error records (found by Dave Bryan)
|
||||
RMS Fixed incorrect error codes (found by Dave Bryan)
|
||||
05-Jan-04 RMS Revised for file I/O library
|
||||
25-Apr-03 RMS Added extended file support
|
||||
28-Mar-03 RMS Added E11 and TPC format support
|
||||
16-Aug-05 RMS Fixed C++ declaration and cast problems
|
||||
02-May-05 RMS Added support for Pierce 7b format
|
||||
28-Jul-04 RMS Fixed bug in writing error records (found by Dave Bryan)
|
||||
RMS Fixed incorrect error codes (found by Dave Bryan)
|
||||
05-Jan-04 RMS Revised for file I/O library
|
||||
25-Apr-03 RMS Added extended file support
|
||||
28-Mar-03 RMS Added E11 and TPC format support
|
||||
|
||||
Public routines:
|
||||
|
||||
sim_tape_attach attach tape unit
|
||||
sim_tape_detach detach tape unit
|
||||
sim_tape_rdrecf read tape record forward
|
||||
sim_tape_rdrecr read tape record reverse
|
||||
sim_tape_wrrecf write tape record forward
|
||||
sim_tape_sprecf space tape record forward
|
||||
sim_tape_sprecr space tape record reverse
|
||||
sim_tape_wrtmk write tape mark
|
||||
sim_tape_wreom erase remainder of tape
|
||||
sim_tape_rewind rewind
|
||||
sim_tape_reset reset unit
|
||||
sim_tape_bot TRUE if at beginning of tape
|
||||
sim_tape_eot TRUE if at or beyond end of tape
|
||||
sim_tape_wrp TRUE if write protected
|
||||
sim_tape_set_fmt set tape format
|
||||
sim_tape_show_fmt show tape format
|
||||
sim_tape_attach attach tape unit
|
||||
sim_tape_detach detach tape unit
|
||||
sim_tape_rdrecf read tape record forward
|
||||
sim_tape_rdrecr read tape record reverse
|
||||
sim_tape_wrrecf write tape record forward
|
||||
sim_tape_sprecf space tape record forward
|
||||
sim_tape_sprecr space tape record reverse
|
||||
sim_tape_wrtmk write tape mark
|
||||
sim_tape_wreom erase remainder of tape
|
||||
sim_tape_rewind rewind
|
||||
sim_tape_reset reset unit
|
||||
sim_tape_bot TRUE if at beginning of tape
|
||||
sim_tape_eot TRUE if at or beyond end of tape
|
||||
sim_tape_wrp TRUE if write protected
|
||||
sim_tape_set_fmt set tape format
|
||||
sim_tape_show_fmt show tape format
|
||||
*/
|
||||
|
||||
#include "sim_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
struct sim_tape_fmt {
|
||||
char *name; /* name */
|
||||
int32 uflags; /* unit flags */
|
||||
t_addr bot; /* bot test */
|
||||
};
|
||||
char *name; /* name */
|
||||
int32 uflags; /* unit flags */
|
||||
t_addr bot; /* bot test */
|
||||
};
|
||||
|
||||
static struct sim_tape_fmt fmts[MTUF_N_FMT] = {
|
||||
{ "SIMH", 0, sizeof (t_mtrlnt) - 1 },
|
||||
{ "E11", 0, sizeof (t_mtrlnt) - 1 },
|
||||
{ "TPC", UNIT_RO, sizeof (t_tpclnt) - 1 },
|
||||
/* { "TPF", UNIT_RO, 0 }, */
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
{ "SIMH", 0, sizeof (t_mtrlnt) - 1 },
|
||||
{ "E11", 0, sizeof (t_mtrlnt) - 1 },
|
||||
{ "TPC", UNIT_RO, sizeof (t_tpclnt) - 1 },
|
||||
{ "P7B", UNIT_RO, 0 },
|
||||
/* { "TPF", UNIT_RO, 0 }, */
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
extern int32 sim_switches;
|
||||
|
||||
@@ -84,29 +87,34 @@ uint32 objc;
|
||||
char gbuf[CBUFSIZE];
|
||||
t_stat r;
|
||||
|
||||
if (sim_switches & SWMASK ('F')) { /* format spec? */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
||||
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
||||
if (sim_tape_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK)
|
||||
return SCPE_ARG; }
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
if (sim_switches & SWMASK ('F')) { /* format spec? */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get spec */
|
||||
if (*cptr == 0) return SCPE_2FARG; /* must be more */
|
||||
if (sim_tape_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK)
|
||||
return SCPE_ARG;
|
||||
}
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
switch (MT_GET_FMT (uptr)) { /* case on format */
|
||||
|
||||
switch (MT_GET_FMT (uptr)) { /* case on format */
|
||||
case MTUF_F_TPC: /* TPC */
|
||||
objc = sim_tape_tpc_map (uptr, NULL); /* get # objects */
|
||||
if (objc == 0) { /* tape empty? */
|
||||
sim_tape_detach (uptr);
|
||||
return SCPE_FMT; } /* yes, complain */
|
||||
uptr->filebuf = calloc (objc + 1, sizeof (t_mtrlnt));
|
||||
if (uptr->filebuf == NULL) { /* map allocated? */
|
||||
sim_tape_detach (uptr);
|
||||
return SCPE_MEM; } /* no, complain */
|
||||
uptr->hwmark = objc + 1; /* save map size */
|
||||
sim_tape_tpc_map (uptr, uptr->filebuf); /* fill map */
|
||||
break;
|
||||
default:
|
||||
break; }
|
||||
case MTUF_F_TPC: /* TPC */
|
||||
objc = sim_tape_tpc_map (uptr, NULL); /* get # objects */
|
||||
if (objc == 0) { /* tape empty? */
|
||||
sim_tape_detach (uptr);
|
||||
return SCPE_FMT; /* yes, complain */
|
||||
}
|
||||
uptr->filebuf = calloc (objc + 1, sizeof (t_addr));
|
||||
if (uptr->filebuf == NULL) { /* map allocated? */
|
||||
sim_tape_detach (uptr);
|
||||
return SCPE_MEM; /* no, complain */
|
||||
}
|
||||
uptr->hwmark = objc + 1; /* save map size */
|
||||
sim_tape_tpc_map (uptr, (t_addr *) uptr->filebuf); /* fill map */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sim_tape_rewind (uptr);
|
||||
return SCPE_OK;
|
||||
@@ -119,17 +127,19 @@ t_stat sim_tape_detach (UNIT *uptr)
|
||||
uint32 f = MT_GET_FMT (uptr);
|
||||
t_stat r;
|
||||
|
||||
r = detach_unit (uptr); /* detach unit */
|
||||
r = detach_unit (uptr); /* detach unit */
|
||||
if (r != SCPE_OK) return r;
|
||||
switch (f) { /* case on format */
|
||||
|
||||
switch (f) { /* case on format */
|
||||
case MTUF_F_TPC: /* TPC */
|
||||
if (uptr->filebuf) free (uptr->filebuf); /* free map */
|
||||
uptr->filebuf = NULL;
|
||||
uptr->hwmark = 0;
|
||||
break;
|
||||
default:
|
||||
break; }
|
||||
case MTUF_F_TPC: /* TPC */
|
||||
if (uptr->filebuf) free (uptr->filebuf); /* free map */
|
||||
uptr->filebuf = NULL;
|
||||
uptr->hwmark = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
sim_tape_rewind (uptr);
|
||||
return SCPE_OK;
|
||||
@@ -138,62 +148,89 @@ return SCPE_OK;
|
||||
/* Read record length forward (internal routine)
|
||||
|
||||
Inputs:
|
||||
uptr = pointer to tape unit
|
||||
bc = pointer to returned record length
|
||||
uptr = pointer to tape unit
|
||||
bc = pointer to returned record length
|
||||
Outputs:
|
||||
status = operation status
|
||||
status = operation status
|
||||
|
||||
exit condition position
|
||||
exit condition position
|
||||
|
||||
unit unattached unchanged
|
||||
read error unchanged, PNU set
|
||||
end of file/medium unchanged, PNU set
|
||||
tape mark updated
|
||||
data record updated, sim_fread will read record forward
|
||||
unit unattached unchanged
|
||||
read error unchanged, PNU set
|
||||
end of file/medium unchanged, PNU set
|
||||
tape mark updated
|
||||
data record updated, sim_fread will read record forward
|
||||
*/
|
||||
|
||||
t_stat sim_tape_rdlntf (UNIT *uptr, t_mtrlnt *bc)
|
||||
{
|
||||
uint8 c;
|
||||
t_bool all_eof;
|
||||
uint32 f = MT_GET_FMT (uptr);
|
||||
t_mtrlnt sbc;
|
||||
t_tpclnt tpcbc;
|
||||
|
||||
MT_CLR_PNU (uptr);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set tape pos */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set tape pos */
|
||||
switch (f) { /* switch on fmt */
|
||||
|
||||
switch (f) { /* switch on fmt */
|
||||
case MTUF_F_STD: case MTUF_F_E11:
|
||||
sim_fread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */
|
||||
sbc = MTR_L (*bc); /* save rec lnt */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return sim_tape_ioerr (uptr); }
|
||||
if (feof (uptr->fileref) || (*bc == MTR_EOM)) { /* eof or eom? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return MTSE_EOM; }
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* spc over rec lnt */
|
||||
if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt) + /* spc over record */
|
||||
((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc);
|
||||
break;
|
||||
case MTUF_F_STD: case MTUF_F_E11:
|
||||
sim_fread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */
|
||||
sbc = MTR_L (*bc); /* save rec lnt */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
if (feof (uptr->fileref) || (*bc == MTR_EOM)) { /* eof or eom? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return MTSE_EOM;
|
||||
}
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* spc over rec lnt */
|
||||
if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt) + /* spc over record */
|
||||
((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc);
|
||||
break;
|
||||
|
||||
case MTUF_F_TPC:
|
||||
sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
*bc = tpcbc; /* save rec lnt */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return sim_tape_ioerr (uptr); }
|
||||
if (feof (uptr->fileref)) { /* eof? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return MTSE_EOM; }
|
||||
uptr->pos = uptr->pos + sizeof (t_tpclnt); /* spc over reclnt */
|
||||
if (tpcbc == TPC_TMK) return MTSE_TMK; /* tape mark? */
|
||||
uptr->pos = uptr->pos + ((tpcbc + 1) & ~1); /* spc over record */
|
||||
break;
|
||||
case MTUF_F_TPC:
|
||||
sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
*bc = tpcbc; /* save rec lnt */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
if (feof (uptr->fileref)) { /* eof? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return MTSE_EOM;
|
||||
}
|
||||
uptr->pos = uptr->pos + sizeof (t_tpclnt); /* spc over reclnt */
|
||||
if (tpcbc == TPC_TMK) return MTSE_TMK; /* tape mark? */
|
||||
uptr->pos = uptr->pos + ((tpcbc + 1) & ~1); /* spc over record */
|
||||
break;
|
||||
|
||||
default:
|
||||
return MTSE_FMT; }
|
||||
case MTUF_F_P7B:
|
||||
for (sbc = 0, all_eof = 1; ; sbc++) { /* loop thru record */
|
||||
sim_fread (&c, sizeof (uint8), 1, uptr->fileref);
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr); /* pos not upd */
|
||||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
if (feof (uptr->fileref)) { /* eof? */
|
||||
if (sbc == 0) return MTSE_EOM; /* no data? eom */
|
||||
break; /* treat like eor */
|
||||
}
|
||||
if ((sbc != 0) && (c & P7B_SOR)) break; /* next record? */
|
||||
if ((c & P7B_DATA) != P7B_EOF) all_eof = 0;
|
||||
}
|
||||
*bc = sbc; /* save rec lnt */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for read */
|
||||
uptr->pos = uptr->pos + sbc; /* spc over record */
|
||||
if (all_eof) return MTSE_TMK; /* tape mark? */
|
||||
break;
|
||||
|
||||
default:
|
||||
return MTSE_FMT;
|
||||
}
|
||||
|
||||
return MTSE_OK;
|
||||
}
|
||||
@@ -201,161 +238,187 @@ return MTSE_OK;
|
||||
/* Read record length reverse (internal routine)
|
||||
|
||||
Inputs:
|
||||
uptr = pointer to tape unit
|
||||
bc = pointer to returned record length
|
||||
uptr = pointer to tape unit
|
||||
bc = pointer to returned record length
|
||||
Outputs:
|
||||
status = operation status
|
||||
status = operation status
|
||||
|
||||
exit condition position
|
||||
exit condition position
|
||||
|
||||
unit unattached unchanged
|
||||
beginning of tape unchanged
|
||||
read error unchanged
|
||||
end of file unchanged
|
||||
end of medium updated
|
||||
tape mark updated
|
||||
data record updated, sim_fread will read record forward
|
||||
unit unattached unchanged
|
||||
beginning of tape unchanged
|
||||
read error unchanged
|
||||
end of file unchanged
|
||||
end of medium updated
|
||||
tape mark updated
|
||||
data record updated, sim_fread will read record forward
|
||||
*/
|
||||
|
||||
t_stat sim_tape_rdlntr (UNIT *uptr, t_mtrlnt *bc)
|
||||
{
|
||||
uint8 c;
|
||||
t_bool all_eof;
|
||||
uint32 f = MT_GET_FMT (uptr);
|
||||
t_addr ppos;
|
||||
t_mtrlnt sbc;
|
||||
t_tpclnt tpcbc;
|
||||
|
||||
MT_CLR_PNU (uptr);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
if (sim_tape_bot (uptr)) return MTSE_BOT; /* at BOT? */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
if (sim_tape_bot (uptr)) return MTSE_BOT; /* at BOT? */
|
||||
switch (f) { /* switch on fmt */
|
||||
|
||||
switch (f) { /* switch on fmt */
|
||||
case MTUF_F_STD: case MTUF_F_E11:
|
||||
sim_fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET);
|
||||
sim_fread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */
|
||||
sbc = MTR_L (*bc);
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */
|
||||
uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over rec lnt */
|
||||
if (*bc == MTR_EOM) return MTSE_EOM; /* eom? */
|
||||
if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */
|
||||
uptr->pos = uptr->pos - sizeof (t_mtrlnt) - /* spc over record */
|
||||
((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc);
|
||||
sim_fseek (uptr->fileref, uptr->pos + sizeof (t_mtrlnt), SEEK_SET);
|
||||
break;
|
||||
case MTUF_F_STD: case MTUF_F_E11:
|
||||
sim_fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET);
|
||||
sim_fread (bc, sizeof (t_mtrlnt), 1, uptr->fileref); /* read rec lnt */
|
||||
sbc = MTR_L (*bc);
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */
|
||||
uptr->pos = uptr->pos - sizeof (t_mtrlnt); /* spc over rec lnt */
|
||||
if (*bc == MTR_EOM) return MTSE_EOM; /* eom? */
|
||||
if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */
|
||||
uptr->pos = uptr->pos - sizeof (t_mtrlnt) - /* spc over record */
|
||||
((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc);
|
||||
sim_fseek (uptr->fileref, uptr->pos + sizeof (t_mtrlnt), SEEK_SET);
|
||||
break;
|
||||
|
||||
case MTUF_F_TPC:
|
||||
ppos = sim_tape_tpc_fnd (uptr, (t_addr *) uptr->filebuf); /* find prev rec */
|
||||
sim_fseek (uptr->fileref, ppos, SEEK_SET); /* position */
|
||||
sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
*bc = tpcbc; /* save rec lnt */
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */
|
||||
uptr->pos = ppos; /* spc over record */
|
||||
if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */
|
||||
sim_fseek (uptr->fileref, uptr->pos + sizeof (t_tpclnt), SEEK_SET);
|
||||
break;
|
||||
|
||||
case MTUF_F_P7B:
|
||||
for (sbc = 1, all_eof = 1; ; sbc++) { /* loop thru record */
|
||||
sim_fseek (uptr->fileref, uptr->pos - sbc, SEEK_SET);
|
||||
sim_fread (&c, sizeof (uint8), 1, uptr->fileref);
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */
|
||||
if ((c & P7B_DATA) != P7B_EOF) all_eof = 0;
|
||||
if (c & P7B_SOR) break; /* start of record? */
|
||||
}
|
||||
uptr->pos = uptr->pos - sbc; /* update position */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for read */
|
||||
if (all_eof) return MTSE_TMK; /* tape mark? */
|
||||
break;
|
||||
|
||||
default:
|
||||
return MTSE_FMT;
|
||||
}
|
||||
|
||||
case MTUF_F_TPC:
|
||||
ppos = sim_tape_tpc_fnd (uptr, uptr->filebuf); /* find prev rec */
|
||||
sim_fseek (uptr->fileref, ppos, SEEK_SET); /* position */
|
||||
sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
*bc = tpcbc; /* save rec lnt */
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
if (feof (uptr->fileref)) return MTSE_EOM; /* eof? */
|
||||
uptr->pos = ppos; /* spc over record */
|
||||
if (*bc == MTR_TMK) return MTSE_TMK; /* tape mark? */
|
||||
sim_fseek (uptr->fileref, uptr->pos + sizeof (t_tpclnt), SEEK_SET);
|
||||
break;
|
||||
default:
|
||||
return MTSE_FMT; }
|
||||
return MTSE_OK;
|
||||
}
|
||||
|
||||
/* Read record forward
|
||||
|
||||
Inputs:
|
||||
uptr = pointer to tape unit
|
||||
buf = pointer to buffer
|
||||
bc = pointer to returned record length
|
||||
max = maximum record size
|
||||
uptr = pointer to tape unit
|
||||
buf = pointer to buffer
|
||||
bc = pointer to returned record length
|
||||
max = maximum record size
|
||||
Outputs:
|
||||
status = operation status
|
||||
status = operation status
|
||||
|
||||
exit condition position
|
||||
exit condition position
|
||||
|
||||
unit unattached unchanged
|
||||
read error unchanged, PNU set
|
||||
end of file/medium unchanged, PNU set
|
||||
invalid record unchanged, PNU set
|
||||
tape mark updated
|
||||
data record updated
|
||||
data record error updated
|
||||
unit unattached unchanged
|
||||
read error unchanged, PNU set
|
||||
end of file/medium unchanged, PNU set
|
||||
invalid record unchanged, PNU set
|
||||
tape mark updated
|
||||
data record updated
|
||||
data record error updated
|
||||
*/
|
||||
|
||||
t_stat sim_tape_rdrecf (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max)
|
||||
{
|
||||
uint32 f = MT_GET_FMT (uptr);
|
||||
t_mtrlnt i, tbc, rbc;
|
||||
t_addr opos;
|
||||
t_stat st;
|
||||
|
||||
opos = uptr->pos; /* old position */
|
||||
if (st = sim_tape_rdlntf (uptr, &tbc)) return st; /* read rec lnt */
|
||||
*bc = rbc = MTR_L (tbc); /* strip error flag */
|
||||
if (rbc > max) { /* rec out of range? */
|
||||
MT_SET_PNU (uptr);
|
||||
uptr->pos = opos;
|
||||
return MTSE_INVRL; }
|
||||
i = sim_fread (buf, sizeof (uint8), rbc, uptr->fileref); /* read record */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr);
|
||||
uptr->pos = opos;
|
||||
return sim_tape_ioerr (uptr); }
|
||||
for ( ; i < rbc; i++) buf[i] = 0; /* fill with 0's */
|
||||
opos = uptr->pos; /* old position */
|
||||
if (st = sim_tape_rdlntf (uptr, &tbc)) return st; /* read rec lnt */
|
||||
*bc = rbc = MTR_L (tbc); /* strip error flag */
|
||||
if (rbc > max) { /* rec out of range? */
|
||||
MT_SET_PNU (uptr);
|
||||
uptr->pos = opos;
|
||||
return MTSE_INVRL;
|
||||
}
|
||||
i = sim_fread (buf, sizeof (uint8), rbc, uptr->fileref); /* read record */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr);
|
||||
uptr->pos = opos;
|
||||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
for ( ; i < rbc; i++) buf[i] = 0; /* fill with 0's */
|
||||
if (f == MTUF_F_P7B) buf[0] = buf[0] & P7B_DPAR; /* p7b? strip SOR */
|
||||
return (MTR_F (tbc)? MTSE_RECE: MTSE_OK);
|
||||
}
|
||||
|
||||
/* Read record reverse
|
||||
|
||||
Inputs:
|
||||
uptr = pointer to tape unit
|
||||
buf = pointer to buffer
|
||||
bc = pointer to returned record length
|
||||
max = maximum record size
|
||||
uptr = pointer to tape unit
|
||||
buf = pointer to buffer
|
||||
bc = pointer to returned record length
|
||||
max = maximum record size
|
||||
Outputs:
|
||||
status = operation status
|
||||
status = operation status
|
||||
|
||||
exit condition position
|
||||
exit condition position
|
||||
|
||||
unit unattached unchanged
|
||||
read error unchanged
|
||||
end of file unchanged
|
||||
end of medium updated
|
||||
invalid record unchanged
|
||||
tape mark updated
|
||||
data record updated
|
||||
data record error updated
|
||||
unit unattached unchanged
|
||||
read error unchanged
|
||||
end of file unchanged
|
||||
end of medium updated
|
||||
invalid record unchanged
|
||||
tape mark updated
|
||||
data record updated
|
||||
data record error updated
|
||||
*/
|
||||
|
||||
t_stat sim_tape_rdrecr (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max)
|
||||
{
|
||||
uint32 f = MT_GET_FMT (uptr);
|
||||
t_mtrlnt i, rbc, tbc;
|
||||
t_stat st;
|
||||
|
||||
if (st = sim_tape_rdlntr (uptr, &tbc)) return st; /* read rec lnt */
|
||||
*bc = rbc = MTR_L (tbc); /* strip error flag */
|
||||
if (rbc > max) return MTSE_INVRL; /* rec out of range? */
|
||||
i = sim_fread (buf, sizeof (uint8), rbc, uptr->fileref); /* read record */
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
for ( ; i < rbc; i++) buf[i] = 0; /* fill with 0's */
|
||||
if (st = sim_tape_rdlntr (uptr, &tbc)) return st; /* read rec lnt */
|
||||
*bc = rbc = MTR_L (tbc); /* strip error flag */
|
||||
if (rbc > max) return MTSE_INVRL; /* rec out of range? */
|
||||
i = sim_fread (buf, sizeof (uint8), rbc, uptr->fileref); /* read record */
|
||||
if (ferror (uptr->fileref)) /* error? */
|
||||
return sim_tape_ioerr (uptr);
|
||||
for ( ; i < rbc; i++) buf[i] = 0; /* fill with 0's */
|
||||
if (f == MTUF_F_P7B) buf[0] = buf[0] & P7B_DPAR; /* p7b? strip SOR */
|
||||
return (MTR_F (tbc)? MTSE_RECE: MTSE_OK);
|
||||
}
|
||||
|
||||
/* Write record forward
|
||||
|
||||
Inputs:
|
||||
uptr = pointer to tape unit
|
||||
buf = pointer to buffer
|
||||
bc = record length
|
||||
uptr = pointer to tape unit
|
||||
buf = pointer to buffer
|
||||
bc = record length
|
||||
Outputs:
|
||||
status = operation status
|
||||
status = operation status
|
||||
|
||||
exit condition position
|
||||
exit condition position
|
||||
|
||||
unit unattached unchanged
|
||||
write protect unchanged
|
||||
write error unchanged, PNU set
|
||||
data record updated
|
||||
unit unattached unchanged
|
||||
write protect unchanged
|
||||
write error unchanged, PNU set
|
||||
data record updated
|
||||
*/
|
||||
|
||||
t_stat sim_tape_wrrecf (UNIT *uptr, uint8 *buf, t_mtrlnt bc)
|
||||
@@ -364,18 +427,19 @@ uint32 f = MT_GET_FMT (uptr);
|
||||
t_mtrlnt sbc;
|
||||
|
||||
MT_CLR_PNU (uptr);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */
|
||||
if (f == MTUF_F_STD) sbc = MTR_L ((bc + 1) & ~1);
|
||||
else sbc = MTR_L (bc);
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */
|
||||
sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
sim_fwrite (buf, sizeof (uint8), sbc, uptr->fileref);
|
||||
sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr);
|
||||
return sim_tape_ioerr (uptr); }
|
||||
uptr->pos = uptr->pos + sbc + (2 * sizeof (t_mtrlnt)); /* move tape */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr);
|
||||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
uptr->pos = uptr->pos + sbc + (2 * sizeof (t_mtrlnt)); /* move tape */
|
||||
return MTSE_OK;
|
||||
}
|
||||
|
||||
@@ -384,14 +448,15 @@ return MTSE_OK;
|
||||
t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat)
|
||||
{
|
||||
MT_CLR_PNU (uptr);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
|
||||
if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */
|
||||
sim_fwrite (&dat, sizeof (t_mtrlnt), 1, uptr->fileref);
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr);
|
||||
return sim_tape_ioerr (uptr); }
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* move tape */
|
||||
if (ferror (uptr->fileref)) { /* error? */
|
||||
MT_SET_PNU (uptr);
|
||||
return sim_tape_ioerr (uptr);
|
||||
}
|
||||
uptr->pos = uptr->pos + sizeof (t_mtrlnt); /* move tape */
|
||||
return MTSE_OK;
|
||||
}
|
||||
|
||||
@@ -415,7 +480,7 @@ t_stat sim_tape_sprecf (UNIT *uptr, t_mtrlnt *bc)
|
||||
{
|
||||
t_stat st;
|
||||
|
||||
st = sim_tape_rdlntf (uptr, bc); /* get record length */
|
||||
st = sim_tape_rdlntf (uptr, bc); /* get record length */
|
||||
*bc = MTR_L (*bc);
|
||||
return st;
|
||||
}
|
||||
@@ -427,10 +492,11 @@ t_stat sim_tape_sprecr (UNIT *uptr, t_mtrlnt *bc)
|
||||
t_stat st;
|
||||
|
||||
if (MT_TST_PNU (uptr)) {
|
||||
MT_CLR_PNU (uptr);
|
||||
*bc = 0;
|
||||
return MTSE_OK; }
|
||||
st = sim_tape_rdlntr (uptr, bc); /* get record length */
|
||||
MT_CLR_PNU (uptr);
|
||||
*bc = 0;
|
||||
return MTSE_OK;
|
||||
}
|
||||
st = sim_tape_rdlntr (uptr, bc); /* get record length */
|
||||
*bc = MTR_L (*bc);
|
||||
return st;
|
||||
}
|
||||
@@ -493,10 +559,12 @@ int32 f;
|
||||
if (uptr == NULL) return SCPE_IERR;
|
||||
if (cptr == NULL) return SCPE_ARG;
|
||||
for (f = 0; f < MTUF_N_FMT; f++) {
|
||||
if (fmts[f].name && (strcmp (cptr, fmts[f].name) == 0)) {
|
||||
uptr->flags = (uptr->flags & ~MTUF_FMT) |
|
||||
(f << MTUF_V_FMT) | fmts[f].uflags;
|
||||
return SCPE_OK; } }
|
||||
if (fmts[f].name && (strcmp (cptr, fmts[f].name) == 0)) {
|
||||
uptr->flags = (uptr->flags & ~MTUF_FMT) |
|
||||
(f << MTUF_V_FMT) | fmts[f].uflags;
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
return SCPE_ARG;
|
||||
}
|
||||
|
||||
@@ -521,12 +589,13 @@ uint32 i, objc;
|
||||
|
||||
if ((uptr == NULL) || (uptr->fileref == NULL)) return 0;
|
||||
for (objc = 0, tpos = 0;; ) {
|
||||
sim_fseek (uptr->fileref, tpos, SEEK_SET);
|
||||
i = sim_fread (&bc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
if (i == 0) break;
|
||||
if (map) map[objc] = tpos;
|
||||
objc++;
|
||||
tpos = tpos + ((bc + 1) & ~1) + sizeof (t_tpclnt); }
|
||||
sim_fseek (uptr->fileref, tpos, SEEK_SET);
|
||||
i = sim_fread (&bc, sizeof (t_tpclnt), 1, uptr->fileref);
|
||||
if (i == 0) break;
|
||||
if (map) map[objc] = tpos;
|
||||
objc++;
|
||||
tpos = tpos + ((bc + 1) & ~1) + sizeof (t_tpclnt);
|
||||
}
|
||||
if (map) map[objc] = tpos;
|
||||
return objc;
|
||||
}
|
||||
@@ -541,11 +610,13 @@ uint32 lo, hi, p;
|
||||
if (map == NULL) return 0;
|
||||
lo = 0;
|
||||
hi = uptr->hwmark - 1;
|
||||
do { p = (lo + hi) >> 1;
|
||||
if (uptr->pos == map[p])
|
||||
return ((p == 0)? map[p]: map[p - 1]);
|
||||
else if (uptr->pos < map[p]) hi = p - 1;
|
||||
else lo = p + 1; }
|
||||
do {
|
||||
p = (lo + hi) >> 1;
|
||||
if (uptr->pos == map[p])
|
||||
return ((p == 0)? map[p]: map[p - 1]);
|
||||
else if (uptr->pos < map[p]) hi = p - 1;
|
||||
else lo = p + 1;
|
||||
}
|
||||
while (lo <= hi);
|
||||
return ((p == 0)? map[p]: map[p - 1]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user