http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.14.tar.gz
[xscreensaver] / hacks / bsod.c
index 9e5c9da0bc3f87c2fb77c3e1df312168199f58be..84f5f312a1a1a47f4fa4039b0bcc361069febc34 100644 (file)
@@ -16,6 +16,7 @@
 #include <math.h>
 #include "screenhack.h"
 #include "xpm-pixmap.h"
+#include "apple2.h"
 #include <stdio.h>
 #include <ctype.h>
 #include <time.h>
@@ -293,12 +294,54 @@ windows (Display *dpy, Window window, int delay, int which)
   const char *wmeb =
     ("    System halted.");
 
+# ifdef __GNUC__
+  __extension__   /* don't warn about "string length is greater than the
+                     length ISO C89 compilers are required to support"
+                     in the following string constant... */
+# endif
+
+  const char *wxpa = /* From Wm. Rhodes <xscreensaver@27.org> */
+    ("A problem has been detected and windows has been shut down to prevent "
+      "damage\n"
+      "to your computer.\n"
+      "\n"
+      "If this is the first time you've seen this Stop error screen,\n"
+      "restart your computer. If this screen appears again, follow\n"
+      "these steps:\n"
+      "\n"
+      "Check to be sure you have adequate disk space. If a driver is\n"
+      "identified in the Stop message, disable the driver or check\n"
+      "with the manufacturer for driver updates. Try changing video\n"
+      "adapters.\n"
+      "\n"
+      "Check with you hardware vendor for any BIOS updates. Disable\n"
+      "BIOS memory options such as caching or shadowing. If you need\n"
+      "to use Safe Mode to remove or disable compinents, restart your\n"
+      "computer, press F8 to select Advanced Startup Options, and then\n"
+      "select Safe Mode.\n"
+      "\n"
+      "Technical information:\n"
+      "\n"
+      "*** STOP: 0x0000007E (0xC0000005,0xF88FF190,0x0xF8975BA0,0xF89758A0)\n"
+      "\n"
+      "\n"
+      "***  EPUSBDSK.sys - Address F88FF190 base at FF88FE000, datestamp "
+      "3b9f3248\n"
+      "\n"
+      "Beginning dump of physical memory\n");
+  const char *wxpb =
+    ("Physical memory dump complete.\n"
+     "Contact your system administrator or technical support group for "
+     "further\n"
+     "assitance.\n"
+     );
+
   if (which < 0 || which > 2) abort();
 
-  /* kludge to lump Win2K and WinME together; seems silly to add another
-     preference/command line option just for this little one. */
+  /* kludge to lump Win2K, WinME, and WinXP together; seems silly to add
+     another preference/command line option just for these little ones. */
   if (which == 2 && (random() % 2))
-    which = 3;
+    which = 3 + (random() % 2);
 
   XGetWindowAttributes (dpy, window, &xgwa);
 
@@ -354,6 +397,16 @@ windows (Display *dpy, Window window, int delay, int which)
       draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, w2kb, 750);
     }
   else if (which == 3)
