[comp.sys.atari.st] The cause of the phantom typist

jan@janhh.hanse.de (Jan Willamowius) (04/02/91)

Hi!

Since this subject keeps comming up since quite some time, here is
an article describing the cause of the phantom typist (including a
"source listing" of the buggy part of GEM). We sent this to Atari quite
some time ago but never got an answer.

The author of this article is a friend of mine who is not reachable
via email, Wolfram Roisch. If there is a need I will forward mail to him.

Happy trails,
              Jan
---

     THE SYMPTOM

in article <881030205326.543196]PCO-MULTICS.HBI.HONEYWELL.COM>,
 Friesen@PCO-MULTICS.HBI.HONEYWELL.COM says:
>    I get the wierdest errors...
  [...]
>     strange things started happening.  As I typed
> in 'ing ' at the end of a word, the computer started hiccupping.  I
> still got the "key-click" sound, but it wouldn't disply what I typed,
> instead it kept duplicating the 'ing ' of the last word I typed.  After
> it did this about 15 times, the system froze with 2 bombs, and I had to
> reset.  When it duplicated the 'ing ', it did it at the same speed that
> I had originally typed it in, and as it reached the end of the line,
> Flash still triggered its wrap-around.
>
> If anyone could figure this out, they sure deserve a pat on the back!
>
> Aric Friesen

in message <27334@cup.portal.com> Bob Retelle@ucbvax.Berkeley.EDU found:
> I would be typing in new text at the bottom of the text buffer..
> A series of quick backspaces would trigger the "phantom typist", resulting
> in the last 10 or so characters being repeated over and over, until the
> system crashed...


     THE CURE

in article imagen!atari!danscott]ucbvax.Berkeley.EDU  (Dan Scott) knew:
> Do you have a joystick or other similar device plugged into your ST?  It
> is a known fact that Proline Joysticks (The ones that work on the 7800
> game system) will cause the ST to act in the manner in which you described.
>
>Dan Scott
> Happy Halloween!

     (The Joystick Fire is hard-wired to the right mouse button. If you have
 a joystick attached to your ST, make shure the Auto Fire switch is turned off
 when booting or running GEM programs..)

in article portal!atari!kbad@apple.com  (Ken Badertscher) knew:
> Now why doesn't that surprise me?  Not to bash GST, but I have found
> that a lot of problems similar to this are a result of bad programming
> practices.  Not intentional, but just because the developer wasn't
> aware of some restriction or another.  It's all too easy to blame TOS.
 [..]
>   I strongly suspect that the problem is caused by  mixing input modes
> between AES/VDI/GEMDOS/BIOS. That has been known to produce results like
> this.  If it is _not_ that, then there is a good chance that it _is_ a bug
> in TOS, and I want to fix it!!!
>
quoting grahamt@syma.sussex.ac.uk (Graham Thomas):
>| People can go for months without it striking, and then have it
>| happen twice in a day.  (Sunspots??? :-) )
>
> Yep, sounds a lot like the ol' cosmic rays.  It is really unfortunate that
> this particular bug is not easily reproducible.  Of course, if it were,
> it would probably have been fixed long ago... :-/
>
 [..]
> While you're at it, don't forget to sprinkle the chicken's blood on the
> keyboard and dance about, chanting at the monitor.
>
>Ken Badertscher  (ames!atari!kbad)
> Atari R&D System Software Engine
> #include <disclaimer>


     THE MEDICINE

in <27180@cup.portal.com> Bob Retelle remarked:
 [..]
>    possibly I didn't sprinkle enough dried chicken blood around my ST, as
> I've had the "Phantom Typist" hit me while using FLASH as a text editor...
>
> Seems odd that someone who's been so involved with the ST has never heard
> of this "feature" that's existed as long as the ST has been available...
>BobR

and in  <27334@cup.portal.com>:
> It didn't happen often, but when it did, it was terribly annoying...
> I wonder if Ken knows where I can buy a new supply of dried chicken blood..?
>BobR

in article att!oucsace!bwhite@ucbvax.Berkeley.EDU  (Bill White):
> After days and days of using FW+ in an attempt to get the
> Phantom to appear, I finally did it.  Unfortunately, I didn't have my
> logic probe with me right there,
 [..]
> Anyone out there have a logic analyzer they'd be willing to send
> me for further testing???
>| Bill White Internet: bwhite@oucsace.cs.ohiou.edu	|


     THE SURGERY

     The Ghostwriter disease is caused by a "coincidus interruptus" (as we
 voodoo doctors say). Input buffers overflow when interrupts of different
 priorities collide in interrupt coding like this:

 struct { /* GEM AES storage segment */
   ..
   struct tRec /* application recording as described in Appl_tRecord() */
   { void(* t_who)(); /* routine */
   long   t_how;     /* arguments */
   } recs[32];
   ..
 }

