[Simh] i1401 Bugs: Tape Handling

Bob Abeles bobabeles at checkerboardsolutions.com
Mon Jul 7 21:33:12 EDT 2008


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:

o Strip parity bit before ALT BCD blank test (previously reported)

o Fixed ZA/ZS bug, should not convert source to BCD (previously  
reported)

o Fixed end-of-reel indicator implementation

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.

(This paragraph is my working model for the operation of the 1401's  
"end-of-reel" indicator, reconstructed from references.)

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 and 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 and 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 and ready tape drive whenever it reads a tape- 
mark character in the first character position of a record.

References:
223-6988, "IBM 729 II, IV, V, VI Magnetic Tape Units, CE Instruction- 
Reference", IBM 1962, pg. 69
223-6845, "IBM 729 II, III, IV Magnetic Tape Units, CE Manual of  
Instruction", IBM 1959, pp. C60-C61, C100, C105, C109, C111-C112
TIE 5-0021, "IBM 1401, 1440 and 1460 Programming and Operating  
Techniques", IBM 1964, pg. J-8
A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM  
1964, pg. F-6

o Added TM detection to tape diagnostic read op

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.

References:
A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM  
1964, pg. F-5

o Fixed TM detection, TM may be 1st ch in multiple char rec

A tape mark is detected by a read or diagnostic read operation if it  
is the first or only character of a record.

References:
A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM  
1964, pg. F-5
TIE 5-0021, "IBM 1401, 1440 and 1460 Programming and Operating  
Techniques", IBM 1964, pg. J-4

o Fixed tape-error indicator set and reset

The tape-error indicator is reset by any tape op.

References:
A24-3069-2, "Tape Input/Output Instructions, IBM 1401 1460", IBM  
1964, pg. F-7
TIE 5-0021, "IBM 1401, 1440 and 1460 Programming and Operating  
Techniques", IBM 1964, pg. J-8

o Fixed memory leak in tape rewind-unload op

Opportunity fix.

o Fixed TM detect, mask off parity

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.

Patch Follows
--------------------------------------------------------------
BobsG5:~/IBM_1401 babeles$ diff -rc simhv38-0 simh-tapefixes
Only in simh-tapefixes: BIN
diff -rc simhv38-0/I1401/i1401_cpu.c simh-tapefixes/I1401/i1401_cpu.c
*** simhv38-0/I1401/i1401_cpu.c Sat Jul  7 14:39:38 2007
--- simh-tapefixes/I1401/i1401_cpu.c    Mon Jul  7 18:13:41 2008
***************
*** 23,34 ****
      used in advertising or otherwise to promote the sale, use or  
other dealings
      in this Software without prior written authorization from  
Robert M Supnik.

      07-Jul-07    RMS     Removed restriction on load-mode binary tape
      28-Jun-07    RMS     Added support for SS overlap modifiers
      22-May-06    RMS     Fixed format error in CPU history (found  
by Peter Schorn)
      06-Mar-06    RMS     Fixed bug in divide (found by Van Snyder)
      22-Sep-05    RMS     Fixed declarations (from Sterling Garwood)
!    01-Sep-05  RMS     Removed error stops in MCE
      16-Aug-05    RMS     Fixed C++ declaration and cast problems
      02-Jun-05    RMS     Fixed SSB-SSG clearing on RESET
                           (reported by Ralph Reinke)
--- 23,37 ----
      used in advertising or otherwise to promote the sale, use or  
other dealings
      in this Software without prior written authorization from  
Robert M Supnik.

+    07-Jul-08    REA     Fixed end-of-reel indicator implementation
+    07-Jul-08    REA     Added TM detection to tape diagnostic read op
+    27-Jun-08    REA     Fixed ZA/ZS bug, should not convert source  
to BCD
      07-Jul-07    RMS     Removed restriction on load-mode binary tape
      28-Jun-07    RMS     Added support for SS overlap modifiers
      22-May-06    RMS     Fixed format error in CPU history (found  
by Peter Schorn)
      06-Mar-06    RMS     Fixed bug in divide (found by Van Snyder)
      22-Sep-05    RMS     Fixed declarations (from Sterling Garwood)