+    {
+      int line_height = font->ascent + font->descent + 1;
+      int x = 4;
+      int y = 4;
+      draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, wxpa, 750);
+      y += line_height * 26;
+      bsod_sleep(dpy, 4);
+      draw_string(dpy, window, gc, &gcv, font, x, y, 10, 10, wxpb, 750);
+    }
+  else if (which == 4)
     {
       int line_height = font->ascent + font->descent;
       int x = 0;
@@ -1453,7 +1506,7 @@ blitdamage (Display *dpy, Window window, int delay)
   
   XGetWindowAttributes(dpy, window, &xwa);
 
-  load_random_image (xwa.screen, window, window);
+  load_random_image (xwa.screen, window, window, NULL);
 
   w = xwa.width;
   h = xwa.height;
@@ -1587,7 +1640,7 @@ make_scrolling_window (Display *dpy, Window window,
   if (!grab_screen_p) ts->sub_height += ts->sub_y, ts->sub_y = 0;
 
   if (grab_screen_p)
-    load_random_image (xgwa.screen, window, window);
+    load_random_image (xgwa.screen, window, window, NULL);
 
   sprintf (buf1, "%.50s.background", name);
   sprintf (buf2, "%.50s.Background", name);
@@ -2319,6 +2372,71 @@ vms (Display *dpy, Window window, int delay)
 }
 
 
+/* HVX (formerly GCOS6) and TPS6 crash
+   by Brian Garratt <brian-m.garratt@bull.co.uk>
+
+   GCOS6 is a Unix-like operating system developed by Honeywell in the
+   1970s in collaboration with MIT and AT&T (who called their version
+   UNIX).  Both are very much like MULTICS which Honeywell got from GE.
+
+   HVX ("High-performance Virtual System on Unix") is an AIX application
+   which emulates GCOS6 hardware on RS6000-like machines.
+ */
+static void
+hvx (Display *dpy, Window window, int delay)
+{
+  XWindowAttributes xgwa;
+  scrolling_window *ts;
+
+  int delay1 = 10000;
+  int delay2 = 100000;
+  const char *hvx_panic_1 =
+    ("(TP) Trap no E   Effective address 00000000   Instruction D7DE\n"
+     "(TP)  Registers :\n"
+     "(TP)  B1 -> B7  03801B02  00000000  03880D45  038BABDB  0388AFFD"
+     "  0389B3F8  03972317\n"
+     "(TP)  R1 -> R7  0001  0007  F10F  090F  0020  0106  0272\n"
+     "(TP)  P I Z M1  0388A18B  3232  0000 FF00\n"
+     "(TP) Program counter is at offset 0028 from string YTPAD\n"
+     "(TP) User id of task which trapped is LT 626\n"
+     "(TP)?\n"
+     );
+  const char *hvx_panic_2 =
+    ("\n"
+     "(TP)?\n"
+     "Core dumps initiated for selected HVX processes ...\n"
+     "Core dumps complete.\n"
+     "Fri Jul 19 15:53:09 2002\n"
+     "Live registers for cp 0:\n"
+     " P    =     7de3  IW=0000     I=32    CI=30000000   S=80006013"
+     "   IV=aa0      Level=13\n"
+     " R1-7 =       1f      913       13        4        8        0        0\n"
+     " B1-7 =   64e71b      a93      50e   64e73c     6c2c     7000      b54\n"
+     "Memory dump starting to file /var/hvx/dp01/diag/Level2 ...\n"
+     "Memory dump complete.\n"
+    );
+
+  XGetWindowAttributes (dpy, window, &xgwa);
+  ts = make_scrolling_window (dpy, window, "HVX", False);
+  XClearWindow(dpy, window);
+
+  scrolling_puts (ts, hvx_panic_1,         delay1);
+  if (bsod_sleep(dpy, 1)) goto DONE;
+  scrolling_puts (ts, " TP CLOSE ALL",     delay2);
+  scrolling_puts (ts, "\n(TP)?\n",         delay1);
+  if (bsod_sleep(dpy, 1)) goto DONE;
+  scrolling_puts (ts, " TP ABORT -LT ALL", delay2);
+  scrolling_puts (ts, "\n(TP)?\n",         delay1);
+  if (bsod_sleep(dpy, 1)) goto DONE;
+  scrolling_puts (ts, "  TP STOP KILL",    delay2);
+  scrolling_puts (ts, hvx_panic_2,         delay1);
+
+  bsod_sleep(dpy, delay);
+ DONE:
+  XClearWindow(dpy, window);
+}
+
+
 \f
 
 /* HPUX panic, by Tobias Klausmann <klausman@schwarzvogel.de>
@@ -2562,83 +2680,20 @@ DONE:
 
 \f
 /*
- * Simulate various Apple II crashes. The memory map encouraged many
- * programs to use the primary hi-res video page for various storage,
- * and the secondary hi-res page for active display. When it crashed
- * into Applesoft or the monitor, it would revert to the primary page
- * and you'd see memory garbage on the screen. Also, it was common for
- * copy-protected games to use the primary text page for important
- * code, because that made it really hard to reverse-engineer them. The
- * result often looked like what this generates.
- *
- * Sometimes an imaginary user types some of the standard commands to
- * recover from crashes.  You can turn off BSOD*apple2SimulateUser to
- * prevent this.
- *
- * It simulates the following characteristics of standard television
- * monitors:
+ * Simulate various Apple ][ crashes. The memory map encouraged many programs
+ * to use the primary hi-res video page for various storage, and the secondary
+ * hi-res page for active display. When it crashed into Applesoft or the
+ * monitor, it would revert to the primary page and you'd see memory garbage on
+ * the screen. Also, it was common for copy-protected games to use the primary
+ * text page for important code, because that made it really hard to
+ * reverse-engineer them. The result often looked like what this generates.
  *
- * - Realistic rendering of a composite video signal
- * - Compression & brightening on the right, as the scan gets truncated
- *   because of saturation in the flyback transformer
- * - Blooming of the picture dependent on brightness
- * - Overscan, cutting off a few pixels on the left side.
- * - Colored text in mixed graphics/text modes
- *
- * It's amazing how much it makes your high-end monitor look like at
- * large late-70s TV.  All you need is to put a big "Solid State" logo
- * in curly script on it and you'd be set.
+ * The Apple ][ logic and video hardware is in apple2.c. The TV is emulated by
+ * analogtv.c for maximum realism
  *
  * Trevor Blackwell <tlb@tlb.org> 
  */
 
-/*
- * Implementation notes:
- *
- * There are roughly 3 parts to this hack:
- *
- * - emulation of A2 Basic and Monitor. Not much more than printing random
- *   plausible messages. Here we work in the A2 memory space.
- *
- * - emulation of the A2's video output section, which shifted bits out of main
- *   memory at a 14 MHz dot clock rate, sort of. You could only read one byte
- *   per MHz, so there were various schemes for turning 8 bits into 14 screen
- *   pixels.
- *
- * - simulation of an NTSC television, which turned the bits into colored
- *   graphics and text.
- * 
- * The A2 had 3 display modes: text, lores, and hires. Text was 40x24, and it
- * disabled color in the TV. Lores gave you 40x48 graphics blocks, using the
- * same memory as the text screen. Each could be one of 16 colors. Hires gave
- * you 280x192 pixels. Odd pixels were blue or purple, and even pixels were
- * orange or green depending on the setting of the high bit in each byte.
- *
- * The graphics modes could also have 4 lines of text at the bottom. This was
- * fairly unreadable if you had a color monitor.
- *
- * Each mode had 2 different screens using different memory space. In hires
- * mode this was sometimes used for double buffering, but more often the lower
- * screen was full of code/data and the upper screen was used for display, so
- * you got random garbage on the screen.
- * 
- * In DirectColor or TrueColor modes, it generates pixel values directly from
- * RGB values it calculates across each scan line. In PseudoColor mode, it
- * consider each possible pattern of 5 preceding bit values in each possible
- * position modulo 4 and allocates a color for each. A few things, like the
- * brightening on the right side as the horizontal trace slows down, aren't
- * done in PseudoColor.
- *
- * The text font is based on X's standard 6x10 font, with a few tweaks like
- * putting a slash across the zero.
- *
- * I'd like to add a bit of visible retrace, but it conflicts with being able
- * to bitcopy the image when fast scrolling. After another couple of CPU
- * generations, we could probably regenerate the whole image from scratch every
- * time. On a P4 2 GHz it can manage this fine for blinking text, but scrolling
- * looks too slow.
- */
-
 static char * apple2_basic_errors[]={
   "BREAK",
   "NEXT WITHOUT FOR",
@@ -2653,6 +2708,12 @@ static char * apple2_basic_errors[]={
   "FORMULA TOO COMPLEX",
   "UNDEF'D FUNCTION",
   "OUT OF DATA"
+#if 0
+  ,
+  "DEFAULT ARGUMENTS ARE NOT ALLOWED IN DECLARATION OF FRIEND "
+  "TEMPLATE SPECIALIZATION"
+#endif
+
 };
 static char * apple2_dos_errors[]={
   "VOLUME MISMATCH",
@@ -2662,1403 +2723,223 @@ static char * apple2_dos_errors[]={
   "PROGRAM TOO LARGE",
 };
 
-struct apple2_state {
-  char hireslines[192][40];
-  char textlines[24][40];
-  int gr_text;
-  enum {
-    A2_GR_FULL=1,
-    A2_GR_LORES=2,
-    A2_GR_HIRES=4
-  } gr_mode;
-  int cursx;
-  int cursy;
-  int blink;
-  int rowimage[24];
-};
-
-enum {
-  A2_SP_ROWMASK=1023,
-  A2_SP_PUT=1024,
-  A2_SP_COPY=2048
-};
-
-static void
-a2_scroll(struct apple2_state *st)
+void a2controller_crash(apple2_sim_t *sim, int *stepno,
+                        double *next_actiontime)
 {
+  apple2_state_t *st=sim->st;
+  char *s;
   int i;
-  int top=(st->gr_mode&(A2_GR_LORES|A2_GR_HIRES)) ? 20 : 0;
-  if ((st->gr_mode&A2_GR_FULL) && (st->gr_mode&A2_GR_HIRES)) return;
-  if (st->gr_mode&A2_GR_FULL) top=0;
-  for (i=top; i<23; i++) {
-    if (memcmp(st->textlines[i],st->textlines[i+1],40)) {
-      memcpy(st->textlines[i],st->textlines[i+1],40);
-      st->rowimage[i]=st->rowimage[i+1];
-    }
-  }
-  memset(st->textlines[23],0xe0,40);
-  st->rowimage[23]=-1;
-}
 
-static void
-a2_printc(struct apple2_state *st, char c)
-{
-  st->textlines[st->cursy][st->cursx] |= 0xc0; /* turn off blink */
-  if (c=='\n') {
-    if (st->cursy==23) {
-      a2_scroll(st);
-    } else {
-      st->rowimage[st->cursy]=-1;
-      st->cursy++;
-      st->rowimage[st->cursy]=-1;
-    }
-    st->cursx=0;
-  } else {
-    st->textlines[st->cursy][st->cursx]=c ^ 0xc0;
-    st->rowimage[st->cursy]=-1;
-    st->cursx++;
-    if (st->cursx==40) {
-      if (st->cursy==23) {
-        a2_scroll(st);
-      } else {
-        st->rowimage[st->cursy]=-1;
-        st->cursy++;
-        st->rowimage[st->cursy]=-1;
-      }
-      st->cursx=0;
-    }
-  }
-  st->textlines[st->cursy][st->cursx] &= 0x7f; /* turn on blink */
-}
+  struct mydata {
+    int fillptr;
+    int fillbyte;
+  } *mine;
 
-static void
-a2_goto(struct apple2_state *st, int r, int c)
-{
-  st->textlines[st->cursy][st->cursx] |= 0xc0; /* turn off blink */
-  st->cursy=r;
-  st->cursx=c;
-  st->textlines[st->cursy][st->cursx] &= 0x7f; /* turn on blink */
-}
-
-static void
-a2_cls(struct apple2_state *st) 
-{
-  int i;
-  for (i=0; i<24; i++) {
-    memset(st->textlines[i],0xe0,40);
-    st->rowimage[i]=-1;
-  }
-}
-
-static void
-a2_invalidate(struct apple2_state *st) 
-{
-  int i;
-  for (i=0; i<24; i++) {
-    st->rowimage[i]=-1;
-  }
-}
-
-static void
-a2_poke(struct apple2_state *st, int addr, int val)
-{
+  if (!sim->controller_data)
+    sim->controller_data = calloc(sizeof(struct mydata),1);
+  mine=(struct mydata *) sim->controller_data;
   
-  if (addr>=0x400 && addr<0x800) {
-    /* text memory */
-    int row=((addr&0x380)/0x80) + ((addr&0x7f)/0x28)*8;
-    int col=(addr&0x7f)%0x28;
-    if (row<24 && col<40) {
-      st->textlines[row][col]=val;
-      if (!(st->gr_mode&(A2_GR_HIRES)) ||
-          (!(st->gr_mode&(A2_GR_FULL)) && row>=20)) {
-        st->rowimage[row]=-1;
-      }
-    }
-  }
-  else if (addr>=0x2000 && addr<0x4000) {
-    int row=(((addr&0x1c00) / 0x400) * 1 +
-             ((addr&0x0380) / 0x80) * 8 +
-             ((addr&0x0078) / 0x28) * 64);
-    int col=((addr&0x07f)%0x28);
-    if (row<192 && col<40) {
-      st->hireslines[row][col]=val;
-      if (st->gr_mode&A2_GR_HIRES) {
-        st->rowimage[row/8]=-1;
-      }
-    }
-  }
-}
-
-/* This table lists fixes for characters that differ from the standard 6x10
-   font. Each encodes a pixel, as (charindex*7 + x) + (y<<10) + (value<<15)
-   where value is 0 for white and 1 for black. */
-static unsigned short a2_fixfont[] = {
-  /* Fix $ */  0x8421, 0x941d,
-  /* Fix % */  0x8024, 0x0028, 0x8425, 0x0426, 0x0825, 0x1027, 0x1426, 0x9427,
-               0x1824, 0x9828,
-  /* Fix * */  0x8049, 0x8449, 0x8849, 0x0c47, 0x0c48, 0x0c4a, 0x0c4b, 0x9049,
-               0x9449, 0x9849,
-  /* Fix , */  0x9057, 0x1458, 0x9856, 0x1857, 0x1c56,
-  /* Fix . */  0x1465, 0x1864, 0x1866, 0x1c65,
-  /* Fix / */  0x006e, 0x186a,
-  /* Fix 0 */  0x8874, 0x8c73, 0x9072,
-  /* Fix 1 */  0x0878, 0x1878, 0x187c,
-  /* Fix 5 */  0x8895, 0x0c94, 0x0c95,
-  /* Fix 6 */  0x809f, 0x8c9c, 0x109c,
-  /* Fix 7 */  0x8ca4, 0x0ca5, 0x90a3, 0x10a4,
-  /* Fix 9 */  0x08b3, 0x8cb3, 0x98b0,
-  /* Fix : */  0x04b9, 0x08b8, 0x08ba, 0x0cb9, 0x90b9, 0x14b9, 0x18b8, 0x18b9,
-               0x18ba, 0x1cb9,
-  /* Fix ; */  0x04c0, 0x08bf, 0x08c1, 0x0cc0, 0x90c0, 0x14c1, 0x98bf, 0x18c0,
-               0x1cbf,
-  /* Fix < */  0x80c8, 0x00c9, 0x84c7, 0x04c8, 0x88c6, 0x08c7, 0x8cc5, 0x0cc6,
-               0x90c6, 0x10c7, 
-               0x94c7, 0x14c8, 0x98c8, 0x18c9,
-  /* Fix > */  0x80d3, 0x00d4, 0x84d4, 0x04d5, 0x88d5, 0x08d6, 0x8cd6, 0x0cd7,
-               0x90d5, 0x10d6, 
-               0x94d4, 0x14d5, 0x98d3, 0x18d4,
-  /* Fix @ */  0x88e3, 0x08e4, 0x8ce4, 0x98e5,
-  /* Fix B */  0x84ef, 0x04f0, 0x88ef, 0x08f0, 0x8cef, 0x90ef, 0x10f0, 0x94ef,
-               0x14f0,
-  /* Fix D */  0x84fd, 0x04fe, 0x88fd, 0x08fe, 0x8cfd, 0x0cfe, 0x90fd, 0x10fe,
-               0x94fd, 0x14fe,
-  /* Fix G */  0x8116, 0x0516, 0x9916,
-  /* Fix J */  0x0129, 0x012a, 0x052a, 0x852b, 0x092a, 0x892b, 0x0d2a, 0x8d2b,
-               0x112a, 0x912b, 
-               0x152a, 0x952b, 0x992a,
-  /* Fix M */  0x853d, 0x853f, 0x093d, 0x893e, 0x093f,
-  /* Fix Q */  0x915a, 0x155a, 0x955b, 0x155c, 0x195b, 0x995c, 0x1d5c,
-  /* Fix V */  0x8d7b, 0x0d7c, 0x0d7e, 0x8d7f, 0x917b, 0x117c, 0x117e, 0x917f,
-  /* Fix [ */  0x819e, 0x81a2, 0x859e, 0x899e, 0x8d9e, 0x919e, 0x959e, 0x999e,
-               0x99a2,
-  /* Fix \ */  0x01a5, 0x19a9,
-  /* Fix ] */  0x81ac, 0x81b0, 0x85b0, 0x89b0, 0x8db0, 0x91b0, 0x95b0, 0x99ac,
-               0x99b0,
-  /* Fix ^ */  0x01b5, 0x05b4, 0x05b6, 0x09b3, 0x89b5, 0x09b7, 0x8db4, 0x8db6,
-               0x91b3, 0x91b7,
-  /* Fix _ */  0x9db9, 0x9dbf,
-  0,
-};
-
-struct ntsc_dec {
-  char pattern[600];
-  int ntscy[600];
-  int ntsci[600];
-  int ntscq[600];
-  int multi[600];
-  int multq[600];
-  int brightness_control;
-};
-
-/*
-  First generate the I and Q reference signals, which we'll multiply by the
-  input signal to accomplish the demodulation. Normally they are shifted 33
-  degrees from the colorburst. I think this was convenient for
-  inductor-capacitor-vacuum tube implementation.
-               
-  The tint control, FWIW, just adds a phase shift to the chroma signal, and 
-  the color control controls the amplitude.
-               
-  In text modes (colormode==0) the system disabled the color burst, and no
-  color was detected by the monitor.
-
-  freq_error gives a mismatch between the built-in oscillator and the TV's
-  colorbust. Older II Plus machines seemed to occasionally get instability
-  problems -- the crystal oscillator was a single transistor if I remember
-  correctly -- and the frequency would vary enough that the tint would change
-  across the width of the screen.  The left side would be in correct tint
-  because it had just gotten resynchronized with the color burst.
-*/
-static void
-ntsc_set_demod(struct ntsc_dec *it, double tint_control, 
-               double color_control, double brightness_control,
-               double freq_error, 
-               int colormode)
-{
-  int i;
-
-  it->brightness_control=(int)(1024.0*brightness_control);
-
-  for (i=0; i<600; i++) {
-    double phase=90.0-90.0*i + freq_error*i/600.0 + tint_control;
-    it->multi[i]=(int)(-cos(3.1415926/180.0*(phase-303)) * 65536.0 * 
-                       color_control * colormode * 4);
-    it->multq[i]=(int)(cos(3.1415926/180.0*(phase-33)) * 65536.0 * 
-                       color_control * colormode * 4);
-  }
-}
-
-/* Here we model the analog circuitry of an NTSC television. Basically, it
-   splits the signal into 3 signals: Y, I and Q. Y corresponds to luminance,
-   and you get it by low-pass filtering the input signal to below 3.57 MHz.
-
-   I and Q are the in-phase and quadrature components of the 3.57 MHz
-   subcarrier. We get them by multiplying by cos(3.57 MHz*t) and sin(3.57
-   MHz*t), and low-pass filtering. Because the eye has less resolution in some
-   colors than others, the I component gets low-pass filtered at 1.5 MHz and
-   the Q at 0.5 MHz. The I component is approximately orange-blue, and Q is
-   roughly purple-green. See http://www.ntsc-tv.com for details.
- */
-static void
-ntsc_to_yiq(struct ntsc_dec *it) 
-{
-  int i;
-  int fyx[10],fyy[10];
-  int fix[10],fiy[10];
-  int fqx[10],fqy[10];
-  int pixghost;
-  int iny,ini,inq,pix,blank;
-  
-  for (i=0; i<10; i++) fyx[i]=fyy[i]=fix[i]=fiy[i]=fqx[i]=fqy[i]=0.0;
-  pixghost=0;
-  for (i=0; i<600; i++) {
-    /* Get the video out signal, and add a teeny bit of ghosting, typical of RF
-       monitor cables. This corresponds to a pretty long cable, but looks right
-       to me. */
-    pix=it->pattern[i]*1024;
-    if (i>=20) pixghost += it->pattern[i-20]*15;
-    if (i>=30) pixghost -= it->pattern[i-30]*15;
-    pix += pixghost;
-
-    /* Get Y, I, Q before filtering */
-    iny=pix;
-    ini=(pix*it->multi[i])>>16;
-    inq=(pix*it->multq[i])>>16;
-            
-    blank = (i>=7 && i<596 ? it->brightness_control : -200);
-
-    /* Now filter them. These are infinite impulse response filters calculated
-       by the script at http://www-users.cs.york.ac.uk/~fisher/mkfilter. This
-       is fixed-point integer DSP, son. No place for wimps. We do it in integer
-       because you can count on integer being faster on most CPUs. We care
-       about speed because we need to recalculate every time we blink text, and
-       when we spew random bytes into screen memory. This is roughly 16.16
-       fixed point arithmetic, but we scale some filter values up by a few bits
-       to avoid some nasty precision errors. */
-            
-    /* Filter y at with a 4-pole low-pass Butterworth filter at 3.5 MHz 
-       with an extra zero at 3.5 MHz, from
-       mkfilter -Bu -Lp -o 4 -a 2.1428571429e-01 0 -Z 2.5e-01 -l
-       Delay about 2 */
-
-    fyx[0] = fyx[1]; fyx[1] = fyx[2]; fyx[2] = fyx[3]; 
-    fyx[3] = fyx[4]; fyx[4] = fyx[5]; fyx[5] = fyx[6]; 
-    fyx[6] = (iny * 1897) >> 13;
-    fyy[0] = fyy[1]; fyy[1] = fyy[2]; fyy[2] = fyy[3]; 
-    fyy[3] = fyy[4]; fyy[4] = fyy[5]; fyy[5] = fyy[6]; 
-    fyy[6] = (fyx[0]+fyx[6]) + 4*(fyx[1]+fyx[5]) + 7*(fyx[2]+fyx[4]) + 8*fyx[3]
-      + ((-151*fyy[2] + 8115*fyy[3] - 38312*fyy[4] + 36586*fyy[5]) >> 16);
-    if (i>=2) it->ntscy[i-2] = blank + (fyy[6]>>3);
-
-    /* Filter I and Q at 1.5 MHz. 3 pole Butterworth from
-       mkfilter -Bu -Lp -o 3 -a 1.0714285714e-01 0
-       Delay about 3.
-
-       The NTSC spec says the Q value should be filtered at 0.5 MHz at the
-       transmit end, But the Apple's video circuitry doesn't any such thing.
-       AFAIK, oldish televisions (before comb filters) simply applied a 1.5 MHz
-       filter to both after the demodulator.
-    */
-
-    fix[0] = fix[1]; fix[1] = fix[2]; fix[2] = fix[3];
-    fix[3] = (ini * 1413) >> 14;
-    fiy[0] = fiy[1]; fiy[1] = fiy[2]; fiy[2] = fiy[3];
-    fiy[3] = (fix[0]+fix[3]) + 3*(fix[1]+fix[2])
-      + ((16559*fiy[0] - 72008*fiy[1] + 109682*fiy[2]) >> 16);
-    if (i>=3) it->ntsci[i-3] = fiy[3]>>2;
-
-    fqx[0] = fqx[1]; fqx[1] = fqx[2]; fqx[2] = fqx[3];
-    fqx[3] = (inq * 1413) >> 14;
-    fqy[0] = fqy[1]; fqy[1] = fqy[2]; fqy[2] = fqy[3];
-    fqy[3] = (fqx[0]+fqx[3]) + 3*(fqx[1]+fqx[2])
-      + ((16559*fqy[0] - 72008*fqy[1] + 109682*fqy[2]) >> 16);
-    if (i>=3) it->ntscq[i-3] = fqy[3]>>2;
-
-  }
-  for (; i<610; i++) {
-    if (i-2<600) it->ntscy[i-2]=0;
-    if (i-3<600) it->ntsci[i-3]=0;
-    if (i-9<600) it->ntscq[i-9]=0;
-  }
-}
-
-enum {
-  A2_CMAP_HISTBITS=5,
-  A2_CMAP_LEVELS=2,
-  A2_CMAP_OFFSETS=4
-};
-
-#define A2_CMAP_INDEX(COLORMODE, LEVEL, HIST, OFFSET) \
-((((COLORMODE)*A2_CMAP_LEVELS+(LEVEL))<<A2_CMAP_HISTBITS)+(HIST))* \
-A2_CMAP_OFFSETS+(OFFSET)
-
-static void
-apple2(Display *dpy, Window window, int delay)
-{
-  int w,h,i,j,x,y,textrow,row,col,stepno,colormode,imgrow;
-  char c,*s;
-  struct timeval basetime_tv;
-  double next_actiontime;
-  XWindowAttributes xgwa;
-  int visclass;
-  int screen_xo,screen_yo;
-  XImage *image=NULL;
-  XGCValues gcv;
-  GC gc=NULL;
-  XImage *text_im=NULL;
-  unsigned long colors[A2_CMAP_INDEX(1, A2_CMAP_LEVELS-1,
-                                     (1<<A2_CMAP_HISTBITS)-1,
-                                     A2_CMAP_OFFSETS-3)+1];
-  int n_colors=0;
-  int screen_plan[24];
-  struct ntsc_dec *dec=NULL;
-  short *raw_rgb=NULL, *rrp;
-  struct apple2_state *st=NULL;
-  char *typing=NULL,*printing=NULL;
-  char printbuf[1024];
-  char prompt=']';
-  int simulate_user;
-  double tint_control,color_control,brightness_control,contrast_control;
-  double freq_error=0.0,freq_error_inc=0.0;
-  double horiz_desync=5.0;
-  int flutter_horiz_desync=0;
-  int flutter_tint=0;
-  double crtload[192];
-  int red_invprec,red_shift,green_invprec,green_shift,blue_invprec,blue_shift;
-  int fillptr, fillbyte;
-  int use_shm,use_cmap,use_color;
-  /* localbyteorder is 1 if MSB first, 0 otherwise */
-  unsigned int localbyteorder_loc = MSBFirst<<24;
-  int localbyteorder=*(char *)&localbyteorder_loc;
-#ifdef HAVE_XSHM_EXTENSION
-  XShmSegmentInfo shm_info;
-#endif
-  
-#ifdef HAVE_XSHM_EXTENSION
-  use_shm=get_boolean_resource ("useSHM", "Boolean");
-#else
-  use_shm=0;
-#endif
-
-  /* Model the video controls on a standard television */
-  tint_control = get_float_resource("apple2TVTint","Apple2TVTint");
-  color_control = get_float_resource("apple2TVColor","Apple2TVColor")/100.0;
-  brightness_control = get_float_resource("apple2TVBrightness",
-                                          "Apple2TVBrightness") / 100.0;
-  contrast_control = get_float_resource("apple2TVContrast",
-                                        "Apple2TVContrast") / 100.0;
-  simulate_user = get_boolean_resource("apple2SimulateUser",
-                                       "Apple2SimulateUser");
-
-  XGetWindowAttributes (dpy, window, &xgwa);
-  visclass=xgwa.visual->class;
-  red_shift=red_invprec=green_shift=green_invprec=blue_shift=blue_invprec=-1;
-  if (visclass == TrueColor || xgwa.visual->class == DirectColor) {
-    use_cmap=0;
-    use_color=!mono_p;
-  }
-  else if (visclass == PseudoColor || visclass == StaticColor) {
-    use_cmap=1;
-    use_color=!mono_p;
-  }
-  else {
-    use_cmap=1;
-    use_color=0;
-  }
-
-  /* The Apple II screen was 280x192, sort of. We expand the width to 300
-     pixels to allow for overscan. We then pick a size within the window
-     that's an integer multiple of 300x192. The small case happens when
-     we're displaying in a subwindow. Then it ends up showing the center
-     of the screen, which is OK. */
-  w=xgwa.width;
-  h = (xgwa.height/192)*192;
-  if (w<300) w=300;
-  if (h==0) h=192;
-
-  dec=(struct ntsc_dec *)malloc(sizeof(struct ntsc_dec));
-  
-  if (use_cmap) {
-    int hist,offset,level;
-    int colorprec=8;
-
-  cmap_again:
-    n_colors=0;
-    /* Typically allocates 214 distinct colors, but will scale back its
-       ambitions pretty far if it can't get them */
-    for (colormode=0; colormode<=use_color; colormode++) {
-      ntsc_set_demod(dec, tint_control, color_control, brightness_control,
-                     0.0, colormode);
-      for (level=0; level<2; level++) {
-        for (hist=0; hist<(1<<A2_CMAP_HISTBITS); hist++) {
-          for (offset=0; offset<4; offset++) {
-            int interpy,interpi,interpq,r,g,b;
-            int levelmult=level ? 64 : 32;
-            int prec=colormode ? colorprec : (colorprec*2+2)/3;
-            int precmask=(0xffff<<(16-prec))&0xffff;
-            XColor col;
-
-            if (A2_CMAP_INDEX(colormode,level,hist,offset) != n_colors) {
-              fprintf(stderr, "apple2: internal colormap allocation error\n");
-              goto bailout;
-            }
+  switch(*stepno) {
+  case 0:
+    
+    a2_init_memory_active(sim);
+    sim->dec->powerup = 1000.0;
 
-            for (i=0; i<600; i++) dec->pattern[i]=0;
-            for (i=0; i<A2_CMAP_HISTBITS; i++) {
-              dec->pattern[64+offset-i]=(hist>>i)&1;
-            }
-        
-            ntsc_to_yiq(dec);
-            interpy=dec->ntscy[63+offset];
-            interpi=dec->ntsci[63+offset];
-            interpq=dec->ntscq[63+offset];
-
-            r=(interpy + ((+68128*interpi+40894*interpq)>>16))*levelmult;
-            g=(interpy + ((-18087*interpi-41877*interpq)>>16))*levelmult;
-            b=(interpy + ((-72417*interpi+113312*interpq)>>16))*levelmult;
-            if (r<0) r=0;
-            if (r>65535) r=65535;
-            if (g<0) g=0;
-            if (g>65535) g=65535;
-            if (b<0) b=0;
-            if (b>65535) b=65535;
-          
-            col.red=r & precmask;
-            col.green=g & precmask;
-            col.blue=b & precmask;
-            col.pixel=0;
-            if (!XAllocColor(dpy, xgwa.colormap, &col)) {
-              XFreeColors(dpy, xgwa.colormap, colors, n_colors, 0L);
-              n_colors=0;
-              colorprec--;
-              if (colorprec<3) {
-                goto bailout;
-              }
-              goto cmap_again;
-            }
-            colors[n_colors++]=col.pixel;
-          }
-        }
-      }
+    if (random()%3==0) {
+      st->gr_mode=0;
+      *next_actiontime+=0.4;
+      *stepno=100;
     }
-  } else {
-    /* Is there a standard way to do this? Does this handle all cases? */
-    int shift, prec;
-    for (shift=0; shift<32; shift++) {
-      for (prec=1; prec<16 && prec<32-shift; prec++) {
-        unsigned long mask=(0xffffUL>>(16-prec)) << shift;
-        if (red_shift<0 && mask==xgwa.visual->red_mask)
-          red_shift=shift, red_invprec=16-prec;
-        if (green_shift<0 && mask==xgwa.visual->green_mask)
-          green_shift=shift, green_invprec=16-prec;
-        if (blue_shift<0 && mask==xgwa.visual->blue_mask)
-          blue_shift=shift, blue_invprec=16-prec;
-      }
+    else if (random()%4==0) {
+      st->gr_mode=A2_GR_LORES;
+      if (random()%3==0) st->gr_mode |= A2_GR_FULL;
+      *next_actiontime+=0.4;
+      *stepno=100;
     }
-    if (red_shift<0 || green_shift<0 || blue_shift<0) {
-      if (0) fprintf(stderr,"Can't figure out color space\n");
-      goto bailout;
+    else if (random()%2==0) {
+      st->gr_mode=A2_GR_HIRES;
+      *stepno=300;
     }
-    raw_rgb=(short *)calloc(w*3, sizeof(short));
-  }
-
-  gcv.background=0;
-  gc = XCreateGC(dpy, window, GCBackground, &gcv);
-  XSetWindowBackground(dpy, window, gcv.background);
-  XClearWindow(dpy,window);
-
-  screen_xo=(xgwa.width-w)/2;
-  screen_yo=(xgwa.height-h)/2;
-
-  if (use_shm) {
-#ifdef HAVE_XSHM_EXTENSION
-    image = create_xshm_image (dpy, xgwa.visual, xgwa.depth, ZPixmap, 0, 
-                               &shm_info, w, h);
-#endif
-    if (!image) {
-      fprintf(stderr, "create_xshm_image failed\n");
-      use_shm=0;
+    else {
+      st->gr_mode=A2_GR_HIRES;
+      *next_actiontime+=0.4;
+      *stepno=100;
     }
-  }
-  if (!image) {
-    image = XCreateImage(dpy, xgwa.visual, xgwa.depth, ZPixmap, 0, 0,
-                         w, h, 8, 0);
-    image->data = (char *)calloc(image->height, image->bytes_per_line);
-  }
-
-  st=(struct apple2_state *)calloc(1,sizeof(struct apple2_state));
-
-  /*
-    Generate the font. It used a 5x7 font which looks a lot like the standard X
-    6x10 font, with a few differences. So we render up all the uppercase
-    letters of 6x10, and make a few tweaks (like putting a slash across the
-    zero) according to fixfont.
-   */
-  {
-    const char *def_font="6x10";
-    XFontStruct *font;
-    Pixmap text_pm;
-    GC gc;
-    
-    font = XLoadQueryFont (dpy, def_font);
-    if (!font) {
-      fprintf(stderr,"Can't load font %s\n",def_font);
-      goto bailout;
-    }
-    
-    text_pm=XCreatePixmap(dpy, window, 64*7, 8, xgwa.depth);
-    
-    gcv.foreground=1;
-    gcv.background=0;
-    gcv.font=font->fid;
-    gc=XCreateGC(dpy, text_pm, GCFont|GCBackground|GCForeground, &gcv);
-    
-    XSetForeground(dpy, gc, 0);
-    XFillRectangle(dpy, text_pm, gc, 0, 0, 64*7, 8);
-    XSetForeground(dpy, gc, 1);
-    for (i=0; i<64; i++) {
-      char c=32+i;
-      int x=7*i+1;
-      int y=7;
-      if (c=='0') {
-        c='O';
-        XDrawString(dpy, text_pm, gc, x, y, &c, 1);
+    break;
+
+  case 100:
+    /* An illegal instruction or a reset caused it to drop into the
+       assembly language monitor, where you could disassemble code & view
+       data in hex. */
+    if (random()%3==0) {
+      char ibytes[128];
+      char itext[128];
+      int addr=0xd000+random()%0x3000;
+      sprintf(ibytes,
+              "%02X",random()%0xff);
+      sprintf(itext,
+              "???");
+      sprintf(sim->printing_buf,
+              "\n\n"
+              "%04X: %-15s %s\n"
+              " A=%02X X=%02X Y=%02X S=%02X F=%02X\n"
+              "*",
+              addr,ibytes,itext,
+              random()%0xff, random()%0xff,
+              random()%0xff, random()%0xff,
+              random()%0xff);
+      sim->printing=sim->printing_buf;
+      a2_goto(st,23,1);
+      if (st->gr_mode) {
+        *stepno=180;
       } else {
-        XDrawString(dpy, text_pm, gc, x, y, &c, 1);
+        *stepno=200;
       }
+      sim->prompt='*';
+      *next_actiontime += 2.0 + (random()%1000)*0.0002;
     }
-    text_im = XGetImage(dpy, text_pm, 0, 0, 64*7, 8, ~0L, ZPixmap);
-    XFreeGC(dpy, gc);
-    XFreePixmap(dpy, text_pm);
-
-    for (i=0; a2_fixfont[i]; i++) {
-      XPutPixel(text_im, a2_fixfont[i]&0x3ff,
-                (a2_fixfont[i]>>10)&0xf,
-                (a2_fixfont[i]>>15)&1);
-    }
-  }
-
-  /*
-    Simulate plausible initial memory contents.
-   */
-  {
-    int addr=0;
-    while (addr<0x4000) {
-      int n;
-
-      switch (random()%4) {
-      case 0:
-      case 1:
-        n=random()%500;
-        for (i=0; i<n && addr<0x4000; i++) {
-          u_char rb=((random()%6==0 ? 0 : random()%16) |
-                     ((random()%5==0 ? 0 : random()%16)<<4));
-          a2_poke(st, addr++, rb);
-        }
-        break;
-      
-      case 2:
-        /* Simulate shapes stored in memory. We use the font since we have it.
-           Unreadable, since rows of each character are stored in consecutive
-           bytes. It was typical to store each of the 7 possible shifts of
-           bitmaps, for fastest blitting to the screen. */
-        x=random()%(text_im->width);
-        for (i=0; i<100; i++) {
-          for (y=0; y<8; y++) {
-            c=0;
-            for (j=0; j<8; j++) {
-              c |= XGetPixel(text_im, (x+j)%text_im->width, y)<<j;
-            }
-            a2_poke(st, addr++, c);
-          }
-          x=(x+1)%(text_im->width);
-        }
-        break;
-
-      case 3:
-        if (addr>0x2000) {
-          n=random()%200;
-          for (i=0; i<n && addr<0x4000; i++) {
-            a2_poke(st, addr++, 0);
-          }
-        }
-        break;
-
-      }
+    else {
+      /* Lots of programs had at least their main functionality in
+         Applesoft Basic, which had a lot of limits (memory, string
+         length, etc) and would sometimes crash unexpectedly. */
+      sprintf(sim->printing_buf,
+              "\n"
+              "\n"
+              "\n"
+              "?%s IN %d\n"
+              "\001]",
+              apple2_basic_errors[random() %
+                                  (sizeof(apple2_basic_errors)
+                                   /sizeof(char *))],
+              (1000*(random()%(random()%59+1)) +
+               100*(random()%(random()%9+1)) +
+               5*(random()%(random()%199+1)) +
+               1*(random()%(random()%(random()%2+1)+1))));
+      sim->printing=sim->printing_buf;
+      a2_goto(st,23,1);
+      *stepno=110;
+      sim->prompt=']';
+      *next_actiontime += 2.0 + (random()%1000)*0.0002;
     }
-  }
-  
-  if (random()%4==0 &&
-      !use_cmap && use_color &&
-      xgwa.visual->bits_per_rgb>=8) {
-    flutter_tint=1;
-  }
-  else if (random()%3==0) {
-    flutter_horiz_desync=1;
-  }
-
-  crtload[0]=0.0;
-  stepno=0;
-  a2_goto(st,23,0);
-  gettimeofday(&basetime_tv, NULL);
-  if (random()%2==0) basetime_tv.tv_sec -= 1; /* random blink phase */
-  next_actiontime=0.0;
-  fillptr=fillbyte=0;
-  while (1) {
-    double curtime,blinkphase;
-    int startdisplayrow=0;
-    int cheapdisplay=0;
-    int nodelay=0;
-    {
-      struct timeval curtime_tv;
-      gettimeofday(&curtime_tv, NULL);
-      curtime=(curtime_tv.tv_sec - basetime_tv.tv_sec) + 
-        0.000001*(curtime_tv.tv_usec - basetime_tv.tv_usec);
+    break;
+
+  case 110:
+    if (random()%3==0) {
+      /* This was how you reset the Basic interpreter. The sort of
+         incantation you'd have on a little piece of paper taped to the
+         side of your machine */
+      sim->typing="CALL -1370";
+      *stepno=120;
     }
-    if (curtime>delay) goto finished;
-
-    if (bsod_sleep(dpy,0)) goto finished;
-
-    if (flutter_tint && st->gr_mode && !printing) {
-      /* Oscillator instability. Look for freq_error below. We should only do
-         this with color depth>=8, since otherwise you see pixels changing. */
-      freq_error_inc += (-0.10*freq_error_inc
-                         + ((int)(random()&0xff)-0x80) * 0.01);
-      freq_error += freq_error_inc;
-      a2_invalidate(st);
-      nodelay=1;
+    else if (random()%2==0) {
+      sim->typing="CATALOG\n";
+      *stepno=170;
     }
-    else if (flutter_horiz_desync) {
-      /* Horizontal sync during vertical sync instability. */
-      horiz_desync += (-0.10*(horiz_desync-3.0) +
-                       ((int)(random()&0xff)-0x80) * 
-                       ((int)(random()&0xff)-0x80) *
-                       ((int)(random()&0xff)-0x80) * 0.0000003);
-      for (i=0; i<3; i++) st->rowimage[i]=-1;
-      nodelay=1;
-    } 
-
-    /* It's super-important to get the cursor/text flash out at exactly the
-       right time, or it looks wrong. So if we're almost due for a blink, wait
-       for it so we don't miss it in the middle of a screen update. */
-    blinkphase=curtime/0.8;
-    if (blinkphase-floor(blinkphase)>0.7 && !printing && !nodelay) {
-      /* We're about to blink */
-      int delay = ((1.0-(blinkphase-floor(blinkphase)))*0.8) * 1000000;
-      if (delay<1000) delay=1000;
-      usleep(delay);
-      continue;
+    else {
+      *next_actiontime+=1.0;
+      *stepno=999;
     }
-
-    /* The blinking rate was controlled by 555 timer with a resistor/capacitor
-       time constant. Because the capacitor was electrolytic, the flash rate
-       varied somewhat between machines. I'm guessing 1.6 seconds/cycle was
-       reasonable. (I soldered a resistor in mine to make it blink faster.) */
-    i=st->blink;
-    st->blink=((int)blinkphase)&1;
-    if (st->blink!=i && !(st->gr_mode&A2_GR_FULL)) {
-      int downcounter=0;
-      /* For every row with blinking text, set the changed flag. This basically
-         works great except with random screen garbage in text mode, when we
-         end up redrawing the whole screen every second */
-      for (row=(st->gr_mode ? 20 : 0); row<24; row++) {
-        for (col=0; col<40; col++) {
-          c=st->textlines[row][col];
-          if ((c & 0xc0) == 0x40) {
-            downcounter=4;
-            break;
-          }
-        }
-        if (downcounter>0) {
-          st->rowimage[row]=-1;
-          downcounter--;
-        }
-      }
-      st->rowimage[st->cursy]=-1;
-      startdisplayrow=random()%24;
-    } 
-    else if (next_actiontime > curtime && !printing && !nodelay) {
-      int delay = (next_actiontime-curtime)*1000000;
-
-      if (delay>100000) delay=100000;
-      if (delay<1000) delay=1000;
-      usleep(delay);
-      continue;
+    break;
+
+  case 120:
+    *stepno=130;
+    *next_actiontime += 0.5;
+    break;
+
+  case 130:
+    st->gr_mode=0;
+    a2_cls(st);
+    a2_goto(st,0,16);
+    for (s="APPLE ]["; *s; s++) a2_printc(st,*s);
+    a2_goto(st,23,0);
+    a2_printc(st,']');
+    *next_actiontime+=1.0;
+    *stepno=999;
+    break;
+
+  case 170:
+    if (random()%50==0) {
+      sprintf(sim->printing_buf,
+              "\nDISK VOLUME 254\n\n"
+              " A 002 HELLO\n"
+              "\n"
+              "]");
+      sim->printing=sim->printing_buf;
     }
-
-    if (printing) {
-      cheapdisplay=1;
-      while (*printing) {
-        if (*printing=='\001') { /* pause */
-          printing++;
-          for (i=20; i<24; i++) st->rowimage[i]=-1;
-          break;
-        } 
-        else if (*printing=='\n') {
-          a2_printc(st,*printing);
-          printing++;
-          break;
-        }
-        else {
-          a2_printc(st,*printing);
-          printing++;
-        }
-      }
-      if (!*printing) printing=NULL;
+    else {
+      sprintf(sim->printing_buf,"\n?%s\n]",
+              apple2_dos_errors[random()%
+                                (sizeof(apple2_dos_errors) /
+                                 sizeof(char *))]);
+      sim->printing=sim->printing_buf;
     }
-    else if (curtime >= next_actiontime) {
-      if (typing) {
-        /* If we're in the midst of typing a string, emit a character with
-           random timing. */
-        a2_printc(st, *typing);
-        if (*typing=='\n') {
-          next_actiontime = curtime;
-        } else {
-          next_actiontime = curtime + (random()%1000)*0.0003 + 0.3;
-        }
-        typing++;
-
-        if (!*typing) typing=NULL;
-
-      } 
-      else {
-        next_actiontime=curtime;
-
-        switch(stepno) {
-        case 0:
-          a2_invalidate(st);
-          if (0) {
-            /*
-              For testing color rendering. The spec is:
-                           red grn blu
-              0  black       0   0   0
-              1  red       227  30  96
-              2  dk blue    96  78 189
-              3  purple    255  68 253
-              4  dk green    0 163  96
-              5  gray      156 156 156
-              6  med blue   20 207 253
-              7  lt blue   208 195 255
-              8  brown      96 114   3
-              9  orange    255 106  60
-              10 grey      156 156 156
-              11 pink      255 160 208
-              12 lt green   20 245  60
-              13 yellow    208 221 141
-              14 aqua      114 255 208
-              15 white     255 255 255
-            */
-            st->gr_mode=A2_GR_LORES;
-            for (row=0; row<24; row++) {
-              for (col=0; col<40; col++) {
-                st->textlines[row][col]=(row&15)*17;
-              }
-            }
-            next_actiontime+=0.4;
-            stepno=88;
-          }
-          else if (random()%3==0) {
-            st->gr_mode=0;
-            next_actiontime+=0.4;
-            stepno=88;
-          }
-          else if (random()%4==0) {
-            st->gr_mode=A2_GR_LORES;
-            if (random()%3==0) st->gr_mode |= A2_GR_FULL;
-            next_actiontime+=0.4;
-            stepno=88;
-          } 
-          else if (random()%2==0) {
-            st->gr_mode=A2_GR_HIRES;
-            stepno=73;
-          }
-          else {
-            st->gr_mode=A2_GR_HIRES;
-            next_actiontime+=0.4;
-            stepno=88;
-          }
-          break;
-
-        case 88:
-          /* An illegal instruction or a reset caused it to drop into the
-             assembly language monitor, where you could disassemble code & view
-             data in hex. */
-          if (random()%3==0) {
-            char ibytes[128];
-            char itext[128];
-            int addr=0xd000+random()%0x3000;
-            sprintf(ibytes,
-                    "%02X",random()%0xff);
-            sprintf(itext,
-                    "???");
-            sprintf(printbuf,
-                    "\n\n"
-                    "%04X: %-15s %s\n"
-                    " A=%02X X=%02X Y=%02X S=%02X F=%02X\n"
-                    "*",
-                    addr,ibytes,itext,
-                    random()%0xff, random()%0xff,
-                    random()%0xff, random()%0xff,
-                    random()%0xff);
-            printing=printbuf;
-            a2_goto(st,23,1);
-            if (st->gr_mode) {
-              stepno=11;
-            } else {
-              stepno=13;
-            }
-            prompt='*';
-            next_actiontime += 2.0 + (random()%1000)*0.0002;
-          }
-          else {
-            /* Lots of programs had at least their main functionality in
-               Applesoft Basic, which had a lot of limits (memory, string
-               length, etc) and would sometimes crash unexpectedly. */
-            sprintf(printbuf,
-                    "\n"
-                    "\n"
-                    "\n"
-                    "?%s IN %d\n"
-                    "\001]",
-                    apple2_basic_errors[random() %
-                                        (sizeof(apple2_basic_errors)
-                                         /sizeof(char *))],
-                    (1000*(random()%(random()%59+1)) +
-                     100*(random()%(random()%9+1)) +
-                     5*(random()%(random()%199+1)) +
-                     1*(random()%(random()%(random()%2+1)+1))));
-            printing=printbuf;
-            a2_goto(st,23,1);
-            stepno=1;
-            prompt=']';
-            next_actiontime += 2.0 + (random()%1000)*0.0002;
-          }
-          break;
-      
-        case 1:
-          if (simulate_user && random()%3==0) {
-            /* This was how you reset the Basic interpreter. The sort of
-               incantation you'd have on a little piece of paper taped to the
-               side of your machine */
-            typing="CALL -1370";
-            stepno=2;
-          } 
-          else if (simulate_user && random()%2==0) {
-            typing="CATALOG\n";
-            stepno=22;
-          }
-          else {
-            next_actiontime+=1.0;
-            stepno=6;
-          }
-          break;
-
-        case 2:
-          stepno=3;
-          next_actiontime += 0.5;
-          break;
-      
-        case 3:
-          st->gr_mode=0;
-          a2_cls(st);
-          a2_goto(st,0,16);
-          for (s="APPLE ]["; *s; s++) a2_printc(st,*s);
-          a2_goto(st,23,0);
-          a2_printc(st,']');
-          next_actiontime+=1.0;
-          stepno=6;
-          break;
-
-        case 6:
-          if (simulate_user && random()%50==0 && 0) { /* disabled, too goofy */
-            typing="10 PRINT \"TRS-80S SUCK!!!\"\n"
-              "]20 GOTO 10\n"
-              "]RUN";
-            stepno=7;
-          }
-          else {
-            stepno=8;
-            next_actiontime += delay;
-          }
-          break;
-
-        case 7:
-          for (i=0; i<30; i++) {
-            for (s="\nTRS-80S SUCK"; *s; s++) a2_printc(st,*s);
-          }
-          stepno=8;
-          next_actiontime+=delay;
-
-        case 8:
-          break;
-
-        case 22:
-          if (random()%50==0) {
-            sprintf(printbuf,"\nDISK VOLUME 254\n\n"
-                    " A 002 HELLO\n"
-                    "\n"
-                    "]");
-            printing=printbuf;
-          }
-          else {
-            sprintf(printbuf,"\n?%s\n]",
-                    apple2_dos_errors[random()%
-                                      (sizeof(apple2_dos_errors) /
-                                       sizeof(char *))]);
-            printing=printbuf;
-          }
-          stepno=6;
-          next_actiontime+=1.0;
-          break;
-
-        case 11:
-          if (simulate_user && random()%2==0) {
-            /* This was how you went back to text mode in the monitor */
-            typing="FB4BG";
-            stepno=12;
-          } else {
-            next_actiontime+=1.0;
-            stepno=6;
-          }
-          break;
-
-        case 12:
-          st->gr_mode=0;
-          a2_invalidate(st);
-          a2_printc(st,'\n');
-          a2_printc(st,'*');
-          stepno=13;
-          next_actiontime+=2.0;
-          break;
-
-        case 13:
-          /* This reset things into Basic */
-          if (simulate_user && random()%2==0) {
-            typing="FAA6G";
-            stepno=2;
-          }
-          else {
-            stepno=8;
-            next_actiontime+=delay;
-          }
-          break;
-
-        case 73:
-          for (i=0; i<1500; i++) {
-            a2_poke(st, fillptr, fillbyte);
-            fillptr++;
-            fillbyte = (fillbyte+1)&0xff;
-          }
-          next_actiontime += 0.08;
-          /* When you hit c000, it changed video settings */
-          if (fillptr>=0xc000) {
-            a2_invalidate(st);
-            st->gr_mode=0;
-          }
-          /* And it seemed to reset around here, I dunno why */
-          if (fillptr>=0xcf00) stepno=3;
-          break;
-        }
-      }
+    *stepno=999;
+    *next_actiontime+=1.0;
+    break;
+
+  case 180:
+    if (random()%2==0) {
+      /* This was how you went back to text mode in the monitor */
+      sim->typing="FB4BG";
+      *stepno=190;
+    } else {
+      *next_actiontime+=1.0;
+      *stepno=999;
     }
-
-    /* Now, we turn the data in the Apple II video into a screen display. This
-       is interesting because of the interaction with the NTSC color decoding
-       in a color television. */
-
-    colormode=use_color && st->gr_mode!=0;
-    if (!use_cmap) {
-      ntsc_set_demod(dec, tint_control, color_control, brightness_control,
-                     freq_error, colormode);
+    break;
+
+  case 190:
+    st->gr_mode=0;
+    a2_invalidate(st);
+    a2_printc(st,'\n');
+    a2_printc(st,'*');
+    *stepno=200;
+    *next_actiontime+=2.0;
+    break;
+
+  case 200:
+    /* This reset things into Basic */
+    if (random()%2==0) {
+      sim->typing="FAA6G";
+      *stepno=120;
     }
-    imgrow=0;
-    for (textrow=0; textrow<24; textrow++) {
-      if (st->rowimage[textrow] == textrow) {
-        screen_plan[textrow]=0;
-      }
-      else if (cheapdisplay && st->rowimage[textrow]>=0 &&
-               textrow<21 && st->rowimage[textrow]<21 && 
-               st->rowimage[textrow]>=2 && textrow>=2 &&
-               (st->rowimage[textrow]+1)*h/24 + screen_xo <= xgwa.height) {
-        screen_plan[textrow]= A2_SP_COPY | st->rowimage[textrow];
-        for (i=0; i<8; i++) {
-          crtload[textrow*8+i]=crtload[st->rowimage[textrow]*8+i];
-        }
-        startdisplayrow=0;
-      }
-      else {
-        st->rowimage[textrow]=imgrow;
-        screen_plan[textrow]=imgrow | A2_SP_PUT;
-        
-        for (row=textrow*8; row<textrow*8+8; row++) {
-          char *pp;
-          int pixmultinc,pixbright;
-          int scanstart_i, scanend_i;
-          int squishright_i, squishdiv;
-          int pixrate;
-          double bloomthisrow,shiftthisrow;
-          int ytop=(imgrow*h/24) + ((row-textrow*8) * h/192);
-          int ybot=ytop+h/192;
-
-          /* First we generate the pattern that the video circuitry shifts out
-             of memory. It has a 14.something MHz dot clock, equal to 4 times
-             the color burst frequency. So each group of 4 bits defines a
-             color.  Each character position, or byte in hires, defines 14
-             dots, so odd and even bytes have different color spaces. So,
-             pattern[0..600] gets the dots for one scan line. */
-
-          memset(dec->pattern,0,sizeof(dec->pattern));
-          pp=dec->pattern+20;
-        
-          if ((st->gr_mode&A2_GR_HIRES) && (row<160 ||
-                                            (st->gr_mode&A2_GR_FULL))) {
-
-            /* Emulate the mysterious pink line, due to a bit getting
-               stuck in a shift register between the end of the last
-               row and the beginning of this one. */
-            if ((st->hireslines[row][0] & 0x80) &&
-                (st->hireslines[row][39]&0x40)) {
-              pp[-1]=1;
-            }
-
-            for (col=0; col<40; col++) {
-              u_char b=st->hireslines[row][col];
-              int shift=(b&0x80)?0:1;
-
-              /* Each of the low 7 bits in hires mode corresponded to 2 dot
-                 clocks, shifted by one if the high bit was set. */
-              for (i=0; i<7; i++) {
-                pp[shift+1] = pp[shift] =(b>>i)&1;
-                pp+=2;
-              }
-            }
-          } 
-          else if ((st->gr_mode&A2_GR_LORES) && (row<160 ||
-                                                 (st->gr_mode&A2_GR_FULL))) {
-            for (col=0; col<40; col++) {
-              u_char nib=(st->textlines[textrow][col] >> (((row/4)&1)*4))&0xf;
-              /* The low or high nybble was shifted out one bit at a time. */
-              for (i=0; i<14; i++) {
-                *pp = (nib>>((col*14+i)&3))&1;
-                pp++;
-              }
-            }
-          }
-          else {
-            for (col=0; col<40; col++) {
-              int rev;
-              c=st->textlines[textrow][col];
-              /* hi bits control inverse/blink as follows:
-                  0x00: inverse
-                  0x40: blink
-                  0x80: normal
-                  0xc0: normal */
-              rev=!(c&0x80) && (!(c&0x40) || st->blink);
-
-              for (i=0; i<7; i++) {
-                for (i=0; i<7; i++) {
-                  unsigned long pix=XGetPixel(text_im,
-                                              ((c&0x3f)^0x20)*7+i, row%8);
-                  pp[1] = pp[2] = pix^rev;
-                  pp+=2;
-                }
-              }
-            }
-          }
-
-          /*
-            Interpolate the 600-dotclock line into however many horizontal
-            screen pixels we're using, and convert to RGB. 
-
-            We add some 'bloom', variations in the horizontal scan width with
-            the amount of brightness, extremely common on period TV sets. They
-            had a single oscillator which generated both the horizontal scan
-            and (during the horizontal retrace interval) the high voltage for
-            the electron beam. More brightness meant more load on the
-            oscillator, which caused an decrease in horizontal deflection. Look
-            for (bloomthisrow).
-
-            Also, the A2 did a bad job of generating horizontal sync pulses
-            during the vertical blanking interval. This, and the fact that the
-            horizontal frequency was a bit off meant that TVs usually went a
-            bit out of sync during the vertical retrace, and the top of the
-            screen would be bent a bit to the left or right. Look for
-            (shiftthisrow).
-
-            We also add a teeny bit of left overscan, just enough to be
-            annoying, but you can still read the left column of text.
-            
-            We also simulate compression & brightening on the right side of the
-            screen. Most TVs do this, but you don't notice because they
-            overscan so it's off the right edge of the CRT. But the A2 video
-            system used so much of the horizontal scan line that you had to
-            crank the horizontal width down in order to not lose the right few
-            characters, and you'd see the compression on the right
-            edge. Associated with compression is brightening; since the
-            electron beam was scanning slower, the same drive signal hit the
-            phosphor harder. Look for (squishright_i) and (squishdiv).
-          */
-
-          for (i=j=0; i<600; i++) {
-            j += dec->pattern[i];
-          }
-          crtload[row] = (crtload[row>1 ? row-1 : 0]) * 0.98 + 0.02*(j/600.0) +
-            (row>180 ? (row-180)*(row-180)*0.0005 : 0.0);
-          bloomthisrow = -10.0 * crtload[row];
-          shiftthisrow=((row<18) ? ((18-row)*(18-row)* 0.002 + (18-row)*0.05)
-                        * horiz_desync : 0.0);
-
-          scanstart_i=(int)((bloomthisrow+shiftthisrow+18.0)*65536.0);
-          if (scanstart_i<0) scanstart_i=0;
-          if (scanstart_i>30*65536) scanstart_i=30*65536;
-          scanend_i=599*65536;
-          squishright_i=scanstart_i + 530*65536;
-          squishdiv=w/15;
-          pixrate=(int)((560.0-2.0*bloomthisrow)*65536.0/w);
-          
-          if (use_cmap) {
-            for (y=ytop; y<ybot; y++) {
-              int level=(!(y==ytop && ybot-ytop>=3) &&
-                         !(y==ybot-1 && ybot-ytop>=5));
-              int hist=0;
-              int histi=0;
-
-              pixmultinc=pixrate;
-              for (x=0, i=scanstart_i;
-                   x<w && i<scanend_i;
-                   x++, i+=pixmultinc) {
-                int pati=(i>>16);
-                int offset=pati&3;
-                while (pati>=histi) {
-                  hist=(((hist<<1) & ((1<<A2_CMAP_HISTBITS)-1)) |
-                        dec->pattern[histi]);
-                  histi++;
-                }
-                XPutPixel(image, x, y, 
-                          colors[A2_CMAP_INDEX(colormode,level,hist,offset)]);
-                if (i >= squishright_i) {
-                  pixmultinc += pixmultinc/squishdiv;
-                }
-              }
-              for ( ; x<w; x++) {
-                XPutPixel(image, x, y, colors[0]);
-              }
-            }
-          } else {
-
-            ntsc_to_yiq(dec);
-
-            pixbright=(int)(contrast_control*65536.0);
-            pixmultinc=pixrate;
-            for (x=0, i=scanstart_i, rrp=raw_rgb;
-                 x<w && i<scanend_i;
-                 x++, i+=pixmultinc, rrp+=3) {
-              int pixfrac=i&0xffff;
-              int invpixfrac=65536-pixfrac;
-              int pati=i>>16;
-              int r,g,b;
-
-              int interpy=((dec->ntscy[pati]*invpixfrac + 
-                            dec->ntscy[pati+1]*pixfrac)>>16);
-              int interpi=((dec->ntsci[pati]*invpixfrac + 
-                            dec->ntsci[pati+1]*pixfrac)>>16);
-              int interpq=((dec->ntscq[pati]*invpixfrac + 
-                            dec->ntscq[pati+1]*pixfrac)>>16);
-
-              /*
-                According to the NTSC spec, Y,I,Q are generated as:
-                
-                y=0.30 r + 0.59 g + 0.11 b
-                i=0.60 r - 0.28 g - 0.32 b
-                q=0.21 r - 0.52 g + 0.31 b
-                
-                So if you invert the implied 3x3 matrix you get what standard
-                televisions implement with a bunch of resistors (or directly in
-                the CRT -- don't ask):
-                
-                r = y + 0.948 i + 0.624 q
-                g = y - 0.276 i - 0.639 q
-                b = y - 1.105 i + 1.729 q
-                
-                These coefficients are below in 16.16 format.
-              */
-
-              r=((interpy + ((+68128*interpi+40894*interpq)>>16))*pixbright)
-                                                           >>16;
-              g=((interpy + ((-18087*interpi-41877*interpq)>>16))*pixbright)
-                                                           >>16;
-              b=((interpy + ((-72417*interpi+113312*interpq)>>16))*pixbright)
-                                                            >>16;
-              if (r<0) r=0;
-              if (g<0) g=0;
-              if (b<0) b=0;
-              rrp[0]=r;
-              rrp[1]=g;
-              rrp[2]=b;
-
-              if (i>=squishright_i) {
-                pixmultinc += pixmultinc/squishdiv;
-                pixbright += pixbright/squishdiv;
-              }
-            }
-            for ( ; x<w; x++, rrp+=3) {
-              rrp[0]=rrp[1]=rrp[2]=0;
-            }
-
-            for (y=ytop; y<ybot; y++) {
-              /* levelmult represents the vertical size of scan lines. Each
-                 line is brightest in the middle, and there's a dark band
-                 between them. */
-              int levelmult;
-              double levelmult_fp=(y + 0.5 - (ytop+ybot)*0.5) / (ybot-ytop);
-              levelmult_fp = 1.0-(levelmult_fp*levelmult_fp*levelmult_fp
-                                  *levelmult_fp)*16.0;
-              if (levelmult_fp<0.0) levelmult_fp=0.0;
-              levelmult = (int)(64.9*levelmult_fp);
-
-              /* Fast special cases to avoid the slow XPutPixel. Ugh. It goes
-                  to show why standard graphics sw has to be fast, or else
-                  people will have to work around it and risk incompatibility.
-                  The quickdraw folks understood this. The other answer would
-                  be for X11 to have fewer formats for bitm.. oh, never
-                  mind. If neither of these cases work (they probably cover 99%
-                  of setups) it falls back on the Xlib routines. */
-              if (image->format==ZPixmap && image->bits_per_pixel==32 && 
-                  sizeof(unsigned long)==4 &&
-                  image->byte_order==localbyteorder) {
-                unsigned long *pixelptr =
-                  (unsigned long *) (image->data + y * image->bytes_per_line);
-                for (x=0, rrp=raw_rgb; x<w; x++, rrp+=3) {
-                  unsigned long ntscri, ntscgi, ntscbi;
-                  ntscri=((unsigned long)rrp[0])*levelmult;
-                  ntscgi=((unsigned long)rrp[1])*levelmult;
-                  ntscbi=((unsigned long)rrp[2])*levelmult;
-                  if (ntscri>65535) ntscri=65535;
-                  if (ntscgi>65535) ntscgi=65535;
-                  if (ntscbi>65535) ntscbi=65535;
-                  *pixelptr++ = ((ntscri>>red_invprec)<<red_shift) |
-                    ((ntscgi>>green_invprec)<<green_shift) |
-                    ((ntscbi>>blue_invprec)<<blue_shift);
-                }
-              }
-              else if (image->format==ZPixmap && image->bits_per_pixel==16 && 
-                       sizeof(unsigned short)==2 &&
-                       image->byte_order==localbyteorder) {
-                unsigned short *pixelptr =
-                (unsigned short *)(image->data + y*image->bytes_per_line);
-                for (x=0, rrp=raw_rgb; x<w; x++, rrp+=3) {
-                  unsigned long ntscri, ntscgi, ntscbi;
-                  ntscri=((unsigned long)rrp[0])*levelmult;
-                  ntscgi=((unsigned long)rrp[1])*levelmult;
-                  ntscbi=((unsigned long)rrp[2])*levelmult;
-                  if (ntscri>65535) ntscri=65535;
-                  if (ntscgi>65535) ntscgi=65535;
-                  if (ntscbi>65535) ntscbi=65535;
-                  *pixelptr++ = ((ntscri>>red_invprec)<<red_shift) |
-                    ((ntscgi>>green_invprec)<<green_shift) |
-                    ((ntscbi>>blue_invprec)<<blue_shift);
-                }
-                
-              }
-              else {
-                for (x=0, rrp=raw_rgb; x<w; x++, rrp+=3) {
-                  unsigned long pixel, ntscri, ntscgi, ntscbi;
-                  /* Convert to 16-bit color values, with saturation. The ntscr
-                     values are 22.10 fixed point, and levelmult is 24.6, so we
-                     get 16 bits out*/
-                  ntscri=((unsigned long)rrp[0])*levelmult;
-                  ntscgi=((unsigned long)rrp[1])*levelmult;
-                  ntscbi=((unsigned long)rrp[2])*levelmult;
-                  if (ntscri>65535) ntscri=65535;
-                  if (ntscgi>65535) ntscgi=65535;
-                  if (ntscbi>65535) ntscbi=65535;
-                  pixel = ((ntscri>>red_invprec)<<red_shift) |
-                    ((ntscgi>>green_invprec)<<green_shift) |
-                    ((ntscbi>>blue_invprec)<<blue_shift);
-                  XPutPixel(image, x, y, pixel);
-                }
-              }
-            }
-          }
-        }
-        imgrow++;
-      }
+    else {
+      *stepno=999;
+      *next_actiontime+=sim->delay;
     }
+    break;
 
-    /* For just the the rows which changed, blit the image to the screen. */
-    for (textrow=0; textrow<24; ) {
-      int top,bot,srcrow,srctop,nrows;
-      
-      nrows=1;
-      while (textrow+nrows < 24 &&
-             screen_plan[textrow+nrows] == screen_plan[textrow]+nrows)
-        nrows++;
-
-      top=h*textrow/24;
-      bot=h*(textrow+nrows)/24;
-      srcrow=screen_plan[textrow]&A2_SP_ROWMASK;
-      srctop=srcrow*h/24;
-
-      if (screen_plan[textrow] & A2_SP_COPY) {
-        if (0) printf("Copy %d screenrows %d to %d\n", nrows, srcrow, textrow);
-        XCopyArea(dpy, window, window, gc,
-                  screen_xo, screen_yo + srctop,
-                  w, bot-top,
-                  screen_xo, screen_yo + top);
-      }
-      else if (screen_plan[textrow] & A2_SP_PUT) {
-        if (0) printf("Draw %d imgrows %d to %d\n", nrows, srcrow, textrow);
-        if (use_shm) {
-#ifdef HAVE_XSHM_EXTENSION
-          XShmPutImage(dpy, window, gc, image, 
-                       0, srctop, screen_xo, screen_yo + top,
-                       w, bot-top, False);
-#endif
-        } else {
-          XPutImage(dpy, window, gc, image, 
-                    0, srctop,
-                    screen_xo, screen_yo + top,
-                    w, bot-top);
-        }
-      }
-      textrow += nrows;
+  case 300:
+    for (i=0; i<1500; i++) {
+      a2_poke(st, mine->fillptr, mine->fillbyte);
+      mine->fillptr++;
+      mine->fillbyte = (mine->fillbyte+1)&0xff;
     }
-    XSync(dpy,0);
-
-    for (textrow=0; textrow<24; textrow++) {
-      st->rowimage[textrow]=textrow;
+    *next_actiontime += 0.08;
+    /* When you hit c000, it changed video settings */
+    if (mine->fillptr>=0xc000) {
+      a2_invalidate(st);
+      st->gr_mode=0;
     }
-  }
+    /* And it seemed to reset around here, I dunno why */
+    if (mine->fillptr>=0xcf00) *stepno=130;
+    break;
 
- finished:
-  XSync(dpy,False);
-  XClearWindow(dpy, window);
-  goto cleanup;
-
- bailout:
-  ;
+  case 999:
+    break;
 
- cleanup:
-  if (image) {
-    if (use_shm) {
-#ifdef HAVE_XSHM_EXTENSION
-      destroy_xshm_image(dpy, image, &shm_info);
-#endif
-    } else {
-      XDestroyImage(image);
-    }
-    image=NULL;
+  case A2CONTROLLER_FREE:
+    free(mine);
+    break;
   }
-  if (text_im) XDestroyImage(text_im);
-  if (gc) XFreeGC(dpy, gc);
-  if (st) free(st);
-  if (raw_rgb) free(raw_rgb);
-  if (dec) free(dec);
-  if (n_colors) XFreeColors(dpy, xgwa.colormap, colors, n_colors, 0L);
 }
 
+static void
+apple2crash (Display* dpy, Window window, int delay)
+{
+  apple2 (dpy, window, delay, a2controller_crash);
+}
 
-\f
 char *progclass = "BSOD";
 
 char *defaults [] = {
@@ -4084,6 +2965,7 @@ char *defaults [] = {
   "*doApple2:              True",
   "*doOS390:               True",
   "*doVMS:                True",
+  "*doHVX:                True",
 
   ".Windows.font:         -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
   ".Windows.font2:        -*-courier-bold-r-*-*-*-180-*-*-m-*-*-*",
@@ -4124,6 +3006,11 @@ char *defaults [] = {
   ".SCO.foreground:       White",
   ".SCO.background:       Black",
 
+  ".HVX.font:             -*-courier-bold-r-*-*-*-120-*-*-m-*-*-*",
+  ".HVX.font2:            -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
+  ".HVX.foreground:       White",
+  ".HVX.background:       Black",
+
   ".Linux.font:                   9x15bold",
   ".Linux.font2:          -*-courier-bold-r-*-*-*-140-*-*-m-*-*-*",
   ".Linux.foreground:      White",
@@ -4168,6 +3055,8 @@ char *defaults [] = {
   ".VMS.foreground:       White",
   ".VMS.background:       Black",
 
+  ANALOGTV_DEFAULTS
+
 #ifdef HAVE_XSHM_EXTENSION
   "*useSHM:                True",
 #endif
@@ -4199,6 +3088,8 @@ XrmOptionDescRec options [] = {
   { "-no-apple2",      ".doApple2",            XrmoptionNoArg,  "False" },
   { "-sco",            ".doSCO",               XrmoptionNoArg,  "True"  },
   { "-no-sco",         ".doSCO",               XrmoptionNoArg,  "False" },
+  { "-hvx",            ".doHVX",               XrmoptionNoArg,  "True"  },
+  { "-no-hvx",         ".doHVX",               XrmoptionNoArg,  "False" },
   { "-bsd",            ".doBSD",               XrmoptionNoArg,  "True"  },
   { "-no-bsd",         ".doBSD",               XrmoptionNoArg,  "False" },
   { "-linux",          ".doLinux",             XrmoptionNoArg,  "True"  },
@@ -4215,6 +3106,7 @@ XrmOptionDescRec options [] = {
   { "-no-os390",       ".doOS390",             XrmoptionNoArg,  "False" },
   { "-vms",            ".doVMS",               XrmoptionNoArg,  "True"  },
   { "-no-vms",         ".doVMS",               XrmoptionNoArg,  "False" },
+  ANALOGTV_OPTIONS
   { 0, 0, 0, 0 }
 };
 
@@ -4224,14 +3116,15 @@ static struct {
   void (*fn) (Display *, Window, int delay);
 } all_modes[] = {
   { "Windows",         windows_31 },
-  { "Nt",              windows_nt },
-  { "2k",              windows_2k },
+  { "NT",              windows_nt },
+  { "Win2K",           windows_2k },
   { "Amiga",           amiga },
   { "Mac",             mac },
   { "MacsBug",         macsbug },
   { "Mac1",            mac1 },
   { "MacX",            macx },
   { "SCO",             sco },
+  { "HVX",             hvx },
   { "SparcLinux",      sparc_linux },
   { "BSD",             bsd },
   { "Atari",           atari },
@@ -4240,7 +3133,7 @@ static struct {
   { "Linux",           linux_fsck },
   { "HPUX",            hpux },
   { "OS390",           os390 },
-  { "Apple2",          apple2 },
+  { "Apple2",          apple2crash },
   { "VMS",             vms },
 };
 
@@ -4277,7 +3170,8 @@ screenhack (Display *dpy, Window window)
       XWindowAttributes xgwa;
       XGetWindowAttributes (dpy, window, &xgwa);
       XSelectInput (dpy, window,
-                    xgwa.your_event_mask | KeyPressMask | ButtonPressMask);
+                    xgwa.your_event_mask |
+                    KeyPressMask | ButtonPressMask | ExposureMask);
     }
 
   while (1)