diff --git a/PDP11/pdp11_tq.c b/PDP11/pdp11_tq.c index ce1d79f8..2fbf5ed9 100644 --- a/PDP11/pdp11_tq.c +++ b/PDP11/pdp11_tq.c @@ -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; diff --git a/sim_tape.c b/sim_tape.c index fd7003fe..d66d584b 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -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? */ diff --git a/sim_tape.h b/sim_tape.h index f851ff6e..3d9f785e 100644 --- a/sim_tape.h +++ b/sim_tape.h @@ -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);