[comp.sys.atari.st] Vertical Blank Interrupts

iarocci@eneevax.UUCP (03/13/87)

I've been doing a lot of work involving use of the vertical blank interrupts
recently, and have noticed certain annoying behaviors.  I'd appreciate com-
ments or suggestions related to either of the following:

First, I install a vertical blank driver at the address pointed to by vblqueue
($456).  I check for the first vector in the list that is NULL before install-
ing it.  This is usually the first one when called from the auto folder, acc-
ording to my debug information.  Then, at some point, the system randomly
writes its own vector right on top of mine.  Great!

Well, I set the program to start checking for an empty slot with the second
entry in the vbi queue next.  Now, my handler survives the boot process.  Un-
fortunately, now I can no longer run Degas Elite!  Apparently it wants the
second entry in vblqueue for something.  In desperation, I set my routine to
start scanning for an unused entry at the end of vblqueue, searching backward.
Everything seems to work now, but I'm still worried about future compatibility.

The other question I have regarding VBIs is this:  I want to use a VBI to
monitor some event, and then after that event occurs, temporarily suspend the
current process and execute some code that takes a bit of time.  Unfortunately,
every time I do this, the system crashes very quickly.  Bios calls are sup-
posed to be re-entrant to only three levels, and my code does make a Bios
call in the interrupt section, so I thought maybe this was the problem.

Flipping through The Guide in the hopes of finding a solution to my problem,
I noticed a variable called savptr ($4a2).  Apparently this is where the OS
saves registers during Bios calls.  I thought I remembered reading somewhere
that the three-level re-entrancy of Bios calls was due to there only being
sufficient space for three sets of register saves.  So, I created a nice big
array (4k), and set savptr to point to the array.  Well, the system still
crashes, although not quite as easily as before.  Anybody got any suggestions,
or will I have to write a multi-tasking kernel just to monitor an i/o port?
Sure seems like overkill!

-------------------------------------------------------------------------------
| Bill Dorsey          'Imagination is more important than knowledge.'        |
|                                            - Albert Einstein                |
|     'He who has imagination without learning has wings and no feet.'        |
|                                            - Joubert                        |
| ARPA : iarocci@eneevax.umd.edu                                              |
| UUCP : [seismo,allegra,rlgvax]!umcp-cs!eneevax!iarocci                      |
-------------------------------------------------------------------------------

dyer@atari.UUCP (03/14/87)

In article <741@eneevax.UUCP>, iarocci@eneevax.UUCP (John Iarocci) writes:
> Then, at some point, the system randomly
> writes its own vector right on top of mine.  Great!
> 
> Well, I set the program to start checking for an empty slot with the second
> entry in the vbi queue next.  Now, my handler survives the boot process.  Un-
> fortunately, now I can no longer run Degas Elite!

The first vblqueue slot is reserved for the VDI, and the
documentation says so.  If an application is hard-coded to use
(say) the 2nd slot, it is doing things wrong, wrong, wrong.

You can always intercept the interrupt itself.  You will have to
do your own mutual exclusion (trivial).

-- 
-Landon Dyer, Atari Corp.	    {sun,lll-lcc,imagen}!atari!dyer

The views expressed here do not not		
necessarily reflect those of Atari Corp.	Segments are for worms.

john@viper.UUCP (John Stanley) (03/18/87)

In article <741@eneevax.UUCP> iarocci@eneevax.UUCP (Bill Dorsey) writes:
 >I've been doing a lot of work involving use of the vertical blank interrupts
 >recently, and have noticed certain annoying behaviors.  I'd appreciate com-
 >ments or suggestions related to either of the following:
 >
 > [_description of details deleted_]
 >
 >The other question I have regarding VBIs is this:  I want to use a VBI to
 >monitor some event, and then after that event occurs, temporarily suspend the
 >current process and execute some code that takes a bit of time.  Unfortunately,
 >every time I do this, the system crashes very quickly.  Bios calls are sup-
 >posed to be re-entrant to only three levels, and my code does make a Bios
 >call in the interrupt section, so I thought maybe this was the problem.
 >
Well, they are supposed to be re-enterant, but it doesn't work right for
bios calls from within an interrupt routine.

  I had lots of fun tracking this roblem in a program I wrote which also
tried to make bios/xbios/gem calls from within an interrupt...  I tracked
the problem for 4 days thru the bios ROMS.  This is one of the problems
I hope they fix in the new ROMs.  (Note to Atari:  If you guys haven't
come up with a solution for this, contact me....)

  There is a bug in how trap 13 and trap 14 (bios and xbios) are handled.
As you pointed out in your message, there is an area used to save registers
while processing a trap call.  The code that does the save and restore was 
written (aparently) by someone with little or no experience dealing with 
an interrupt driven system.

  The code in question consists of 10-20 lines of assembly.  Since the
interrupts are not disabled and the code is not written in a way that
would allow interrupts to occur without causing problems, you eventualy
end up with a VBI or some other interrupt occuring in the middle of this
save or restore code.  If you then try to make a call to the bios (or to
any GEM function which uses the bios) the registers saved for your call
overwrite some (randomly 0-15 of them) of the registers saved for the
call being made at the time of the interrupt.  When your interrupt call
returns, the save/restore register bios routine finishes it's job and
the system continues on with no knowledge that the registers saved are
incorrect.  When it trys to return to the function that called the bios
in the 1st place, the incorrect registers are "restored" causing lots of
problems all over the place depending on the program being run...

  One other possibility is that the bios calls you were making took too
much time to return.  There are a few places in the VBI code I doubt will
work very well if you call them a second time before they return from a
previous interrupt...

  Hope this explains the problems you (and I) have been having.  As a
general rule, "Don't make any BIOS/XBIOS/GEM calls from an interrupt
routine.".  There's almost allways a way to get things done without
using them (Note: I said "ALMOST".)  So far, I've been able to use
several tricks to get things done when I need to.  Hope you can too..

 >.......  Anybody got any suggestions,
 >or will I have to write a multi-tasking kernel just to monitor an i/o port?
 >Sure seems like overkill!

Sure would be.  Since Beckemeyer has already done just that, perhaps
you would want to try using his multitasking system before you go to
all the trouble of writing your own...

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

braner@batcomputer.tn.cornell.edu (braner) (03/19/87)

[]

You must avoid reentering your VBI routine upon every VBI (71 times a second
with a monochrome monitor)!  (That's why it crashes...)  (I learned it the
hard way...)

I solved it like this:  the first time your VBI routine is called, it sets
a flag, which is cleared at the end of the routine.  At the beginning of
the routine it checks the flag, and if it is set it knows that it is a
recursive interrupt and it simply returns, doing nothing.

- Moshe Braner