[comp.sys.atari.st] strange bug?

brianp@ernie.Berkeley.EDU (Brian Peterson) (11/25/87)

I wrote a little routine which just jumped to an exception handling routine,
and put the address of my routine in the exception vector in place of the
original.  If the exception was the divide by zero, it worked as expected.
When it was the midi/kboard exception, the results were strange.
My routine was like this:
	move.l #fc281c a0
	jmp (a0)

with the routine's address in $118.  (actually, I wrote it in Forth,
so it was all backwards.)  The result varied depending on whether
I used a0, a1, or a2.

    a0 caused the computer to just die,
    a1 caused one of [illegal instruction, address error, bus error]
	at random to happen, 
    a2 caused beeps. 

The a1 and a2 ones did their thing some but not all times I hit a
computer key, and also did their things sometimes when a midi byte
went in.  The a2 one also made blocks of randomly colored pixels
occaisionally, which were the width of the screen, and went from some point
on the screen down to just above the next prompt-n-cursor on the screen.
I could fix the a2 version by replacing fc281c in 118.  The a1
one wouldn't let me type that many consecutive characters per prompt.

Does anyone know what would cause that behaviour?  Might it be
fried hardware, buggy roms, bugs in my software (Forthmacs by Mitch Bradley -
quite a useful package), or something I don't know about how exceptions
happen and interact and whatever ?????   Thanx for any info!

	Brian Peterson, ...!ucbvax!ucbernie!brianp (brianp@ernie.berkeley.edu)

braner@batcomputer.UUCP (11/25/87)

[]

The trick in redirecting an interrupt vector is to preserve all the
registers.  My solution usually is thus:

	MOVE.L vector,-(SP)
	RTS

(Look Ma, no registers!)

- Moshe Braner

dag@chinet.UUCP (Daniel A. Glasser) (11/26/87)

Your posting indicates that you are changing a machine register in an
exception handler without restoring it.  This is a no-no in systems
programming, at least on the 68000.  You don't know what's going on
when most hardware exceptions take place, and when the exception handler
returns, whatever it was that was taking place tries to continue.  If
it needs the data in that address register that you clobbered, the system
is likely to start doing very odd things.

I suggest reading up on exception handling in a 68000 manual (though the
idea is the same as most register machines).
-- 
					Daniel A. Glasser
					...!ihnp4!chinet!dag
					...!ihnp4!mwc!dag
					...!ihnp4!mwc!gorgon!dag
	One of those things that goes "BUMP!!! (ouch!)" in the night.

john@viper.Lynx.MN.Org (John Stanley) (11/27/87)

In article <21951@ucbvax.BERKELEY.EDU> brianp@ernie.Berkeley.EDU.UUCP (Brian Peterson) writes:
 >I wrote a little routine which just jumped to an exception handling routine,
 >and put the address of my routine in the exception vector in place of the
 >original.  If the exception was the divide by zero, it worked as expected.
 >When it was the midi/kboard exception, the results were strange.
 >My routine was like this:
 >	move.l #fc281c a0
 >	jmp (a0)

  If it's any consolation, this is a common mistake made by people who
aren't used to writing dirty-tricks code on the 68000.  The method
you're using to jump to the original exception handler is the problem.

  First off, do-NOT use a constant address for the jump.  Save the
address originaly contained in the exception vector and jump to -that-
location.  This will allow your code to work on machines where the
roms may have changed, and with any other code that may have already
"hooked the vector".

  Secondly, if you've saved the original vector in a long (4 byte)
variable called olvect, use this code to jump to it:

	move.l	olvect,-(a7)
	rts

This allows you to make an indirect jump without modifying any
registers.

  Third, be sure you restore the original vector before you exit your
program.  Not doing so can cause very very bad things to happen.

 >The result varied depending on whether I used a0, a1, or a2.

  ..because altering a0, a1, or a2 had the effect of altering the
contents of those registers in-the-program-making-the-exception(!).
After your routine changed a0/1/2, the exception handler (doing it's
job by-the-rules) would then store and restore the altered values and
then RTE to the program running when the exception occured.  Remember,
never alter the contents of a register from within an exception unless
you can restore that register before your code releases control of the 
machine -or- you're really sure what you're doing.

 >	Brian Peterson, ...!ucbvax!ucbernie!brianp (brianp@ernie.berkeley.edu)

  PS, just out of curiosity, what are you writing that needs to
replace an exception vector?

--- 
John Stanley (john@viper.UUCP)
Software Consultant - DynaSoft Systems
UUCP: ...{amdahl,ihnp4,rutgers}!meccts!viper!john