<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">This collection of patches resolves several problems, mainly with i1401's magnetic tape handling. With these patches applied, the Autocoder tape from the "Cincinatti" collection generates a system tape that in turn assembles the Autocoder. The patches are:<div><br></div><div>o Strip parity bit before ALT BCD blank test (previously reported)</div><div><br></div><div>o Fixed ZA/ZS bug, should not convert source to BCD (previously reported)</div><div><br></div><div>o Fixed end-of-reel indicator implementation</div><div><br></div><div>The original 1401 implemented a "tape indicate" latch per tape unit, i1401 implements a single global end-of-file indicator. i1401 resets its global end-of-file indicator more often than the original 1401 and under different circumstances. </div><div><br></div><div><div>(This paragraph is my working model for the operation of the 1401's "end-of-reel" indicator, reconstructed from references.)</div><div><br></div><div>The 1401 implements a "tape indicator" latch per tape drive. When a 1401 branch-on-indicator instruction addresses the "end-of-reel" indicator, the 1401 addresses the "tape indicator" latch in the currently selected <i>and</i> ready tape drive. The tape drive itself resets its "tape indicator" latch only when a tape unload occurs. Tape unload may be initiated by push button control or by the CPU "Rewind Tape and Unload" instruction. The tape drive sets the "tape indicator" latch when in write status and the end-of-reel reflective strip photocell is activated. The CPU resets the "tape indicator" latch in the selected <i>and</i> ready tape drive when the "end-of-reel" indicator is tested by a branch-on-indicator instruction. If no tape drive is selected, or the currently selected tape drive is not ready, the "end-of-reel" indicator will appear to be off and no "tape indicator" latch will be reset. The CPU sets the "tape indicator" latch in the selected <i>and</i> ready tape drive whenever it reads a tape-mark character in the first character position of a record. </div><div><br></div><div>References:</div><div>223-6988, "IBM 729 II, IV, V, VI Magnetic Tape Units, CE Instruction-Reference", IBM 1962, pg. 69</div><div>223-6845, "IBM 729 II, III, IV Magnetic Tape Units, CE Manual of Instruction", IBM 1959, pp. C60-C61, C100, C105, C109, C111-C112</div><div>TIE 5-0021, "IBM 1401, 1440 and 1460 Programming and Operating Techniques", IBM 1964, pg. J-8</div><div>A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM 1964, pg. F-6</div><div><br></div></div><div>o Added TM detection to tape diagnostic read op</div><div><br></div><div>The tape diagnostic read op should detect the presence of a TM as the first or only character of a record and set the tape drive's indicator latch as appropriate.</div><div><br></div><div>References:</div><div><div>A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM 1964, pg. F-5</div><div><br></div></div><div>o Fixed TM detection, TM may be 1st ch in multiple char rec</div><div><br></div><div>A tape mark is detected by a read or diagnostic read operation if it is the first or only character of a record.</div><div><br></div><div>References:</div><div><div>A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM 1964, pg. F-5</div><div><div>TIE 5-0021, "IBM 1401, 1440 and 1460 Programming and Operating Techniques", IBM 1964, pg. J-4</div><div><br></div></div></div><div>o Fixed tape-error indicator set and reset</div><div><br></div><div>The tape-error indicator is reset by any tape op.</div><div><br></div><div>References:</div><div><div>A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM 1964, pg. F-7</div><div><div>TIE 5-0021, "IBM 1401, 1440 and 1460 Programming and Operating Techniques", IBM 1964, pg. J-8</div><div><br></div></div></div><div>o Fixed memory leak in tape rewind-unload op</div><div><br></div><div>Opportunity fix.</div><div><br></div><div>o Fixed TM detect, mask off parity</div><div><br></div><div>Similar to "Strip parity bit before ALT BCD blank test" bug. Present in sim_tape.c, prevents TM detection when TM was written in binary mode on tape with C track intact. Also affects i7094 simulator.</div><div><br></div><div>Patch Follows</div><div>--------------------------------------------------------------</div><div><div>BobsG5:~/IBM_1401 babeles$ diff -rc simhv38-0 simh-tapefixes</div><div>Only in simh-tapefixes: BIN</div><div>diff -rc simhv38-0/I1401/i1401_cpu.c simh-tapefixes/I1401/i1401_cpu.c</div><div>*** simhv38-0/I1401/i1401_cpu.c Sat Jul  7 14:39:38 2007</div><div>--- simh-tapefixes/I1401/i1401_cpu.c    Mon Jul  7 18:13:41 2008</div><div>***************</div><div>*** 23,34 ****</div><div>     used in advertising or otherwise to promote the sale, use or other dealings</div><div>     in this Software without prior written authorization from Robert M Supnik.</div><div>  </div><div>     07-Jul-07    RMS     Removed restriction on load-mode binary tape</div><div>     28-Jun-07    RMS     Added support for SS overlap modifiers</div><div>     22-May-06    RMS     Fixed format error in CPU history (found by Peter Schorn)</div><div>     06-Mar-06    RMS     Fixed bug in divide (found by Van Snyder)</div><div>     22-Sep-05    RMS     Fixed declarations (from Sterling Garwood)</div><div>!    01-Sep-05  RMS     Removed error stops in MCE</div><div>     16-Aug-05    RMS     Fixed C++ declaration and cast problems</div><div>     02-Jun-05    RMS     Fixed SSB-SSG clearing on RESET</div><div>                          (reported by Ralph Reinke)</div><div>--- 23,37 ----</div><div>     used in advertising or otherwise to promote the sale, use or other dealings</div><div>     in this Software without prior written authorization from Robert M Supnik.</div><div>  </div><div>+    07-Jul-08    REA     Fixed end-of-reel indicator implementation</div><div>+    07-Jul-08    REA     Added TM detection to tape diagnostic read op</div><div>+    27-Jun-08    REA     Fixed ZA/ZS bug, should not convert source to BCD</div><div>     07-Jul-07    RMS     Removed restriction on load-mode binary tape</div><div>     28-Jun-07    RMS     Added support for SS overlap modifiers</div><div>     22-May-06    RMS     Fixed format error in CPU history (found by Peter Schorn)</div><div>     06-Mar-06    RMS     Fixed bug in divide (found by Van Snyder)</div><div>     22-Sep-05    RMS     Fixed declarations (from Sterling Garwood)</div><div>!    01-Sep-05    RMS     Removed error stops in MCE</div><div>     16-Aug-05    RMS     Fixed C++ declaration and cast problems</div><div>     02-Jun-05    RMS     Fixed SSB-SSG clearing on RESET</div><div>                          (reported by Ralph Reinke)</div><div>***************</div><div>*** 220,228 ****</div><div>  extern t_stat inq_io (int32 flag, int32 mod);</div><div>  extern t_stat mt_io (int32 unit, int32 flag, int32 mod);</div><div>  extern t_stat dp_io (int32 fnc, int32 flag, int32 mod);</div><div>! extern t_stat mt_func (int32 unit, int32 mod);</div><div>  extern t_stat sim_activate (UNIT *uptr, int32 delay);</div><div>  extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);</div><div>  </div><div>  /* CPU data structures</div><div>  </div><div>--- 223,232 ----</div><div>  extern t_stat inq_io (int32 flag, int32 mod);</div><div>  extern t_stat mt_io (int32 unit, int32 flag, int32 mod);</div><div>  extern t_stat dp_io (int32 fnc, int32 flag, int32 mod);</div><div>! extern t_stat mt_func (int32 unit, int32 mod, int32 bcd);</div><div>  extern t_stat sim_activate (UNIT *uptr, int32 delay);</div><div>  extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);</div><div>+ extern t_bool mt_testind();</div><div>  </div><div>  /* CPU data structures</div><div>  </div><div>***************</div><div>*** 802,807 ****</div><div>--- 806,816 ----</div><div>      case OP_B:                                          /* branch */</div><div>          if (ilnt == 4) { BRANCH; }                      /* uncond branch? */</div><div>          else if (ilnt == 5) {                           /* branch on ind? */</div><div>+             if (D == IN_END) {                          /* test tape indicator */</div><div>+                 if (mt_testind())</div><div>+                     { BRANCH; }</div><div>+                 else break;</div><div>+             }</div><div>              if (ind[D]) { BRANCH; }                     /* test indicator */</div><div>              if (ind_table[D]) ind[D] = 0;               /* reset if needed */</div><div>              }</div><div>***************</div><div>*** 868,874 ****</div><div>              if (a & WM) wm = M[BS] = (M[BS] & WM) | BCD_ZERO;</div><div>              else {</div><div>                  a = M[AS];                              /* get A char */</div><div>!                 t = (a & CHAR)? bin_to_bcd[a & DIGIT]: 0;</div><div>                  wm = M[BS] = (M[BS] & WM) | t;          /* move digit */</div><div>                  MM (AS);</div><div>                  }</div><div>--- 877,883 ----</div><div>              if (a & WM) wm = M[BS] = (M[BS] & WM) | BCD_ZERO;</div><div>              else {</div><div>                  a = M[AS];                              /* get A char */</div><div>!                 t = a & DIGIT;                          /* isolate digit bits */</div><div>                  wm = M[BS] = (M[BS] & WM) | t;          /* move digit */</div><div>                  MM (AS);</div><div>                  }</div><div>***************</div><div>*** 1056,1062 ****</div><div>          if (ilnt < 4) reason = STOP_INVL;               /* too short? */</div><div>          else if (ioind != BCD_PERCNT) reason = STOP_INVA;</div><div>          else if (reason = iomod (ilnt, D, mtf_mod)) break; /* valid modifier? */</div><div>!         reason = mt_func (unit, D);                     /* mt func, error? */</div><div>          break;                                          /* can't branch */</div><div>  </div><div>      case OP_RF: case OP_PF:                             /* read, punch feed */</div><div>--- 1065,1071 ----</div><div>          if (ilnt < 4) reason = STOP_INVL;               /* too short? */</div><div>          else if (ioind != BCD_PERCNT) reason = STOP_INVA;</div><div>          else if (reason = iomod (ilnt, D, mtf_mod)) break; /* valid modifier? */</div><div>!         reason = mt_func (unit, D, (dev == IO_MT));     /* mt func, error? */</div><div>          break;                                          /* can't branch */</div><div>  </div><div>      case OP_RF: case OP_PF:                             /* read, punch feed */</div><div>diff -rc simhv38-0/I1401/i1401_mt.c simh-tapefixes/I1401/i1401_mt.c</div><div>*** simhv38-0/I1401/i1401_mt.c  Sat Jul  7 14:40:32 2007</div><div>--- simh-tapefixes/I1401/i1401_mt.c     Mon Jul  7 18:14:01 2008</div><div>***************</div><div>*** 25,30 ****</div><div>--- 25,36 ----</div><div>  </div><div>     mt           7-track magtape</div><div>  </div><div>+    07-Jul-08    REA     Fixed memory leak in tape rewind-unload op</div><div>+    07-Jul-08    REA     Fixed tape-error indicator set and reset</div><div>+    07-Jul-08    REA     Fixed TM detection, TM may be 1st ch in multiple char rec</div><div>+    07-Jul-08    REA     Fixed end-of-reel indicator implementation</div><div>+    07-Jul-08    REA     Added TM detection to tape diagnostic read op</div><div>+    29-Jun-08    REA     Strip parity bit before ALT BCD blank test</div><div>     07-Jul-07    RMS     Removed restriction on load-mode binary tape</div><div>     28-Jun-07    RMS     Revised read tape mark behavior based on real hardware</div><div>                          (found by Van Snyder)</div><div>***************</div><div>*** 86,95 ****</div><div>--- 92,105 ----</div><div>  extern UNIT cpu_unit;</div><div>  extern FILE *sim_deb;</div><div>  </div><div>+ UNIT *mt_sel = NULL;                                    /* selected mt unit */</div><div>+ </div><div>  t_stat mt_reset (DEVICE *dptr);</div><div>  t_stat mt_boot (int32 unitno, DEVICE *dptr);</div><div>  t_stat mt_map_status (t_stat st);</div><div>  UNIT *get_unit (int32 unit);</div><div>+ t_stat mt_attach (UNIT *uptr, char *cp);</div><div>+ t_stat mt_detach (UNIT *uptr);</div><div>  </div><div>  /* MT data structures</div><div>  </div><div>***************</div><div>*** 115,123 ****</div><div>               UNIT_ROABLE + UNIT_BCD, 0) }</div><div>      };</div><div>  </div><div>  REG mt_reg[] = {</div><div>-     { FLDATA (END, ind[IN_END], 0) },</div><div>      { FLDATA (ERR, ind[IN_TAP], 0) },</div><div>      { DRDATA (POS1, mt_unit[1].pos, T_ADDR_W), PV_LEFT + REG_RO },</div><div>      { DRDATA (POS2, mt_unit[2].pos, T_ADDR_W), PV_LEFT + REG_RO },</div><div>      { DRDATA (POS3, mt_unit[3].pos, T_ADDR_W), PV_LEFT + REG_RO },</div><div>--- 125,141 ----</div><div>               UNIT_ROABLE + UNIT_BCD, 0) }</div><div>      };</div><div>  </div><div>+ #define UNIT_V_IND      (MTUF_V_UF + 0)                 /* tape indicator latch */</div><div>+ #define UNIT_IND        (1 << UNIT_V_IND)</div><div>+ </div><div>  REG mt_reg[] = {</div><div>      { FLDATA (ERR, ind[IN_TAP], 0) },</div><div>+     { FLDATA (IND1, mt_unit[1].flags, UNIT_V_IND) },</div><div>+     { FLDATA (IND2, mt_unit[2].flags, UNIT_V_IND) },</div><div>+     { FLDATA (IND3, mt_unit[3].flags, UNIT_V_IND) },</div><div>+     { FLDATA (IND4, mt_unit[4].flags, UNIT_V_IND) },</div><div>+     { FLDATA (IND5, mt_unit[5].flags, UNIT_V_IND) },</div><div>+     { FLDATA (IND6, mt_unit[6].flags, UNIT_V_IND) },</div><div>      { DRDATA (POS1, mt_unit[1].pos, T_ADDR_W), PV_LEFT + REG_RO },</div><div>      { DRDATA (POS2, mt_unit[2].pos, T_ADDR_W), PV_LEFT + REG_RO },</div><div>      { DRDATA (POS3, mt_unit[3].pos, T_ADDR_W), PV_LEFT + REG_RO },</div><div>***************</div><div>*** 141,147 ****</div><div>      "MT", mt_unit, mt_reg, mt_mod,</div><div>      MT_NUMDR, 10, 31, 1, 8, 8,</div><div>      NULL, NULL, &mt_reset,</div><div>!     &mt_boot, &sim_tape_attach, &sim_tape_detach,</div><div>      NULL, DEV_DEBUG</div><div>      };</div><div>  </div><div>--- 159,165 ----</div><div>      "MT", mt_unit, mt_reg, mt_mod,</div><div>      MT_NUMDR, 10, 31, 1, 8, 8,</div><div>      NULL, NULL, &mt_reset,</div><div>!     &mt_boot, &mt_attach, &mt_detach,</div><div>      NULL, DEV_DEBUG</div><div>      };</div><div>  </div><div>***************</div><div>*** 154,180 ****</div><div>          status  =       status</div><div>  */</div><div>  </div><div>! t_stat mt_func (int32 unit, int32 mod)</div><div>  {</div><div>! t_mtrlnt tbc;</div><div>  UNIT *uptr;</div><div>  t_stat st;</div><div>  </div><div>  if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid unit? */</div><div>  if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;   /* attached? */</div><div>  switch (mod) {                                          /* case on modifier */</div><div>  </div><div>      case BCD_A:                                         /* diagnostic read */</div><div>          if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,</div><div>              ">>MT%d: diagnostic read\n", unit);</div><div>!         ind[IN_END] = 0;                                /* clear end of file */</div><div>!         st = sim_tape_sprecf (uptr, &tbc);              /* space fwd */</div><div>          break;</div><div>  </div><div>      case BCD_B:                                         /* backspace */</div><div>          if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,</div><div>              ">>MT%d: backspace\n", unit);</div><div>-         ind[IN_END] = 0;                                /* clear end of file */</div><div>          st = sim_tape_sprecr (uptr, &tbc);              /* space rev */</div><div>          break;                                          /* end case */</div><div>  </div><div>--- 172,211 ----</div><div>          status  =       status</div><div>  */</div><div>  </div><div>! t_stat mt_func (int32 unit, int32 mod, int32 bcd)</div><div>  {</div><div>! t_mtrlnt i, tbc;</div><div>  UNIT *uptr;</div><div>  t_stat st;</div><div>  </div><div>+ ind[IN_TAP] = 0;                                        /* clear error */</div><div>  if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid unit? */</div><div>+ mt_sel = uptr;                                          /* select mt unit */</div><div>  if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;   /* attached? */</div><div>+ </div><div>  switch (mod) {                                          /* case on modifier */</div><div>  </div><div>      case BCD_A:                                         /* diagnostic read */</div><div>          if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,</div><div>              ">>MT%d: diagnostic read\n", unit);</div><div>!         st = sim_tape_rdrecf (uptr, dbuf, &tbc, MT_MAXFR); /* read rec */</div><div>!         if (st == MTSE_RECE) ind[IN_TAP] = 1;           /* rec in error? */</div><div>!         else if (st == MTSE_TMK) {                      /* tape mark? */</div><div>!             tbc = 1;                                    /* one char read */</div><div>!             dbuf[0] = BCD_TAPMRK;                       /* BCD tapemark */</div><div>!             }</div><div>!         else if (st != MTSE_OK) {                       /* stop on error */</div><div>!             if (DEBUG_PRS (mt_dev))</div><div>!                 fprintf (sim_deb, ", stopped by status = %d\n", st);</div><div>!             break;</div><div>!             }</div><div>!         if ((dbuf[0] & CHAR) == BCD_TAPMRK)</div><div>!             st = MTSE_TMK;                              /* TM 1st ch in buf */</div><div>          break;</div><div>  </div><div>      case BCD_B:                                         /* backspace */</div><div>          if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,</div><div>              ">>MT%d: backspace\n", unit);</div><div>          st = sim_tape_sprecr (uptr, &tbc);              /* space rev */</div><div>          break;                                          /* end case */</div><div>  </div><div>***************</div><div>*** 200,206 ****</div><div>          if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,</div><div>              ">>MT%d: rewind and unload\n", unit);</div><div>          sim_tape_rewind (uptr);                         /* update position */</div><div>!         return detach_unit (uptr);                      /* detach */</div><div>  </div><div>      default:</div><div>          return STOP_INVM;</div><div>--- 231,238 ----</div><div>          if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,</div><div>              ">>MT%d: rewind and unload\n", unit);</div><div>          sim_tape_rewind (uptr);                         /* update position */</div><div>!         st = mt_detach (uptr);                          /* detach */</div><div>!         break;</div><div>  </div><div>      default:</div><div>          return STOP_INVM;</div><div>***************</div><div>*** 233,239 ****</div><div>--- 265,274 ----</div><div>  t_bool passed_eot;</div><div>  UNIT *uptr;</div><div>  </div><div>+ ind[IN_TAP] = 0;                                        /* clear error */</div><div>+ </div><div>  if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid unit? */</div><div>+ mt_sel = uptr;                                          /* select mt unit */</div><div>  if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;   /* attached? */</div><div>  </div><div>  switch (mod) {</div><div>***************</div><div>*** 241,252 ****</div><div>      case BCD_R:                                         /* read */</div><div>          if (DEBUG_PRS (mt_dev))</div><div>              fprintf (sim_deb, ">>MT%d: read from %d", unit, BS);</div><div>-         ind[IN_TAP] = ind[IN_END] = 0;                  /* clear error */</div><div>          wm_seen = 0;                                    /* no word mk seen */</div><div>          st = sim_tape_rdrecf (uptr, dbuf, &tbc, MT_MAXFR); /* read rec */</div><div>          if (st == MTSE_RECE) ind[IN_TAP] = 1;           /* rec in error? */</div><div>          else if (st == MTSE_TMK) {                      /* tape mark? */</div><div>-             ind[IN_END] = 1;                            /* set indicator */</div><div>              tbc = 1;                                    /* one char read */</div><div>              dbuf[0] = BCD_TAPMRK;                       /* BCD tapemark */</div><div>              }</div><div>--- 276,285 ----</div><div>***************</div><div>*** 255,260 ****</div><div>--- 288,295 ----</div><div>                  fprintf (sim_deb, ", stopped by status = %d\n", st);</div><div>              break;</div><div>              }</div><div>+         if ((dbuf[0] & CHAR) == BCD_TAPMRK)</div><div>+             mt_sel->flags |= UNIT_IND;                  /* TM 1st ch in buf */</div><div>          for (i = 0; i < tbc; i++) {                     /* loop thru buf */</div><div>              if (M[BS] == (BCD_GRPMRK + WM)) {           /* GWM in memory? */</div><div>                  if (DEBUG_PRS (mt_dev))</div><div>***************</div><div>*** 266,272 ****</div><div>                      }</div><div>                  return SCPE_OK;                         /* done */</div><div>                  }</div><div>!             t = dbuf[i];                                /* get char */</div><div>              if (!(flag & MD_BIN) && (t == BCD_ALT))     /* BCD mode alt blank? */</div><div>                  t = BCD_BLANK;                          /* real blank */</div><div>              if (flag & MD_WM) {                         /* word mk mode? */</div><div>--- 301,307 ----</div><div>                      }</div><div>                  return SCPE_OK;                         /* done */</div><div>                  }</div><div>!             t = dbuf[i] & CHAR;                         /* get char */</div><div>              if (!(flag & MD_BIN) && (t == BCD_ALT))     /* BCD mode alt blank? */</div><div>                  t = BCD_BLANK;                          /* real blank */</div><div>              if (flag & MD_WM) {                         /* word mk mode? */</div><div>***************</div><div>*** 302,308 ****</div><div>          if (M[BS] == (BCD_GRPMRK + WM)) return STOP_MTZ;/* eor? */</div><div>          if (DEBUG_PRS (mt_dev))</div><div>              fprintf (sim_deb, ">>MT%d: write from %d", unit, BS);</div><div>-         ind[IN_TAP] = ind[IN_END] = 0;                  /* clear error */</div><div>          for (tbc = 0; (t = M[BS++]) != (BCD_GRPMRK + WM); ) {</div><div>              if ((t & WM) && (flag & MD_WM))             /* WM in wm mode? */</div><div>                  dbuf[tbc++] = BCD_WM;</div><div>--- 337,342 ----</div><div>***************</div><div>*** 360,366 ****</div><div>          return SCPE_MTRLNT;</div><div>  </div><div>      case MTSE_TMK:                                      /* end of file */</div><div>!         ind[IN_END] = 1;                                /* set end mark */</div><div>          break;</div><div>  </div><div>      case MTSE_IOERR:                                    /* IO error */</div><div>--- 394,400 ----</div><div>          return SCPE_MTRLNT;</div><div>  </div><div>      case MTSE_TMK:                                      /* end of file */</div><div>!         mt_sel->flags |= UNIT_IND;                      /* set indicate latch */</div><div>          break;</div><div>  </div><div>      case MTSE_IOERR:                                    /* IO error */</div><div>***************</div><div>*** 380,385 ****</div><div>--- 414,432 ----</div><div>  return SCPE_OK;</div><div>  }</div><div>  </div><div>+ /* Test and reset selected tape drive's indicator latch */</div><div>+ </div><div>+ t_bool mt_testind ()</div><div>+ {</div><div>+ t_bool v;</div><div>+ if (!mt_sel) return FALSE;                              /* any mt selected? */</div><div>+ if (!(mt_sel->flags & UNIT_ATT)) return FALSE;          /* attached? */</div><div>+ </div><div>+ v = mt_sel->flags & UNIT_IND;                           /* save latch */</div><div>+ mt_sel->flags &= ~UNIT_IND;                             /* reset latch */</div><div>+ return (v);</div><div>+ }</div><div>+ </div><div>  /* Reset routine */</div><div>  </div><div>  t_stat mt_reset (DEVICE *dptr)</div><div>***************</div><div>*** 387,396 ****</div><div>  int32 i;</div><div>  UNIT *uptr;</div><div>  </div><div>! for (i = 0; i < MT_NUMDR; i++) {                        /* clear pos flag */</div><div>!     if (uptr = get_unit (i)) MT_CLR_PNU (uptr);</div><div>      }</div><div>! ind[IN_END] = ind[IN_TAP] = 0;                          /* clear indicators */</div><div>  return SCPE_OK;</div><div>  }</div><div>  </div><div>--- 434,450 ----</div><div>  int32 i;</div><div>  UNIT *uptr;</div><div>  </div><div>! for (i = 0; i < MT_NUMDR; i++) {                        /* per drive resets */</div><div>!     if (uptr = get_unit (i)) {</div><div>!         MT_CLR_PNU (uptr);                              /* clear pos flag */</div><div>!         uptr->flags &= ~UNIT_IND;                       /* clear ind latch */</div><div>      }</div><div>! }</div><div>! </div><div>! ind[IN_TAP] = 0;                                        /* clear mt error ind */</div><div>! </div><div>! mt_sel = NULL;                                          /* clear unit select */</div><div>! </div><div>  return SCPE_OK;</div><div>  }</div><div>  </div><div>***************</div><div>*** 406,408 ****</div><div>--- 460,480 ----</div><div>  saved_IS = 1;</div><div>  return SCPE_OK;</div><div>  }</div><div>+ </div><div>+ /* Attach routine */</div><div>+ </div><div>+ t_stat mt_attach (UNIT *uptr, char *cp)</div><div>+ {</div><div>+     uptr->flags &= ~UNIT_IND;                           /* reset indicator latch */</div><div>+     </div><div>+     return sim_tape_attach(uptr, cp);                   /* tape unit attach */</div><div>+ }</div><div>+ </div><div>+ /* Detach routine */</div><div>+ </div><div>+ t_stat mt_detach (UNIT *uptr)</div><div>+ {</div><div>+     uptr->flags &= ~UNIT_IND;                           /* reset indicator latch */</div><div>+     </div><div>+     return sim_tape_detach(uptr);                       /* tape unit detach */</div><div>+ }</div><div>diff -rc simhv38-0/sim_tape.c simh-tapefixes/sim_tape.c</div><div>*** simhv38-0/sim_tape.c        Wed Jan 24 21:58:58 2007</div><div>--- simh-tapefixes/sim_tape.c   Mon Jul  7 17:15:58 2008</div><div>***************</div><div>*** 26,31 ****</div><div>--- 26,32 ----</div><div>     Ultimately, this will be a place to hide processing of various tape formats,</div><div>     as well as OS-specific direct hardware access.</div><div>  </div><div>+    07-Jul-08    REA     Fixed TM detect, mask off parity</div><div>     23-Jan-07    JDB     Fixed backspace over gap at BOT</div><div>     22-Jan-07    RMS     Fixed bug in P7B format read reclnt rev (found by Rich Cornwell)</div><div>     15-Dec-06    RMS     Added support for small capacity tapes</div><div>***************</div><div>*** 240,246 ****</div><div>                  break;                                  /* treat like eor */</div><div>                  }</div><div>              if ((sbc != 0) && (c & P7B_SOR)) break;     /* next record? */</div><div>!             if ((c & P7B_DPAR) != P7B_EOF) all_eof = 0;</div><div>              }</div><div>          *bc = sbc;                                      /* save rec lnt */</div><div>          sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for read */</div><div>--- 241,247 ----</div><div>                  break;                                  /* treat like eor */</div><div>                  }</div><div>              if ((sbc != 0) && (c & P7B_SOR)) break;     /* next record? */</div><div>!             if ((c & P7B_DATA) != P7B_EOF) all_eof = 0;</div><div>              }</div><div>          *bc = sbc;                                      /* save rec lnt */</div><div>          sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for read */</div><div>***************</div><div>*** 336,342 ****</div><div>              if (ferror (uptr->fileref))                 /* error? */</div><div>                  return sim_tape_ioerr (uptr);</div><div>              if (feof (uptr->fileref)) return MTSE_EOM;  /* eof? */</div><div>!             if ((c & P7B_DPAR) != P7B_EOF) all_eof = 0;</div><div>              if (c & P7B_SOR) break;                     /* start of record? */</div><div>              }</div><div>          uptr->pos = uptr->pos - sbc;                    /* update position */</div><div>--- 337,343 ----</div><div>              if (ferror (uptr->fileref))                 /* error? */</div><div>                  return sim_tape_ioerr (uptr);</div><div>              if (feof (uptr->fileref)) return MTSE_EOM;  /* eof? */</div><div>!             if ((c & P7B_DATA) != P7B_EOF) all_eof = 0;</div><div>              if (c & P7B_SOR) break;                     /* start of record? */</div><div>              }</div><div>          uptr->pos = uptr->pos - sbc;                    /* update position */</div><div><br></div></div><div>---------------------------------------------------------------</div><div>end of patch</div></body></html>