!    01-Sep-05    RMS     Removed error stops in MCE
      16-Aug-05    RMS     Fixed C++ declaration and cast problems
      02-Jun-05    RMS     Fixed SSB-SSG clearing on RESET
                           (reported by Ralph Reinke)
***************
*** 220,228 ****
   extern t_stat inq_io (int32 flag, int32 mod);
   extern t_stat mt_io (int32 unit, int32 flag, int32 mod);
   extern t_stat dp_io (int32 fnc, int32 flag, int32 mod);
! extern t_stat mt_func (int32 unit, int32 mod);
   extern t_stat sim_activate (UNIT *uptr, int32 delay);
   extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,  
UNIT *uptr, int32 sw);

   /* CPU data structures

--- 223,232 ----
   extern t_stat inq_io (int32 flag, int32 mod);
   extern t_stat mt_io (int32 unit, int32 flag, int32 mod);
   extern t_stat dp_io (int32 fnc, int32 flag, int32 mod);
! extern t_stat mt_func (int32 unit, int32 mod, int32 bcd);
   extern t_stat sim_activate (UNIT *uptr, int32 delay);
   extern t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,  
UNIT *uptr, int32 sw);
+ extern t_bool mt_testind();

   /* CPU data structures

***************
*** 802,807 ****
--- 806,816 ----
       case OP_B:                                          /* branch */
           if (ilnt == 4) { BRANCH; }                      /* uncond  
branch? */
           else if (ilnt == 5) {                           /* branch  
on ind? */
+             if (D == IN_END) {                          /* test  
tape indicator */
+                 if (mt_testind())
+                     { BRANCH; }
+                 else break;
+             }
               if (ind[D]) { BRANCH; }                     /* test  
indicator */
               if (ind_table[D]) ind[D] = 0;               /* reset  
if needed */
               }
***************
*** 868,874 ****
               if (a & WM) wm = M[BS] = (M[BS] & WM) | BCD_ZERO;
               else {
                   a = M[AS];                              /* get A  
char */
!                 t = (a & CHAR)? bin_to_bcd[a & DIGIT]: 0;
                   wm = M[BS] = (M[BS] & WM) | t;          /* move  
digit */
                   MM (AS);
                   }
--- 877,883 ----
               if (a & WM) wm = M[BS] = (M[BS] & WM) | BCD_ZERO;
               else {
                   a = M[AS];                              /* get A  
char */
!                 t = a & DIGIT;                          /* isolate  
digit bits */
                   wm = M[BS] = (M[BS] & WM) | t;          /* move  
digit */
                   MM (AS);
                   }
***************
*** 1056,1062 ****
           if (ilnt < 4) reason = STOP_INVL;               /* too  
short? */
           else if (ioind != BCD_PERCNT) reason = STOP_INVA;
           else if (reason = iomod (ilnt, D, mtf_mod)) break; /*  
valid modifier? */
!         reason = mt_func (unit, D);                     /* mt func,  
error? */
           break;                                          /* can't  
branch */

       case OP_RF: case OP_PF:                             /* read,  
punch feed */
--- 1065,1071 ----
           if (ilnt < 4) reason = STOP_INVL;               /* too  
short? */
           else if (ioind != BCD_PERCNT) reason = STOP_INVA;
           else if (reason = iomod (ilnt, D, mtf_mod)) break; /*  
valid modifier? */
!         reason = mt_func (unit, D, (dev == IO_MT));     /* mt func,  
error? */
           break;                                          /* can't  
branch */

       case OP_RF: case OP_PF:                             /* read,  
punch feed */
diff -rc simhv38-0/I1401/i1401_mt.c simh-tapefixes/I1401/i1401_mt.c
*** simhv38-0/I1401/i1401_mt.c  Sat Jul  7 14:40:32 2007
--- simh-tapefixes/I1401/i1401_mt.c     Mon Jul  7 18:14:01 2008
***************
*** 25,30 ****
--- 25,36 ----

      mt           7-track magtape

