[comp.sys.amiga.hardware] Shared Interrupts

kent@swrinde.nde.swri.edu (Kent D. Polk) (09/14/90)

In article <1990Sep13.000531.15782@msuinfo.cl.msu.edu> wille@frith.msu.edu
(Jeffrey Wille) writes:
>I am currently working on a project which involves data acquisition.  I need
>to read the parallel port at an average rate of every 35 microseconds.
...
>data processing.  What I would like to do, is put the data in a buffer, and
>have my A500 periodically empty the buffer in the tightest loop possible.

This brings to mind some of my questions regarding PORTB shared interrupts.
Now shared interrupts are a bit new to me, so please forgive my ignorance...

Anyway, I am using an open collector, inverted logic signal interrupt
hooked to the PORTB interrupt line on my A2500/30 so I can be nice and
share the interrupt with the three other tasks that typically are using
it. When I generate an interrupt, I hold the line low until I can read
my interrupt status register to determine if it was my board or not
that pulled the line low. If mine, I reset the interrupt line to high
and reenable my interrupt when leaving the isr. Note that I have my own
enable/disable interrupt control handling for this stuff.

Questions regarding the proper use of shared interrupts:

1) Should I reset the interrupt line first thing in the isr, or hold it
low until I'm finished? My isr is pretty busy & takes about 600 us to
complete its dirty work. (at least for now, since it is written in
'C'). In case you were wondering, this is what Jeffrey's input buffer
question has to do with this whole discussion...

2) What about shared interrupts hitting at or near the same time:
  a. Do the other PORTB isr's hold the line low until finished (2091 SCSI,
     Keyboard * timer) ?
  b. How are multiple interrupts hits (at the 'same time') recognized
     by the system?
  c. Guru's Guide indicates how one should exit a shared isr when you
     determine it was your hardware which pulled the interrupt. - If
     multiple hits at the same time aren't registered, how do I know that
     I'm not stealing an interrupt when my hardware says it did it? As a
     matter of fact, I can do just that - not hook up my interrupt line & still
     process what are actually someone else's interrupts as if they were
     mine.
  d. Can I just say 'Not mine' to all of them? Does the system get confused
     when no one claims a shared interrupt? I realize that might slow things
     down a bit, but if it is safer then I can do it.

3) Do most shared interrupts incorporate a timeout - say - maybe 100 ms or
so? I plan on doing this as it is pretty easy, but am mainly curious. The
main reason is that when my program exits ungracefully, the interrupt doesn't
get serviced & poor Amy is left out in the cold, waiting for someone to
rescue her from the evil clutches of Dr. Loe :^) 

Right now Mr. Crowbar and I attack Dr. Loe in an effort to rescue the
fair lady.

(Ok, Ok, you would be this way too after spending a few weeks of 15
hour days on this project)

4) My trigger circuits have a recovery time (tank circuit) of about 5
ms. & the interrupt is tied to them.  Right now, I don't need to
service interrupts any faster, & indeed seem to be able to do this
quite easily with the 2500. Problem is, every now and then, I seem to
be trashing the machine - trackdisk.device appears to be the culprit,
but I know better, so apparently I am trashing trackdisk.device.

I suspect this has something to do with how I am exiting my isr.  Any
suggestions? (other than writing it in assembler - I know, some day
when I get around to it)

>        I looked at the hardware RKM for some help, but found it terse
>at best.  If someone could answer my questions, or direct me to a book
>with decent information, it would be appreciated.

Me too. The Guru's Guide is great, but doesn't answer all my questions.

>I would really appreciate getting some answers to these questions, or
>being directed to a book that has the info I'm looking for.  Actually,
>a book would be best.  I am writing this in behalf of my brother, whose
>machine is not on the net.

Ditto, except for the brother part :^)

Thanks Much,

Kent Polk: Southwest Research Institute (512) 522-2882
Internet : kent@swrinde.nde.swri.edu
UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent

rsbx@cbmvax.commodore.com (Raymond S. Brand) (09/14/90)

In article <28208@swrinde.nde.swri.edu>, kent@swrinde.nde.swri.edu (Kent D. Polk) writes:
> In article <1990Sep13.000531.15782@msuinfo.cl.msu.edu> wille@frith.msu.edu
> (Jeffrey Wille) writes:
> >I am currently working on a project which involves data acquisition.  I need
> >to read the parallel port at an average rate of every 35 microseconds.
> ...
> >data processing.  What I would like to do, is put the data in a buffer, and
> >have my A500 periodically empty the buffer in the tightest loop possible.
> 
> This brings to mind some of my questions regarding PORTB shared interrupts.
> Now shared interrupts are a bit new to me, so please forgive my ignorance...
> 
> Anyway, I am using an open collector, inverted logic signal interrupt
> hooked to the PORTB interrupt line on my A2500/30 so I can be nice and
> share the interrupt with the three other tasks that typically are using
> it. When I generate an interrupt, I hold the line low until I can read
> my interrupt status register to determine if it was my board or not
> that pulled the line low. If mine, I reset the interrupt line to high
> and reenable my interrupt when leaving the isr. Note that I have my own
> enable/disable interrupt control handling for this stuff.
> 
> Questions regarding the proper use of shared interrupts:
> 
> 1) Should I reset the interrupt line first thing in the isr, or hold it
> low until I'm finished? My isr is pretty busy & takes about 600 us to

Doesn't matter when you release the interrupt line; however, we recomend your
interrupt code take less than 250 us.

> complete its dirty work. (at least for now, since it is written in
> 'C'). In case you were wondering, this is what Jeffrey's input buffer
> question has to do with this whole discussion...
> 
> 2) What about shared interrupts hitting at or near the same time:
>   a. Do the other PORTB isr's hold the line low until finished (2091 SCSI,
>      Keyboard * timer) ?
>   b. How are multiple interrupts hits (at the 'same time') recognized
>      by the system?
>   c. Guru's Guide indicates how one should exit a shared isr when you
>      determine it was your hardware which pulled the interrupt. - If
>      multiple hits at the same time aren't registered, how do I know that
>      I'm not stealing an interrupt when my hardware says it did it? As a
>      matter of fact, I can do just that - not hook up my interrupt line & still
>      process what are actually someone else's interrupts as if they were
>      mine.
>   d. Can I just say 'Not mine' to all of them? Does the system get confused
>      when no one claims a shared interrupt? I realize that might slow things
>      down a bit, but if it is safer then I can do it.

Everytime a shared interrupt happens, everyone on the list gets to check for
it's interrupt (unless someone short circuits the list). Exec takes care of
the bits in _intena for you. If after processing the list of servers, an
interrupt is (still) pending, the list is re-traversed. What this means is:
if your box that drags the interrupt line needs to be tickled to release it
and no-one tickles it, your Amiga will "busy wait" at the interrupt level.

> 3) Do most shared interrupts incorporate a timeout - say - maybe 100 ms or
> so? I plan on doing this as it is pretty easy, but am mainly curious. The
> main reason is that when my program exits ungracefully, the interrupt doesn't
> get serviced & poor Amy is left out in the cold, waiting for someone to
> rescue her from the evil clutches of Dr. Loe :^) 
> 
> Right now Mr. Crowbar and I attack Dr. Loe in an effort to rescue the
> fair lady.

The idea is to make sure that there is an interrupt server for your box in the
chain at any time that your box can generate an interrupt (see "busy wait"
above).

> (Ok, Ok, you would be this way too after spending a few weeks of 15
> hour days on this project)
> 
> 4) My trigger circuits have a recovery time (tank circuit) of about 5
> ms. & the interrupt is tied to them.  Right now, I don't need to
> service interrupts any faster, & indeed seem to be able to do this
> quite easily with the 2500. Problem is, every now and then, I seem to
> be trashing the machine - trackdisk.device appears to be the culprit,
> but I know better, so apparently I am trashing trackdisk.device.

Debugging interrupt routines involves staring at the code for a long time,
disassembling the code the processor is executing and staring at that for
a long time, and the use of an analyzer if you have one. Check for race-
conditions with the process part of your code.

> I suspect this has something to do with how I am exiting my isr.  Any
> suggestions? (other than writing it in assembler - I know, some day
> when I get around to it)
> 
> >        I looked at the hardware RKM for some help, but found it terse
> >at best.  If someone could answer my questions, or direct me to a book
> >with decent information, it would be appreciated.
> 
> Me too. The Guru's Guide is great, but doesn't answer all my questions.

A good source of information on writing interrupt servers for the Amiga is
the Amiga itself and a disassembler... :-)

> >I would really appreciate getting some answers to these questions, or
> >being directed to a book that has the info I'm looking for.  Actually,
> >a book would be best.  I am writing this in behalf of my brother, whose
> >machine is not on the net.
> 
> Kent Polk: Southwest Research Institute (512) 522-2882

						rsbx

