diff --git a/sim_tape.c b/sim_tape.c index b347d7b8..6728971b 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -124,7 +124,7 @@ static const uint32 bpi [] = { /* tape density table, i static t_stat sim_tape_ioerr (UNIT *uptr); static t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat); -static uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map); +static uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map, uint32 mapsize); static t_stat sim_tape_simh_check (UNIT *uptr); static t_stat sim_tape_e11_check (UNIT *uptr); static t_addr sim_tape_tpc_fnd (UNIT *uptr, t_addr *map); @@ -133,7 +133,7 @@ static void sim_tape_data_trace (UNIT *uptr, const uint8 *data, size_t len, cons struct tape_context { DEVICE *dptr; /* Device for unit (access to debug flags) */ - uint32 dbit; /* debugging bit */ + uint32 dbit; /* debugging bit for trace */ uint32 auto_format; /* Format determined dynamically */ #if defined SIM_ASYNCH_IO int asynch_io; /* Asynchronous Interrupt scheduling enabled */ @@ -485,7 +485,7 @@ switch (MT_GET_FMT (uptr)) { /* case on format */ break; case MTUF_F_TPC: /* TPC */ - objc = sim_tape_tpc_map (uptr, NULL); /* get # objects */ + objc = sim_tape_tpc_map (uptr, NULL, 0); /* get # objects */ if (objc == 0) { /* tape empty? */ sim_tape_detach (uptr); return SCPE_FMT; /* yes, complain */ @@ -496,7 +496,7 @@ switch (MT_GET_FMT (uptr)) { /* case on format */ return SCPE_MEM; /* no, complain */ } uptr->hwmark = objc + 1; /* save map size */ - sim_tape_tpc_map (uptr, (t_addr *) uptr->filebuf); /* fill map */ + sim_tape_tpc_map (uptr, (t_addr *) uptr->filebuf, objc);/* fill map */ break; default: @@ -2142,20 +2142,22 @@ return SCPE_OK; /* Map a TPC format tape image */ -static uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map) +static uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map, uint32 mapsize) { -t_addr tpos; +t_addr tpos, leot; t_addr tape_size; t_tpclnt bc, last_bc; -t_bool had_double_tape_mark = FALSE; +uint32 had_double_tape_mark = 0; size_t i; uint32 objc, sizec; uint32 *countmap = NULL; +uint8 *recbuf = NULL; DEVICE *dptr = find_dev_from_unit (uptr); if ((uptr == NULL) || (uptr->fileref == NULL)) return 0; countmap = calloc (65536, sizeof(*countmap)); +recbuf = malloc (65536); tape_size = (t_addr)sim_fsize (uptr->fileref); sim_debug (MTSE_DBG_STR, dptr, "tpc_map: tape_size: %" T_ADDR_FMT "u\n", tape_size); for (objc = 0, sizec = 0, tpos = 0;; ) { @@ -2166,19 +2168,38 @@ for (objc = 0, sizec = 0, tpos = 0;; ) { if (countmap[bc] == 0) sizec++; ++countmap[bc]; - if (map) + if (map && (objc < mapsize)) map[objc] = tpos; - sim_debug (MTSE_DBG_STR, dptr, "tpc_map: %d byte count at pos: %" T_ADDR_FMT "u\n", bc, tpos); + if (bc) { + sim_debug (MTSE_DBG_STR, dptr, "tpc_map: %d byte count at pos: %" T_ADDR_FMT "u\n", bc, tpos); + if (sim_deb && (dptr->dctrl & MTSE_DBG_STR)) { + sim_fread (recbuf, 1, bc, uptr->fileref); + sim_data_trace(dptr, uptr, ((dptr->dctrl & MTSE_DBG_DAT) ? recbuf : NULL), "", bc, "Data Record", MTSE_DBG_STR); + } + } + else + sim_debug (MTSE_DBG_STR, dptr, "tpc_map: tape mark at pos: %" T_ADDR_FMT "u\n", tpos); objc++; tpos = tpos + ((bc + 1) & ~1) + sizeof (t_tpclnt); - if ((bc == 0) && (last_bc == 0)) /* double tape mark? */ - had_double_tape_mark |= TRUE; + if ((bc == 0) && (last_bc == 0)) { /* double tape mark? */ + had_double_tape_mark = objc; + leot = tpos; + } last_bc = bc; } -sim_debug (MTSE_DBG_STR, dptr, "tpc_map: objc: %d, sizec: %d\n", objc, sizec); +sim_debug (MTSE_DBG_STR, dptr, "tpc_map: objc: %u, different record sizes: %u\n", objc, sizec); +for (i=0; i<65535; i++) { + if (countmap[i]) { + if (i == 0) + sim_debug (MTSE_DBG_STR, dptr, "tpc_map: summary - %u tape marks\n", countmap[i]); + else + sim_debug (MTSE_DBG_STR, dptr, "tpc_map: summary - %u %d byte record%s\n", countmap[i], (int)i, (countmap[i] > 1) ? "s" : ""); + } + } if (((last_bc != 0xffff) && - (tpos > tape_size)) || - (!had_double_tape_mark) || + (tpos > tape_size) && + (!had_double_tape_mark)) || + (!had_double_tape_mark) || ((objc == countmap[0]) && (countmap[0] != 2))) { /* Unreasonable format? */ if (last_bc != 0xffff) @@ -2188,13 +2209,20 @@ if (((last_bc != 0xffff) && if (objc == countmap[0]) sim_debug (MTSE_DBG_STR, dptr, "tpc_map: ERROR tape cnly contains tape marks\n"); free (countmap); + free (recbuf); return 0; } +if ((last_bc != 0xffff) && (tpos > tape_size)) { + sim_debug (MTSE_DBG_STR, dptr, "tpc_map: WARNING unexpected EOT byte count: %d, double tape mark before %" T_ADDR_FMT "u provides logical EOT\n", last_bc, leot); + objc = had_double_tape_mark; + tpos = leot; + } if (map) map[objc] = tpos; sim_debug (MTSE_DBG_STR, dptr, "tpc_map: OK objc: %d\n", objc); free (countmap); +free (recbuf); return objc; }