Added support for Logical End of Tape (EOT) detection when required

This commit is contained in:
Mark Pizzolato 2012-01-24 10:12:26 -08:00
parent 3e8b43b4c6
commit 7a558a4e63
3 changed files with 43 additions and 13 deletions

View file

@ -25,6 +25,8 @@
tq TQK50 tape controller
23-Jan-12 MP Added missing support for Logical EOT detection while
positioning.
05-Mar-11 MP Added missing state for proper save/restore
01-Mar-11 MP - Migrated complex physical tape activities to sim_tape
- adopted use of asynch I/O interfaces from sim_tape
@ -1451,11 +1453,13 @@ switch (cmd) { /* case on command */
sim_tape_position_a (uptr,
((mdf & MD_RWD) ? MTPOS_M_REW : 0) |
((mdf & MD_REV) ? MTPOS_M_REV : 0) |
((mdf & MD_OBC) ? MTPOS_M_OBJ : 0) ,
((mdf & MD_OBC) ? MTPOS_M_OBJ : 0) |
(((mdf & MD_DLE) && !(mdf & MD_REV)) ? MTPOS_M_DLE : 0),
nrec, &res->skrec, ntmk, &res->sktmk, (uint32 *)&res->objupd, tq_io_complete);
return SCPE_OK;
}
if (res->io_status)
res->sts = tq_map_status (uptr, res->io_status);
if ((res->io_status != MTSE_OK) && (res->io_status != MTSE_BOT) && (res->io_status != MTSE_LEOT))
return tq_mot_err (uptr, 0); /* log, end */
sim_debug (DBG_REQ, &tq_dev, "Position Done: mdf=0x%04X, nrec=%d, ntmk=%d, skrec=%d, sktmk=%d, skobj=%d\n",
mdf, nrec, ntmk, res->skrec, res->sktmk, res->objupd);
@ -1558,6 +1562,9 @@ switch (st) {
case MTSE_WRP:
uptr->flags = uptr->flags | UNIT_SXC;
return ST_WPR;
case MTSE_LEOT:
return ST_LED;
}
return ST_SUC;

View file