+    07-Jul-08    REA     Fixed memory leak in tape rewind-unload op
+    07-Jul-08    REA     Fixed tape-error indicator set and reset
+    07-Jul-08    REA     Fixed TM detection, TM may be 1st ch in  
multiple char rec
+    07-Jul-08    REA     Fixed end-of-reel indicator implementation
+    07-Jul-08    REA     Added TM detection to tape diagnostic read op
+    29-Jun-08    REA     Strip parity bit before ALT BCD blank test
      07-Jul-07    RMS     Removed restriction on load-mode binary tape
      28-Jun-07    RMS     Revised read tape mark behavior based on  
real hardware
                           (found by Van Snyder)
***************
*** 86,95 ****
--- 92,105 ----
   extern UNIT cpu_unit;
   extern FILE *sim_deb;

+ UNIT *mt_sel = NULL;                                    /* selected  
mt unit */
+
   t_stat mt_reset (DEVICE *dptr);
   t_stat mt_boot (int32 unitno, DEVICE *dptr);
   t_stat mt_map_status (t_stat st);
   UNIT *get_unit (int32 unit);
+ t_stat mt_attach (UNIT *uptr, char *cp);
+ t_stat mt_detach (UNIT *uptr);

   /* MT data structures

***************
*** 115,123 ****
                UNIT_ROABLE + UNIT_BCD, 0) }
       };

   REG mt_reg[] = {
-     { FLDATA (END, ind[IN_END], 0) },
       { FLDATA (ERR, ind[IN_TAP], 0) },
       { DRDATA (POS1, mt_unit[1].pos, T_ADDR_W), PV_LEFT + REG_RO },
       { DRDATA (POS2, mt_unit[2].pos, T_ADDR_W), PV_LEFT + REG_RO },
       { DRDATA (POS3, mt_unit[3].pos, T_ADDR_W), PV_LEFT + REG_RO },
--- 125,141 ----
                UNIT_ROABLE + UNIT_BCD, 0) }
       };

+ #define UNIT_V_IND      (MTUF_V_UF + 0)                 /* tape  
indicator latch */
+ #define UNIT_IND        (1 << UNIT_V_IND)
+
   REG mt_reg[] = {
       { FLDATA (ERR, ind[IN_TAP], 0) },
+     { FLDATA (IND1, mt_unit[1].flags, UNIT_V_IND) },
+     { FLDATA (IND2, mt_unit[2].flags, UNIT_V_IND) },
+     { FLDATA (IND3, mt_unit[3].flags, UNIT_V_IND) },
+     { FLDATA (IND4, mt_unit[4].flags, UNIT_V_IND) },
+     { FLDATA (IND5, mt_unit[5].flags, UNIT_V_IND) },
+     { FLDATA (IND6, mt_unit[6].flags, UNIT_V_IND) },
       { DRDATA (POS1, mt_unit[1].pos, T_ADDR_W), PV_LEFT + REG_RO },
       { DRDATA (POS2, mt_unit[2].pos, T_ADDR_W), PV_LEFT + REG_RO },
       { DRDATA (POS3, mt_unit[3].pos, T_ADDR_W), PV_LEFT + REG_RO },
***************
*** 141,147 ****
       "MT", mt_unit, mt_reg, mt_mod,
       MT_NUMDR, 10, 31, 1, 8, 8,
       NULL, NULL, &mt_reset,
!     &mt_boot, &sim_tape_attach, &sim_tape_detach,
       NULL, DEV_DEBUG
       };

--- 159,165 ----
       "MT", mt_unit, mt_reg, mt_mod,
       MT_NUMDR, 10, 31, 1, 8, 8,
       NULL, NULL, &mt_reset,
!     &mt_boot, &mt_attach, &mt_detach,
       NULL, DEV_DEBUG
       };

