Hai you SNES fans,

This is version 1.2 of SNES debugger (c) M.C.A./ELITE
Developed with Devpack 3.0 (What would I do without it!?)

No permission to sell this program for ANY amount of money.
Swap against other warez is ok.

The object of this tool is, to load a snesfile, edit a little, send to snes
and see the effect of your changes as fast as possible.(make trainers)

Updates in v1.1 > 1.2
---------------------
Edit Text removed all spaces in text. Works ok now.
Little d0/d1 extend error fixed, gave sometimes 2 bombs.
Ascii display arrow up/down now add/subs whole line.
Error in Save blocks fixed, took length as name.
New: Toggle labels on/off.
New: Disassemble to file 3 types.
New: Special search.
New: Hex display.
New: Set breakpoint type.
New: Replace word or Triple byte size.
New: Set Originate.

HOW DOES IT WORK?
~~~~~~~~~~~~~~~~~

FM_DEBUG.PRG is for mono and FC_DEBUG.PRG is for color.

Install Application:
--------------------
You can install an application in the desktop window so that files will
automatically load after clicking on them. I think this is a VERY useful
option. This is how to do it: 
Click once on fm_debug or fc_debug. (should be inverted now)
Click on Install Application in the gem desktop.
Fill in filetype (document type) like 'SMC'.
Always keep bootstatus NORMAL!
Set default directory to TOP WINDOW.(tos 2.x)
Application type to GEM.
Click on Ok.
And save the Desktop configuration.

Now every time you click on a *.smc file, it starts fm_debug.prg or the 
color version, passes drive, path & filename to the debugger which
will automaticly load the file and set drive & path to the chosen
filename.


TAB
---
Switches between left and right window. Displays the current filename
at the top of screen. Lets you see which window is active, and what
file it contains. If 1 file loaded, both have the same name.
If 2 files are loaded, they might be different.

L = Load a file
---------------
Pops up the fileselector and let you choose a file. Cancel will return
to the debugger, nothing changed. When a correct file has been chosen,
it'll FREE the old reserved memory, check the new filelength, and reserves
the new space. If there is not enough memory at this point, there is a lot
of change when returning to the debugger. The old memory has been free'd
and previous loaded files can be corrupted! Same for file errors...  
Correctly loaded files will go to the 1st part of memory.
Then it gets the reset vector (intel format) and sets window 1 to where 
it points to. This is the START of the code (always between $8000-$ffff).
window 2 can now also be used to display file 1.

If loading a 2nd file there will be a prompt asking ...[L/R]
if you pick the [R] it will be loaded at window 2.
Now window 1 contains file number 1 and window 2 contains file number 2.
no mixing possible, this will also reserve extra space!
This option is made for file comparisons. (see C) 
If 2nd file is loaded at [L] it will overwrite file 1 in memory,
and also free file number 2!
Right load can be done without affecting number 1.

C=Compare 2 files
-----------------
If 2 files are loaded Left & Right, Compare option is active.
Set Left & Right window to $8000 (use tab) and press C
Every time there is a difference, the comparing...text will be replaced
by a decimal offset from the start of the header and the decimal contents
of the offset. Also the contents of each window will be updated. 
This I use to easily create BASELINE format trainer files.
Like bluesbrothers legend trainer, I load the legend file left and
the original file to the right, then press C each time and write down
all numbers, until I reach $108000 which is the start of the intro.
then I create a file using these numbers, add a few for header, length
etc.. and glue the intro.      
Compare starts at start of left window and start of right window.
If window 1 has reached file 2 it will show 'end of file reached'.

B = Breakpoint Type
-------------------
You can pick your own instructions to set a breakpoint with.
Enter values between 0000-ffff.

Example: eaea converts to nop/nop
or 60ea converts to rts/nop

Standard boot-up value is 80fe bra to itself.
Breakpoint set always takes the value you have set with this option.

D = Decimal offset,contents
---------------------------
Display current offset from headerstart to top active window in decimal
value, and the contents of the byte inside.
Same as in compare. (handy for making *.bsl files)

H = Hex offset
--------------
Display current offset from headerstart to top active window in hex.
(handy for making trainers the 'legend way')

