68000 EXCEPTIONS & INTERRUPTS
Part 3: Bomb handler, TRAPS
This is the conclusion of a three-part series providing advanced programming information about how the ST's 68000 microprocessor handles "exceptions" to normal processing. The first two installments appeared in the May and June, 1986 issues of ST Resource. All interrupts on the 68000 are classified as "exceptions" to normal processing. Some exceptions indicate hardware faults. Others indicate software problems. Finally, some are interrupts which we discussed in the previous two issues.
All three types of "exceptions" send the 68000 off to an exception handler. (An interrupt handler is just a type of exception handler). The vectors (addresses) of these handlers are in locations $00-$13C on the Atari ST.
Exceptions come in two flavors- planned and "surprise" The planned exceptions do something useful, like drawing onscreen. The surprise exceptions give you bombs on-screen, letting you know something went wrong.
If you make one of these planned exceptions, you'll meet the System Bomb Handler. This handler will display the exception number onscreen as bombs and then direct GEM to try to restart. To determine the exception number, just count the bombs. The bomb handler also saves crash information in memory for you to look at. See ST Crash Clues in the February, 1986 ST Resource, for more on this.
If you look at low memory, you will see that most of the exception vectors take you straight to the bomb handler. A typical disaster could be something as simple as dividing by zero, or trying to write where no memory is available.
In the table below, the system bomb is the default handler. Unless the operating system installed a specific handler to do something, an exception will result in a bomb.
Bomb/Vector# Address Description:
2 $8 Bus Error
You tried to access an illegal area in the memory map and the MMU / GLUE chips let you know by forcing a bus error. Typically, you tried to access hardware directly when not in supervisor mode or tried to access non-existent hardware.
3 $C Address Error
You did a memory access at an odd address, or tried to
execute an instruction on an odd address, or (a subtle one)
the stack was at an odd address. (Did you push a byte?)
4 $10 Illegal instruction
You executed an illegal 68000 instruction. Commonly used for breakpoints.
Very handy. Usually not seen as a bomb.
5 $14 Divide by zero
Self explanatory. Uncommon.
8 $20 Privilege violation
You tried to do something that is only allowed in supervisor mode, like .move into the status register, or write supervisor RAM. Switch to supervisor mode, try again.
9 $24 Trace
If the trace bit in the status register is set, this vector gets called after every opcode. Very handy for implementing a debugger trace. SID uses it.
10 $28 Line-A trap
GEM VDI uses this for various video drawing functions, etc. No bomb.
11 $2C Line F trap
GEM AES uses this. No bomb.
26 $68 Level 2 interrupt.
Points to hblank handler.
28 $70 Level 4 interrupt
Points to vblank handler.
33 $84 Trap #1
GEMDOS BDOS interface. This is high level I/O, things like: "Get a line from the keyboard" or "write a file to disk."
45 $B4 Trap #13
Atari BIOS. This handles GEMDOS requests and is extremely low level I/O. Things like: "Get one byte from the keyboard" or "Write a sector to disk."
46 $B8 Trap #14
Atari XBIOS. Atari-specific stuff: generally handles requests like "Play some music" or "fiddle with the MFP" or "change colors."
64 $100 MFP 68901
Unassigned interrupts from here to $13C could bomb. Did you accidentally enable an MFP interrupt and forget to give it a handler address?
The first 8 bytes of memory (locations $0-$7) are quite special to the 68000. When the system is RESET, either by powerup or by pressing the [RESET] button, the 68000 sets its Supervisor Stack Pointer to the value found in $0-$3. It then sets the program counter (PC) to the value found in $4-$7. You can find where the system RESET routine is by looking at $4.
However, there's a Catch-22 here. The 68000 is trying to read "Where do I begin?" from RAM. And RAM is not yet initialized when the system powers up. On the Atari ST, unless you initialize the memory controller chip, even RAM physically present on the machine will not respond to you.
Atari solved this problem by "shadowing" the first 8 bytes of memory to system ROM. Shadowing means the first 8 bytes of RAM are really ROM- you cannot write to them. If you try it, a bus error will result. The 68000 grabs its initial SSP and PC from ROM. If you look at the start of ROM at $FC00 0000, you'll see these same 8 bytes.
<Hacker Note>: SID, the debugger, switches into supervisor any time it attempts to access low memory or hardware locations. When finished it switches back to user mode. That's why SID can "see" low memory without getting an error.
SUPERVISOR VS. USER
In the 8-bit Atari machines, the user (you) had endless power. You could do anything-if you knew what you were doing. The machine didn't try to prevent you from causing problems or crashing it.
The 68000 has a feature that's going to be new to you. You can be a "supervisor" who can basically go anywhere and do anything, or you can be a "user."
Being a user means that you are restricted from anything having to do with the hardware, the exception tables in low memory, any memory address that isn't RAM and a few other things.
Why all these restrictions? They were built into the 68000 architecture to-believe it or not-help make it "bomb proof." A casual user can be locked out of hardware access and be prevented from damaging the system, either accidentally or deliberately. If you're in the user mode-which you are when GEM powers up- there are some things you simply cannot do. If you try, you'll get a Privilege Error.
If you're a supervisor, however, you can do anything. On the other hand, you are not protected from your mistakes.
This is entirely different from the 6502 on the 8-bit computers. With the 6502, you could write directly to the video hardware registers and change colors. But on the Atari ST, you cannot if you're in user mode. You'll get an exception if you try. In fact, everything below $800 and above RAM seems to be walled off to the user.
So how do you become a supervisor? First, some warnings. You can't stay supervisor and get back to the GEM desktop without crashing. So you need to become a supervisor only for the time needed to do supervisor stuff (like hardware tweaking) and then return to user mode.
A user may become a supervisor by setting the "supervisor" bit in the 68000 status register. But you may not set this bit from user mode.
Think about this carefully for a moment. You are a user, locked out of the hardware and into a small section of memory. You need to do something the machine will not let you do directly. The answer lies in the fact that the 68000 performs all its interrupts in supervisor mode, and exceptions are nothing but fancy user-called interrupts.
Thus, if the user can cause an exception, and the exception vector points to your own code, you may become a supervisor indirectly. However, the exception vector is off limits to you. You cannot alter it directly, but must use a special BIOS call (#5 setexec) to do it for you. So when you cause that exception, you become a supervisor.
Fortunately, there are at least two other ways to perform supervisor work. First, the ST lets us become a supervisor with a special GEMDOS call (#20 super) to switch us in or out of supervisor mode. It is difficult to use and you must be careful to restore things the way they were before you became a supervisor.
Second, there's an easier call from Atari XBIOS, (#38 supexec). You pass supexec the address of a routine that you would like executed in supervisor mode, and supexec worries about switching into supervisor mode, executing your code, and switching you out.
LOOKING AT TRAPS
A TRAP is a 68000 instruction which deliberately generates an exception. It is your way of asking the ST for an operating system function. On the 8-bit Ataris, all I/O was handled by a master I/O routine known as CIO. You set up your I/O parameters and did a JSR CIOV. CIO acted as a "black box," did your input and output, and gave you the results.
The JSR CIOV is now a TRAP command; that's just about a direct translation. You have three TRAPS you are likely to use:
TRAP #1: High level input/output. Things like: "Send this string to the modem" or "read me in a named file." This is the sort of I/O where you are insulated from the rigors of the machine's hardware.
TRAP #13: Low level input/output. Things like: "Is there a character ready at the keyboard?" or "send one sector to the disk drive." Pretty heavy stuff, often requiring hardware knowledge.
TRAP #14: Atari ST-specific stuff. Things like: "Set the colors on the screen" or "wait for Vertical Blank."
Consult the Atari Developer's documentation, or Atari ST Internals published by Abacus Software, for more details about what all the various TRAPs do and what their parameters are.
I hope the information in this series has helped bridge
some of the gaps in the Atari ST Developer's documentation, which assumes
previous expertise in the 68000