@ -26,6 +26,7 @@
Ultimately, this will be a place to hide processing of various tape formats,
as well as OS-specific direct hardware access.
23-Jan-12 MP Added support for Logical EOT detection while positioning
05-Feb-11 MP Refactored to prepare for SIM_ASYNC_IO support
Added higher level routines:
sim_tape_wreomrw - erase remainder of tape & rewind
@ -251,7 +252,7 @@ struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
ctx->io_status = sim_tape_spfilef (uptr, ctx->vbc, ctx->bc);
break;
case TOP_SFRF:
ctx->io_status = sim_tape_spfilebyrecf (uptr, ctx->vbc, ctx->bc, ctx->fc);
ctx->io_status = sim_tape_spfilebyrecf (uptr, ctx->vbc, ctx->bc, ctx->fc, ctx->max);
break;
case TOP_SPFR:
ctx->io_status = sim_tape_spfiler (uptr, ctx->vbc, ctx->bc);
@ -1425,6 +1426,7 @@ return r;
count = count of files to skip
skipped = pointer to number of files actually skipped
recsskipped = pointer to number of records skipped
check_leot = flag to detect and stop skip between two successive tape marks
Outputs:
status = operation status
@ -1438,14 +1440,23 @@ return r;
data record error updated
*/
t_stat sim_tape_spfilebyrecf (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped)
t_stat sim_tape_spfilebyrecf (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped, t_bool check_leot)
{
struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
t_stat st;
t_bool last_tapemark = FALSE;
uint32 filerecsskipped;
sim_debug (ctx->dbit, ctx->dptr, "sim_tape_spfilebyrecf(unit=%d, count=%d)\n", uptr-ctx->dptr->units, count);
sim_debug (ctx->dbit, ctx->dptr, "sim_tape_spfilebyrecf(unit=%d, count=%d, check_leot=%d)\n", uptr-ctx->dptr->units, count, check_leot);
if (check_leot) {
t_mtrlnt rbc;
st = sim_tape_rdlntr (uptr, &rbc);
last_tapemark = (MTSE_TMK == st);
if ((st == MTSE_OK) || (st == MTSE_TMK))
sim_tape_rdlntf (uptr, &rbc);
}
*skipped = 0;
*recsskipped = 0;
while (*skipped < count) { /* loopo */
@ -1455,20 +1466,28 @@ while (*skipped < count) { /* loopo */
if (st != MTSE_OK)
break;
}
if (st == MTSE_TMK)
if (st == MTSE_TMK) {
*skipped = *skipped + 1; /* # files skipped */
if (check_leot && (filerecsskipped == 0) && last_tapemark) {
uint32 filefileskipped;
sim_tape_spfilebyrecr (uptr, 1, &filefileskipped, &filerecsskipped);
*skipped = *skipped - 1; /* adjust # files skipped */
return MTSE_LEOT;
}
last_tapemark = TRUE;
}
else
return st;
}
return MTSE_OK;
}
t_stat sim_tape_spfilebyrecf_a (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped, TAPE_PCALLBACK callback)
t_stat sim_tape_spfilebyrecf_a (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped, t_bool check_leot, TAPE_PCALLBACK callback)
{
t_stat r = MTSE_OK;
AIO_CALLSETUP
r = sim_tape_spfilebyrecf (uptr, count, skipped, recsskipped);
AIO_CALL(TOP_SPFF, NULL, skipped, recsskipped, 0, count, 0, 0, NULL, callback);
r = sim_tape_spfilebyrecf (uptr, count, skipped, recsskipped, check_leot);
AIO_CALL(TOP_SFRF, NULL, skipped, recsskipped, check_leot, count, 0, 0, NULL, callback);
return r;
}
@ -1498,7 +1517,7 @@ uint32 totalrecsskipped;
sim_debug (ctx->dbit, ctx->dptr, "sim_tape_spfilef(unit=%d, count=%d)\n", uptr-ctx->dptr->units, count);
return sim_tape_spfilebyrecf (uptr, count, skipped, &totalrecsskipped);
return sim_tape_spfilebyrecf (uptr, count, skipped, &totalrecsskipped, FALSE);
}
t_stat sim_tape_spfilef_a (UNIT *uptr, uint32 count, uint32 *skipped, TAPE_PCALLBACK callback)
@ -1664,7 +1683,7 @@ else {
if (flags & MTPOS_M_REV) /* reverse? */
r = sim_tape_spfilebyrecr (uptr, files, filesskipped, &fileskiprecs);
else
r = sim_tape_spfilebyrecf (uptr, files, filesskipped, &fileskiprecs);
r = sim_tape_spfilebyrecf (uptr, files, filesskipped, &fileskiprecs, (flags & MTPOS_M_DLE));
if (r != MTSE_OK)
return r;
if (flags & MTPOS_M_REV) /* reverse? */

View file

@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
23-Jan-12 MP Added support for Logical EOT detection while positioning
05-Feb-11 MP Add Asynch I/O support
30-Aug-06 JDB Added erase gap support
14-Feb-06 RMS Added variable tape capacity
@ -99,6 +100,8 @@ typedef uint16 t_tpclnt; /* magtape rec lnt */
#define MTPOS_M_REV (1u << MTPOS_V_REV) /* Reverse Direction */
#define MTPOS_V_OBJ 1
#define MTPOS_M_OBJ (1u << MTPOS_V_OBJ) /* Objects vs Records/Files */
#define MTPOS_V_DLE 4
#define MTPOS_M_DLE (1u << MTPOS_V_DLE) /* Detect LEOT */
/* Return status codes */
@ -112,6 +115,7 @@ typedef uint16 t_tpclnt; /* magtape rec lnt */
#define MTSE_EOM 7 /* end of medium */
#define MTSE_RECE 8 /* error in record */
#define MTSE_WRP 9 /* write protected */
#define MTSE_LEOT 10 /* Logical End Of Tape */
typedef void (*TAPE_PCALLBACK)(UNIT *unit, t_stat status);
@ -140,8 +144,8 @@ t_stat sim_tape_sprecsf (UNIT *uptr, uint32 count, uint32 *skipped);
t_stat sim_tape_sprecsf_a (UNIT *uptr, uint32 count, uint32 *skipped, TAPE_PCALLBACK callback);
t_stat sim_tape_spfilef (UNIT *uptr, uint32 count, uint32 *skipped);
t_stat sim_tape_spfilef_a (UNIT *uptr, uint32 count, uint32 *skipped, TAPE_PCALLBACK callback);
t_stat sim_tape_spfilebyrecf (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped);
t_stat sim_tape_spfilebyrecf_a (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped, TAPE_PCALLBACK callback);
t_stat sim_tape_spfilebyrecf (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped, t_bool check_leot);
t_stat sim_tape_spfilebyrecf_a (UNIT *uptr, uint32 count, uint32 *skipped, uint32 *recsskipped, t_bool check_leot, TAPE_PCALLBACK callback);
t_stat sim_tape_sprecr (UNIT *uptr, t_mtrlnt *bc);
t_stat sim_tape_sprecr_a (UNIT *uptr, t_mtrlnt *bc, TAPE_PCALLBACK callback);
t_stat sim_tape_sprecsr (UNIT *uptr, uint32 count, uint32 *skipped);