>   void /* enqueue input for forker */
> forkq( void(* who)(), long how)
> { reg struct tRec* rec;
>   extern fpcnt, fpt; /* fork-pipe-tail index */
>   if( fpcnt < 32)
>   { rec= (long )((fpt++ << 3) + &D.recs);
>     if( fpt == 32) fpt= 0;
>     rec->t_who= who;
>     rec->t_how= how;
>     fpcnt++;
> } }

 (copyright by Digital Research Inc, 1985, April 15 (!))

 This routine is used to queue inputs for later use at dispatch time.
 It is called in interrupts from the VDI input vectors (timvec, butvec and
 motvec) as well as non-interrupt from a keyboard check, application replay
 (appl_tplay) or mouse change to cancel a double-click.

     Tick-tick-tick-CRASH! - Revenge of the Ghostwriter..

 What happens if forkq() is called non-interrupt, the fpt index is at 31 and
 the code gets reentered (interrupted) between fpt++ and if( fpt == 32) ..?

 To exorcise one may
 1) Replace expressions like ++i; if(i == ANYPOWEROFTWO) i= 0;
    by ++i &= (ANYPOWEROFTWO - 1)
 2) make sure the interrupts are disabled whenever forkq() is called
    (from chkkbd(), mchange() and ap_tplay())
 3) recompile, assemble and link the system.

 Any questions?

 Wolfram Roisch, Hamburg, Germany

--
Jan Willamowius      E-Mail: jan@janhh.hanse.de
Nienredder 6
2000 Hamburg 54      "A-Ram-A-Lam-A-Ding-Dong" (The Edsels)

micro@imada.dk (Klaus Pedersen) (04/04/91)

jan@janhh.hanse.de (Jan Willamowius) writes:

> struct { /* GEM AES storage segment */
>   ..
>   struct tRec /* application recording as described in Appl_tRecord() */
>   { void(* t_who)(); /* routine */
>   long   t_how;     /* arguments */
>   } recs[32];
>   ..
> }

>>   void /* enqueue input for forker */
>> forkq( void(* who)(), long how)
>> { reg struct tRec* rec;
>>   extern fpcnt, fpt; /* fork-pipe-tail index */
>>   if( fpcnt < 32)
>>   { rec= (long )((fpt++ << 3) + &D.recs);
>>     if( fpt == 32) fpt= 0;
>>     rec->t_who= who;
>>     rec->t_how= how;
>>     fpcnt++;
>> } }
> (copyright by Digital Research Inc, 1985, April 15 (!))
> What happens if forkq() is called non-interrupt, the fpt index is at 31 and
> the code gets reentered (interrupted) between fpt++ and if( fpt == 32) ..?

You might be right there...

> To exorcise one may
> 1) Replace expressions like ++i; if(i == ANYPOWEROFTWO) i= 0;
>    by ++i &= (ANYPOWEROFTWO - 1)

????? in what language do you want to write that ?????

What you are writing is :
    ++i = ++i & (APO2-1);
 - no matter how you try to hide it...

But ok, I understand what you mean - what you want is a interlocked add cyclic.
  IAC 1,APO2,i  - but no compiler can generate that to a 68K. Some
signal processors can (and they are not restricted to powers of 2 (Analog 
Devices).


> 2) make sure the interrupts are disabled whenever forkq() is called
>    (from chkkbd(), mchange() and ap_tplay())

This is a lot easier than making a new CPU with new instructions and a new
C-like compiler that can generate them...

> 3) recompile, assemble and link the system.

might be hard to do with '1)'...

---

Klaus  (micro@imada.dk)

apratt@atari.UUCP (Allan Pratt) (04/05/91)

micro@imada.dk (Klaus Pedersen) writes:
>> To exorcise one may
>> 1) Replace expressions like ++i; if(i == ANYPOWEROFTWO) i= 0;
>>    by ++i &= (ANYPOWEROFTWO - 1)

>jan@janhh.hanse.de (Jan Willamowius) writes:
> in what language do you want to write that?
>What you are writing is :
>    ++i = ++i & (APO2-1);
> - no matter how you try to hide it...

That's not true. Semantically, "i += 2;" is equivalent to "i = i + 2;"
but "++i += 2;" is not equivalent to "++i = ++i + 2;" because the
people who designed C are smarter than that.  The side-effect is
performed only once.

But regardless of that, you are suggesting that what happens in a C
statement is uninterruptable, so doing something in a single statement
makes it safe when it might be unsafe in multiple statements.  This is
not true.  On the 68000 family, an interrupt can come between any two
instructions.  Individual instructions can't be interrupted, but the
bus can be arbitrated away (for DMA, for example) between the read and
the write of a read-modify-write instruction, except for the TAS
instruction which is explicitly atomic.

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt