Newsgroups: comp.sys.amiga.tech
Path: utzoo!utgpu!watserv1!watdragon!spurge!ccplumb
From: ccplumb@spurge.uwaterloo.ca (Colin Plumb)
Subject: Re: CIA Timers and Interrupt priority problems
Message-ID: <1991Jan3.030604.21890@watdragon.waterloo.edu>
Sender: daemon@watdragon.waterloo.edu (Owner of Many System Processes)
Organization: University of Waterloo
References: <650@faatcrl.UUCP>
Date: Thu, 3 Jan 91 03:06:04 GMT
Lines: 81

In article <650@faatcrl.UUCP> jimb@faatcrl.UUCP (Jim Burwell) writes:
>Hi...
>
>I'm writing a CLI based [Med|*tracker] module player.  The thing is pretty
>much done, 'cept for one problem.  The music player routine uses Interrupts
>from a CIA timer for its timing.  This is better than using vblank since
>you don't have to worry about NTSC/PAL timing differences.  But now that CBM 
>has stolen both CIA A timers for 2.0, I must use one of the CIA B timers.  

Both CIA A timers are in use in 1.x, it's just that it wasn't properly
documented for a long time.  See Appendix F of the 1.3 Hardware manual, or
other recent sources.

>This works fine, except that the CIA B timer hardware Interrupt priorities 
>are so high that the music player now interrupts EVERYTHING.  This is no 
>problem until you try to call up you favorite BBS while listening to some 
>modules.  The timer interrupt constantly interrupts the serial port Receive 
>Buffer Full interrupt service routine (or just blocks the interrupt), often
>causing a buffer overflow on the serial port.  The result, of course, are 
>lots of dropped characters from the serial port, making telcom impossible.
>This is unacceptable to me since one of my main reasons for writing this 
>player is to give Amiga users the ability listen to modules while modeming. 

Well, you need to, somehow, make your interrupt server faster, putting more
work at lower interrupt levels.  The ultimate is to just have it trigger a
lower-priority event and return.  The ones that are available are:

- Lower-priority hardware interrupts.  Number 2, SOFT, looks particularly
inviting, and it's level 1, the lowest there is.  You can also trigger
(using a write to the INTREQ register) a PORTS (CIA A) interrupt and install
your own server in the chain.  This is completely multitasking-friendly,
and lets you use all of your old code, changing only the checking to see if
it's "really for me".
- Software interrupts.  Probably the thing to use, if you can.  These are
really quite responsive.
- Tasks.  It should be possible to sufficiently preprocess the information the
interrupt server needs that it can be fast enough.  All it's doing, after all,
is stuffing new values into the chip registers and CIA.  I'd be surprised
if you couldn't MOVEM a table into registers and store it out.

>Does anyone have any suggestons ?  

>I have been thinking of a scheme to use Software Interrupts called in the
>timer interrupt routine.  Something like this:
>
>
>TimerIntServer:  trap (or whatever)
>                 rts

Actually, it's the exec.library Cause() function.

>This would get in and out of the high-priority interrupt server quickly,
>hopefully giving the time back to other interrupts.  I'm assuming that
>there's some sort of software interrupt which doesn't interrupt hardware
>interrupt service routines, or is maskable, and which would take effect
>upon an rte from the hardware interrupt service routine.  The software
>interrupt, would of course be vectored to the music player routine.  

Yup.  Make an interrupt structure, and pass a pointer to it to Cause().

>If I remember correctly, the software interrupt service routine can be
>interrupted by other hardware interrupts.  Those that arn't "as important"
>could be masked, but important interrupts like the RBF, could interrupt
>the music player routine at certain points, hopefully solving the serial
>overflow problems.

There's no good multitasking-friendly way to mask off other people's
interrupts except to operate at a certain level interrupt yourself.
I seriously doubt it would be necessary.

>The only problem I see is that the timing could be 
>thrown off if the right set of events happens between the rte from the 
>hardware interrupt and the calling of the software interrupt (LOTS of
>hardware interrupts, leading to/or a Timer interrupt occuring before the
>software interrupt was serviced or before it could be masked).  
>But I think it could work under most circumstances.

If too much is happening, *something* isn't going to get serviced.  I suggest
that a bobble in the music player is preferable to some other things.
-- 
	-Colin
