6502 (NSF) Debugger 1.00beta
by Adam Milazzo (adamm@san.rr.com)

This program is a 6502 debugger which I threw together for a friend over the
course of a few days. It is especially geared towards debugging .NSF files.

This version is probably the only one I will release, and it's not even
complete.  If a few people actually like this program and want to see it
finished, email me at and I'll see what I can do.

TODO: (sorted by increasing order of difficulty)
 * Draw buttons for the toolbar
 * Improve source window
 * Add watch display
 * Add code to display the source, synched with the disassembly
 * Add nsf playing support and an assembler so you can modify the code and
   listen to it on the fly
 * Add support for bankswitched nsf files

The basics:
If you open file as NSF, the load address and program offset will be
determined from the file itself, but if you load a file as generic, the
program will ask you two questions:
  1) Where in memory to load the program (there is only 64k of memory)
  2) The offset of the program in the file

If the program won't fit an error will occur.
Currently, bankswitched NSF files are not supported, and they too will cause
an error.

If you've used a debugger before, everything should be pretty
self-explanatory.

The breakpoints display lets you add memory breakpoints as well as execution
breakpoints. As you all know, memory breakpoints are slow (well.. not TOO
slow). When adding a memory breakpoint, you choose the memory location,
an operation, and a value.  The only two operations supported so far are
!= and ==.  == checks for equality and is used to break when a memory
location equals a certain value.  != checks for inequality and can be used
to break when a memory location changes.

The source display is a bit unusual, so it may be tricky at first.

The source display uses a recursive disassembler to disassemble from the
play and init addresses (or just the program start if it is a non-NSF).
It will follow branches and jumps, and return when hitting rti's and rts's,
but it cannot follow indirect jumps.

Any memory not touched by the disassember is marked as unknown. In standard
mode, this unknown memory is displayed as single bytes.  Pressing Numpad *
in the source window will toggle "Dumb" mode, in which it stupidly
disassembles the unknown bytes based on a certain offset.

Numpad + and Numpad - increment and decrement the offset, respectively, and
Numpad / resets it to zero.

Laziness prevailed on this code, so the way it works is as follows:
When it draws the source window, it displays the first 'offset' unknown bytes
as bytes, and then starts disassembling the unknowns after that.  The
disassembled unknowns are marked in green to distinguish them from the known
ones.  Since the dumb mode was a hack, cursor movement may not work properly.
The way to fix this is simple. If you want to select an unknown with the
mouse, it will probably not work unless it is the first unknown on the
screen.  This isn't so bad as it may seem.. and if it doesnt work, you can
always hit Numpad * to toggle the dumb display off for a second. The purpose
of the dump display is so that you can find the valid code not touched by
the standard disassembler.  Once found, select the code and right click on
it. A menu will pop up. One of the options is Disassemble.  Choose this to
begin recursively disassembling from the cursor point, and adding all the
touched code to the list of valid code. Scrolling may also act strangely
in the dumb mode. You'll get the hang of it :)
I recommend that you turn off dumb mode when you dont need it, so that
scrolling and cursor movement work properly.

I hope this program is useful to you.. etc etc..
#include <standard_disclaimer.h>