***************
*** 154,180 ****
           status  =       status
   */

! t_stat mt_func (int32 unit, int32 mod)
   {
! t_mtrlnt tbc;
   UNIT *uptr;
   t_stat st;

   if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid  
unit? */
   if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;   /*  
attached? */
   switch (mod) {                                          /* case on  
modifier */

       case BCD_A:                                         /*  
diagnostic read */
           if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,
               ">>MT%d: diagnostic read\n", unit);
!         ind[IN_END] = 0;                                /* clear  
end of file */
!         st = sim_tape_sprecf (uptr, &tbc);              /* space  
fwd */
           break;

       case BCD_B:                                         /*  
backspace */
           if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,
               ">>MT%d: backspace\n", unit);
-         ind[IN_END] = 0;                                /* clear  
end of file */
           st = sim_tape_sprecr (uptr, &tbc);              /* space  
rev */
           break;                                          /* end  
case */

--- 172,211 ----
           status  =       status
   */

! t_stat mt_func (int32 unit, int32 mod, int32 bcd)
   {
! t_mtrlnt i, tbc;
   UNIT *uptr;
   t_stat st;

+ ind[IN_TAP] = 0;                                        /* clear  
error */
   if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid  
unit? */
+ mt_sel = uptr;                                          /* select  
mt unit */
   if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;   /*  
attached? */
+
   switch (mod) {                                          /* case on  
modifier */

       case BCD_A:                                         /*  
diagnostic read */
           if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,
               ">>MT%d: diagnostic read\n", unit);
!         st = sim_tape_rdrecf (uptr, dbuf, &tbc, MT_MAXFR); /* read  
rec */
!         if (st == MTSE_RECE) ind[IN_TAP] = 1;           /* rec in  
error? */
!         else if (st == MTSE_TMK) {                      /* tape  
mark? */
!             tbc = 1;                                    /* one char  
read */
!             dbuf[0] = BCD_TAPMRK;                       /* BCD  
tapemark */
!             }
!         else if (st != MTSE_OK) {                       /* stop on  
error */
!             if (DEBUG_PRS (mt_dev))
!                 fprintf (sim_deb, ", stopped by status = %d\n", st);
!             break;
!             }
!         if ((dbuf[0] & CHAR) == BCD_TAPMRK)
!             st = MTSE_TMK;                              /* TM 1st  
ch in buf */
           break;

       case BCD_B:                                         /*  
backspace */
           if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,
               ">>MT%d: backspace\n", unit);
           st = sim_tape_sprecr (uptr, &tbc);              /* space  
rev */
           break;                                          /* end  
case */

***************
*** 200,206 ****
           if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,
               ">>MT%d: rewind and unload\n", unit);
           sim_tape_rewind (uptr);                         /* update  
position */
!         return detach_unit (uptr);                      /* detach */

       default:
           return STOP_INVM;
--- 231,238 ----
           if (DEBUG_PRS (mt_dev)) fprintf (sim_deb,
               ">>MT%d: rewind and unload\n", unit);
           sim_tape_rewind (uptr);                         /* update  
position */
!         st = mt_detach (uptr);                          /* detach */
!         break;

       default:
           return STOP_INVM;
***************
*** 233,239 ****
--- 265,274 ----
   t_bool passed_eot;
   UNIT *uptr;

