diff --git a/PDP10/pdp10_tu.c b/PDP10/pdp10_tu.c index 7724a22e..0941aba1 100644 --- a/PDP10/pdp10_tu.c +++ b/PDP10/pdp10_tu.c @@ -1,6 +1,6 @@ /* pdp10_tu.c - PDP-10 RH11/TM03/TU45 magnetic tape simulator - Copyright (c) 1993-2022, Robert M Supnik + Copyright (c) 1993-2023, 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"), @@ -25,6 +25,7 @@ tu RH11/TM03/TU45 magtape + 06-Nov-23 RMS Fixed BOT logic 26-Mar-22 RMS Added extra case points for new MTSE definitions 07-Sep-20 RMS Fixed || -> | in macro (Mark Pizzolato) 12-Jan-18 RMS Fixed missing () in logical test (Mark Pizzolato) @@ -94,6 +95,10 @@ level sensitive. - The DONE interrupt, once set, is not disabled if IE is cleared, but the SC interrupt is. + + BOT is not the same as POS == 0. BOT is set after rewinding or after + a reverse operation from before the first record. It is cleared by + any successful motion operation. */ #include "pdp10_defs.h" @@ -183,7 +188,7 @@ */ #define FS_SAT 0000001 /* slave attention */ -#define FS_BOT 0000002 /* ^beginning of tape */ +#define FS_BOT 0000002 /* +beginning of tape */ #define FS_TMK 0000004 /* end of file */ #define FS_ID 0000010 /* ID burst detected */ #define FS_SLOW 0000020 /* slowing down NI */ @@ -191,7 +196,7 @@ #define FS_SSC 0000100 /* slave stat change */ #define FS_RDY 0000200 /* ^formatter ready */ #define FS_FPR 0000400 /* formatter present */ -#define FS_EOT 0002000 /* +end of tape */ +#define FS_EOT 0002000 /* ^end of tape */ #define FS_WRL 0004000 /* ^write locked */ #define FS_MOL 0010000 /* ^medium online */ #define FS_PIP 0020000 /* +pos in progress */ @@ -675,7 +680,7 @@ switch (fnc) { /* case on function */ tufs = tufs & ~(FS_SAT | FS_SSC | FS_ID | FS_ERR); if (!(uptr->TU_STATEFLAGS & TUS_ATTPENDING)) sim_cancel (uptr); /* stop motion, not on-line delay */ - uptr->USTAT = 0; + uptr->USTAT &= FS_BOT; /* fall through */ /* fall through */ case FNC_NOP: tucs1 = tucs1 & ~CS1_GO; /* no operation */ @@ -687,8 +692,10 @@ switch (fnc) { /* case on function */ break; } tutc = TC_RIP; /* density = 800 */ - sim_tape_rewind (&tu_unit[0]); /* rewind unit 0 */ - tu_unit[0].USTAT = 0; + if (tu_unit[0].flags & UNIT_ATT) { /* attached? */ + sim_tape_rewind (&tu_unit[0]); /* rewind unit 0 */ + tu_unit[0].USTAT = FS_BOT; + } tucs1 = tucs1 & ~CS1_GO; tufs = tufs & ~FS_TMK; return; @@ -733,7 +740,7 @@ switch (fnc) { /* case on function */ set_tuer (ER_UNS); break; } - if (sim_tape_bot (uptr) || ((tutc & TC_FCS) == 0)) { + if ((uptr->USTAT & FS_BOT) || ((tutc & TC_FCS) == 0)) { set_tuer (ER_NXF); break; } @@ -761,7 +768,7 @@ switch (fnc) { /* case on function */ case FNC_WCHKR: /* wchk = read */ case FNC_READR: /* read rev */ - if (tufs & FS_BOT) { /* beginning of tape? */ + if (uptr->USTAT & FS_BOT) { /* beginning of tape? */ set_tuer (ER_NXF); break; } @@ -835,7 +842,9 @@ if (uptr->TU_STATEFLAGS & TUS_ATTPENDING) { if (uptr->USTAT & FS_REW) { /* rewind or unload? */ sim_tape_rewind (uptr); /* rewind tape */ - uptr->USTAT = 0; /* clear status */ + if (uptr->flags & UNIT_ATT) /* attached? */ + uptr->USTAT = FS_BOT; /* set BOT */ + else uptr->USTAT = 0; /* clear status */ tufs = tufs | FS_ATA | FS_SSC; update_tucs (CS1_SC, drv); /* update status */ return SCPE_OK; @@ -1041,21 +1050,17 @@ if ((flag & ~tucs1) & CS1_DONE) /* DONE 0 to 1? */ tuiff = (tucs1 & CS1_IE)? 1: 0; /* CSTB INTR <- IE */ if (GET_FMTR (tucs2) == 0) { /* formatter present? */ tufs = (tufs & ~FS_DYN) | FS_FPR; - if (tu_unit[drv].TU_STATEFLAGS & TUS_ATTPENDING) /* Delayed on-line timer running? */ - act = 0; /* Not a tape motion op */ + if (tu_unit[drv].TU_STATEFLAGS & TUS_ATTPENDING) /* delayed on-line timer running? */ + act = 0; /* not a tape motion op */ else { if (tu_unit[drv].flags & UNIT_ATT) { - tufs = tufs | FS_MOL | tu_unit[drv].USTAT; + tufs = tufs | FS_MOL | (tu_unit[drv].USTAT & 0177777); if (tu_unit[drv].UDENS == TC_1600) tufs = tufs | FS_PE; if (sim_tape_wrp (&tu_unit[drv])) tufs = tufs | FS_WRL; - if (!act) { - if (sim_tape_bot (&tu_unit[drv])) - tufs = tufs | FS_BOT; - if (sim_tape_eot (&tu_unit[drv])) + if (!act && sim_tape_eot (&tu_unit[drv])) tufs = tufs | FS_EOT; - } } } if (tuer) @@ -1138,6 +1143,7 @@ switch (st) { break; case MTSE_BOT: /* reverse into BOT */ + uptr->USTAT = FS_BOT; /* set BOT */ break; case MTSE_WRP: /* write protect */ @@ -1178,7 +1184,9 @@ for (u = 0; u < TU_NUMDR; u++) { /* loop thru units */ if (!sim_is_active(uptr) ) sim_activate_after(uptr, SPINUPDLY); } - uptr->USTAT = 0; + if ((uptr->flags & UNIT_ATT) && sim_tape_bot (uptr)) + uptr->USTAT = FS_BOT; + else uptr->USTAT = 0; } if (xbuf == NULL) xbuf = (uint8 *) calloc (MT_MAXFR + 4, sizeof (uint8)); @@ -1197,7 +1205,7 @@ t_stat r; r = sim_tape_attach (uptr, cptr); if (r != SCPE_OK) return r; -uptr->USTAT = 0; /* clear unit status */ +uptr->USTAT = FS_BOT; /* set BOT */ uptr->UDENS = UD_UNK; /* unknown density */ /* Delay setting MOL since we may have just detached a previous file. * In that case, the OS must see MOL clear, so that it will know that the @@ -1243,7 +1251,7 @@ return sim_tape_detach (uptr); } /* Device bootstrap */ -/* Note that the dec and ITS boot code is word for word identical, +/* Note that the DEC and ITS boot code is word for word identical, * except for the IO instructions. The ITS instructions encode the * UBA number. No attempt is made to allow UBA selection under ITS, * though it should work with the DEC rom. diff --git a/PDP11/pdp11_ts.c b/PDP11/pdp11_ts.c index 23e89f34..7da3e141 100644 --- a/PDP11/pdp11_ts.c +++ b/PDP11/pdp11_ts.c @@ -1,6 +1,6 @@ /* pdp11_ts.c: TS11/TSV05 magnetic tape simulator - Copyright (c) 1993-2022, Robert M Supnik + Copyright (c) 1993-2023, 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"), @@ -25,6 +25,8 @@ ts TS11/TSV05 magtape + 29-Oct-23 RMS Implemented distinction between BOT and POS==0 + INIT command is a NOP 26-Mar-22 RMS Added extra case points for new MTSE definitions 27-Oct-14 RMS Fixed bug in read forward with byte swap 23-Oct-13 RMS Revised for new boot setup routine @@ -87,6 +89,25 @@ - PDP-11 Unibus 22b systems - the TS11 behaves as an 18b Unibus peripheral and must go through the I/O map - VAX Q22 systems - the TS11 must go through the I/O map + + The TS11 must distinguish between true beginning of tape (BOT) - + positioned at the tape marker - and positioned before the first + record (POS == 0). BOT is set under the following circumstances: + + - Mount (ATTACH) + - Rewind + - Backward operation, !BOT && POS==0. This sets RIB (rewind into + BOT) and is an error + + It is cleared by any successful forward operation. + + Therefore, reverse operations (except rewind) have three states: + + - !BOT, POS != 0. BOT unchanaged. + - !BOT, POS == 0. Set BOT and RIB; error. + - BOT. Set function reject. + + Rewind always moves the tape to BOT, even if it is already at BOT. */ #if defined (VM_PDP10) /* PDP10 version */ @@ -275,11 +296,12 @@ int32 tsdbx = 0; /* data buf ext */ int32 tscmdp[CMD_PLNT] = { 0 }; /* command packet */ int32 tsmsgp[MSG_PLNT] = { 0 }; /* message packet */ int32 tswchp[WCH_PLNT] = { 0 }; /* wr char packet */ +int32 ts_bot = 0; /* at BOT */ int32 ts_ownc = 0; /* tape owns cmd */ int32 ts_ownm = 0; /* tape owns msg */ int32 ts_qatn = 0; /* queued attn */ int32 ts_bcmd = 0; /* boot cmd */ -int32 ts_time = 2000; /* record latency */ +int32 ts_time = 10; /* record latency */ static uint16 cpy_buf[MAX_PLNT]; /* copy buffer */ t_stat ts_rd (int32 *data, int32 PA, int32 access); @@ -293,6 +315,7 @@ int32 ts_updtssr (int32 t); int32 ts_updxs0 (int32 t); void ts_cmpendcmd (int32 s0, int32 s1); void ts_endcmd (int32 ssf, int32 xs0f, int32 msg); +void ts_set_mot (int32 bot); int32 ts_map_status (t_stat st); t_stat ts_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); const char *ts_description (DEVICE *dptr); @@ -335,6 +358,7 @@ REG ts_reg[] = { { GRDATAD (WOPT, wchopt, DEV_RDX, 16, 0, "write char packet options") }, { GRDATAD (WXOPT, wchxopt, DEV_RDX, 16, 0, "write char packet extended options") }, { FLDATAD (INT, IREQ (TS), INT_V_TS, "interrupt pending") }, + { FLDATAD (BOT, ts_bot, 0, "beginning of tape") }, { FLDATAD (ATTN, ts_qatn, 0, "attention message pending") }, { FLDATAD (BOOT, ts_bcmd, 0, "boot request pending") }, { FLDATAD (OWNC, ts_ownc, 0, "if set, tape owns command buffer") }, @@ -401,6 +425,7 @@ switch ((PA >> 1) & 01) { /* decode PA<1> */ case 0: /* TSBA */ *data = tsba & DMASK; /* low 16b of ba */ break; + case 1: /* TSSR */ *data = tssr = ts_updtssr (tssr); /* update tssr */ break; @@ -433,7 +458,7 @@ switch ((PA >> 1) & 01) { /* decode PA<1> */ CLR_INT (TS); /* clr int req */ t = Map_ReadW (tsba, CMD_PLNT << 1, cpy_buf); /* read cmd pkt */ tsba = tsba + ((CMD_PLNT << 1) - t); /* incr tsba */ - if (t) { /* nxm? */ + if (t != 0) { /* nxm? */ ts_endcmd (TSSR_NXM + TC5, 0, MSG_ACK|MSG_MNEF|MSG_CFAIL); return SCPE_OK; } @@ -478,11 +503,11 @@ switch (st) { break; case MTSE_TMK: - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ return (XTC (XS0_TMK | XS0_RLS, TC2)); case MTSE_RECE: /* record in error */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ case MTSE_INVRL: /* invalid rec lnt */ case MTSE_IOERR: /* IO error */ default: /* unknown error */ @@ -497,6 +522,7 @@ switch (st) { case MTSE_BOT: /* reverse into BOT */ msgxs3 = msgxs3 | XS3_RIB; /* set status */ + ts_bot = 1; /* set BOT */ return (XTC (XS0_BOT | XS0_RLS, TC2)); /* tape alert */ case MTSE_WRP: /* write protect */ @@ -518,7 +544,7 @@ do { msgrfc = fc; if ((st = sim_tape_sprecf (uptr, &tbc))) /* space rec fwd, err? */ return ts_map_status (st); /* map status */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ } while (fc != 0); return 0; } @@ -536,7 +562,7 @@ do { st = sim_tape_sprecf (uptr, &tbc); /* space rec fwd */ if (st == MTSE_TMK) { /* tape mark? */ msgrfc = (msgrfc - 1) & DMASK; /* decr count */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ if (tmkprv && (wchopt & WCH_ESS)) /* 2nd tmk & ESS? */ return (XTC ((msgrfc? XS0_RLS: 0) | XS0_TMK | XS0_LET, TC2)); @@ -545,7 +571,7 @@ do { else if (st != MTSE_OK) return ts_map_status (st); else tmkprv = FALSE; /* not a tmk */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ } while (msgrfc != 0); return 0; } @@ -561,7 +587,7 @@ do { msgrfc = fc; if ((st = sim_tape_sprecr (uptr, &tbc))) /* space rec rev, err? */ return ts_map_status (st); /* map status */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ } while (fc != 0); return 0; } @@ -577,7 +603,7 @@ do { st = sim_tape_sprecr (uptr, &tbc); /* space rec rev */ if (st == MTSE_TMK) { /* tape mark? */ msgrfc = (msgrfc - 1) & DMASK; /* decr count */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ if (tmkprv && (wchopt & WCH_ESS)) /* 2nd tmk & ESS? */ return (XTC ((msgrfc? XS0_RLS: 0) | XS0_TMK | XS0_LET, TC2)); @@ -586,7 +612,7 @@ do { else if (st != MTSE_OK) return ts_map_status (st); else tmkprv = FALSE; /* not a tmk */ - msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ + ts_set_mot (0); /* tape has moved, !BOT */ } while (msgrfc != 0); return 0; } @@ -605,7 +631,7 @@ if (fc == 0) /* byte count */ fc = 0200000; tsba = (cmdadh << 16) | cmdadl; /* buf addr */ wbc = (tbc > fc)? fc: tbc; /* cap buf size */ -msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ +ts_set_mot (0); /* tape has moved, !BOT */ if (cmdhdr & CMD_SWP) { /* swapped? */ for (i = 0; i < wbc; i++) { /* copy buffer */ wa = tsba ^ 1; /* apply OPP */ @@ -620,7 +646,7 @@ if (cmdhdr & CMD_SWP) { /* swapped? */ else { t = Map_WriteB (tsba, wbc, tsxb); /* store record */ tsba = tsba + (wbc - t); /* update tsba */ - if (t) { /* nxm? */ + if (t != 0) { /* nxm? */ tssr = ts_updtssr (tssr | TSSR_NXM); /* set error */ return (XTC (XS0_RLS, TC4)); } @@ -647,7 +673,7 @@ if (fc == 0) /* byte count */ fc = 0200000; tsba = ((cmdadh << 16) | cmdadl) + fc; /* buf addr */ wbc = (tbc > fc)? fc: tbc; /* cap buf size */ -msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ +ts_set_mot (0); /* tape has moved, !BOT */ for (i = wbc; i > 0; i--) { /* copy buffer */ tsba = tsba - 1; wa = (cmdhdr & CMD_SWP)? tsba ^ 1: tsba; /* apply OPP */ @@ -687,14 +713,14 @@ if (cmdhdr & CMD_SWP) { /* swapped? */ else { t = Map_ReadB (tsba, fc, tsxb); /* fetch record */ tsba = tsba + (fc - t); /* update tsba */ - if (t) { /* nxm? */ + if (t != 0) { /* nxm? */ tssr = ts_updtssr (tssr | TSSR_NXM); return TC5; } } if ((st = sim_tape_wrrecf (uptr, tsxb, fc))) /* write rec, err? */ return ts_map_status (st); /* return status */ -msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ +ts_set_mot (0); /* tape has moved, !BOT */ msgrfc = 0; if (sim_tape_eot (&ts_unit)) /* EOT on write? */ return XTC (XS0_EOT, TC2); @@ -707,7 +733,7 @@ t_stat st; if ((st = sim_tape_wrtmk (uptr))) /* write tmk, err? */ return ts_map_status (st); /* return status */ -msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ +ts_set_mot (0); /* tape has moved, !BOT */ if (sim_tape_eot (&ts_unit)) /* EOT on write? */ return XTC (XS0_EOT, TC2); return XTC (XS0_TMK, TC0); @@ -738,7 +764,7 @@ static const char *fnc_name[CMD_N_FNC] = { "30", "31", "32", "33", "34", "35", "36", "37" }; -if (ts_bcmd) { /* boot? */ +if (ts_bcmd != 0) { /* boot? */ ts_bcmd = 0; /* clear flag */ sim_tape_rewind (uptr); /* rewind */ if (uptr->flags & UNIT_ATT) { /* attached? */ @@ -750,6 +776,7 @@ if (ts_bcmd) { /* boot? */ else tssr = ts_updtssr (tssr | TSSR_SSR | TC3); if (cmdhdr & CMD_IE) SET_INT (TS); + ts_bot = 0; /* unatt or !BOT */ return SCPE_OK; } @@ -792,7 +819,7 @@ if ((fnc_flg[fnc] & FLG_WR) && /* write? */ } if ((((fnc == FNC_READ) && (mod == 1)) || /* read rev */ ((fnc == FNC_POS) && (mod & 1))) && /* space rev */ - sim_tape_bot (uptr)) { /* BOT? */ + (ts_bot != 0)) { /* BOT? */ ts_endcmd (TC3, XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } @@ -805,9 +832,6 @@ st0 = st1 = 0; switch (fnc) { /* case on func */ case FNC_INIT: /* init */ - if (!sim_tape_bot (uptr)) /* set if tape moves */ - msgxs0 = msgxs0 | XS0_MOT; - sim_tape_rewind (uptr); /* rewind */ case FNC_WSSM: /* write mem */ case FNC_GSTA: /* get status */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); /* send end packet */ @@ -822,7 +846,7 @@ switch (fnc) { /* case on func */ bc = ((WCH_PLNT << 1) > cmdlnt)? cmdlnt: WCH_PLNT << 1; t = Map_ReadW (tsba, bc, cpy_buf); /* fetch packet */ tsba = tsba + (bc - t); /* inc tsba */ - if (t) { /* nxm? */ + if (t != 0) { /* nxm? */ ts_endcmd (TSSR_NBA | TSSR_NXM | TC5, 0, 0); return SCPE_OK; } @@ -844,11 +868,12 @@ switch (fnc) { /* case on func */ tssr = ts_updtssr (tssr | TSSR_SSR); /* set SSR */ if (wchopt & WCH_ERI) SET_INT (TS); - ts_ownc = 0; ts_ownm = 1; /* keep msg */ + ts_ownc = 0; + ts_ownm = 1; /* keep msg */ break; case 01: /* rewind and unload */ - if (!sim_tape_bot (uptr)) /* if tape moves */ + if (ts_bot == 0) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_detach (uptr); /* unload */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); @@ -863,9 +888,8 @@ switch (fnc) { /* case on func */ return SCPE_OK; case 04: /* rewind */ - if (!sim_tape_bot (uptr)) /* if tape moves */ - msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); + ts_set_mot (1); /* always moves, BOT */ ts_endcmd (TC0, XS0_BOT, MSG_ACK | MSG_CEND); break; } @@ -960,9 +984,8 @@ switch (fnc) { /* case on func */ break; case 04: /* rewind */ - if (!sim_tape_bot (uptr)) /* if tape moves */ - msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); + ts_set_mot (1); /* always moves, BOT */ break; } ts_cmpendcmd (st0, 0); @@ -983,6 +1006,13 @@ else t = t | TSSR_OFL; return (t & ~TSSR_MBZ); } +void ts_set_mot (int32 bot) +{ +msgxs0 = msgxs0 | XS0_MOT; /* tape has moved */ +ts_bot = bot; /* set BOT state */ +return; +} + int32 ts_updxs0 (int32 t) { t = (t & ~(XS0_ONL | XS0_WLK | XS0_BOT | XS0_IE)) | XS0_PET; @@ -990,7 +1020,7 @@ if (ts_unit.flags & UNIT_ATT) { t = t | XS0_ONL; if (sim_tape_wrp (&ts_unit)) t = t | XS0_WLK; - if (sim_tape_bot (&ts_unit)) + if (ts_bot != 0) t = (t | XS0_BOT) & ~XS0_EOT; if (sim_tape_eot (&ts_unit)) t = (t | XS0_EOT) & ~XS0_BOT; @@ -1056,6 +1086,9 @@ t_stat ts_reset (DEVICE *dptr) int32 i; sim_tape_rewind (&ts_unit); +if ((ts_unit.flags & UNIT_ATT) != 0) + ts_bot = 1; +else ts_bot = 0; tsba = tsdbx = 0; ts_ownc = ts_ownm = 0; ts_bcmd = 0; @@ -1085,6 +1118,7 @@ t_stat r; r = sim_tape_attach_ex (uptr, cptr, DBG_TAP, 0); /* attach unit */ if (r != SCPE_OK) /* error? */ return r; +ts_bot = 1; /* at BOT */ tssr = tssr & ~TSSR_OFL; /* clr offline */ if ((tssr & TSSR_NBA) || !(wchopt & WCH_EAI)) /* attn msg? */ return r; @@ -1108,6 +1142,7 @@ if (!(uptr->flags & UNIT_ATT)) /* attached? */ r = sim_tape_detach (uptr); /* detach unit */ if (r != SCPE_OK) return r; /* error? */ +ts_bot = 0; tssr = tssr | TSSR_OFL; /* set offline */ if ((tssr & TSSR_NBA) || !(wchopt & WCH_EAI)) /* attn msg? */ return r; diff --git a/PDP11/pdp11_tu.c b/PDP11/pdp11_tu.c index 2333806d..ddae4a81 100644 --- a/PDP11/pdp11_tu.c +++ b/PDP11/pdp11_tu.c @@ -1,6 +1,6 @@ /* pdp11_tu.c - PDP-11 TM02/TU16 TM03/TU45/TU77 Massbus magnetic tape controller - Copyright (c) 1993-2017, Robert M Supnik + Copyright (c) 1993-2023, 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"), @@ -25,6 +25,7 @@ tu TM02/TM03 magtape + 06-Nov-23 RMS Fixed BOT logic 28-Dec-17 RMS Read tape mark must set Massbus EXC 13-Mar-17 RMS Annotated fall through in switch 23-Oct-13 RMS Revised for new boot setup routine @@ -53,6 +54,10 @@ If the byte count is odd, the record is padded with an extra byte of junk. File marks are represented by a single record length of 0. End of tape is two consecutive end of file marks. + + BOT is not the same as POS == 0. BOT is set after rewinding or after + a reverse operation from before the first record. It is cleared by + any successful motion operation. */ #if defined (VM_PDP10) @@ -117,11 +122,12 @@ /* TUFS - formatter status - offset 1 + indicates kept in drive status ^ indicates calculated on the fly + Rewinding is a pseudo-status flag and never appears in TUFS */ #define FS_OF 1 #define FS_SAT 0000001 /* slave attention */ -#define FS_BOT 0000002 /* ^beginning of tape */ +#define FS_BOT 0000002 /* +beginning of tape */ #define FS_TMK 0000004 /* end of file */ #define FS_ID 0000010 /* ID burst detected */ #define FS_SLOW 0000020 /* slowing down NI */ @@ -129,7 +135,7 @@ #define FS_SSC 0000100 /* slave stat change */ #define FS_RDY 0000200 /* ^formatter ready */ #define FS_FPR 0000400 /* formatter present */ -#define FS_EOT 0002000 /* +end of tape */ +#define FS_EOT 0002000 /* ^end of tape */ #define FS_WRL 0004000 /* ^write locked */ #define FS_MOL 0010000 /* ^medium online */ #define FS_PIP 0020000 /* +pos in progress */ @@ -502,7 +508,7 @@ switch (fnc) { /* case on function */ tutc = tutc & ~TC_FCS; /* clear fc status */ tufs = tufs & ~(FS_SAT | FS_SSC | FS_ID | FS_ERR); sim_cancel (uptr); /* reset drive */ - uptr->USTAT = 0; + uptr->USTAT &= FS_BOT; /* fall through */ /* fall through */ case FNC_NOP: tucs1 = tucs1 & ~CS1_GO; /* no operation */ @@ -510,8 +516,10 @@ switch (fnc) { /* case on function */ case FNC_RIP: /* read-in preset */ tutc = TC_RIP; /* set tutc */ - sim_tape_rewind (&tu_unit[0]); /* rewind unit 0 */ - tu_unit[0].USTAT = 0; + if (tu_unit[0].flags & UNIT_ATT) { /* unit 0 attached? */ + sim_tape_rewind (&tu_unit[0]); /* rewind unit 0 */ + tu_unit[0].USTAT = FS_BOT; + } tucs1 = tucs1 & ~CS1_GO; tufs = tufs & ~FS_TMK; return SCPE_OK; @@ -556,7 +564,7 @@ switch (fnc) { /* case on function */ tu_set_er (ER_UNS); break; } - if (sim_tape_bot (uptr) || ((tutc & TC_FCS) == 0)) { + if ((uptr->USTAT & FS_BOT) || ((tutc & TC_FCS) == 0)) { tu_set_er (ER_NXF); break; } @@ -565,7 +573,7 @@ switch (fnc) { /* case on function */ case FNC_WCHKR: /* wchk = read */ case FNC_READR: /* read rev */ - if (tufs & FS_BOT) { /* beginning of tape? */ + if (uptr->USTAT & FS_BOT) { /* beginning of tape? */ tu_set_er (ER_NXF); break; } @@ -636,7 +644,9 @@ t_stat st, r = SCPE_OK; drv = (int32) (uptr - tu_dev.units); /* get drive # */ if (uptr->USTAT & FS_REW) { /* rewind or unload? */ sim_tape_rewind (uptr); /* rewind tape */ - uptr->USTAT = 0; /* clear status */ + if (uptr->flags & UNIT_ATT) /* standard rewind? */ + uptr->USTAT = FS_BOT; /* set BOT */ + else uptr->USTAT = 0; /* clear status */ tu_update_fs (FS_ATA | FS_SSC, drv); return SCPE_OK; } @@ -835,17 +845,13 @@ int32 act = sim_activate_time (&tu_unit[drv]); tufs = (tufs & ~FS_DYN) | FS_FPR | flg; if (tu_unit[drv].flags & UNIT_ATT) { - tufs = tufs | FS_MOL | tu_unit[drv].USTAT; + tufs = tufs | FS_MOL | (tu_unit[drv].USTAT & 0177777); if (tu_unit[drv].UDENS == TC_1600) tufs = tufs | FS_PE; if (sim_tape_wrp (&tu_unit[drv])) tufs = tufs | FS_WRL; - if (!act) { - if (sim_tape_bot (&tu_unit[drv])) - tufs = tufs | FS_BOT; - if (sim_tape_eot (&tu_unit[drv])) + if (!act && sim_tape_eot (&tu_unit[drv])) tufs = tufs | FS_EOT; - } } if (tuer) tufs = tufs | FS_ERR; @@ -904,6 +910,7 @@ switch (st) { break; case MTSE_BOT: /* reverse into BOT */ + tu_unit[drv].USTAT = FS_BOT; /* set BOT */ return SCPE_OK; case MTSE_WRP: /* write protect */ @@ -938,7 +945,10 @@ for (u = 0; u < TU_NUMDR; u++) { /* loop thru units */ uptr = tu_dev.units + u; sim_tape_reset (uptr); /* clear pos flag */ sim_cancel (uptr); /* cancel activity */ - uptr->USTAT = 0; + if ((uptr->flags & UNIT_ATT) && /* if attached */ + sim_tape_bot (uptr)) /* and BOT */ + uptr->USTAT = FS_BOT; /* set BOT */ + else uptr->USTAT = 0; } if (xbuf == NULL) xbuf = (uint8 *) calloc (MT_MAXFR + 4, sizeof (uint8)); @@ -961,7 +971,7 @@ t_stat r; r = sim_tape_attach (uptr, cptr); if (r != SCPE_OK) return r; -uptr->USTAT = 0; /* clear unit status */ +uptr->USTAT = FS_BOT; /* set BOT */ uptr->UDENS = UD_UNK; /* unknown density */ flg = FS_ATA | FS_SSC; /* set attention */ if (GET_DRV (tutc) == drv) /* sel drv? set SAT */