ADC Home > Reference Library > Technical Notes > Legacy Documents > Hardware & Drivers >

Legacy Documentclose button

Important: This document is part of the Legacy section of the ADC Reference Library. This information should not be used for new development.

Current information on this Reference Library topic can be found here:

MicroBug: The ROM Debugger


This Technote describes the features of MicroBug, the ROM debugger present in all Macintoshes from the Mac Plus onward.

This Note is directed at bored developers looking for something historically interesting to read on the train going home after a hard day's coding. It's also directed at developers trying to debug a problem that disappears when they install MacsBug.

 Updated: [Sep 28 1998]

About MicroBug

MicroBug was first introduced with the Mac Plus and has been a standard component in the ROM of all Mac OS computers since then. MicroBug is invoked when the system takes a Non-Maskable Interrupt (NMI) and there is no other debugger (e.g., MacsBug) installed.

MicroBug is not present on the Macintosh 128, Macintosh 512, and Macintosh XL computers.


MicroBug uses standard system services to operate its user interface. Specifically, MicroBug uses QuickDraw to draw its window and the Event Manager to get keyboard events. Internally, it shares a lot of code with the System Error Handler. This stands in contrast to MacsBug, which uses its own low-level drawing and input handling routines. The upshot is that MicroBug is less likely to be functional in the face of a "damaged" system than MacsBug.


MicroBug expressions consist of:

hex number (with or without a leading "$")
Yields the value of the hex number.
Yields the dot address. This address is initially set to 0 and is subsequently set by DM and SM commands.
@ <expr>
Yields the value of the memory at <expr>.
Yields the contents of 680x0 address register Ax .
Yields the contents of 680x0 address register Dx .
Yields the contents of the 680x0 Program Counter register.
- <expr>
Yields <expr> negated.
<expr> + <expr>
Yields the sum of the two expressions.
<expr> - <expr>
Yields the difference of the two expressions.

All expressions have an inherent size, which is the number of valid bytes the expression returns. The size of a hex number is determined by the number of hex digits in the number. One or two hex digits yields a size of one (1) byte, three or four hex digits yields a size of two (2) bytes, and five or more hex digits yields a size of four (4) bytes.

The size of ".", indirect, and all register expressions is four (4) bytes.

The size of an arithmetic expression is the maximum of the size of the components.

Back to top

MicroBug Commands

Dump Memory

DM addr


With an argument, the dump memory command dumps the contents of memory at the address specified by addr . Without an argument, the dump memory command continues dumping memory from the memory location where the previous dump memory command left off.

Both variants set the dot address to the address where the dump started.

Typing Return after entering this command will continue dumping memory.

Set Memory

SM addr expr...

The set memory command sets the contents of memory, starting at the address specified by addr, to the values specified by the expr expressions. The command stores either a byte, word or long, depending on the size of the expression. On completion, the command displays a dump of the memory, starting at the first location set.

The command sets the dot address to the address where the dump started.

Typing Return after entering this command will continue dumping memory.


G addr


With an argument, the go command starts execution at the address specified by addr. Without an argument, the go command resumes execution from where MicroBug was entered.

Total Display


Displays all the standard 680x0 registers by dumping the memory where they were stored on entry to MicroBug. The following table describes the specific memory locations of interest:






16 x 4 bytes

680x0 registers d0-d7 and a0-a7 in that order



4 bytes

680x0 SP register



4 bytes

680x0 PC register



2 bytes

680x0 SR register


Typing Return after entering this command will repeat the command.

Set and Display Register

Ax expr


Dx expr


PC expr


SR expr


With an argument, these command set the specified register to the expr . Without an argument, these commands display the specified register. x determines the address or data register of interest, and can be any digit from 0 through 7.

Typing Return after entering one of these commands will repeat the command.

Back to top

MicroBug Esoterica

Force Quitting

If you want to force quit the current process, you can just type:

SM 0 A9F4G 0

This places an _ExitToShell trap at location 0 and then continues execution at that trap. Of course, this trick is now mostly pointless because Mac OS supports the Command-Option-Escape key sequence to force quit a hung process.

Some enterprising souls have discovered that commands like:



will also force quit an application. This is because MicroBug's expression evaluator is extremely forgiving, so seemingly irrelevant strings will successfully evaluate to expressions. In both cases shown above, the resulting value is odd. Going to an odd address causes the 680x0 microprocessor (or the emulated microprocessor, on PowerPC-based computers) to take an "address error" exception. Mac OS responds to this exception by terminating the current process, which was the desired result.

Given the serendipitous nature of this feature, DTS continues to recommend the first sequence of commands.

A Pascal version of MicroBug's expression evaluation algorithm is shown below.

function StringToNumber(numberText : string) : longint;
        result : longint;
        i : integer;
        digit : integer;
    result := 0;
    for i := 1 to length(numberText) do begin
        digit := ord(numberText[i]);
        if digit > $39 then begin
            digit := digit - 7;
        end; (* if *)
        digit := band(digit, $000F);
        result := result * 16 + digit;
    end; (* for *)
    StringToNumber := result;
end; (* StringToNumber *)

Using this algorithm, the value for "FINDER" is $00F27DEB and the value for "EXITTOSHELL" is $DD8C1E55.

MicroBug and the Modem

If you crash into the debugger and the system hangs, try turning off your modem.

I have no idea whether this is still useful advice, but how could I remove such a cryptic comment from the technote? -- 1998

Using MicroBug Seriously

If you're using MicroBug to debug a problem, it really pays off to have another machine running MacsBug right next to it. You can then use MacsBug commands to assist in your debugging. MacsBug commands like dh (to disassemble hex words), mcd and wh (to find low-memory globals), and dm 0 <template> (to find the offsets of fields within a structure) are all extremely helpful.

Back to top


MacsBug is your friend. MicroBug is much less of your friend, but when you're a Mac programmer with a bug that disappears when you install MacsBug, you need all the friends you can get.

Back to top


MacsBug Reference and Debugging Guide, for MacsBug version 6.2 , Apple Computer, Inc., Addison-Wesley, 1990

Back to top

Change History


Originally written as Technote 38 "ROM Debugger."


Revised as Technote PT 33 "The ROM Debugger."


Rewritten as Technote 1136 "MicroBug: The ROM Debugger".
This version contains a more complete description of the debugger commands.


Revised to explain why "G FINDER" works.

Back to top



Acrobat version of this Note (36K).


Back to top

Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.