Well, we've almost completed this huge coverage of the Devpac
system, which was typed in its entirety by the Animal House.
Edited by Sewer Rat for use in Doc Disk Number 8.
CHAPTER 4
SYMBOLIC DEBUGGER
Introduction
Programs written in assembly language are particularly error-
prone because even a slight mistake can result in the entire
machine crashing. There are various forms of bugs, ranging from
the trivial (e.g. a missing CR in a printout), though the usual
(e.g. an incorrect result_ to the very serious (e.g. the machine
completely hanging, perhaps with a weird display).
To help you find and correct all forms of bugs, DevpacST includes
MonST. MonST is a symbolic debugger and disassembler which lets
you examine programs and memory, execute programs an instruction
at a time and trap processor exceptions caused by programmer
error. As MonST is symbolic you can look at your program complete
with all the original labels, making debugging very much easier
than having to battle with 6-digit hex numbers.
Although MonSt is a low-level debugger, displaying such things as
68000 instructions and bytes of memory, it can also be used for
debugging programs written with any compiler that generates
machine-code output. If the compiler has the option to dump the
symbols into the binary code then you will see your procedure and
function names within the code, and you can even view your
original source code. We ourselves used MonST when debugging
LinkST, which was written in a C compiler, MonST and GenST
themselves were written entirely in assembly language.
As MonST uses its own screen memory, the display of your program
is not destroyed when you single-step or breakpoint, making it
particularly useful for graphical-output programs such as GEM
applications or games. It also uses it own screen drivers so it
is possible to single-step into the operating system screen
routines such as the AES or BIOS without affecting the debugger.
There are three versions of MonST supplied on the disk. All are
similar to use and are provided to make the debugging of
different types of programs easy. the Exact differences are
detailed later.
68000 Exceptions
MonST uses the 68000 processor exceptions to stop runaway
programs and to single-step, so at this point it would be useful
to explain them and what normally happens when they occur on an
ST.
There are various types of exception that can occur, some
deliberately, others accidentally. When one does occur the
processor saves some information on the SSP, goes into Supervisor
mode and jumps to an exception handler. When MonST is active it
re-directs some of these exceptions so it can take control when
they occur. The various forms of exceptions, their usual results,
and what happens when they occur with MonST active is shown in
the following table:
Ex. No. Exception Usual effect MonST active
2 bus error bombs trapped
3 address error bombs trapped
4 illegal instruction bombs trapped
5 zero divide bombs trapped
6 CHK instruction bombs trapped
7 TRAPV instruction bombs trapped
8 privilege violation bombs trapped
9 trace bombs trapped
10 line 1010 emulator fast VDI interface fast VDI interface
11 line 1111 emulator internal TOS internal TOS
32 trap #0 bombs trapped
33 trap #1 GEMDOS call GEMDOS call
34 trap #2 AES/VDI call AES/VDI call
35-44 trap #3-#12 bombs trapped
45 trap #13 XBIOS call XBIOS call
46 trap #14 BIOS call BIOS call
47 trap #15 bombs trapped
The exact causes of the above exceptions (and how best to recover
from them) are detailed at the end of this section, but to
summarise:
Exceptions 2 to 8 are caused by a programmer error and are
trapped by MonST.
Exception 9 can remotely be caused by programmer error and is
used by MonST for single stepping.
Exceptions 10, 11, 33, 34, 45 and 46 are used by the system and
left alone.
The rest (i.e. the unused Trap exceptions) are diverted into
MonST, but can subsequently be re-defined to be exploited by
programs if required.
The 'bombs' entry in the table above means that the ST will
attempt to recover from the exception, but it is not always
successful.
When an exception occurs, the ST prints on the screen a number of
bomb shapes or mushrooms on disk-loaded GEMDOS), the number
being equal to the exception number. Having done this, it will
abort the current program (losing any unsaved data from it) and
attempt a return to Desktop.
If the exception was caused by or resulted in important system
variables being destroyed then the attempt may fail and the
machine will not recover.
Occasionally very nasty crashes can cause the whole screen to
fill with bombs (or mushrooms) which looks very impressive, but
is not very useful!
Memory Layout
The usual versions of MonSt co-reside with programs being
debugged; that is, they are loaded, ask for a filename, and load
that file in together with any labels.
It is useful to examine the usual logical memory map (the
physical layout in shown in Appendix C) both with and without
MonST, shown in Figure 4.1 on the next page.
high memory
Free Free
Program Program
MonST
System System
low memory
Without MonST With MonST
Figure 4.1 - Logical Memory Map
The actual code size of MonST is around 23k, but in addition it
requires an additional 32k of workspace. This may seem large but
it is required for the copy of the ST screen memory saved by
MonSt; this is a most useful feature of the debugger.
The three versions of MonST supplied are:
MONST2.PRG GEM interactive version
MONST2.TOS TOS interactive version
AMONST2. PRG Auto-resident version
For now the first two will be described; the auto-resident
version is described later but is very similar in use to the
others.
Invoking MonST
From the Desktop
The two interactive versions of MonST are actually identical
except for the filename extension. The GEM version should be used
for GEM-based programs, which require use of the mouse and have
initially a grey-pattern screen, while the TOS version should be
used for TOS-based programs which require the flashing TOS cursor
and have initially a white screen display. Both versions are
invoked by double-clicking on their respective icons from the
Desktop.
Note: If you debug a TOS program with the GEM version of the
debugger it will work fine but the screen display will probably
be messy; however, debugging a GEM program with a TOS debugger
will cause all sorts of nasty problems to occur and should be
avoided.
From the Editor
When GenST is invoked it automatically looks for and loads the
file MONST2.PRG into memory (unless this option is disabled in
the Preferences option in the editor). The debugger is then
instantly available at the press of a key from within the editor.
Pressing Alt-M or clicking on MonST from the Program menu will
then invoke it in a similar way to that described for the disk-
based version only very much more quickly.
Pressing Alt-D or clicking on Debug from the Program menu will
invoke MonST but will also automatically prepare a program
previously assembled to memory to be run, including any symbols
within it.
The type of initial screen mode used when invoked from the editor
is determined by the Run with GEM menu item on the Program menu -
if a check mark is present then GEM screen initialisation is
done, otherwise TOS screen initialisation is used. The rules
described above about using the wrong type of screen
initialisation are also relevant to the in-memory debugger.
Symbolic Debugging
A major feature of MonST is its ability to use symbols taken from
the original program whilst debugging. MonST supports two formats
for debug information - the DRI standard, which allows up to 8
characters per symbol, and the HiSoft Extended Debug format,
allowing up to 22 characters. Both GenST and LinkST can produce
both formats, and many other vendors' compilers and linkers have
an option to produce DRI-format debugging information. We are
trying to establish the Hi-Soft Extended format as a second
standard on the ST, but at the time of writing the only other
products to support the format are HiSoft BASIC and FTL-Modula 2.
MonST Dialogue and Alert Boxes
MonST makes extensive use of dialogue and alert-boxes which are
similar in concept to those in GEM programs but have several
differences. MonST does not use genuine GEM-type boxes in order
for it to remain robust - that is to avoid interaction when
debugging programs that themselves use GEM calls. In addition the
mouse is not available within the debugger itself which makes
things like true GEM buttons impossible.
A MonST dialogue box displays the prompt ESC to abort above the
top left corner of the box together with a prompt, normally
followed by a blank line with a cursor. At any time a dialogue
box may be aborted by pressing Esc, or data may be entered by
typing. The cursor keys, Backspace and Del keys may be used to
edit entered text in the usual way and the whole line may be
delted by pressing the Clr key - note that this is different to
GEM dialogue boxes which use the Esc key to delete a whole line
of text. An entered line is terminated by pressing the Return
key, though if the line contains errors the screen will flash and
the Return key will be ignored allowing correction of the data
before pressing Return again. Another difference is that dialogue
boxes that require more than one line of data to be entered do
not allow the use of the cursor up and down keys to switch
between different lines - in MonST the lines have to be entered
in order.
A MonST alert box is a small box displaying a message together
with the prompt (Return) and is normally used to inform the user
of some form of error. The box will disappear on pressing the
Return or Esc keys, whichever is more convenient.
Initial Display
Unless you have chosen the Debug option within the editor you
will be presented with a dialogue box prompting for an executable
program name. If you wish to debug a program from disk you should
enter the filename (which defaults to an extension of .PRG) then
press Return, then you will be prompted for any command line. If
you do not wish to debug a program from disk at this stage, for
example you wish to investigate memory, press the Esc key or
enter a blank filename.
Low Res: Certain features work differently or are not available
when using MonST in low resolution. They are shown with this
icon.
Front Panel Display
The main display of MonST is via a Front Panel showing registers,
memory and instructions. The name Front Panel stems from the type
of panels that were mounted on mainframe and mini computers to
provide information on the state of the machine at a particular
moment, usually through the use of flashing lights. These lights
represent whether or not particular flip-flops (electronic
switches) within the computer are open or closed; the flip-flops
that are chosen to be shown on this panel are normally those that
make up the internal registers and flags of the computer thus
enabling programmers and engineers to observe what the computer
is doing when running a program.
So these are hardware front panel displays; what MonST provides
you with is a software front panel - the code within MonST works
out the state of your computer and then displays this information
on the screen.
The initial MonSt display consists of four windows, similar to
those shown in Figure 4.1. In low-resolution the arrangement of
two of the windows is slightly different to allow efficient use
of the smaller available screen space.
1. Registers
D0:00000000 601E 0100 00FC 0020
D1:00000000 601E 0100 00FC 0020
D2:00000000 601E 0100 00FC 0020
D3:00000000 601E 0100 00FC 0020
D4:00000000 601E 0100 00FC 0020
D5:00000000 601E 0100 00FC 0020
D6:00000000 601E 0100 00FC 0020
D7:00000000 601E 0100 00FC 0020
SR:0000 U
PC:00FC0020 MOVE,W #$2700,SR
A0:00000000 601E 0100 00FC 0020 0003 9752
A1:00000000 601E 0100 00FC 0020 0003 9752
A2:00000000 601E 0100 00FC 0020 0003 9752
A3:00000000 601E 0100 00FC 0020 0003 9752
A4:00000000 601E 0100 00FC 0020 0003 9752
A5:00000000 601E 0100 00FC 0020 0003 9752
A6:00000000 601E 0100 00FC 0020 0003 9752
A7:00000000 601E 0100 00FC 0020 0003 9752
A7'00000000 601E 0100 00FC 0020 0003 9752
2. Disassembly PC
00FC0020 *MOVE, W #$2700,SR
00FC0024 RESET
00FC0026 CMPI.L #$FA52235F,$FA0000
00FC0030 BNE.S $FC003C
00FC0032 LEA $FC003C(PC),A6
00FC0036 JMP $FA0004
00FC003C LEA $FC0044(PC),A6
00FC0040 BRA $FC0508
00FC0044 BNE,S $FC0050
00FC0046 MOVE,B $424,$FFFF8001
00FC0050 SUBA.L A5,A5
00FC0052 CMPI.L #$31415926,$426(A5)
3. Memory
00000000 601E 0100
00000004 00FC 0020
00000008 0003 9752
0000000C 0003 9758
00000010 0003 97C0
00000014 0003 97C6
00000018 0003 97CC
0000001C 0003 97D2
00000020 0003 97D8
00000024 0003 97DE
00000028 0003 9C48
0000002C 0003 953E
MonST 2.0 HiSoft 1988
Figure 4.1 MonSt Initial Display
The top window (number 1) displays the values of the data and
address registers, together with the memory pointed to by these
registers.
The next window (number 2) is the disassembly window which
displays several lines of instructions, by default based around
the program counter (PC), shown in the title area of the window.
A => sign is used to denote the currant value of the PC
Window number 3 is the memory window which displays a section of
memory in word-aligned hex and ASCII.
The final window at the bottom of the screen, which is un-
numbered, is the smallest window and is used to display messages.
One of the most powerful features of MonST is its flexibility
with windows - up to 2 additional windows may be created, the
font size can be changed, and windows may be locked to
particular registers, these features are detailed later.
Simple Window Handling
MonST has the concept of a current window - this is denoted by
displaying its title in black. The current window may be changed
by pressing the Tab key to cycle between them, or by pressing the
Alt key together with the window number, for example Alt-2
selects the disassembly window. (AZERTY keyboard users please
note - the Shift key is not required when using Alt to select
windows). Note that the lowest window can never may made the
current window - it is used solely for displaying messages.
Command Input
MonST is controlled by single-key commands which creates a very
fast user-interface, though this can take getting used to if you
are familiar with a line-oriented command interface of another
debugger. Users of HiSoft Devpac on other machines will find many
commands are identical, particulary with the Spectrum and QL
debuggers, though the window commands are unique to MonST.
In general the Alt key is the window key - when used in
conjunction with other keys it it acts on the current window.
Commands may be entered in either upper or lower case. Those
commands whose effects are potentially disastrous require the
Ctrl key to be pressed in addition to a command key. The keys
used where chosen to be easy to remember, wherever possible.
Commands take effect immediately - there is no need to press
Return and invalid commands are simply ignored. The relevant
sections of the front panel display are updated after each
command so any effects can be seen immediately.
MonSt is a powerful and sometimes complex program and we realise
that it is unlikely that many users will use every single
command. For this reason the remainder of the MonST manual is
divided into two sections - the former is an introduction to the
basic commands of the program, while the latter is a full
reference section. It is possible for new users and beginners to
use the debugger effectively while having only read the Overview;
don't be intimidated by the Reference section.
MonST Overview
To start with you will need to load a program to debug; if you
have assembled a program to memory you can use the Debug option
from the editor, else you will need to load a program from
disk. When initially loaded you will be prompted for a file name,
if you got an error or didn't specify a filename you can have
another go by pressing Ctrl-L.
A program's symbols will be used by the debugger, if found. A
program will have symbols included if you used the Debug or
Extended Debug options of the assembler. The extended debug
option means you will get longer symbols, the normal option
forces them to be truncated to 8 characters.
The most common command in MonST is probably single-step,
obtained by pressing Ctrl-Z (or Ctrl-Y if you find it more
convenient). This will execute the instruction at the PC, the one
shown in the Register window and, normally, also in the Disas�
sembly window. After executing it the debugger re-displays the
values of the registers and memory displayed, so you can watch
the processor execute your program, step by step. Single-stepping
is the best way of going through sections of code that are
suspect and require deeper investigation, but it is also the
slowest - you may only be interested in a section of code near
the end of your program which could take ages to get to if you
have to single-step all the way. There is, of course, an answer.
A breakpoint is a special word placed into your program to stop
it running and enter MonST. There are many types of breakpoint
but we will restrict ourselves to the simplest for now. A
breakpoint may be set by pressing Alt-B, then entering the
address you wish to place the breakpoint. You can enter addresses
in MonSt in hex (the default base), as a symbol, or as a complex
expression. Examples of a valid address are 1A2B0, prog_start,
10+mydata. If you type in an invalid address the screen will
flash and allow you to correct the expression.
Having set a breakpoint you need some way of letting your program
actually run, and Ctrl-R will do this. If will execute your
program using the registers displayed and starting from the PC.
MonST will be re-entered if a breakpoint has been hit, or if an
exception occurs.
MonST uses its own screen display which is independent from your
own programs. If you press the v key you will see your current
programs display, pressing another key switches you back to
MonST. This allows you to debug programs without disturbing their
output at all.
MonST uses its own windows to, and any window may be zoomed to
the full screen size by pressing Alt-Z. To return to the main
display press Alt-Z or the Esc key. The Esc key is also the best
way of getting out of anything you may have invoked by accident.
The Zoom command, like all Alt- commands, works on the current
window which you can change by pressing Tab. You can dump the
current window to your printer by pressing Alt-P.
To change the address from which a window displays its data,
press Alt-A, then enter the new address. Note that the
disassembly window will always re-display from the PC after you
single-step, because it is locked to the PC. The locking of
windows is detailed in the Reference section.
To quit MonST press Ctrl-C. Strange as it may sound this will not
always work - what Ctrl-C does is terminate the current program,
which may be MonST or, more likely, the program you are
debugging. You know when you have terminated the program under
investigation because it will say so in the lower window. Once
your program has been terminated, pressing Ctrl-C will terminate
MonST. If you used the Debug option from the editor then Ctrl-C
will always terminate MonST as well as your program.
We hope this overview has given you a good idea of the most
common features of MonST to let you get on with the complex
process of writing and debugging assembly language programs. When
you feel more confident you should try and read the Reference
section, probably best taken, like all medicine, in small doses.
MonST REFERENCE
Numeric Expressions
MonST has a full expression evaluator, based on that in GenST,
including operator precedence. The main differences are that the
default base is hexadecimal (decimal may be denoted with a \
sign), there is no concept of types of expressions (relative or
absolute), ø is used only for multiplication and there is a not-
equals operator, <>.
Symbols may be referred to and are normally case-sensitive and
significant to either 8 or 22 characters (depending on the form
of debug used), though this can be changed with Preferences.
Registers may be referred to simply by name, such as A3 or D7
(case insensitive), but this clashes with hex numbers. To obtain
such hex numbers precede them with either a leading zero or a $
sign. A7 refers to the user stack pointer.
There are several reserved symbols which are case insensitive,
namely TEXT, DATA, BSS, END, SP, SR, and SSP. END refers to one
byte past the end of the BSS section and SP refers to either the
user- or supervisor-stack, depending on the current value of the
status register.
In addition there are 10 memories numbered M0 through M9, which
are treated in a similar way to registers and can be assigned to
using the Register Set command. Memories 2 through 5 inclusive
refer to the current start address of the relevant window and
assigning to them will change the start address of that window.
The MonSt expression evaluator also supports indirection using
the { and } symbols. Indirection may be performed on a byte word
or long basis, by following the } with a period then the required
size, which defaults to long. If the pointer is invalid, either
because the memory is unreadable or even (if the word or longword
indirection is used) then the expression will not be valid.
For example, the expression
{data_start+10},w
will return the word contents of location data_start+10, assuming
data_start is even. Indirection may be nested in a similar way to
ordinary parenthesis.
Window Types
There are four window types and the exact contents of these
windows and how they are displayed is detailed below. The allowed
types of windows is shown in the table below.
Window Allowed Types
1 Register
2 Disassembly
3 Memory
4 Disassembly, Memory or Source-code
5 Memory
Register Window Display
The data registers are shown in hex, together with the ASCII
display of their low byte and then a hex display of the eight
bytes they point to in memory. The address registers are also
shown in hex, together with a hex display of 12 bytes. As with
all hex displays in MonST this is word-aligned, with non-readable
memory.
The status register is shown in hex and in flag form,
additionally with U or S denoting user- or supervisor-modes. A7'
denotes the supervisor stack pointer, displayed in a similar way
to the other address registers.
The PC value is shown together with a disassembly of the current
instruction. Where this involves one or more effective addresses
these are shown in hex, together with a suitably-sized display of
the memory they point to.
For example, the display
TST.W $12A(A3) ;00001FAE 0F01
signifies that the value of $12A plus register A3 is $1FAE, and
that the word memory pointed to by this is $0F01. A more complex
example is the display
MOVE.W $12A(A3),-(SP) ;00001FAE 0F01 =>002AC08 FFFF
The source addressing mode is as before but the destination
address is $2AC08, presently containing $FFFF. Note that this
display is always of a suitable size (MOVEM data being displayed
as a quad-word) and when pre-decrement addressing is used this is
included in the address calculations.
Low Res: No hex data is shown for the data registers and the
address register data area is reduced to 4 bytes. In addition the
disassembly line may not be long enough to display complex
addressing modes such as the second example above.
Disassembly Window Display
Disassembly windows display memory as disassembled instructions
to the standard described below. On the left the hex address is
shown, followed by any symbol, then the disassembly itself. The
current value of the PC is denoted with =>.
If the instruction has a breakpoint placed on it this is shown
using square brackets ([ ]) afterwards, the contents of which
depend on the type of breakpoint. For stop breakpoints this will
be the number of times left for this instruction to execute, for
conditional breakpoints this will be a ? followed by the
beginning of the conditional expression, for count breakpoints
this will be a = sign followed by the current count, and for
permanent breakpoints a symbol resembling a small zero in
superscript is shown.
The exact format of the disassembled op-codes is Motorola
standard, as GenST accepts. All output is upper-case (except
lower-case labels) and all numeric output is hex, except Trap
numbers. Leading zeroes are suppressed and the $ hex delimiter is
not shown on numbers less than 10. Where relevant numerics are
shown signed. the only deviation from Motorola standard is the
register lists shown in MOVEM instructions - in order to save
display space the type of the second register in a range is
abbreviated, for example
MOVEM.L d0-d3/a0-a2,-(sp)
will be disassembled as
MOVEM.L d0-3/a0-2,-(sp)
Low Res: Any displayed symbols replace the hex address display,
limited to a maximum of 8 characters
Memory Window Display
Memory windows display memory in the form of a hex address,
word-aligned hex display and ASCII. Unreadable memory locations
are denoted by (two zeros in superscript). The number of bytes
shown is calculated from the window width, up to a maximum of 16
bytes per line.
Source-code Window display
The source code window displays ASCII files in a similar way to a
screen editor. The default tab setting is 8 though this can be
toggled to 4 with the Edit Window command.
Window Commands
The Alt key is generally used for controlling windows, and when
used to apply to the current window. This is denoted by having an
inverse title and can be changed by pressing the Tab or Alt plus
the window number.
Most window commands work in any window, zoomed or not, though
when it does not make sense to do something the command is
ignored.
Alt-A Set Address
This sets the starting address of a memory or disassembly window.
Alt-B Set Breakpoint
Allows the setting of any type of breakpoint, described later
under Breakpoints.
Alt-E Edit Window
On a memory window this lets you edit memory in hex or ASCII. Hex
editing can be accomplished using keys 1-9, A-F, together with
the cursor keys. Pressing Tab switches between hex & ASCII, ASCII
editing takes each keypress and writes it to memory. The cursor
keys can be used to move about memory. To leave edit mode press
the Esc key.
On a register window this is the same as Alt-R, Register Set,
described shortly.
On a source code window this toggles the tab setting between 4
and 8.
Alt-F Font size
This changes the font size in a window. In high resolution 16 and
8 pixel high fonts are used, in colour 8 and 6 pixel high fonts
are used. This allows a greater number of lines to be displayed,
assuming your monitor can cope.
Changing the font size on the register window causes the position
of windows 2 and 3 to be re-calculated to fill the available
space.
Alt-L Lock Windows
This allows disassembly and register windows to be locked to a
particular register. After any exception the start address of the
window is re-calculated, depending on the locked register.
To unlock simply enter a blank string. By default window 2 is
locked to the PC. You can lock windows to each other by
specifying a lock to a memory window, ash as M2.
Alt-O Show Other
This prompts for an expression and displays it in hex, decimal
and as a symbol if relevant.
Alt-P Printer Dump
Dumps the current window onto the printer. It can be aborted by
pressing Esc.
Alt-R Register Set
Allows any register to be set to a value, by specifying the
register, an equals sign, then its new value. It can also be used
to set the value of memories. For example the line
a3=a2+4
sets register A3 to be A2 plus 4. You can also use this to set
the start address of windows when in zoom mode so that on exit
from zoom mode the relevant window starts at the required
address.
Note: Do not assign M4 if window 4 is currently a source-code
window.
Alt-S Split windows
This either splits windows 2 into 2 and 4, or splits window 3
into 3 and 5. Each new window is independent from its creator.
Pressing Alt-S again will un-split the window.
Low Res: This command has no effect.
Alt-T Change Type
This only works on window 4 (created either by splitting window 2
or by loading a source file). It changes the type of the window
between disassembly, memory and source-code (if a file has been
loaded).
Alt-Z Zoom Window
This zooms the current window to be full size. Other Alt commands
are still available and normal size can be achieved by pressing
Esc or Alt-Z again.
Note: Zooming the register windows is unlikely to be useful.
Cursor Keys
The cursor keys can be used on the current window, the action of
which depends on the window type.
On a memory window all four cursor keys change the current
address, and Shift Up Cursor and Shift Down Cursor move a page in
either direction.
On a disassembly window Up Cursor and Down Cursor change the
start address on an instruction basis, Left Cursor and Right
Cursor change the address on a word basis.
On a source-code window Up Cursor and Down Cursor change the
display on a line basis and Shift Up Cursor and Shift Down Cursor
on a page basis.
Screen Switching
MonST uses its own screen display and drivers to prevent
interference with a program's own screen output. To prevent
flicker caused by excessive screen switching when single-stepping
the screen display is only switched to the program's after 20
milliseconds, producing a flicker-free display while in the
debugger. In addition the debugger display can have a different
screen resolution to your program's if using a colour monitor.
V View Other Screen
This flips the screen to that of the programs, any key returns to
the MonST display.
Ctrl-O Other Screen Mode
This changes the screen mode of MonST's display between low and
medium resolution. It re-initialises window font sizes and
positions to the initial display. This will not affect the screen
mode of the program being debugged.
This command is ignored on a monochrome monitor.
As MonST has its own idea of where the screen is, what mode it is
in and what palettes to use you can use MonST to actually look at
the screen memory in use by your program, ideal for low-level
graphics programs.
Note: If your program changes screen position or resolution, via
the XBIOS or the hardware registers, it is important that you
temporarily disable screen switching using Preferences while
executing such code else MonST will not notice the new attributes
of your program's screen.
When a disk is accessed, when loading or saving, the screen
display will probably switch to the program's during the
operation. This is in case a disk error occurs, such as write-
protected or read errors, as it allows any GEM alert boxes to be
seen and acted upon.
Breaking into Programs
Shift-Alt-Help Interrupt Program
While a program is running it can be interrupted by pressing this
key combination, which will cause a trace exception at the
current value of the PC. With computationally-intense program
sections this will be within the program itself but with a
program making extensive use of the ROM, such as the BDOS or AES,
the interruption will normally be in the ROm itself, or the line-
F handler stored in low-memory. If this is the case it is
recommended that a breakpoint be placed in your actual program
area then a Return to Program command (Ctrl-R) issued.
Pressing Alt-Help without the Shift key will normally produce a
screen dump to the printer - if you press this accidentally it
should be pressed again to cancel the dump.
It is possible for this key combination to be ignored when
pressed - if this occurs press it again when it should work.
Pressing it when in MonST will produce no effect.
Note: A program should never be terminated (using Ctrol-C) if it
has just been interrupted in the middle of a ROM routine. This is
likely to cause a system crash.
Breakpoints
Breakpoints allow you to stop the execution of your program at
specified points within it. MonST allows up to eight simultaneous
breakpoints, each of which may be one of five types. When a
breakpoint is hit MonST is entered and then decides whether or
not to halt execution of your program, entering the front panel
display, or continue, this decision is based on the type of the
breakpoint and the state of your program's variables.
Simple Breakpoints
These are one-off breakpoints which, when executed, are cleared
and cause MonST to be entered.
Stop Breakpoints
These are breakpoints that cause program execution to stop after
a particular instruction has been executed a particular number of
times. In fact a simple breakpoint is really a stop breakpoint
with a count of one.
Count Breakpoints
Merely counters; each time such a breakpoint is reached a counter
associated with it is incremented, and the program will resume.
Permanent Breakpoints
These are similar to simple breakpoints except that they are
never cleared - every time execution reaches a permanent
breakpoint MonST will be entered.
Conditional Breakpoints
The most powerful type of breakpoint and these allow program
execution to stop at a particular address, only if an arbitrarily
complex set of conditions apply. Each conditional breakpoint has
associated with it an expression (conforming to the rules already
described). Every time the breakpoint is reached this expression
is evaluated, and if it is non-zero (i.e. true) then the program
will be stopped, otherwise it will resume.
Alt-B Set Breakpoint
This is a window command allowing the setting or clearing of
breakpoints at any time. The line entered should be one of the
following forms, depending on the type of breakpoint required.
<address>
will set a simple breakpoint.
<address>,<expression>
will set a stop breakpoint at the given address, after it has
executed <expression> times.
<address>,=
will set a count breakpoint. The initial value of the count will
be zero.
<address>,(small zero in superscript)
will set a permanent breakpoint.
<address>,?<Expression>
will set a conditional breakpoint, using the given expression.
<address>,-
will clear any breakpoint at the given address.
Breakpoints cannot be set on addresses which are odd or
unreadable, or in ROM though ROM breakpoints may be emulated
using the Run Until command.
Every time a breakpoint is reached, regardless of whether the
program is interrupted or resumed, the program state is
remembered in the History buffer, described later.
Help Show Help and Breakpoints
This displays the text, data and BSS segment addresses and
lengths, together with every current breakpoint, Alt-commands are
available within this display.
Ctrl-B Set Breakpoint
Included mainly for compatibility with MonST 1, this sets a
simple breakpoint at the start address of the current window, so
long as it is a disassembly window. If a breakpoint is already
there then it will be cleared.
U Go Until
This prompts for an address, at which a simple breakpoint will be
placed then program execution resumed.
Ctrl-K Kill Breakpoints
This clears all set breakpoints.
Ctrl-A Set Breakpoint then Execute
A command that places a simple breakpoint at the instruction
after that at the PC and resumes execution from the PC. This is
particularly for DBF-type loops if you don't want to go through
the loop, but just want to see the result after the loop is over.
Ctrl-D BDOS Breakpoint
This allows a breakpoint to be set on specific BDOS calls. The
required BDOS number should be entered, or a blank line if any
existing BDOS breakpoint needs to be cleared.
History
MonST has a history buffer in which the machine status is
remembered for later investigation.
The most common way of entering data into the history buffer is
when you single-step, but in addition every breakpoint reached
and every exception caused enters the machine state into the
buffer. Various forms of the Run command also cause entries to be
made into this buffer.
Note: The history buffer has room for five entries - when it
fills the oldest entry is removed to make room for the newest
entry.
H Show History Buffer
This opens a large window displaying the contents of the history
buffer. All register values are shown including the PC as well as
a disassembly of the next instruction to be executed.
Note: If a disassembly in the History display includes an
instruction which has a breakpoint placed on the [ ]s will show
the current values for that breakpoint, not the values at the
time of the entry into the history buffer.
Quitting MonST
Ctrl-C Terminate
This will issue a terminate trap to the current GEMDOS task. If a
program has been loaded from within MonST it will be terminated
and the message Program Terminated appear in the lower window.
Another program can be loaded, if required.
If no program has been loaded into MonST it will itself terminate
when this command is used.
If the Debug option has been used from the GenSt editor then
MonST will terminate automatically when the program it is
debugging has terminated.
Note: Terminating some GEM programs prematurely, before they have
closed workstations window control properly can seriously confuse
the AES and VDI. This may not be noticeable immediately but often
causes crashes when a subsequent program is executed.
Loading & Saving
Ctrl-L Load Executable Program
This will prompt for an executable filename then a command line
and will attempt to load the file ready for execution. If MonST
has already loaded a program it is not possible to load another
until the former has terminated.
The file to be loaded must be an executable file - attempting to
load a non-executable file will normally result in TOS error 66
and further attempts to load executable files will normally fail
as GEMDOS does not de-allocate the memory it allocated before
trying to load the errant file. If this occurs terminate MonST
then re-execute it and use the Load Binary File command.
Note: This command in not available in the auto-resident version
of MonST or in MonST invoked using Debug from the editor.
B Load Binary File
This will prompt for a filename and optional load address
(separated by a comma) and will then load the file where
specified. If no load address is given then memory will be
allocated from GEMDOS and used. M0 will be set to the start
address and M1 to the end address.
S Save Binary File
This will prompt for a filename, a start address and an
(inclusive) end address. To re-save a file recently loaded with
the above command <filename>,M0,M1 may be specified, assuming of
course that M0 and M1 may be specified, assuming of course that
M0 and M1 have not been re-assigned.
A Load ASCII File
This powerful command allows an ASCII file, normally of source
code, to be loaded and viewed within MonST, Window 4 will be
created if required then set up as a source code window. Memory
for the source code is taken from GEMDOS so sufficient free
memory must be available. It is recommended that source-code be
loaded before an executable program to ensure enough memory.
Low Res: Window 4 is not an ASCII file though may be loaded in
low-res then viewed after switching to medium resolution using
Ctrl-O and pressing Alt-S, Alt-T, Alt-T.
Note: If an ASCII file is loaded after an executable program the
memory used will be owned by the program itself, not MonST. when
such a program terminates, any displayed source-code window will
be closed. The auto-resident version of the debugger cannot
detect this so care should be taken if loading source code into
it.
Executing Programs
Ctrl-R Return to program/Run
This runs the current program with the given register values at
full speed and is the normal way to resume execution after entry
via a breakpoint.
Ctrl-Z Single-Step
This single-steps the instruction at the PC with the current
register values. Single-stepping a Trap, Line-A or Line-F opcode
will, by default, be treated as a single instruction. This can be
changed using Preferences.
Ctrl-Y Single-Step
Identical to Ctrl-Z above but included for the convenience of
German users.
Ctrl-T Interpret on Instruction (Trace)
This interprets the instruction at the PC using the displayed
register values. It is similar to Ctrl-Z but skips over BSRs,
JSRs, Traps, Line-A and Line-F calls, re-entering the debugger on
return from them to save stepping all the way through the routine
or trap it works on instructions in ROM or RAM.
R Run (various)
This is a general Run command and prompts for the type of the Run
to be done, selected by pressing a particular key.
Run G Go
This is identical to Ctrl-R, and resumes the program at full
speed.
Run S Slowly
This will run the program at reduced speed, remembering every
step in the history buffer.
Run I Instruction
This is similar to Run Slowly but allows a count to be entered,
so that a particular number of instructions may be executed
before MonST is entered.
Run U Until
You will be prompted for an expression which will be evaluated
after every instruction. The program will then run, albeit at
reduced speed, until the given expression evaluates to non-zero
(true) when MonST will be entered. For example if single-stepping
a DBF loop which used d6 in the ROM code you could say Run Until
d6&ffff=ffff (waiting for the low word of d6 to be $FFFF) or,
alternatively, PC=FC8B1A, or whatever.
Note: This should not be confused with the Until command which
takes an address, places a breakpoint there then resumes
execution.
With all of these commands (except Run Go) you will then be
asked Watch Y/N? If Y is selected then the MonST display will be
shown after every instruction and you can watch registers and
memory as they change, or interrupt execution by pressing both
Shift keys simultaneously. If N is selected then execution will
occur while showing your program's display and execution may be
interrupted by pressing Shift-Alt-Help.
Note: Selection Watch mode with screen switching turned off is
likely to result in a great deal of eye strain as the display
will be flipped after each and every instruction, particularly
alarming with colour monitors.
With any of these Run modes (except Go) all information after
every instruction will be remembered in the history buffer. In
addition Traps will be treated as single-instructions, unless
changed with Preferences, though see the warnings under that
command about tracing all the way through ROM routines.
When a program is running with one of the above modes a couple of
pixels near the top left of the display will flicker, to denote
that something is happening, as it is possible to think the
machine has hung when in fact, it is simply taking a while to Run
through the code an instruction at a time.
Searching Memory
G search memory (Get a sequence)
This will prompt Search for B/W/L/T/I?, standing for Bytes,
Words, Longs, Text and Instructions.
If you select B, W or L you will then be prompted to enter the
sequence of numbers you wish to search for, each separated by
commas. MonST is not fussy about word-alignment when searching,
so it can find longs on odd boundaries, for example.
If you select T you may search for any given text string, which
you will be prompted for. The search will be case-dependent.
If you select I you can search for part or all of the mnemonic of
an instruction, for example if you searched for $14 (A you would
find an instruction like MOVE.L D2,$14(A0). The case of the
string you enter is important (unlike MonST version 1), but you
should bear in mind the format the disassembler produces, e.g.
always use hex numbers, refer to A7 rather than SP and so on.
Having selected the search type and parameters, the search
begins, control passing to the Next command, described below.
N find Next
This can be used after the G command to find subsequent occuren�
ces of the search data. With the B, W, L and T options you will
always find at least one occurrence, which will be in the buffer
within MonST that is used for storing the sequence. With the T
option you may also find a copy in the system keyboard buffer.
With these options, the Esc key is tested every 64k bytes and can
be used to stop the search. With the be used to stop the search.
With the I option, which is very much slower, the Esc key is
tested every 2 bytes.
The search area of memory goes from 0 to the end of RAM, then
from $FA0000 to $FEFFFF (the cartridge and system ROM area), then
back to 0.
The search will start just past the start address of the current
window (except register windows) and if an occurrence is found
re-display the window at the given address.
Searching Source-Code Windows
If the G command is used on a source-code window the T sub-
command is automatically chosen and if the text is found the
window will re-display the line containing it.
Miscellaneous
Ctrl-P Preferences
This permits control over various options within MonST. The first
three require Y/N answers, pressing Esc aborts or Return leaves
them alone.
Screen Switching
Defaulting to On, this causes the display to switch to your
program's only after 20 milliseconds. It should be switched off
when a program is about to change a screen address or resolution,
then turned back on afterwards.
Follow Traps
By default single-stepping and the various forms of the run
command treat Traps, Line A and Line F calls as single
instructions. However by turning this option On the relevant
routines will be entered allowing ROM code to be investigated.
Note: Important: This option should be used with care. Certain
time critical routines, such as the floppy- or hard-disk drivers
have portions of code designed to be atomic, i.e. not interrup
table, and being traced will cause malfunctions within such code
and possible loss of data. On the other hand it can be fun to
watch the AES as it draws pull-down menus or opens windows.
If you have let ROM execute for a while you can interrupt it by
pressing Shift-Alt-Help, then resume at normal speed by pressing
Ctrl-R. However the AES and VDI both use Line-A and Line-F calls
and it is very likely that there are pending stack frames left
with the Trace bit set, so having resumed a traced program it is
likely that seemingly spurious trace exceptions will be
generated. Pressing Ctrl-R will resume at normal speed, though a
few more such exceptions are likely until program flow reaches
the lowest level, i.e. your program.
There is a side effect of this that can cause machine to crash
though: If you have traced through any AES event-type calls then
stack frames can be created in desk accessories with the Trace
bit set. If your program terminates before the accessory has a
chance to respond to its own event call, a trace exception will
occur after MonST terminates and returns to the Desktop or GenST,
causing a system crash, unless an auto-resident MonST is
installed or the NOTRACE.PRG program is used.
NOTRACE Program
This is a very small program intended to be added to the AUTO
folder of your boot disk which causes trace exceptions to be
ignored, instead of producing a large number of bombs as it will
do by default. The source code is also supplied.
Relative Offsets
This option defaults to On and effects the disassembly of the
address register indirect with offset addressing modes, i.e.
xxx(An). With the option on the current value of the given
address register is added to the offset then searched for in the
symbol table. If found it is disassembled as symbol (An). This
option is very useful for certain styles of assembly language
programming as well as high level languages which use a base
register as a major offset, such as HiSoft BASIC which uses A3 as
a pointer to the run-time system.
Symbols Option
This allows control over the use of symbols in expressions in
MonST. It will firstly ask whether the case of symbols should be
ignored, pressing Y will cause case independent searching to be
used. It will then prompt for the maximum length of symbols,
which is normally 22 but may be reduced to as low as 8.
I Intelligent Copy
This copies a block of memory to another area. The addresses
should be entered in the form
<start>,<inclusive end>,<destination>
The copy is intelligent in that the block of memory may be copied
to a location which overlaps its previous location.
NOTE: No checks at all are made on the validity of the move;
copying to non-existent areas of memory is likely to crash MonST
and corrupting system areas may well crash the machine.
L List Lables
This opens up a large window and displays all loaded symbols. Any
key displays the next page, pressing Esc aborts. The symbols will
be displayed in the order they were found on the disk (or in
memory if using the Debug option from the editor).
W Fill Memory With
This fills a section of memory with a particular byte. The range
should be entered in the form
<start>,<inclusive_end>,<filbyte>
The warning described previously about no checks applies equally
to this command.
P Disassemble to Printer/Disk
This command allows the disassembly of an area of memory to
printer or disk, complete with original labels and, optionally,
an automatic list of labels created by MonST, based on cross-
references. The first line should be entered as
<buffer_start>,<buffer_end>
Next is the prompt for data areas which will be disassembled as
DC instructions, of the form
<data_start>,<data_end>[,<size>]
The optional size field should be B, W or L , defaulting to L,
determining the size of the data. When all data areas have been
defined, a blank line should be entered.
Finally, a filename prompt will appear; if this is blank all
output will be to the printer, else it will be assumed to be a
disk file.
If automatic labels were specified there may be a delay at this
point while the table is generated. Automatic labels are of the
form Lxxxxx where xxxxx is the actual hex address.
Printer Output
This is of the form of an 8 digit hex number, then up to 10 words
of hex data, 12 characters of any symbol, then the disassembly
itself. Printer output may be aborted by pressing Esc.
Disk Output
This is in a form directly loadable by GenST, consisting of any
symbol, a tab, then the disassembly itself, with a tab separating
any operand from the op-code. If you are disassembling an area of
memory without loaded symbols then the XREF option should be used
else no symbols will appear in the output file. Pressing Esc or a
disk error will abort the disassembly.
M Modify Address
Included for compatibility with MonST 1, equivalent to Alt-A.
O Show Other Bases
Included for compatibility with MonST 1, equivalent to Alt-O.
D Change Drive & Directory
This allows the current drive and sub-directory to be changed.
Auto-Residemt MonST
The additional version of MonST called AMONST2.PRG will now be
described. When placed in the AUTO folder on a boot disk, it will
be loaded and initialised automatically on boot-up.
Once booted, this version of MonSt lies dormant, ready to be
invoked when any exception occurs in the machine, such as an
address error. It is intended primarily for programmers writing
and debugging desk accessories or other AUTO-type applications,
as if there is a problem in the code which gets called as the
machine boots, it hangs before you get a chance to use the normal
MonST. If required you can deliberately put an illegal opcode,
such as ILLEGAL, at the start of your auto program so that MonST
will be invoked then use it to investigate any problems your code
has.
The auto-resident version may be double-clicked from the Desktop
and will initialise itself in the same way as from the AUTO
folder, unless a version of MonST is already resident.
Once invoked the auto-resident version is very similar in use to
the other versions except that programs or labels cannot be
loaded and the base page variables are unknown and so set to 0.
The other difference is that when the program being debugged
exits or Ctrl-C is pressed within MonST, MonST itself stays
active in memory.
In addition any program may be interrupted by pressing the Shift-
Alt-Help key combination when a resident version of MonST is
installed.
The resident version of MonST cannot be reclaimed from memory
except by resetting the machine and booting with a disk which does
not contain MonST in the AUTO folder.
When an auto-resident version of MonST is loaded, the usual
versions can still be used as normal, memory permitting, and the
resident version will be ignored until the non-resident version
exits, when it will become active once again.
Note: Do not invoke an auto-resident MonST from within a program
other than the Desktop, such as using Run Other from within
GenST, as large areas of system memory will become locked away
and unusable until a machine reset.
If both shift keys are held down during the installation of the
auto-resident MonST, the debugger is itself entered, allowing the
editing of memory or setting of BDOS breakpoints. When entered
via this method the debugger should be left using Ctrl-C when the
debugger will remain resident.
Command Summary
Window Commands
Alt-A ..................... Set Address
Alt-B ..................... Set Breakpoint
Alt-E ..................... Edit Window
Alt-F ..................... Font Size
Alt-L ..................... Lock Window
Alt-O ..................... Show Other
Alt-P ..................... Printer Dump
Alt-R ..................... Register Set
Alt-S ..................... Split Windows
Alt-T ..................... Change Type
Alt-Z ..................... Zoom Window
Screen Switching
V ......................... View Other Screen
Ctrl-O .................... Other Screen Mode
Breakpoints
Alt-B ..................... Set Breakpoint
Help ...................... Show Help and Breakpoints
Ctrl-B .................... Set Breakpoint
U ......................... Go Until
Ctrl-K .................... Kill Breakpoints
Ctrl-A .................... Set Breakpoint then Execute
Ctrl-D .................... BDOS Breakpoint
Loading and Saving
Ctrl-L .................... Load Executable Program
B ......................... Load Binary File
S ......................... Save Binary File
A ......................... Load ASCII File
Executing Programs
Ctrl-R .................... Return to program/Run
Ctrl-Z .................... Single-Step
Ctrl-Y .................... Single-Step
Ctrl-T .................... Interpret an Instruction (Trace)
R ......................... Run (various)
Searching Memory
G ......................... Search Memory (Get a sequence)
N ......................... Find Next
Miscellaneous
Ctrl-C .................... Terminate
Ctrl-P .................... Preferences
I ......................... Intelligent Copy
W ......................... Fill Memory With
L ......................... List Labels
P ......................... Disassemble to Printer/Disk
M ......................... Modify Address
O ......................... Show Other Bases
D ......................... Change Drive & Directory
Shift-Alt-Help ............ Interrupt Program
H ......................... Show History Buffer
Debugging Stratagem
Hints & Tips
If you have interrupted a program using Shift-Alt-Help or by a
Run Until command and have found yourself in the middle of the
ROM, there is a way of returning to the exact point in your
program which called the ROM. Firstly ensure the Follow Traps
option is on, then do Run Until with an expression of sp=a7. This
will re-enter MonST the moment user mode is restored which will
be in your program.
If you are in a subrouting which doesn't interest you and want to
let it run but return to MonST the easiest way is to use Until
(not Run Until) then specify the expression (sp) - this sets a
breakpoint at the return address. If the subroutine has placed
something on the stack, or uses a local stack frame (normally the
case for compiled programs) then try Run Until (pc).w=4e75 which
will run slowly until the instruction RTS is reached. This won't
work if the subroutine in question calls another, so it may
require a further condition, such as ({pc}.w=4e75)&(sp>xxx) where
xxx is one less than the current value.
When using Run Until and you know it will take a quite a while
for the condition to be satisfied, give MonST a hand by pre-
computing as much of the expression as you can, for example
(a3>(3A400-\100+M1))
could be reduced to
a3>xxx
where xxx has been calculated by you using the Alt-O command.
MonST Command Line
If you use a CLI-type program you can pass a command line to
MonST, consisting of the program you wish to load and optionally,
a command line to pass on to it.
Bug Hunting
There are probably as many strategies for finding bugs as there
are programmers; there is really no substitute for learning the
hard way, by experience. However, there are some hints which we
have learnt, the hard way!
Firstly, a very good way of finding bugs is to look at the source
code and think. The disadvantage of reaching first for the
debugger, then second for the source code, is that it gets you
into bad habits. You may switch to a machine or programming
environment that does not offer low-level debugging, or at least
not one as powerful as you are used to.
If a program fails in a very detectable way, such as causing an
exception, debugging is normally easier than if, say, a program
sometimes doesn't quite work exactly as it should.
Many bugs are caused by a particular memory location being
stepped on. Whether the offending memory location is detectable,
by producing a bus error, for example, a conditional breakpoint
placed at one or more main subroutines can help greatly. For
example, suppose the global variable main_ptr is somehow becoming
odd during execution, the conditional expression could be set up
as
{main_ptr]&1
If this method fails, and the global variable is being corrupted
somewhere un-detectable, the remaining solution is to Run Until
that expression, which could take a considerable time. Even then
it may not find it, for example if the bug is caused by an
interrupt happening at a certain time when the stack is in a
particular place.
Count breakpoints are a good way of tracking down bugs before
they occur. For example, suppose a particular subroutine is known
to eventually fail but you cannot see why, they you should set a
count breakpoint on it, then let the program run. At the point
where the program stops, because of an exception say, look at the
value of the count breakpoint (using Help). Terminate the
program, re-load it, then set a stop breakpoint on the subroutine
for that particular value or one before it. Let it run, then you
can follow through the sub-routine on the very call that it
fails on, to try and work out why.
Good luck!
AUTO-folder programs
If these crash during initialisation then use AMONST (which must
be before your program in the directory) to catch the exception.
Including a deliberate ILLEGAL instruction at its beginning will
let you single step the initialisation.
Desk Accessories
If an accessory is mis-behaving during normal execution then use
AMONST. To find a desk accessory in memory, enter the debugger by
pressing Shift-Alt-Help then start looking from location 0 for
the upper-cased name of your .ACC file, padded to eight
characters with spaces. Ignore occurrences within directory
buffers (these will be preceded by an ASCII T character). The
correct occurrence will have a longword 12 bytes after the start
of the name. This will point to the basepage of your accessory
and $100 bytes after that will be the start of your program. From
looking at this you should be able to find your main loop and set
a suitable breakpoint. Normal execution should be resumed with
Ctrl-R then MonST will be re-entered when your breakpoint is
reached.
If an accessory is misbehaving during its initialisation then you
have to stop it at the very beginning before it has a chance to
do anything. The recommended way is to re-assemble the accessory
with an ILLEGAL instruction at the beginning and let AMONST catch
it, but this is sometimes not possible. There follows a method
that works on current ST ROMs to stop the AES just before it
executes your program, but please note the method is complicated
and not recommended for beginners.
Firstly hold down both shift keys to enter AMONST during the boot
sequence then set a BDOS Breakpoint on the Open call, $3D, then
press Ctrl-C to let the boot sequence resume.
MonST will be re-entered every time something tries to Open a
file, so make window 3 the current window and after every BDOS
breakpoint is hit set its address to (sp+2) - if the name is not
your accessory then Ctrl-Z, to execute the Open call, set another
BDOS breakpoint on $3D then Ctrl-R, and try again. If the name is
your accessory then set a BDOS breakpoint on $4B, then Ctrl-R.
MonST will then be entered just before it loads the accessory, so
Ctr-Z to do the GEMDOS call, then Alt-B and enter d0+100 which
sets a breakpoint on the very first instruction. Now Ctrl-R and
the next time MonST appears it will be on the first instruction
of the accessory. This method takes a while but it's often the
only way of finding bugs in accessories.
Exception Analysis
When an unexpected exception occurs, it's very useful to be able
to work out where and why it occurred and, possibly, to resume
execution.
Bus Error
If the PC is in some non-existent area of memory then look at the
relevant stack to try and find a return address to give a clue as
to the cause, probably an unbalanced stack. If the PC is in a
correct area of your program then the bus error must have been
caused by a memory access to non-existent or protected memory.
Recovering from bus errors and resuming execution is generally
not possible.
Address Error
If the PC is somewhere strange the method above should be used,
otherwise the error must have been caused by a program access to
an odd address. Correcting a register value may be enough to
resume execution, at least temporarily.
Illegal Instruction
If the PC is in very low memory, below around $30, it is probable
that it was caused by a jump to location 0. If you use MonST to
look here you will see a short branch together with normally,
various ORI instructions (really longword pointers) and
eventually an illegal instruction.
Privilege Violation
This is caused by executing a privileged instruction in user
mode, normally meaning your program has gone horribly wrong.
Bumping the PC past the offending instruction is unlikely to be
much help in resuming the program.