From 6edc4994ebf6bd3f13972ded5f1a4b67673078fa Mon Sep 17 00:00:00 2001 From: Bob Supnik Date: Tue, 8 Jun 2021 01:43:32 -0700 Subject: [PATCH] PDP8, PDP18b: Fixed RF, DF, DT device bug if read overwrites WC memory location --- PDP18B/pdp18b_dt.c | 20 +++++++++++--------- PDP18B/pdp18b_rf.c | 12 +++++++----- PDP8/pdp8_df.c | 13 ++++++++----- PDP8/pdp8_dt.c | 19 ++++++++++--------- PDP8/pdp8_rf.c | 10 ++++++---- 5 files changed, 42 insertions(+), 32 deletions(-) diff --git a/PDP18B/pdp18b_dt.c b/PDP18B/pdp18b_dt.c index 86d390bd..3d0672c8 100644 --- a/PDP18B/pdp18b_dt.c +++ b/PDP18B/pdp18b_dt.c @@ -27,6 +27,7 @@ (PDP-9) TC02/TU55 DECtape (PDP-15) TC15/TU56 DECtape + 03-May-21 RMS Fixed bug if read overwrites WC memory location 15-Mar-17 RMS Fixed dt_seterr to clear successor states 09-Mar-17 RMS Fixed dt_seterr to handle nx unit select (COVERITY) 10-Mar-16 RMS Added 3-cycle databreak set/show entries @@ -959,10 +960,10 @@ switch (fnc) { /* at speed, check fnc * sim_activate (uptr, DTU_LPERB (uptr) * dt_ltime);/* sched next block */ M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* inc WC */ ma = M[DT_CA] & AMASK; /* get mem addr */ - if (MEM_ADDR_OK (ma)) /* store block # */ - M[ma] = blk; if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0)) dtsb = dtsb | DTB_DTF; /* set DTF */ + if (MEM_ADDR_OK (ma)) /* store block # */ + M[ma] = blk; if (DEBUG_PRI (dt_dev, LOG_MS)) fprintf (sim_deb, ">>DT%d: found block %d\n", unum, blk); break; @@ -998,6 +999,8 @@ switch (fnc) { /* at speed, check fnc * case 0: /* normal read */ M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */ M[DT_CA] = (M[DT_CA] + 1) & DMASK; + if (M[DT_WC] == 0) /* wc ovf? */ + dt_substate = DTO_WCO; ma = M[DT_CA] & AMASK; /* mem addr */ ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */ dtdb = fbuf[ba]; /* get tape word */ @@ -1005,16 +1008,15 @@ switch (fnc) { /* at speed, check fnc * dtdb = dt_comobv (dtdb); if (MEM_ADDR_OK (ma)) /* mem addr legal? */ M[ma] = dtdb; - if (M[DT_WC] == 0) /* wc ovf? */ - dt_substate = DTO_WCO; + /* fall through */ case DTO_WCO: /* wc ovf, not sob */ if (wrd != (dir? 0: DTU_BSIZE (uptr) - 1)) /* not last? */ sim_activate (uptr, DT_WSIZE * dt_ltime); else { - dt_substate = dt_substate | DTO_SOB; sim_activate (uptr, ((2 * DT_HTLIN) + DT_WSIZE) * dt_ltime); - if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0)) + if (((dtsa & DTA_MODE) == 0) || (dt_substate == DTO_WCO)) dtsb = dtsb | DTB_DTF; /* set DTF */ + dt_substate = dt_substate | DTO_SOB; } break; @@ -1100,6 +1102,8 @@ switch (fnc) { /* at speed, check fnc * relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */ M[DT_WC] = (M[DT_WC] + 1) & DMASK; /* incr WC, CA */ M[DT_CA] = (M[DT_CA] + 1) & DMASK; + if (M[DT_WC] == 0) + dt_substate = DTO_WCO; ma = M[DT_CA] & AMASK; /* mem addr */ if ((relpos >= DT_HTLIN) && /* in data zone? */ (relpos < (DTU_LPERB (uptr) - DT_HTLIN))) { @@ -1113,9 +1117,7 @@ switch (fnc) { /* at speed, check fnc * sim_activate (uptr, DT_WSIZE * dt_ltime); if (MEM_ADDR_OK (ma)) /* mem addr legal? */ M[ma] = dtdb; - if (M[DT_WC] == 0) - dt_substate = DTO_WCO; - if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0)) + if (((dtsa & DTA_MODE) == 0) || (dt_substate == DTO_WCO)) dtsb = dtsb | DTB_DTF; /* set DTF */ break; diff --git a/PDP18B/pdp18b_rf.c b/PDP18B/pdp18b_rf.c index fd0c28a8..647ebaef 100644 --- a/PDP18B/pdp18b_rf.c +++ b/PDP18B/pdp18b_rf.c @@ -1,6 +1,6 @@ /* pdp18b_rf.c: fixed head disk simulator - Copyright (c) 1993-2016, Robert M Supnik + Copyright (c) 1993-2021, 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"), @@ -26,6 +26,7 @@ rf (PDP-9) RF09/RF09 (PDP-15) RF15/RS09 + 21-Apr-21 RMS Fixed bug if read overwrites WC memory location 10-Mar-16 RMS Added 3-cycle databreak set/show entries 07-Mar-16 RMS Revised for dynamically allocated memory 13-Sep-15 RMS Added APIVEC register @@ -271,6 +272,7 @@ return dat; t_stat rf_svc (UNIT *uptr) { int32 f, pa, d, t; +int32 wc = 0; int32 *fbuf = (int32 *) uptr->filebuf; if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ @@ -284,8 +286,8 @@ do { rf_updsta (RFS_NED); /* nx disk error */ break; } - M[RF_WC] = (M[RF_WC] + 1) & DMASK; /* incr word count */ - pa = M[RF_CA] = (M[RF_CA] + 1) & AMASK; /* incr mem addr */ + wc = M[RF_WC] = (M[RF_WC] + 1) & DMASK; /* incr word count */ + pa = M[RF_CA] = (M[RF_CA] + 1) & AMASK; /* incr mem addr */ if ((f == FN_READ) && MEM_ADDR_OK (pa)) /* read? */ M[pa] = fbuf[rf_da]; if ((f == FN_WCHK) && (M[pa] != fbuf[rf_da])) { /* write check? */ @@ -306,9 +308,9 @@ do { } } rf_da = rf_da + 1; /* incr disk addr */ - } while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */ + } while ((wc != 0) && (rf_burst != 0)); /* brk if wc, no brst */ -if ((M[RF_WC] != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */ +if ((wc != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */ sim_activate (&rf_unit, rf_time); /* sched next */ else rf_updsta (RFS_DON); return SCPE_OK; diff --git a/PDP8/pdp8_df.c b/PDP8/pdp8_df.c index 368167b2..2a16e031 100644 --- a/PDP8/pdp8_df.c +++ b/PDP8/pdp8_df.c @@ -1,6 +1,6 @@ /* pdp8_df.c: DF32 fixed head disk simulator - Copyright (c) 1993-2013, Robert M Supnik + Copyright (c) 1993-2021, 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 @@ df DF32 fixed head disk + 21-Apr-21 RMS Fixed bug if read overwrites WC memory location 17-Sep-13 RMS Changed to use central set_bootpc routine 03-Sep-13 RMS Added explicit void * cast 15-May-06 RMS Fixed bug in autosize attach (Dave Gesswein) @@ -252,6 +253,7 @@ t_stat df_svc (UNIT *uptr) int32 pa, t, mex; uint32 da; int16 *fbuf = (int16 *) uptr->filebuf; +uint16 wc = 0; UPDATE_PCELL; /* update photocell */ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ @@ -267,11 +269,12 @@ do { df_sta = df_sta | DFS_NXD; break; } - M[DF_WC] = (M[DF_WC] + 1) & 07777; /* incr word count */ + wc = M[DF_WC] = (M[DF_WC] + 1) & 07777; /* incr word count */ M[DF_MA] = (M[DF_MA] + 1) & 07777; /* incr mem addr */ pa = mex | M[DF_MA]; /* add extension */ if (uptr->FUNC == DF_READ) { /* read? */ - if (MEM_ADDR_OK (pa)) M[pa] = fbuf[da]; /* if !nxm, read wd */ + if (MEM_ADDR_OK (pa)) /* if !nxm, read wd */ + M[pa] = fbuf[da]; } else { /* write */ t = (da >> 14) & 07; /* check wr lock */ @@ -283,9 +286,9 @@ do { } } da = (da + 1) & 0377777; /* incr disk addr */ - } while ((M[DF_WC] != 0) && (df_burst != 0)); /* brk if wc, no brst */ + } while ((wc != 0) && (df_burst != 0)); /* brk if wc, no brst */ -if ((M[DF_WC] != 0) && ((df_sta & DFS_ERR) == 0)) /* more to do? */ +if ((wc != 0) && ((df_sta & DFS_ERR) == 0)) /* more to do? */ sim_activate (&df_unit, df_time); /* sched next */ else { if (uptr->FUNC != DF_READ) diff --git a/PDP8/pdp8_dt.c b/PDP8/pdp8_dt.c index 773e7b3b..54387779 100644 --- a/PDP8/pdp8_dt.c +++ b/PDP8/pdp8_dt.c @@ -25,6 +25,7 @@ dt TC08/TU56 DECtape + 03-May-21 RMS Fixed bug if read overwrites WC memory location 01-Jul-20 RMS Fixed comments in bootstrap (Bernhard Baehr) 15-Mar-17 RMS Fixed dt_seterr to clear successor states 17-Sep-13 RMS Changed to use central set_bootpc routine @@ -764,10 +765,10 @@ switch (fnc) { /* at speed, check fnc * sim_activate (uptr, DTU_LPERB (uptr) * dt_ltime);/* sched next block */ M[DT_WC] = (M[DT_WC] + 1) & 07777; /* incr word cnt */ ma = DTB_GETMEX (dtsb) | M[DT_CA]; /* get mem addr */ - if (MEM_ADDR_OK (ma)) /* store block # */ - M[ma] = blk & 07777; if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0)) dtsb = dtsb | DTB_DTF; /* set DTF */ + if (MEM_ADDR_OK (ma)) /* store block # */ + M[ma] = blk & 07777; break; case DTS_OFR: /* off reel */ @@ -806,22 +807,22 @@ switch (fnc) { /* at speed, check fnc * case 0: /* normal read */ M[DT_WC] = (M[DT_WC] + 1) & 07777; /* incr WC, CA */ M[DT_CA] = (M[DT_CA] + 1) & 07777; + if (M[DT_WC] == 0) /* wc ovf? */ + dt_substate = DTO_WCO; ma = DTB_GETMEX (dtsb) | M[DT_CA]; /* get mem addr */ ba = (blk * DTU_BSIZE (uptr)) + wrd; /* buffer ptr */ dat = fbuf[ba]; /* get tape word */ if (dir) /* rev? comp obv */ dat = dt_comobv (dat); if (MEM_ADDR_OK (ma)) /* mem addr legal? */ - M[ma] = dat; - if (M[DT_WC] == 0) /* wc ovf? */ - dt_substate = DTO_WCO; /* fall through */ + M[ma] = dat; /* fall through */ case DTO_WCO: /* wc ovf, not sob */ if (wrd != (dir? 0: DTU_BSIZE (uptr) - 1)) /* not last? */ sim_activate (uptr, DT_WSIZE * dt_ltime); else { dt_substate = dt_substate | DTO_SOB; sim_activate (uptr, ((2 * DT_HTLIN) + DT_WSIZE) * dt_ltime); - if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0)) + if (((dtsa & DTA_MODE) == 0) || (dt_substate == DTO_WCO)) dtsb = dtsb | DTB_DTF; /* set DTF */ } break; @@ -910,6 +911,8 @@ switch (fnc) { /* at speed, check fnc * relpos = DT_LIN2OF (uptr->pos, uptr); /* cur pos in blk */ M[DT_WC] = (M[DT_WC] + 1) & 07777; /* incr WC, CA */ M[DT_CA] = (M[DT_CA] + 1) & 07777; + if (M[DT_WC] == 0) + dt_substate = DTO_WCO; ma = DTB_GETMEX (dtsb) | M[DT_CA]; /* get mem addr */ if ((relpos >= DT_HTLIN) && /* in data zone? */ (relpos < (DTU_LPERB (uptr) - DT_HTLIN))) { @@ -923,9 +926,7 @@ switch (fnc) { /* at speed, check fnc * sim_activate (uptr, DT_WSIZE * dt_ltime); if (MEM_ADDR_OK (ma)) /* mem addr legal? */ M[ma] = dat; - if (M[DT_WC] == 0) - dt_substate = DTO_WCO; - if (((dtsa & DTA_MODE) == 0) || (M[DT_WC] == 0)) + if (((dtsa & DTA_MODE) == 0) || (dt_substate == DTO_WCO)) dtsb = dtsb | DTB_DTF; /* set DTF */ break; diff --git a/PDP8/pdp8_rf.c b/PDP8/pdp8_rf.c index bd75b3a4..ac825d17 100644 --- a/PDP8/pdp8_rf.c +++ b/PDP8/pdp8_rf.c @@ -1,6 +1,6 @@ /* pdp8_rf.c: RF08 fixed head disk simulator - Copyright (c) 1993-2013, Robert M Supnik + Copyright (c) 1993-2021, 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 @@ rf RF08 fixed head disk + 21-Apr-21 RMS Fixed bug if read overwrites WC memory location 17-Sep-13 RMS Changed to use central set_bootpc routine 03-Sep-13 RMS Added explicit void * cast 15-May-06 RMS Fixed bug in autosize attach (Dave Gesswein) @@ -305,6 +306,7 @@ t_stat rf_svc (UNIT *uptr) { int32 pa, t, mex; int16 *fbuf = (int16 *) uptr->filebuf; +uint16 wc = 0; UPDATE_PCELL; /* update photocell */ if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */ @@ -320,7 +322,7 @@ do { rf_sta = rf_sta | RFS_NXD; break; } - M[RF_WC] = (M[RF_WC] + 1) & 07777; /* incr word count */ + wc = M[RF_WC] = (M[RF_WC] + 1) & 07777; /* incr word count */ M[RF_MA] = (M[RF_MA] + 1) & 07777; /* incr mem addr */ pa = mex | M[RF_MA]; /* add extension */ if (uptr->FUNC == RF_READ) { /* read? */ @@ -338,9 +340,9 @@ do { } } rf_da = (rf_da + 1) & 03777777; /* incr disk addr */ - } while ((M[RF_WC] != 0) && (rf_burst != 0)); /* brk if wc, no brst */ + } while ((wc != 0) && (rf_burst != 0)); /* brk if wc, no brst */ -if ((M[RF_WC] != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */ +if ((wc != 0) && ((rf_sta & RFS_ERR) == 0)) /* more to do? */ sim_activate (&rf_unit, rf_time); /* sched next */ else { rf_done = 1; /* done */