From 92fe35fb9ce6996e0507d6e38d5eefbd2758ade8 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 19 Feb 2016 12:28:56 -0800 Subject: [PATCH] PDP10: Fix nested indirect address limit exceeded (from Bob Supnik) If the nested indirect/execute limit (INDMAX, XCTMAX) is set to 0, the simulator will loop indefinitely in an indirect address or execute loop, testing for interrupts before each memory reference. Thus, on an infinite loop, the simulator will never complete the instruction, but the instruction is interruptible. So for example, under TOPS-10: .r ddt 1/ 0 jrstf @1 1$g ^C ^C . The JRSTF will never finish, but it can be interrupted by any device, and double ^C will return control to the command line. If INDMAX or XCTMAX is non-zero, the previous behavior of limiting loops to a specific depth is retained. However, the default value is now 0. This closes issue #218. Conflicts: doc/pdp10_doc.doc --- PDP10/pdp10_bug_history.txt | 3 ++ PDP10/pdp10_cpu.c | 68 ++++++++++++++++++++++++------------ doc/pdp10_doc.doc | Bin 107008 -> 107520 bytes 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/PDP10/pdp10_bug_history.txt b/PDP10/pdp10_bug_history.txt index b4a31144..3916d172 100644 --- a/PDP10/pdp10_bug_history.txt +++ b/PDP10/pdp10_bug_history.txt @@ -23,3 +23,6 @@ Bugs Found and Fixed During Simulator Debug 16. RHCS1: writing IE cannot trigger an interrupt 17. Tape bootstrap was set to 800bpi instead of 1600bpi 18. FIXR off by 1 in testing for lower limit to process +19. Indirect loops and XCT loops should run indefinitely, + test for interrupts on each memory reference + diff --git a/PDP10/pdp10_cpu.c b/PDP10/pdp10_cpu.c index 5bae639c..fe863cbf 100644 --- a/PDP10/pdp10_cpu.c +++ b/PDP10/pdp10_cpu.c @@ -1,6 +1,6 @@ /* pdp10_cpu.c: PDP-10 CPU simulator - Copyright (c) 1993-2012, Robert M. Supnik + Copyright (c) 1993-2016, 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 @@ cpu KS10 central processor + 09-Feb-16 RMS Fixed nested indirects and executes (Tim Litt) 25-Mar-12 RMS Added missing parameters to prototypes (Mark Pizzolato) 17-Jul-07 RMS Fixed non-portable usage in SHOW HISTORY 28-Apr-07 RMS Removed clock initialization @@ -191,8 +192,8 @@ int32 flags = 0; /* flags */ int32 its_1pr = 0; /* ITS 1-proceed */ int32 stop_op0 = 0; /* stop on 0 */ int32 rlog = 0; /* extend fixup log */ -int32 ind_max = 32; /* nested ind limit */ -int32 xct_max = 32; /* nested XCT limit */ +int32 ind_max = 0; /* nested ind limit */ +int32 xct_max = 0; /* nested XCT limit */ int32 t20_idlelock = 0; /* TOPS-20 idle lock */ a10 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ int32 pcq_p = 0; /* PC queue ptr */ @@ -388,8 +389,8 @@ REG cpu_reg[] = { { FLDATA (F1PR, its_1pr, 0) }, { BRDATA (PCQ, pcq, 8, VASIZE, PCQ_SIZE), REG_RO+REG_CIRC }, { ORDATA (PCQP, pcq_p, 6), REG_HRO }, - { DRDATA (INDMAX, ind_max, 8), PV_LEFT + REG_NZ }, - { DRDATA (XCTMAX, xct_max, 8), PV_LEFT + REG_NZ }, + { DRDATA (INDMAX, ind_max, 8), PV_LEFT }, + { DRDATA (XCTMAX, xct_max, 8), PV_LEFT }, { ORDATA (WRU, sim_int_char, 8) }, { FLDATA (STOP_ILL, stop_op0, 0) }, { BRDATA (REG, acs, 8, 36, AC_NUM * AC_NBLK) }, @@ -857,17 +858,23 @@ its_2pr = its_1pr; /* save 1-proc flag */ XCT: op = GET_OP (inst); /* get opcode */ ac = GET_AC (inst); /* get AC */ -for (indrct = inst, i = 0; i < ind_max; i++) { /* calc eff addr */ +for (indrct = inst, i = 0; ; i++) { /* calc eff addr */ ea = GET_ADDR (indrct); xr = GET_XR (indrct); if (xr) ea = (ea + ((a10) XR (xr, MM_EA))) & AMASK; - if (TST_IND (indrct)) - indrct = Read (ea, MM_EA); + if (TST_IND (indrct)) { /* indirect? */ + if (i != 0) { /* not first cycle? */ + int32 t = test_int (); /* test for intr */ + if (t != 0) /* err or intr? */ + ABORT (t); + if ((ind_max != 0) && (i >= ind_max)) /* limit exceeded? */ + ABORT (STOP_IND); + } + indrct = Read (ea, MM_EA); /* fetch indirect */ + } else break; } -if (i >= ind_max) - ABORT (STOP_IND); /* too many ind? stop */ if (hst_lnt) { /* history enabled? */ hst_p = (hst_p + 1); /* next entry */ if (hst_p >= hst_lnt) @@ -1072,10 +1079,15 @@ case 0255: if (flags & (ac << 14)) { /* JFCL */ CLRF (ac << 14); } break; -case 0256: if (xct_cnt++ >= xct_max) /* XCT */ - ABORT (STOP_XCT); - inst = Read (ea, MM_OPND); - if (ac && !TSTF (F_USR) && !Q_ITS) +case 0256: if (xct_cnt++ != 0) { /* XCT: not first? */ + int32 t = test_int (); /* test for intr */ + if (t != 0) /* intr or err? */ + ABORT (t); + if ((xct_max != 0) && (xct_cnt >= xct_max)) + ABORT (STOP_XCT); + } + inst = Read (ea, MM_OPND); /* get opnd */ + if (ac && !TSTF (F_USR) && !Q_ITS) /* PXCT? */ pflgs = pflgs | ac; goto XCT; case 0257: if (Q_ITS) goto MUUO; /* MAP */ @@ -1831,17 +1843,23 @@ a10 calc_ea (d10 inst, int32 prv) int32 i, ea, xr; d10 indrct; -for (indrct = inst, i = 0; i < ind_max; i++) { +for (indrct = inst, i = 0; ; i++) { ea = GET_ADDR (indrct); xr = GET_XR (indrct); if (xr) ea = (ea + ((a10) XR (xr, prv))) & AMASK; - if (TST_IND (indrct)) + if (TST_IND (indrct)) { /* indirect? */ + if (i != 0) { /* not first cycle? */ + int32 t = test_int (); /* test for intr */ + if (t != 0) /* intr or error? */ + ABORT (t); + if ((ind_max != 0) && (i >= ind_max)) /* limit exceeded? */ + ABORT (STOP_IND); + } indrct = Read (ea, prv); + } else break; } -if (i >= ind_max) - ABORT (STOP_IND); return ea; } @@ -1882,17 +1900,23 @@ d10 calc_jrstfea (d10 inst, int32 pflgs) int32 i, xr; d10 mb; -for (i = 0; i < ind_max; i++) { +for (i = 0; ; i++) { mb = inst; xr = GET_XR (inst); if (xr) mb = (mb & AMASK) + XR (xr, MM_EA); - if (TST_IND (inst)) + if (TST_IND (inst)) { /* indirect? */ + if (i != 0) { /* not first cycle? */ + int32 t = test_int (); /* test for intr */ + if (t != 0) /* intr or error? */ + ABORT (t); + if ((ind_max != 0) && (i >= ind_max)) /* limit exceeded? */ + ABORT (STOP_IND); + } inst = Read (((a10) mb) & AMASK, MM_EA); + } else break; } -if (i >= ind_max) - ABORT (STOP_IND); return (mb & DMASK); } diff --git a/doc/pdp10_doc.doc b/doc/pdp10_doc.doc index 813c08c4f521de37ca66708161f806521bb54478..9400d18d2dc0600fd42bcdece47180dcb03e240b 100644 GIT binary patch delta 22178 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¬r4D3>W>U9iE4ASKq5qx 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

M` L+S`}OW99z=T$|$3 delta 21736 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