tangent

Differences between PiDP-8/I software and upstream SIMH 4

Mar 12th, 2017
42
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. diff -ru /usr/local/src/pidp8i/trunk/simh-update-temp/simh/ours/PDP8/pdp8_cpu.c ./src/PDP8/pdp8_cpu.c
  2. --- /usr/local/src/pidp8i/trunk/simh-update-temp/simh/ours/PDP8/pdp8_cpu.c  2017-03-18 20:42:31.000000000 -0600
  3. +++ ./src/PDP8/pdp8_cpu.c   2017-03-18 19:46:38.000000000 -0600
  4. @@ -23,6 +23,35 @@
  5.     used in advertising or otherwise to promote the sale, use or other dealings
  6.     in this Software without prior written authorization from Robert M Supnik.
  7.  
  8. +   ----------------------------------------------------------------------------
  9. +
  10. +   Portions copyright (c) 2015-2017, Oscar Vermeulen and Warren Young
  11. +
  12. +   Permission is hereby granted, free of charge, to any person obtaining a
  13. +   copy of this software and associated documentation files (the "Software"),
  14. +   to deal in the Software without restriction, including without limitation
  15. +   the rights to use, copy, modify, merge, publish, distribute, sublicense,
  16. +   and/or sell copies of the Software, and to permit persons to whom the
  17. +   Software is furnished to do so, subject to the following conditions:
  18. +
  19. +   The above copyright notice and this permission notice shall be included in
  20. +   all copies or substantial portions of the Software.
  21. +
  22. +   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. +   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. +   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  25. +   THE AUTHORS LISTED ABOVE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. +   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  27. +   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  28. +   DEALINGS IN THE SOFTWARE.
  29. +
  30. +   Except as contained in this notice, the names of the authors above shall
  31. +   not be used in advertising or otherwise to promote the sale, use or other
  32. +   dealings in this Software without prior written authorization from those
  33. +   authors.
  34. +
  35. +   ----------------------------------------------------------------------------
  36. +
  37.     cpu          central processor
  38.  
  39.     09-Mar-17    RMS     Fixed PCQ_ENTRY for interrupts (COVERITY)
  40. @@ -192,7 +221,10 @@
  41.          pdp8_sys.c      add sim_devices table entry
  42.  */
  43.  
  44. -#include "pdp8_defs.h"
  45. +/* ---PiDP change------------------------------------------------------------------------------------------- */
  46. +#include "gpio-common.h"
  47. +#include "pidp8i.h"
  48. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  49.  
  50.  #define PCQ_SIZE        64                              /* must be 2**n */
  51.  #define PCQ_MASK        (PCQ_SIZE - 1)
  52. @@ -339,10 +371,33 @@
  53.  int_req = INT_UPDATE;
  54.  reason = 0;
  55.  
  56. +
  57. +/* ---PiDP add--------------------------------------------------------------------------------------------- */
  58. +// PiDP-8/I specific flag, set when the last instruction was an IOT
  59. +// instruction to a real device.  SIMH doesn't track this, but the front
  60. +// panel needs it.
  61. +int Pause = 0;
  62. +
  63. +// Set our initial IPS value from the throttle, if given.
  64. +static time_t last_update = 0;
  65. +static size_t max_skips = 0;
  66. +static const size_t pidp8i_updates_per_sec = 3200;
  67. +max_skips = get_pidp8i_initial_max_skips (pidp8i_updates_per_sec);
  68. +srand48 (time (&last_update));
  69. +
  70. +// Reset display info in case we're re-entering the simulator from Ctrl-E
  71. +extern display display_bufs[2];
  72. +memset (display_bufs, 0, sizeof(display_bufs));
  73. +static size_t skip_count, dither, inst_count;
  74. +skip_count = dither = inst_count = 0;
  75. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  76. +
  77. +
  78.  /* Main instruction fetch/decode loop */
  79.  
  80.  while (reason == 0) {                                   /* loop until halted */
  81.  
  82. +    // Allow clean exit to SCP: https://github.com/simh/simh/issues/387
  83.      if (cpu_astop != 0) {
  84.          cpu_astop = 0;
  85.          reason = SCPE_STOP;
  86. @@ -350,10 +405,64 @@
  87.          }
  88.  
  89.      if (sim_interval <= 0) {                            /* check clock queue */
  90. -        if ((reason = sim_process_event ()))
  91. +        if ((reason = sim_process_event ())) {
  92. +/* ---PiDP add--------------------------------------------------------------------------------------------- */
  93. +            // We're about to leave the loop, so repaint one last time
  94. +            // in case this is a Ctrl-E and we later get a "cont"
  95. +            // command.  Set a flag that will let us auto-resume.
  96. +            extern int resumeFromInstructionLoopExit, swStop, swSingInst;
  97. +            resumeFromInstructionLoopExit = swStop = swSingInst = 1;
  98. +            set_pidp8i_leds (PC, MA, MB, IR, LAC, MQ, IF, DF, SC,
  99. +                    int_req, Pause);
  100. +
  101. +            // Also copy SR hardware value to software register in case
  102. +            // the user tries poking at it from the sim> prompt.
  103. +            SR = get_switch_register();
  104. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  105.              break;
  106. +            }
  107.          }
  108.  
  109. +/* ---PiDP add--------------------------------------------------------------------------------------------- */
  110. +
  111. +    switch (handle_flow_control_switches(M, &PC, &MA, &MB, &LAC, &IF,
  112. +            &DF, &int_req)) {
  113. +        case pft_stop:
  114. +            // Tell the SIMH event queue to keep running even though
  115. +            // we're stopped.  Without this, it will ignore Ctrl-E
  116. +            // until the simulator is back in free-running mode.
  117. +            sim_interval = sim_interval - 1;
  118. +
  119. +            // Have to keep display updated while stopped.  This does
  120. +            // mean if the software starts with the STOP switch held
  121. +            // down, we'll put garbage onto the display for MA, MB, and
  122. +            // IR, but that's what the real hardware does, too.  See
  123. +            // https://github.com/simh/simh/issues/386
  124. +            set_pidp8i_leds (PC, MA, MB, IR, LAC, MQ, IF, DF, SC,
  125. +                    int_req, Pause);
  126. +
  127. +            // Go no further in STOP mode.  In particular, fetch no more
  128. +            // instructions, and do not touch PC!
  129. +            continue;
  130. +
  131. +        case pft_halt:
  132. +            // Clear all registers and halt simulator
  133. +            PC  = saved_PC  = 0;
  134. +            IF  = saved_PC  = 0;
  135. +            DF  = saved_DF  = 0;
  136. +            LAC = saved_LAC = 0;
  137. +            MQ  = saved_MQ  = 0;
  138. +            int_req = 0;
  139. +            reason = STOP_HALT;
  140. +            continue;
  141. +
  142. +        case pft_normal:
  143. +            // execute normally
  144. +            break;
  145. +    }
  146. +
  147. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  148. +
  149.      if (int_req > INT_PENDING) {                        /* interrupt? */
  150.          int_req = int_req & ~INT_ION;                   /* interrupts off */
  151.          SF = (UF << 6) | (IF >> 9) | (DF >> 12);        /* form save field */
  152. @@ -923,10 +1032,19 @@
  153.                  tsc_cdf = 0;                            /* clear flag */
  154.                  }
  155.              else {
  156. -                if (IR & 04)                            /* OSR */
  157. +                if (IR & 04) {                          /* OSR */
  158. +/* ---PiDP add--------------------------------------------------------------------------------------------- */
  159. +                    SR = get_switch_register();         /* get current SR */
  160. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  161.                      LAC = LAC | SR;
  162. -                if (IR & 02)                            /* HLT */
  163. -                    reason = STOP_HALT;
  164. +                    }
  165. +                if (IR & 02) {                          /* HLT */
  166. +//--- PiDP change-----------------------------------------------------------------------
  167. +                    // reason = STOP_HALT;
  168. +                    extern int swStop;
  169. +                    swStop = 1;
  170. +                    }
  171. +//--- end of PiDP change----------------------------------------------------------------
  172.                  }
  173.              break;
  174.              }                                           /* end if group 2 */
  175. @@ -1346,6 +1464,10 @@
  176.  
  177.          default:                                        /* I/O device */
  178.              if (dev_tab[device]) {                      /* dev present? */
  179. +/* ---PiDP add--------------------------------------------------------------------------------------------- */
  180. +                // Any other device will trigger IOP, so light pause
  181. +                Pause = 1;
  182. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  183.                  iot_data = dev_tab[device] (IR, iot_data);
  184.                  LAC = (LAC & 010000) | (iot_data & 07777);
  185.                  if (iot_data & IOT_SKP)
  186. @@ -1358,6 +1480,72 @@
  187.              }                                           /* end switch device */
  188.          break;                                          /* end case IOT */
  189.          }                                               /* end switch opcode */
  190. +
  191. +/* ---PiDP add--------------------------------------------------------------------------------------------- */
  192. +    // Update the front panel with this instruction's final state.
  193. +    //
  194. +    // There's no point saving *every* LED "on" count.  We just need a
  195. +    // suitable amount of oversampling.  We can skip this if we called
  196. +    // set_pidp8i_leds recently enough, avoiding all the expensive bit
  197. +    // shift and memory update work it does.
  198. +    //
  199. +    // The trick here is figuring out what "recently enough" means
  200. +    // without making expensive OS timer calls.  These timers aren't
  201. +    // hopelessly slow (http://stackoverflow.com/a/13096917/142454) but
  202. +    // we still don't want to be taking dozens of cycles per instruction
  203. +    // just to keep our update estimate current in the face of system
  204. +    // load changes and SET THROTTLE updates.
  205. +    //
  206. +    // Instead, we maintain a model of the current IPS value — seeded
  207. +    // with the initial "SET THROTTLE" value, if any — to figure out
  208. +    // how many calls we can skip while still meeting our other goals.
  209. +    // This involves a bit of math, but when paid only once a second,
  210. +    // it amortizes much nicer than estimating the skip count directly
  211. +    // based on a more accurate time source which is more expensive
  212. +    // to call.  It's also cheaper than continually asking SIMH to
  213. +    // estimate the SIMH IPS value, since it uses FP math.
  214. +    //
  215. +    // Each LED panel repaint takes about 10 ms, so we do about 100
  216. +    // full-panel updates per second.  We need a bare minimum of 32
  217. +    // discernible brightness values per update for ILS, so if we don't
  218. +    // update the LED status data at least 3,200 times per second, we
  219. +    // don't have enough data for smooth panel updates.  Fortunately,
  220. +    // computers are pretty quick, and our slowest script runs at 30
  221. +    // kIPS.  (5.script.)
  222. +    //
  223. +    // We deliberately add some timing jitter here to get stochastic
  224. +    // sampling of the incoming instructions to avoid beat frequencies
  225. +    // between our update rate and the instruction pattern being
  226. +    // executed by the front panel.  It's a form of dithering.
  227. +    //
  228. +    // You might think to move this code to the top of set_pidp8i_leds,
  229. +    // but the function call itself is a nontrivial hit.  In fact, you
  230. +    // don't even want to move all of this to a function here in this
  231. +    // module and try to get GCC to inline it: that's good for a 1 MIPS
  232. +    // speed hit in my testing!  (GCC 4.9.2, Raspbian Jessie on Pi 3B.)
  233. +
  234. +    if (++skip_count >= (max_skips - dither)) {
  235. +        // Save skips to inst counter and reset
  236. +        inst_count += skip_count;
  237. +        skip_count = 0;
  238. +
  239. +        // We need to update the LED data again
  240. +        set_pidp8i_leds (PC, MA, MB, IR, LAC, MQ, IF, DF, SC, int_req, Pause);
  241. +        Pause = 0;
  242. +
  243. +        // Has it been ~1s since we updated our max_skips value?
  244. +        time_t now;
  245. +        if (time(&now) > last_update) {
  246. +            // Yep; simulator IPS may have changed, so freshen it.
  247. +            last_update = now;
  248. +            max_skips = inst_count / pidp8i_updates_per_sec;
  249. +            //printf("Inst./repaint: %zu - %zu; %.2f MIPS\r\n",
  250. +            //        max_skips, dither, inst_count / 1e6);
  251. +            inst_count = 0;
  252. +            }
  253. +        dither = max_skips > 32 ? lrand48() % (max_skips >> 3) : 0; // 12.5%
  254. +        }
  255. +/* ---PiDP end---------------------------------------------------------------------------------------------- */
  256.      }                                                   /* end while */
  257.  
  258.  /* Simulation halted */
  259. diff -ru /usr/local/src/pidp8i/trunk/simh-update-temp/simh/ours/scp.c ./src/scp.c
  260. --- /usr/local/src/pidp8i/trunk/simh-update-temp/simh/ours/scp.c    2017-03-18 20:42:31.000000000 -0600
  261. +++ ./src/scp.c 2017-03-18 20:21:21.000000000 -0600
  262. @@ -23,6 +23,35 @@
  263.     used in advertising or otherwise to promote the sale, use or other dealings
  264.     in this Software without prior written authorization from Robert M Supnik.
  265.  
  266. +   ----------------------------------------------------------------------------
  267. +
  268. +   Portions copyright (c) 2015-2017, Oscar Vermeulen and Warren Young
  269. +
  270. +   Permission is hereby granted, free of charge, to any person obtaining a
  271. +   copy of this software and associated documentation files (the "Software"),
  272. +   to deal in the Software without restriction, including without limitation
  273. +   the rights to use, copy, modify, merge, publish, distribute, sublicense,
  274. +   and/or sell copies of the Software, and to permit persons to whom the
  275. +   Software is furnished to do so, subject to the following conditions:
  276. +
  277. +   The above copyright notice and this permission notice shall be included in
  278. +   all copies or substantial portions of the Software.
  279. +
  280. +   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  281. +   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  282. +   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  283. +   THE AUTHORS LISTED ABOVE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  284. +   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  285. +   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  286. +   DEALINGS IN THE SOFTWARE.
  287. +
  288. +   Except as contained in this notice, the names of the authors above shall
  289. +   not be used in advertising or otherwise to promote the sale, use or other
  290. +   dealings in this Software without prior written authorization from those
  291. +   authors.
  292. +
  293. +   ----------------------------------------------------------------------------
  294. +
  295.     08-Mar-16    RMS     Added shutdown flag for detach_all
  296.     20-Mar-12    MP      Fixes to "SHOW <x> SHOW" commands
  297.     06-Jan-12    JDB     Fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan)  
  298. @@ -214,6 +243,11 @@
  299.  
  300.  /* Macros and data structures */
  301.  
  302. +#ifdef PIDP8I
  303. +#include "gpio-common.h"        // for start/stop_pidp8i_gpio_thread()
  304. +#include "PDP8/pidp8i.h"        // for build_pidp8i_scp_cmd()
  305. +#endif
  306. +
  307.  #define NOT_MUX_USING_CODE /* sim_tmxr library provider or agnostic */
  308.  
  309.  #include "sim_defs.h"
  310. @@ -1997,6 +2031,10 @@
  311.  t_bool lookswitch;
  312.  t_stat stat;
  313.  
  314. +#ifdef PIDP8I
  315. +if (start_pidp8i_gpio_thread ("PiDP-8/I simulator", 1) != 0) exit (EXIT_FAILURE);
  316. +#endif
  317. +
  318.  #if defined (__MWERKS__) && defined (macintosh)
  319.  argc = ccommand (&argv);
  320.  #endif
  321. @@ -2140,6 +2178,11 @@
  322.  sim_cleanup_sock ();                                    /* cleanup sockets */
  323.  fclose (stdnul);                                        /* close bit bucket file handle */
  324.  free (targv);                                           /* release any argv copy that was made */
  325. +
  326. +#ifdef PIDP8I
  327. +stop_pidp8i_gpio_thread ();
  328. +#endif
  329. +
  330.  return 0;
  331.  }
  332.  
  333. @@ -2152,6 +2195,11 @@
  334.  
  335.  stat = SCPE_BARE_STATUS(stat);                          /* remove possible flag */
  336.  while (stat != SCPE_EXIT) {                             /* in case exit */
  337. +#ifdef PIDP8I
  338. +    if (cptr = build_pidp8i_scp_cmd (cbuf, sizeof (cbuf)))
  339. +        printf ("Running '%s'...\n", cptr);
  340. +    else
  341. +#endif
  342.      if ((cptr = sim_brk_getact (cbuf, sizeof(cbuf))))   /* pending action? */
  343.          printf ("%s%s\n", sim_prompt, cptr);            /* echo */
  344.      else if (sim_vm_read != NULL) {                     /* sim routine? */
RAW Paste Data