1
0
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:
Bob Supnik
2005-09-09 18:09:00 -07:00
committed by Mark Pizzolato
parent ec60bbf329
commit b7c1eae41f
257 changed files with 107140 additions and 97195 deletions

View File

@@ -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]);
}