+ ind[IN_TAP] = 0;                                        /* clear  
error */
+
   if ((uptr = get_unit (unit)) == NULL) return STOP_INVMTU; /* valid  
unit? */
+ mt_sel = uptr;                                          /* select  
mt unit */
   if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT;   /*  
attached? */

   switch (mod) {
***************
*** 241,252 ****
       case BCD_R:                                         /* read */
           if (DEBUG_PRS (mt_dev))
               fprintf (sim_deb, ">>MT%d: read from %d", unit, BS);
-         ind[IN_TAP] = ind[IN_END] = 0;                  /* clear  
error */
           wm_seen = 0;                                    /* no word  
mk seen */
           st = sim_tape_rdrecf (uptr, dbuf, &tbc, MT_MAXFR); /* read  
rec */
           if (st == MTSE_RECE) ind[IN_TAP] = 1;           /* rec in  
error? */
           else if (st == MTSE_TMK) {                      /* tape  
mark? */
-             ind[IN_END] = 1;                            /* set  
indicator */
               tbc = 1;                                    /* one  
char read */
               dbuf[0] = BCD_TAPMRK;                       /* BCD  
tapemark */
               }
--- 276,285 ----
***************
*** 255,260 ****
--- 288,295 ----
                   fprintf (sim_deb, ", stopped by status = %d\n", st);
               break;
               }
+         if ((dbuf[0] & CHAR) == BCD_TAPMRK)
+             mt_sel->flags |= UNIT_IND;                  /* TM 1st  
ch in buf */
           for (i = 0; i < tbc; i++) {                     /* loop  
thru buf */
               if (M[BS] == (BCD_GRPMRK + WM)) {           /* GWM in  
memory? */
                   if (DEBUG_PRS (mt_dev))
***************
*** 266,272 ****
                       }
                   return SCPE_OK;                         /* done */
                   }
!             t = dbuf[i];                                /* get char */
               if (!(flag & MD_BIN) && (t == BCD_ALT))     /* BCD  
mode alt blank? */
                   t = BCD_BLANK;                          /* real  
blank */
               if (flag & MD_WM) {                         /* word mk  
mode? */
--- 301,307 ----
                       }
                   return SCPE_OK;                         /* done */
                   }
!             t = dbuf[i] & CHAR;                         /* get char */
               if (!(flag & MD_BIN) && (t == BCD_ALT))     /* BCD  
mode alt blank? */
                   t = BCD_BLANK;                          /* real  
blank */
               if (flag & MD_WM) {                         /* word mk  
mode? */
***************
*** 302,308 ****
           if (M[BS] == (BCD_GRPMRK + WM)) return STOP_MTZ;/* eor? */
           if (DEBUG_PRS (mt_dev))
               fprintf (sim_deb, ">>MT%d: write from %d", unit, BS);
-         ind[IN_TAP] = ind[IN_END] = 0;                  /* clear  
error */
           for (tbc = 0; (t = M[BS++]) != (BCD_GRPMRK + WM); ) {
               if ((t & WM) && (flag & MD_WM))             /* WM in  
wm mode? */
                   dbuf[tbc++] = BCD_WM;
--- 337,342 ----
***************
*** 360,366 ****
           return SCPE_MTRLNT;

       case MTSE_TMK:                                      /* end of  
file */
!         ind[IN_END] = 1;                                /* set end  
mark */
           break;

       case MTSE_IOERR:                                    /* IO  
error */
--- 394,400 ----
           return SCPE_MTRLNT;

       case MTSE_TMK:                                      /* end of  
file */
!         mt_sel->flags |= UNIT_IND;                      /* set  
indicate latch */
           break;

       case MTSE_IOERR:                                    /* IO  
error */
***************
*** 380,385 ****
--- 414,432 ----
   return SCPE_OK;
   }

+ /* Test and reset selected tape drive's indicator latch */
+
+ t_bool mt_testind ()
+ {
+ t_bool v;
+ if (!mt_sel) return FALSE;                              /* any mt  
selected? */
+ if (!(mt_sel->flags & UNIT_ATT)) return FALSE;          /*  
attached? */
+
+ v = mt_sel->flags & UNIT_IND;                           /* save  
latch */
+ mt_sel->flags &= ~UNIT_IND;                             /* reset  
latch */
+ return (v);
+ }
+
   /* Reset routine */

   t_stat mt_reset (DEVICE *dptr)
***************
*** 387,396 ****
   int32 i;
   UNIT *uptr;

! for (i = 0; i < MT_NUMDR; i++) {                        /* clear  
pos flag */
!     if (uptr = get_unit (i)) MT_CLR_PNU (uptr);
       }
! ind[IN_END] = ind[IN_TAP] = 0;                          /* clear  
indicators */
   return SCPE_OK;
   }

