68000 EXCEPTIONS & INTERRUPTS
Part II: Into the STby DAVID and SANDY SMALL
This is the second of three articles detailing exception and interrupt
theory for the Atari ST computers. This series is aimed primarily at advanced
or intermediate programmers. Last month, the Smalls laid the foundation
by discussing interrupts on the 6502 microprocessor. In this issue, they
plunge ahead with the 68000.
Before beginning however, you should note that part of the discussion deals with interrupts as they are implemented specifically for the ST. This is a superset of the normal 68000 interrupts, helped along by the ST's special chips. Not all aspects of the following material will necessarily work on other 68000 computers such as the Macintosh. -ST RESOURCE
Last month we were continually referring to "interrupts" on the 6502. Well, now we can tell you that the 68000 microprocessor doesn't have interrupts. It has "exceptions". Exceptions, says the Motorola book, are "exceptions to normal processing." Doesn't this sound like an interrupt? Does to me. But there's more to it than just an interrupt.
First, let's discuss "Interrupt Exceptions," one type of exception that is close to the 6502 type of interrupt.
There are three pins that input to the 68000, called IPL0,
and IPL2. IPL stands for Interrupt Priority Level. Whenever something
(namely, the ST chip called GLUE) trips these pins, an interrupt is generated.
But there's a catch-the interrupt may be ignored, depending on the "current
processor interrupt priority level" (IPL), a register within the 68000.
Note: Don't confuse the IPL pins, which I have printed in bold type, with the IPL register. The IPL register is part of the general Status Register (SR) that tells the 68000 which interrupts to handle, and which to ignore. (So it's the "masking" part of the interrupt system).
There are 8 levels of interrupts, starting at 0 and ending at 7. They are organized like this: Level 0 interrupts are strictly low priority stuff (like a 6502 IRQ); Level 7 has the interrupts that Really Ought To Be Dealt With Right Now, No Fooling Around (like a 6502 NMI). You place a number from 0 to 7 in the IPL. The 68000 then ignores any interrupts equal to or below your current IPL level.
You find the IPL as the low 3 bits of the high byte of the status register. The status register is 16 bits, and the IPL bits (0-7) are as follows:
xxxx xipl xxxx xxxx
You can move into, AND, OR, XOR, or whatever, to the status register to set the LPL. For instance, to set IPL = 2, you could move.w #$0200,SR. There's more to it than that, and we'll get to it in a moment.
<Hacker Note: The "below," two paragraphs above, is "equal to or below", not simply "below". If you are at IPL = 4 and you get a Level 4 interrupt, the 68000 will ignore it. Careful!>
An example? Okay. At the beginning of every horizontal TV line (HBLANK), the 68000 gets a Level 2 interrupt. If we handled each one of these interrupts, a great deal of the 68000's time would be taken up without reason. So we set the IPL to 3, and the 68000 ignores Level 2 interrupts.
<Hacker Note: The interrupt remains "pending." But as long as the IPL stays above or equal to 2, it isn't dealt with. However, if you ever let the IPL slip to below 2, even for one instruction, you're going to be interrupted. Suppose we were masking a 5 into the LPL by getting rid of the old bits with an ANDI and then adding the new bits with an ORI:
ANDI.W #$F0FF,SR Mask off old IPL bits
ORI.W #$0500,SR Put in new IPL bits
You'll be at IPL 0 for a moment after the AND, and all sorts of unpleasant things may happen. Careful! A better idea is to copy the SR into a temporary data register, modify the IPL there, then copy it back in one instruction.>
Now, let's say an applications program sets the LPL down to 0. (It shouldn't, but many 68000 programs do.) An HBLANK interrupt occurs. You know what the Atari engineers do? They handle this by setting the IPL back up to 3, and returning-nothing else-thus disabling the HBLANKs again. Of course, if you need HBLANKS, primarily for fancy graphics, you can use the HBLANK vector.
What interrupts are hooked up this way? There are:
HBLANK-Level 2. This tries to happen every time we start a new scan line-very often. It is usually not allowed to happen.
VBLANK-Level 4. This tries to happen every 1/70th of a second in monochrome. It is usually allowed to happen. (PAL color runs on the ST at 50 refreshes per second, NTSC color runs at 60.) If you are a 6502 programmer used to a standard 1/60th of a second vertical blank rate, you will need to readjust your thinking.
MFP-Level 6. These are a whole new breed, which we will talk about shortly. Generally, they are always allowed to happen.
If you're a hardware type, you'll see that there are no odd numbered interrupts. The lowest interrupt request line, IPL0, is tied off to nothing. The three IPL pins are a binary code for the interrupt request priority level. This means: No odd numbered interrupt requests exist on the ST. IPL1 hooks to HBLANK, IPL2 hooks to VBLANK, through the GLUE chip. Ordinarily, IPL1 (Level 2 interrupt) gets triggered each HBLANK, and IPL2 (Level 4 interrupt) gets triggered each VBLANK. As I said before, the 68000 generally lives at IPL 3, so it ignores Level 2, but responds to Level 4 and above.
MFP (Multifunction Peripheral Controller) interrupts, which we'll get to in a moment, are Level 6 (both IPL1 and IPL2 triggered). The GLUE chip temporarily unhooks the IPL lines from HBLANK and VBLANK, and trips them together to get a Level 6 interrupt request when the MFP chip asks.
The IPL 2 and LPL 4 interrupts are known as "auto-vector interrupts". This is a flavor of interrupt for the 68000. There are two flavors of interrupts: auto-vector and user-vector. In the auto-vector mode, the 68000 is told to interrupt, and given a priority level. It figures out the "auto vector address" all by itself. This address contains the address of the interrupt handler. In other words, the 68000 looks up the address to jump to, for handling the interrupt.
The table is located in low memory, and looks like this:
AUTO-VEC1OR INTERRUPT EXCEPTION TABLE
$64-Level 1 interrupt handler address (bomb)
$68-Level 2 interrupt handler address-HBLANK HANDLER
$6C-Level 3 interrupt handler address (bomb)
$70-Level 4 interrupt handler address-VBLANK HANDLER
$74-Level 5 interrupt handler address (bomb)
$78-Level 6 interrupt handler address (bomb)
$7C-Level 7 interrupt handler address (bomb)
If you look at location $68, you will see a 4-byte address. At that 4-byte address is the HBLANK handler we talked about a moment ago. Remember, this is a table of addresses . . . pointers, if you will.
When the 68000 gets a Level 2 interrupt, it looks up the address that's been placed in $68, and starts executing at whatever address it found there. If $68 contains $FC001234, the 68000 will jump to $FC001234.
Note the addresses that are marked (bomb). Since we're not supposed to get interrupts like these, they go to a special diagnostic to let you know that something is terribly wrong. (In this case, you may have a hardware problem. Perhaps the GLUE chip is not socketed properly). The error handler generates a row of bombs onscreen. (In the older disk TOS, the error symbols were mushroom clouds.) Then it tries to restart GEM.
<Hacker Note: GEM is restarted by using the Terminate Process call. It works if things aren't too badly fouled up (such as RAM data structures). However, be forewarned. Terminate Process can seem to work-yet things in memory are still left damaged.
Even RESET does not necessarily cure a memory table damage problem. You may have to power off, then on to cure some problems. The RESET routine looks at two memory locations to see if memory was ever initialized. If it has been initialized, various tables of memory are not re-initialized by RESET. So if you press RESET and tables in "already initialized" memory are damaged, they won't get fixed.
Now things get a bit trickier. Let's talk about the other style of interrupts, which are MFP interrupts.
As far as I have been able to determine, MFP interrupts are Level 6 interrupts. They quit happening if your IPL is 6 or above.
When the 68000 is told to interrupt, a complex set of events takes place on the system bus. It boils down to this: The 68000 can either be told where to go, or figure this out for itself. The GLUE chip determines this. When we get an HBLANK or VBLANK interrupt, the 68000 figures this out by itself, using the above auto-vector table. (Hence the auto-vector term-it's automatic.)
However, the MFP is a whole different breed. When the MFP asks for an interrupt, it tells the 68000 exactly where to go. The 68000 does not use the "auto-vector 6" for the MFP's Level 6 interrupt as you would expect.
The MFP is many things rolled into one chip. The intent of the MFP is to reduce chip count in a system by combining a bunch of needed functions all in one chip. There's a serial port for your modem, timers and- important to us here-an interrupt controller.
The MFP can generate 16 different interrupts. Furthermore, it will supply the 68000 with an address for those interrupts, skipping the whole auto-vector table above (even though it is a Level 6 interrupt). This is important because the 68000 doesn't have to spend time hunting around trying to find who interrupted it (polling). The MFP jumps the 68000 straight to the interrupt service routine.
Just where the 68000 is sent is determined by what MFP interrupt happened. There's a table, starting at $100, that covers all 16 MFP interrupts. It tells the 68000 where to go to handle that particular interrupt.
As you will see, most of the MFP interrupts start life unused. They are disabled, exactly as we turned off the 6502's interrupts with IRQEN. (In fact, there are 16 bits in the interrupt mask registers of the 68901 IMRA and IMRB registers that are the mask bits.) However, they are there if you wish to use them:
MFP INTERRUPT VECTOR TABLE
$100 (initially disabled)-Parallel port interrupt handler
$104 (initially disabled)-RS-232 carrier detect pin handler
$108 (initially disabled)-RS-232 clear to send pin handler
$10C (initially disabled)-Graphics blitter chip done interrupt handler (see below!)
$110 (initially disabled)-MFP Timer D done handler
$114-200Hz System Clock (MFP Timer C) Handler
$118-Keyboard or MIDI interrupt handler
$11C (initially disabled)-Floppy/hard disk data request handler
$120 (initially disabled)-Horizontal blank counter: MFP Timer B
$124-RS-232 transmit error handler
$128-RS-232 transmit buffer empty handler
$12C-RS-232 receive error handler
$130-RS-232 receive buffer full handler
$134 (initially disabled)-MFP timer A
$138 (initially disabled)-RS-232 ring detect pin
$13C (initially disabled)-Monochrome/color monitor change detecter
<Hacker Note: The 68901 itself is told the base of the interrupt table in the VR register. You can change this if you wish. You need a copy of the 68901 documentation.
Interrupt Vector $10C is used by the Atari graphics "blitter" chip, which is to be a high-speed memory move chip very similar to what the Amiga uses. While not officially announced at this writing, Atari internal sources say the blitter chip is on the way, and Atari officials speak of it openly. It's clear from the documentation (BIOS) that support for the chip is already built in. My guess is we'll see it on the extended ST due out eventually.
Eight of the 16 MFP interrupts are from external sources, things like RS-232 connection pins. The other eight are generated internally, either timers which have counted down and need to be attended to, or the RS-232 port internal to the MFP
The initially disabled vectors can be used for various things. For instance, if your modem generates a "ring detect" signal, you could hook this to the Atari ST, and have an interrupt occur whenever your phone rings. This could be a very good thing for a bulletin board system.
If you look at these vectors with your debugger, you'll see that once again, most are pointed at the system bomb handler (the unused ones) and some are pointed at real handlers. Remember, what you see is the address of the handler routine, not executable instructions.
Though all 68000 interrupts are classified as exceptions,
not all exceptions are interrupts. Next month, we'll expand our examination
of 68000 exceptions and the exception handlers.