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 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 05-Mar-11 MP Added missing state for proper save/restore
01-Mar-11 MP - Migrated complex physical tape activities to sim_tape 01-Mar-11 MP - Migrated complex physical tape activities to sim_tape
- adopted use of asynch I/O interfaces from 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, sim_tape_position_a (uptr,
((mdf & MD_RWD) ? MTPOS_M_REW : 0) | ((mdf & MD_RWD) ? MTPOS_M_REW : 0) |
((mdf & MD_REV) ? MTPOS_M_REV : 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); nrec, &res->skrec, ntmk, &res->sktmk, (uint32 *)&res->objupd, tq_io_complete);
return SCPE_OK; 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 */ 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", 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); mdf, nrec, ntmk, res->skrec, res->sktmk, res->objupd);
@ -1558,6 +1562,9 @@ switch (st) {
case MTSE_WRP: case MTSE_WRP:
uptr->flags = uptr->flags | UNIT_SXC; uptr->flags = uptr->flags | UNIT_SXC;
return ST_WPR; return ST_WPR;
case MTSE_LEOT:
return ST_LED;
} }
return ST_SUC; return ST_SUC;

View file

@ -26,6 +26,7 @@
Ultimately, this will be a place to hide processing of various tape formats, Ultimately, this will be a place to hide processing of various tape formats,
as well as OS-specific direct hardware access. 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 05-Feb-11 MP Refactored to prepare for SIM_ASYNC_IO support
Added higher level routines: Added higher level routines:
sim_tape_wreomrw - erase remainder of tape & rewind 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); ctx->io_status = sim_tape_spfilef (uptr, ctx->vbc, ctx->bc);
break; break;
case TOP_SFRF: 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; break;
case TOP_SPFR: case TOP_SPFR:
ctx->io_status = sim_tape_spfiler (uptr, ctx->vbc, ctx->bc); ctx->io_status = sim_tape_spfiler (uptr, ctx->vbc, ctx->bc);
@ -1425,6 +1426,7 @@ return r;
count = count of files to skip count = count of files to skip
skipped = pointer to number of files actually skipped skipped = pointer to number of files actually skipped
recsskipped = pointer to number of records skipped recsskipped = pointer to number of records skipped
check_leot = flag to detect and stop skip between two successive tape marks
Outputs: Outputs:
status = operation status status = operation status
@ -1438,14 +1440,23 @@ return r;
data record error updated 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; struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
t_stat st; t_stat st;
t_bool last_tapemark = FALSE;
uint32 filerecsskipped; 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; *skipped = 0;
*recsskipped = 0; *recsskipped = 0;
while (*skipped < count) { /* loopo */ while (*skipped < count) { /* loopo */
@ -1455,20 +1466,28 @@ while (*skipped < count) { /* loopo */
if (st != MTSE_OK) if (st != MTSE_OK)
break; break;
} }
if (st == MTSE_TMK) if (st == MTSE_TMK) {
*skipped = *skipped + 1; /* # files skipped */ *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 else
return st; return st;
} }
return MTSE_OK; 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; t_stat r = MTSE_OK;
AIO_CALLSETUP AIO_CALLSETUP
r = sim_tape_spfilebyrecf (uptr, count, skipped, recsskipped); r = sim_tape_spfilebyrecf (uptr, count, skipped, recsskipped, check_leot);
AIO_CALL(TOP_SPFF, NULL, skipped, recsskipped, 0, count, 0, 0, NULL, callback); AIO_CALL(TOP_SFRF, NULL, skipped, recsskipped, check_leot, count, 0, 0, NULL, callback);
return r; 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); 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) 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? */ if (flags & MTPOS_M_REV) /* reverse? */
r = sim_tape_spfilebyrecr (uptr, files, filesskipped, &fileskiprecs); r = sim_tape_spfilebyrecr (uptr, files, filesskipped, &fileskiprecs);
else 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) if (r != MTSE_OK)
return r; return r;
if (flags & MTPOS_M_REV) /* reverse? */ 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 used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. 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 05-Feb-11 MP Add Asynch I/O support
30-Aug-06 JDB Added erase gap support 30-Aug-06 JDB Added erase gap support
14-Feb-06 RMS Added variable tape capacity 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_M_REV (1u << MTPOS_V_REV) /* Reverse Direction */
#define MTPOS_V_OBJ 1 #define MTPOS_V_OBJ 1
#define MTPOS_M_OBJ (1u << MTPOS_V_OBJ) /* Objects vs Records/Files */ #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 */ /* Return status codes */
@ -112,6 +115,7 @@ typedef uint16 t_tpclnt; /* magtape rec lnt */
#define MTSE_EOM 7 /* end of medium */ #define MTSE_EOM 7 /* end of medium */
#define MTSE_RECE 8 /* error in record */ #define MTSE_RECE 8 /* error in record */
#define MTSE_WRP 9 /* write protected */ #define MTSE_WRP 9 /* write protected */
#define MTSE_LEOT 10 /* Logical End Of Tape */
typedef void (*TAPE_PCALLBACK)(UNIT *unit, t_stat status); 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_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 (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_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 (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, 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 sim_tape_sprecr (UNIT *uptr, t_mtrlnt *bc); 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_sprecr_a (UNIT *uptr, t_mtrlnt *bc, TAPE_PCALLBACK callback);
t_stat sim_tape_sprecsr (UNIT *uptr, uint32 count, uint32 *skipped); t_stat sim_tape_sprecsr (UNIT *uptr, uint32 count, uint32 *skipped);