--- 434,450 ----
   int32 i;
   UNIT *uptr;

! for (i = 0; i < MT_NUMDR; i++) {                        /* per  
drive resets */
!     if (uptr = get_unit (i)) {
!         MT_CLR_PNU (uptr);                              /* clear  
pos flag */
!         uptr->flags &= ~UNIT_IND;                       /* clear  
ind latch */
       }
! }
!
! ind[IN_TAP] = 0;                                        /* clear mt  
error ind */
!
! mt_sel = NULL;                                          /* clear  
unit select */
!
   return SCPE_OK;
   }

***************
*** 406,408 ****
--- 460,480 ----
   saved_IS = 1;
   return SCPE_OK;
   }
+
+ /* Attach routine */
+
+ t_stat mt_attach (UNIT *uptr, char *cp)
+ {
+     uptr->flags &= ~UNIT_IND;                           /* reset  
indicator latch */
+
+     return sim_tape_attach(uptr, cp);                   /* tape  
unit attach */
+ }
+
+ /* Detach routine */
+
+ t_stat mt_detach (UNIT *uptr)
+ {
+     uptr->flags &= ~UNIT_IND;                           /* reset  
indicator latch */
+
+     return sim_tape_detach(uptr);                       /* tape  
unit detach */
+ }
diff -rc simhv38-0/sim_tape.c simh-tapefixes/sim_tape.c
*** simhv38-0/sim_tape.c        Wed Jan 24 21:58:58 2007
--- simh-tapefixes/sim_tape.c   Mon Jul  7 17:15:58 2008
***************
*** 26,31 ****
--- 26,32 ----
      Ultimately, this will be a place to hide processing of various  
tape formats,
      as well as OS-specific direct hardware access.

+    07-Jul-08    REA     Fixed TM detect, mask off parity
      23-Jan-07    JDB     Fixed backspace over gap at BOT
      22-Jan-07    RMS     Fixed bug in P7B format read reclnt rev  
(found by Rich Cornwell)
      15-Dec-06    RMS     Added support for small capacity tapes
***************
*** 240,246 ****
                   break;                                  /* treat  
like eor */
                   }
               if ((sbc != 0) && (c & P7B_SOR)) break;     /* next  
record? */
!             if ((c & P7B_DPAR) != P7B_EOF) all_eof = 0;
               }
           *bc = sbc;                                      /* save  
rec lnt */
           sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for  
read */
--- 241,247 ----
                   break;                                  /* treat  
like eor */
                   }
               if ((sbc != 0) && (c & P7B_SOR)) break;     /* next  
record? */
!             if ((c & P7B_DATA) != P7B_EOF) all_eof = 0;
               }
           *bc = sbc;                                      /* save  
rec lnt */
           sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for  
read */
***************
*** 336,342 ****
               if (ferror (uptr->fileref))                 /* error? */
                   return sim_tape_ioerr (uptr);
               if (feof (uptr->fileref)) return MTSE_EOM;  /* eof? */
!             if ((c & P7B_DPAR) != P7B_EOF) all_eof = 0;
               if (c & P7B_SOR) break;                     /* start  
of record? */
               }
           uptr->pos = uptr->pos - sbc;                    /* update  
position */
--- 337,343 ----
               if (ferror (uptr->fileref))                 /* error? */
                   return sim_tape_ioerr (uptr);
               if (feof (uptr->fileref)) return MTSE_EOM;  /* eof? */
!             if ((c & P7B_DATA) != P7B_EOF) all_eof = 0;
               if (c & P7B_SOR) break;                     /* start  
of record? */
               }
           uptr->pos = uptr->pos - sbc;                    /* update  
position */

---------------------------------------------------------------
end of patch
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.trailing-edge.com/pipermail/simh/attachments/20080707/44d44791/attachment-0003.html>


More information about the Simh mailing list