------------------------------------------------------------------------
  Raymond S. Brand			rsbx@cbmvax.commodore.com
  Commodore-Amiga Engineering		...!uunet!cbmvax!rsbx
  1200 Wilson Drive			(215)-431-9100
  West Chester PA 19380			"Looking"
------------------------------------------------------------------------

daveh@cbmvax.commodore.com (Dave Haynie) (09/14/90)

In article <28208@swrinde.nde.swri.edu> kent@swrinde.nde.swri.edu (Kent D. Polk) writes:
>In article <1990Sep13.000531.15782@msuinfo.cl.msu.edu> wille@frith.msu.edu

>1) Should I reset the interrupt line first thing in the isr, or hold it
>low until I'm finished? My isr is pretty busy & takes about 600 us to
>complete its dirty work. (at least for now, since it is written in
>'C'). In case you were wondering, this is what Jeffrey's input buffer
>question has to do with this whole discussion...

In general, it can't hurt to clear an interrupt as soon as the software 
watching that interrupt is called up.  Most of the chips, like the Amiga CIAs,
which pull interrupts on their own will negate their interrupt output as 
soon as the service routine reads their interrupt registers.  Simple things
can be done in the actual interrupt service routine, but if you have an very
lengthy bit of work to accomplish, it's much better for your interrupt service
routine to simply clear the interrupt register in the device and signal a
server task that an interrupt has come in.  This doesn't make sense for a
simple device that's interrupting you for a single byte coming in, but it's
necessary for things like hard disk drives that send over large packets.

>2) What about shared interrupts hitting at or near the same time:
>  a. Do the other PORTB isr's hold the line low until finished (2091 SCSI,
>     Keyboard * timer) ?

Other devices will hold the line low at least until the software that manages
them has been notified of the interrupt.  There's no need to go beyond that.

>  b. How are multiple interrupts hits (at the 'same time') recognized
>     by the system?

The interrupts are level-sensitive (except for level 7, NMI, which isn't 
supported in the A2000).  This means that, as long as interrupts are enabled
(both in the Amiga interrupt controller and 680x0 sense), the 680x0 CPU will
sample the interrupt code every so often and dispatch the appropriate 
interrupt service vector as long as an interrupt is held low.  I think what 
happens now is that the OS interrupt dispatcher will walk down the list of 
interrupt servers until one indicates that it manages the device that actually
pulled the interrupt.  The OS then will RTI, at which point the 680x0 will 
take that interrupt again if it's still low.  Or something along those lines.

>  c. Guru's Guide indicates how one should exit a shared isr when you
>     determine it was your hardware which pulled the interrupt. - If
>     multiple hits at the same time aren't registered, how do I know that
>     I'm not stealing an interrupt when my hardware says it did it? As a
>     matter of fact, I can do just that - not hook up my interrupt line & still
>     process what are actually someone else's interrupts as if they were
>     mine.

If your hardware thinks it pulled the interrupt, your server needs to respond.
The only thing that would cause a problem for other devices would be if your
server responded positively every time the interrupt were served, whether it
pulled it or not.  Now, of course, your device isn't going to do what it's
supposed to if its interrupt line isn't connected, but other than slowing the
system down more, you can't hurt any other device by responding to an interrupt
you think you pulled.

>  d. Can I just say 'Not mine' to all of them? Does the system get confused
>     when no one claims a shared interrupt? I realize that might slow things
>     down a bit, but if it is safer then I can do it.

You only worry about interrupts you pull.  And you can't answer for another
device, even if you want to.  You would confuse the system pretty heavily if
you presented it with an interrupt that couldn't be serviced.  First of all,
the system would be caught constantly servicing that interrupt.  There's no
way to force all interrupt generating devices to stop.  Of course, if you just
pull an interrupt and don't service it, you're doing something illegal anyway;
a device should never pull an interrupt until its server is installed.  The
other effect of permanently pulling an interrupt is that no lower priority 
interrupts would ever get through.  They work a little like tasks -- as long as
a higher level interrupt is pulled, no lower level interrupts can be seen.

>3) Do most shared interrupts incorporate a timeout - say - maybe 100 ms or
>so? I plan on doing this as it is pretty easy, but am mainly curious. The
>main reason is that when my program exits ungracefully, the interrupt doesn't
>get serviced & poor Amy is left out in the cold, waiting for someone to
>rescue her from the evil clutches of Dr. Loe :^) 