HELP = Help window
------------------
Short info about all functions, general info about vectors,registers and
opcodes with their meaning.
Each screen can be aborted back to the monitor by pressing ESC.
Other keys will display next screen (1-6).

A-X
---
The rep/sep/plp/rti instructions affect the processor status bits 4/5
(Flag X/M),these bits affect the width of various instructions.
In order to get a 100% correct disassembly you need to step through the
code in the same way as the snes would. This is almost impossible.
Therefore I have included the option to set your own width.
A = toggle accumulator immediate instructions between 8 and 16 bit.
affect lda #$12 - lda #$1234  adc/and/cmp/etc..
X = toggle x and y (indexed) immediate instructions between 8 and 16 bit.
affect all cpx/cpy/ldx/etc..

G = Get or search for
---------------------
B = byte
W = word (2 bytes)
L = triple bytes (3 bytes)
T = text (case sensitive choice)
I = instruction
S = special

Instruction search is not so fast, but very handy!

Example:  jml
          #$1
          #$1ff ;tough to find all of these with word or byte search! 
          8]
 
Special: when searching for 5c??c0
1st one needs to be a BYTE then insert no more as 25 ?'s
each ? stands for a byte, last one also must be a BYTE.

So 5c??c0 means look for jml(5c) and the 4rth must be c0 (bank number)
this will find EVERY long jump to bank \192 
also 8d???????22 ok, 1st must be 8d and the 9th must be 22
also 8d?42 nice to find all sta dma registers.
or 9c?21 to find all stz audio registers.

1234??56 is not ok! keep 1st and last at byte length.

Search starts in active window at screen adres start.
ESC cancels search. Checks every xx Kb for key.

N = Next search
---------------

Last entered string of G option stays in buffer. This will be 
searched for again.

M = Modify window adress
------------------------
This changes all typed number/symbols into fake SEGMENTED adresses.
Type any adres in range of $xx8000-$xxFFFF.
Adresses below $8000 are variable/stack/etc.. area's.
They are out of range for this debugger.
If you enter $408000 it will display $8000
Every thing above segment $3fxxxx will be masked.
So $419314 will display $019314.

HEADER is used as a filestart symbol.
If you type HEADER it'll show strange adresses but it will
show the header bytes. Also very handy if you have hex offset adresses
and want to know where they are... So then type HEADER+9c334 or whatever.
It'll bring you to the right adress. 

O = various calculation
-----------------------
Enter any value or operator.(recursive)

\ = decimal
$ = heximal (not needed is standard)
+ = plus
- = minus
* = times
/ = divide
! = or
~ = not
% = binary
& = and
^ = eor
>> = shift right
<< = shift left
also () and []
header = this symbol will display the linear actual filestart.
         If you want to know where the st keeps the program.

Alt-B = Binary Block Save
-------------------------
If Y is chosen, pick name with fileselector, next it'll ask the filelength.
Length is taken in hex, so a value of 20 will save 32 decimal bytes.
You also can save decimal lengths by putting a slash in front.
like: \32
The starting point of save, is at the top of the ACTIVE window.  

Alt-D = Disassemble to file
---------------------------
First asks for Type A/B/C
There are 3 ways of outputting to a file. (ascii field never included)
Each field will be separated by a tab, spaces between hexnumbers.

Type A: Adres Hexnumbers Opcode Operand.
        (use tabsize 8 for neat display)

Type B: Adres Opcode Operand.

Type C: Label Opcode(ext) Operand. 

This last type will convert only the USED adresses into labels.
Also it checks on the size of immediate instructions and put .l extension
behind the opcode if needed.(also some long stuff)

The start of active window is the first line for disassembly.
After chosen the type you can scroll DOWN with the down arrow 1 line
adding each time or with space 24 lines DOWN.
Up is impossible.(I would have to rearrange tables)
X and M flag can be set about 1000 times each set will be saved when
skipping a line or page. When this flag buffer is full, no more changes
are added! it shows ok on the screen however.
Escape cancels Disassembly. Labels can be set on/off.
When you type G the number of lines are calculated and disassembly
starts. At this point it looks for labels on or off, so you cannot
get mixed hardware adresses & labels.

Don't forget that the lines you see in the window are NOT included.

when the fileselector appears the disassembly is finished.
Pick a new name and save the file.
If you pick an existing name the disassembly will ATTATCH to the end
of that file.

