[comp.sys.apple] Interrupts, TIC, //c clock drvr, P8

AWCTTYPA@UIAMVS.BITNET ("David A. Lyons") (08/03/88)

>Date:         Mon, 1 Aug 88 07:42:00 EDT
>From:         McAllister@DOCKMASTER.ARPA
>Subject:      TIC and ProDOS

Some pretty non-obvious stuff is going on with interrupts and ProDOS
8.  I browsed around and *think* I have a pretty good handle on it
now.  Please chime in if you have any additional info.

>In trying to discover why TIC doesn't work with my IIc System
>Clock, I see that the system global page is modified:

>from    $BF00 JMP BFB7             to    $BF00 JMP $BF4B
>
>                                         $BF4B PHP
>                                               SEI
>                                               JMP $BFB7

I looked at my global page a minute ago, and it looks like the
SECOND version.  I have *not* run TIC lately (specifically, not
since I booted and not even today, actually).

The two versions of the global page come from two different versions
of ProDOS 8!  I'm running version 1.6, and I believe the part you
quoted has been like that ever since 1.2 (anything after 1.1.1).

There *is* a good reason for the change.  It involves a documented
technique for making ProDOS 8 calls during interrupts.  There is a
flag that indicates whether ProDOS is already busy processing a call
or not.  P8 is *not* designed to be re-entrant:  in other words,
calling P8 while it is already in the middle of a call is a very Bad
Thing to do.

So an interupting program that wants to call P8 must check the busy
flag (the "MLIACTV" flag).  If it is clear, no problem--make the P8
call.  But if it is SET, the new call must wait until the old one
finishes.  The technique Apple documented for this is neat:  The
interrupting is supposed to grab the return address and other
information from the current P8 call from the global page, keep it
for future use, and put its OWN address on the global page.  Then it
should return from the interrupt.  When P8 finished with the active
call, it will use the return address from global page to go back to
the caller.  But since we've stuffed a new address onto the global
page, it will go to the new code instead.  That code can then make
the P8 call it originally wanted to and then use the info it GOT
from global page earlier to return to the main program.  Pretty
slick, actually.

The only problem was this did *not* work reliably under older
versions of ProDOS.  Why?  Because the MLIACTV flag was set before
all of the necessary info was set up on the global page!  It was
possible for an interrupt to occur and for a by-the-rules program to
*really* foul things up by grabbing inconsistent info from there and
using it just how it was supposed to.  [continued below]

>This has the effect of turning off interrupts on *all* ProDOS MLI
>calls.

Aha, but it *doesn't*!  Interrupts are only disabled very
temporarily; after ProDOS JMPs to $DE00 and fiddles around a bit
more, interrupts are RE-ENABLED.  Really, I took a quick peek (which
is easy to do on the IIgs; the monitor has no problem Listing
through the language card areas).  Interrupts are only kept off
while the global-page data is in an intermediate state that should
not be available to an interrupting program that wants to make P8
calls.  (The time they're disabled for is only about 20
instructions.  Shouldn't cause any data loss at sane baud rates!)

>Since clocks are read by an MLI call, GET_TIME, and the IIc System
>Clock driver takes an inordinate amount of time, serial port
>interrupts are lost.

I don't have this all figured out, but I'll throw out some ideas.
First, I *don't* think the problem is having interrupts disabled,
although I suppose it *could* be *if* your clock driver is disabling
interrupts, or if ProDOS is doing it during the GET_TIME call (I
don't think it is; haven't checked to make sure).

What seems more likely to me is this:  Your clock driver sends some
special code out to the serial port to instruct the clock hardware
to send back the current time over the same serial port.  But the
driver has no way to distinguish between incoming data from the
modem and incoming data from the clock hardware. -- Alternatively,
maybe the clock hardware is set to IGNORE incoming modem data while
it's in the process of sending the current time back to the
computer.  It definitely seems to me that it would be *very* tricky
for the clock driver to distinguish between its "own" characters and
other characters as they came in over the same serial port, and to
call the user's interrupt routine in one case but not the other.
(Presumably it's POLLING for the characters rather than using
interrupts; *maybe* the driver is even disabling interrupts for the
whole time.)

If you have the option of putting the clock on your PRINTER port
rather than your modem port, that might be worth a try.

Finally, it would probably solve your problems if TIC didn't call
GET_TIME while you were sitting in terminal mode.  (I think it does
that just to display the time at the top of the screen.)  You might
ask Don Elton (nicely!) for a patch...probably 5 bytes of NOPs...to
avoid the call.

Good luck!

>                         McAllister at Dockmaster.ARPA

--David A. Lyons  a.k.a.  DAL Systems
  PO Box 287 | North Liberty, IA 52317
  BITNET: AWCTTYPA@UIAMVS
  CompuServe: 72177,3233
  GEnie mail: D.LYONS2

CAMHARK@UBVMSC.CC.BUFFALO.EDU ("Daniel J. Harkavy") (08/08/88)

I have a //c systems clock, and it is hooked up to the printer rahter than 
the modem.   Nontheless it is not compatable with TIC 2.04

Oh well...


Dan Harkavy