If you don't eventually get serviced, something is very wrong.  But I don't 
have any good number on the longest you'll have to wait to get serviced.  We
have a working limit of 8ms on the A3000 for any I/O device to respond (though
this actually is set to 1/4 sec, with a bus error following).  That's just one
cycle.  While it's extremely evil to grab the bus that long, there are 
definitely some of these programmed I/O hard disk controllers out there which
grab the bus and shut off all interrupts for multiple block transfers from 
disk.  So you could be waiting awhile.  You definitely want to reset any
interrupt lines on system reset, and don't enable interrupts until your server
is installed, but I wouldn't recommend a timeout.

>Problem is, every now and then, I seem to be trashing the machine - 
>trackdisk.device appears to be the culprit, but I know better, so apparently 
>I am trashing trackdisk.device.

Hmm... I dunno about that one.  You can't actually harm floppy transfers even
by hogging interrupts; the transfer itself happens via the floppy's 
preallocated chip bus DMA slots.  Interrupts only signal the system when the
transfer is finished.

>Kent Polk: Southwest Research Institute (512) 522-2882

-- 
Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: hazy     BIX: hazy
      Get that coffee outta my face, put a Margarita in its place!

kent@swrinde.nde.swri.edu (Kent D. Polk) (09/14/90)

In article <14434@cbmvax.commodore.com> rsbx@cbmvax.commodore.com (Raymond S. Brand) writes:
>In article <28208@swrinde.nde.swri.edu>, kent@swrinde.nde.swri.edu (Kent D. Polk) writes:
>> low until I'm finished? My isr is pretty busy & takes about 600 us to
>
>Doesn't matter when you release the interrupt line; however, we recomend your
>interrupt code take less than 250 us.

Ok, I guess I have some work to do :^) I did notice that when I try to
'overload' the system with my interrupts, a system crash is much more
imminent. When I just service the interrupt hardware (~45 us) I don't seem
to have much of a problem. Maybe I'm just taking too long.

>>   d. Can I just say 'Not mine' to all of them? Does the system get confused
>                             If after processing the list of servers, an
>interrupt is (still) pending, the list is re-traversed. What this means is:

Just to make sure, let me re-phrase: Can I go ahead & service my
interrupt & tell the system that it wasn't my interrupt by returning a
0? If I understand correctly, all that will happen is that the list
traversal will continue versus being 'short-circuited'. Correct?

>------------------------------------------------------------------------
>  Raymond S. Brand			rsbx@cbmvax.commodore.com
>  Commodore-Amiga Engineering		...!uunet!cbmvax!rsbx
>  1200 Wilson Drive			(215)-431-9100
>  West Chester PA 19380			"Looking"
>------------------------------------------------------------------------

Thanks very much for your assistance,

Kent Polk: Southwest Research Institute (512) 522-2882
Internet : kent@swrinde.nde.swri.edu
UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent

rsbx@cbmvax.commodore.com (Raymond S. Brand) (09/15/90)

In article <28220@swrinde.nde.swri.edu>, kent@swrinde.nde.swri.edu (Kent D. Polk) writes:
> In article <14434@cbmvax.commodore.com> rsbx@cbmvax.commodore.com (Raymond S. Brand) writes:
> >In article <28208@swrinde.nde.swri.edu>, kent@swrinde.nde.swri.edu (Kent D. Polk) writes:
> >> low until I'm finished? My isr is pretty busy & takes about 600 us to
> >
> >Doesn't matter when you release the interrupt line; however, we recomend your
> >interrupt code take less than 250 us.
> 
> Ok, I guess I have some work to do :^) I did notice that when I try to
> 'overload' the system with my interrupts, a system crash is much more
> imminent. When I just service the interrupt hardware (~45 us) I don't seem
> to have much of a problem. Maybe I'm just taking too long.
> 
> >>   d. Can I just say 'Not mine' to all of them? Does the system get confused
> >                             If after processing the list of servers, an
> >interrupt is (still) pending, the list is re-traversed. What this means is:
> 
> Just to make sure, let me re-phrase: Can I go ahead & service my
> interrupt & tell the system that it wasn't my interrupt by returning a
> 0? If I understand correctly, all that will happen is that the list
> traversal will continue versus being 'short-circuited'. Correct?

Yes you can. Yes it will.

> >  Raymond S. Brand			rsbx@cbmvax.commodore.com
> 
> Kent Polk: Southwest Research Institute (512) 522-2882

					rsbx