The number of lines are limited to $ffff (\65535). When $ffff is reached
next one will be 0000 !!
I disassembled with C Type half a bank (16k) into about 10.000 lines,
takes about 2 minutes and the output file was about 130k.
This is the slowest method, but is closest to assembling again.
If unlabeled adresses are In code range you probably forgot to set the
M/X flags at the right point. If they are out of code range you need
to set new labels by hand.

Types A/B are must faster. 

People are used to enter start/end adres to disassemble a piece of file,
but rep/set/plb/etc.. makes sure this fucks up a LOT of places!
The only file who will work on this method is the baseline sneswish
source, with this rep/sep are set only once!
Most snes-files use 1000ands of these things!

C Type option can be improved a lot with dcb/add 1 byte/backward/etc..
But this has to do for now.


Alt-O = Originate
-----------------
Sets the start of window 1/2 to the entered value.
All new adresses will be calculated accordingly.
Only works ok on the 1st file.
Mainly used to study rom stuff or pieces of code which are copied to
other places.
Works fine with the disassemble option.
M option also works fine.
DON'T save if originate is other than $8000.
Boundery checks and maybe some more stuff, will not work correct
with this option!
When Alt-O is pressed again it will restore to standard mode.
 

Alt-E = Edit
------------
Edit bytes, words, longs(triple bytes), or text. Escape to cancel.
Enter accepts & updates top left active window.

If you type 'G','L', and enter a 4 byte string instead of 3, like 12345678
it will write 345678 !! So the 1st byte is masked off.
123456 entered will work 100%.

I = Insert file
-------------------
On Y, pick file with fileselector, the file will overwrite the top active
window. It does NOT reserve any memory. Nice option to put an intro
INTO a game, of course you''l need to adapt the reset vector, and the
back jml's. Check with Contrl-G if reset has changed ok.   


Alt-P = Profighter/wildcard send & run
--------------------------------------
Sends adapted sytem & active window IF the header+2=$30 (wildcard)
or header+3=$80 (profighter).


Alt-R = Replace value
---------------------
This option gets active when you use 'G' with Word or Long(triple byte).
The first time it asks for a value, enter correct size, and the bytes 
at the top of the active window will be replaced, then the search continues.
Then all other times it will use the 1st entered value.
When you choose another G search option, you have to re-enter a value.
Use N(ext) if you want no change.
Watch out: If W or L was last used and you accidently press Alt-R
it WILL replace and search for the next one.
All other G options will disable Replace.    

Alt-S = Save file
-----------------
Save WHOLE file in active window, same length. Pick name with fileselector.

Control-A = Ascii/code toggle
-----------------------------
Switch between code display(default) and ascii display.
Works on both windows. Nice for Text hackin'.

Control-B = Set or Clear Breakpoint
-----------------------------------
This seems a little strange. Each Breakpoint (10 max) you set will
put a branch to itself (if not changed with B) at the top of the
active window. So if you run a game it stops at this point, sometimes
this can be handy to find what certain places do.
If you have set other values like 6060 (rts/rts) it will skip the routine
at that point so you can see what it did not do.
Use your imagination on this subject.
If a breakpoint is set on a place which has alreay be set, it will
be restored.

Control-H = Hex/Code toggle
---------------------------
Switch between code and hex display.

Control-K = Kill all breakpoints
--------------------------------
Restore original values at all breakpoint adresses.
You can use the B option mixed, no problem.

Control-L = Labels on/off
-------------------------
Put them off if you don't have an equate table of the used labels, when
you disassemble to a file. Or if you rather do without them.
On = default.
Complete label equate table is included with this program.

Control-C = Quit all
--------------------
Go back to the Desktop.

Control-G = Go to start of file
-------------------------------
This gets the reset vector adres and sets the current window to
that adres.

Control-S = Send & Run file
---------------------------
Send active window (whole file) to snes and run it.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you have any suggestions on improving this tool, let us know!

All info for this SNES debugger is gathered from info on different
BBS's, A Lot of new Hardware registers by CYNIX and
65SC816 info from the Dutch book "Het Microprocessor data boek" from
P.Hoogeboom (elektuur), pages 129-138.
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