------------------------------------------------------------------------
  Raymond S. Brand			rsbx@cbmvax.commodore.com
  Commodore-Amiga Engineering		...!uunet!cbmvax!rsbx
  1200 Wilson Drive			(215)-431-9100
  West Chester PA 19380			"Looking"
------------------------------------------------------------------------

mrush@csuchico.edu (Matt "C P." Rush) (09/15/90)

In article <14444@cbmvax.commodore.com> daveh@cbmvax.commodore.com (Dave Haynie) writes:
>
>The interrupts are level-sensitive (except for level 7, NMI, which isn't 
>supported in the A2000).  This means that, as long as interrupts are enabled
>(both in the Amiga interrupt controller and 680x0 sense), the 680x0 CPU will
>sample the interrupt code every so often and dispatch the appropriate 
>interrupt service vector as long as an interrupt is held low.

	What does that mean that level 7, NMI, interrupts aren't supported in
the A2000?  Is that to say that it is impossible for anything to assert a level
7 interrupt, or that if anything does it will be ignored?

>-- 
>Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests"
>   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: hazy     BIX: hazy
>      Get that coffee outta my face, put a Margarita in its place!

	There's a Margarita waiting for ya any time you find yourself in Chico!

	-- Matt

    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
    %    The Chico branch of the "Anything    %  mrush@csuchico.edu      %
    %    Associated with Amiga" Fan Club.     %  mrush@cscihp.UUCP       %
    %                                                                    %
    %                              Now:  mrush@cscihp.ecst.csuchico.edu  %
    *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
     This is a SCHOOL!  Do you think they even CARE about MY opinions?!

kent@swrinde.nde.swri.edu (Kent D. Polk) (09/16/90)

In article <1990Sep15.011910.704@ecst.csuchico.edu> mrush@cscihp.UUCP writes:
>In article <14444@cbmvax.commodore.com> daveh@cbmvax.commodore.com (Dave Haynie) writes:
>>
>>The interrupts are level-sensitive (except for level 7, NMI, which isn't 
>>supported in the A2000).  This means that, as long as interrupts are enabled
>>(both in the Amiga interrupt controller and 680x0 sense), the 680x0 CPU will
>>sample the interrupt code every so often and dispatch the appropriate 
>>interrupt service vector as long as an interrupt is held low.
>
>	What does that mean that level 7, NMI, interrupts aren't supported in
>the A2000?  Is that to say that it is impossible for anything to assert a level
>7 interrupt, or that if anything does it will be ignored?

According to Carl Sassenrath's "Guru's Guide to the Amiga", the Amiga
Interrupt Controller is the only thing that pulls the three IPL lines
in a standard Amiga and the AIC cannot generate the NMI itself. If you
use the IPL lines directly, "the AIC, its enabling, disabling,
requesting, and prioritizing mechanisms are bypassed. This creates a
number of serious problems for most of the system software, which
relies entirely on the AIC for interrupts."

So... Any more questions? (I did my homework. Right Dave? :^)

Kent Polk: Southwest Research Institute (512) 522-2882
Internet : kent@swrinde.nde.swri.edu
UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent

daveh@cbmvax.commodore.com (Dave Haynie) (09/18/90)

In article <1990Sep15.011910.704@ecst.csuchico.edu> mrush@cscihp.UUCP writes:
>In article <14444@cbmvax.commodore.com> daveh@cbmvax.commodore.com (Dave Haynie) writes:

>>The interrupts are level-sensitive (except for level 7, NMI, which isn't 
>>supported in the A2000).  

>	What does that mean that level 7, NMI, interrupts aren't supported in
>the A2000?  Is that to say that it is impossible for anything to assert a level
>7 interrupt, or that if anything does it will be ignored?

It means that a level 7 interrupt can break a Disable().  The way the extra
expansion bus interrupts (levels 1,4,5, and 7) were defined on the A2000, they
didn't pass through any sort of interrupt controller like the level 2 and 6
interrupts do.  So there's no disabling mechanism, and therefore no support for
them under AmigaOS.  The A3000 has an interrupt controller that properly 
supports these extra interrupts, at least if you're using the 2.0 definitions
of Disable and Enable.

>There's a Margarita waiting for ya any time you find yourself in Chico!

A way's to go just for a drink, but if I'm ever in the neighborhood...

>	-- Matt

-- 
Dave Haynie Commodore-Amiga (Amiga 3000) "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: hazy     BIX: hazy
      Get that coffee outta my face, put a Margarita in its place!