Historical information about the Atari 2600 console
-
-
-
-
-
-
-
-
-
-
-
diff --git a/htdocs/background.gif b/htdocs/background.gif
deleted file mode 100644
index de3b56d4192023f92ebd8646aa90b45c79b00139..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 53
zcmZ?wbhEHb+`_=f(7?d(`zR{|1B2pE79h#MpaUX6G7L;SE&VG`zvW*%XUnZH1_o;Y
DMd%HY
diff --git a/htdocs/cssprint.css b/htdocs/cssprint.css
deleted file mode 100644
index f3c7b44fa..000000000
--- a/htdocs/cssprint.css
+++ /dev/null
@@ -1,23 +0,0 @@
-body { color: black; font-size: 12pt; font-family: Arial, Helvetica, Geneva, Swiss, SunSans-Regular, sans-serif; background: white 0px 0px; margin: 20px }
-p {}
-td { font-size: 12pt; }
-img { border: none }
-a:link { color: blue }
-a:active { color: blue }
-a:visited { color: blue }
-a:hover { color: red }
-.rightcolumn { }
-.header { }
-.content { margin-top: 20px }
-.footer { font-size: 10pt; margin-top: 40px }
-.footer img { float: left; padding-right: 20px }
-.leftcolumn { display: none }
-.leftcolumn img { }
-.menuheader { }
-.leftcolumn ul { }
-.leftcolumn ul li { }
-.leftcolumn ul li a { }
-.leftcolumn ul li a:link { }
-.leftcolumn ul li a:active { }
-.leftcolumn ul li a:visited { }
-.leftcolumn ul li a:hover { }
diff --git a/htdocs/cssscreen.css b/htdocs/cssscreen.css
deleted file mode 100644
index f074150c4..000000000
--- a/htdocs/cssscreen.css
+++ /dev/null
@@ -1,33 +0,0 @@
-body { color: black; font-size: 12pt; font-family: Arial, Helvetica, Geneva, Swiss, SunSans-Regular, sans-serif; background: white url(background.gif) repeat-y 0px 0px; margin: 20px }
-p {}
-td { font-size: 12pt; }
-img { border: none }
-a:link { color: blue }
-a:active { color: blue }
-a:visited { color: blue }
-a:hover { color: red }
-.rightcolumn { float: right; padding-right: 20px; padding-bottom: 20px; position: absolute; top: 20px; left: 200px }
-.header { }
-.content { margin-top: 20px }
-.footer { font-size: 10pt; margin-top: 40px }
-.footer img { float: left; padding-right: 20px }
-.leftcolumn { font-size: 10pt; float: left; padding-bottom: 20px; position: absolute; top: 20px; left: 20px; width: 140px; overflow: hidden }
-.leftcolumn img { }
-.menuheader { font-weight: bold; font-size: 11pt; margin-top: 20px; margin-bottom: 5px }
-.leftcolumn ul { list-style-type: none; margin: 0px; padding: 0px }
-.leftcolumn ul li { }
-.leftcolumn ul li a { text-decoration: none; margin-bottom: 3px; padding: 3px; width: 130px; display: block }
-.leftcolumn ul li a:link { color: black; background-color: #ffd766 }
-.leftcolumn ul li a:active { color: white; background-color: red }
-.leftcolumn ul li a:visited { color: black; background-color: #ffd766 }
-.leftcolumn ul li a:hover { color: red; background-color: white }
-body#about a#about { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#screenshots a#screenshots { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#news a#news { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#team a#team { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#mailing a#mailing { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#guide a#guide { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#stable a#stable { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#development a#development { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#atarilinks a#atarilinks { color: black; background: white url(menucurrent.gif) no-repeat right top }
-body#homebrew a#homebrew { color: black; background: white url(menucurrent.gif) no-repeat right top }
diff --git a/htdocs/development.php b/htdocs/development.php
deleted file mode 100644
index cb45ee3c3..000000000
--- a/htdocs/development.php
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- Stella: "A Multi-Platform Atari 2600 VCS Emulator"
-
-
-
-
-
-
-
-
-
-
-
Instructions for compiling Stella from source code can be found in the
- User's Guide, which vary depending on your operating system. Feel free to
- email Stephen Anthony if
- you encounter problems, or you wish to contribute in any way to the Stella
- project.
-
-
The latest sourcecode for Stella can always be downloaded using Subversion from
- the Sourceforge servers. Instructions for using Subversion on Sourceforge can be
- found here.
-
Note: Developers can check out from 'trunk' with the following command:
-
svn co https://stella.svn.sourceforge.net/svnroot/stella/trunk/stella
The debugger in Stella may never be complete, as we're constantly
-adding new features requested by homebrew developers. However, even in its
-current form it's still quite powerful, and is able to boast at least one
-feature that no other 2600 debugger has; it's completely cross-platform.
-
-
Here's a list of what the debugger can do so far:
-
-
Display registers and memory
-
Dump state of TIA and RIOT, with things like joystick directions and
- NUSIZx decoded into English (more-or-less).
-
Change registers/memory, including toggles for flags in P register
-
Single step/trace
-
Breakpoints - break running program and enter debugger when the
- Program Counter hits a predefined address. You can set as many
- breakpoints as you want.
-
Conditional breakpoints - Break running program when some arbitrary
- condition is true (e.g. "breakif {a == $7f && c}" will break when the
- Accumulator value is $7f and the Carry flag is true, no matter where
- in the program this happens). Unlike the cond breaks in PCAE, Stella's
- are *fast*: the emulation will run at full speed unless you use lots
- of breakif's at the same time, or have a slow CPU.
-
Watches - View contents of a location/register before every
- debugger prompt.
-
Traps - Like breakpoints, but break on read/write/any access to
- *any* memory location.
-
Frame advance (automatic breakpoint at beginning of next frame)
- You can advance multiple frames with one command.
-
Disassembly
-
Support for DASM symbol files (created with DASM's -s option),
- including automatically loading symbol files if they're named
- romname.sym
-
Built-in VCS.H symbols, if no symbol file is loaded
-
Symbolic names in disassembly
-
Symbolic names accepted as input
-
Tab completion for commands and symbol names
-
Graphical editor for RIOT RAM. Acts a lot like a spreadsheet.
- Input in hex, with displays for label/decimal/binary for
- currently-selected location.
-
GUI CPU state window
-
-
Reset the 6502
-
Start emulator in debugger (via command-line option "-debug")
-
Save CLI session to a text file.
-
Supports hex, decimal, and binary input and output almost everywhere.
- (disassembly is still hex)
-
Support for bank switching. You can see how many banks a cart has,
- and switch banks. There's still more to be done here though.
-
Registers/memory that get changed by the CPU during debugging are
- highlighted when they're displayed.
-
Scanline advance (like frame advance, break at beginning
- of next scanline).
-
TIA display is updated during step/trace, so we can see our
- scanlines being drawn as it happens. This isn't 100% perfect: unlike
- a real TIA, the one in Stella only updates when it's written to.
-
Graphical TIA tab, with register names and GUI buttons for
- various bits (e.g. click ENAM0 to turn it on).
-
GUI Disassembly window, scrollable, with checkboxes for breakpoints.
-
Script (batch) file support, including auto-running a script file
- named after the ROM image.
-
Saving the current debugger state to a script file (including
- breakpoints, traps, etc).
-
Built-in functions for use with "breakif", to support common conditions
- (such as breaking when the user presses Game Select...)
-
Patching ROM in-place.
-
Save patched ROM ("saverom filename.bin").
-
-
-
Future planned features (post 2.0):
-
-
-
GUI for cheat codes (Cheetah and normal codes).
-
Perhaps 2 panes in the disassembly window (so you can see 2 parts of the
- code at once).
-
Add bookmark support to disassembly window.
-
Bankswitch support in the debugger for the few remaining cart types
- that aren't supported.
-
Patch ROM support for a few cart types doesn't work. Must fix.
-
Source-level debugging: if a DASM .lst file is available, we'll show
- the listing in the ROM tab instead of a disassembly. This is already
- available in a very crude form ("loadlist" and "list" commands).
-
More "special variables" for the expression parser.
-
Possibly a mini-assembler
-
Support for extra RAM in Supercharger and other cart types.
-
Possibly support for recording and playing back input files, like
- MAME. This isn't a debugger feature per se, but it'll make it easier
- to reliably trigger a bug so you can debug it.
-
Graphics ROM view, so you can see your sprite data (it might still
- be upside-down though :)
-
Various new GUI enhancements
-
-
-
How to use the debugger
-
-
Pressing ` (aka backtick, backquote, grave accent) toggles the debugger on
-& off. When you exit the debugger, the emulation resumes at the current
-program counter, and continues until either a breakpoint/trap is hit,
-or the ` key is pressed again.
-
-
The main debugger window will look similar to the following (note that the
-letters here are for reference in the document below; they aren't actually
-present in the debugger):
-
-
-
For space reasons, the Prompt, TIA, I/O and Audio displays are split into
-4 tabs, only one of which is visible at a time. You can use the mouse or
-keyboard to select which tab you want to view. Pressing Shift with the left
-or right arrow keys cycles between tabs from right-to-left and left-to-right,
-respectively. Pressing Tab cycles between widgets in the current tab (except
-for in the Prompt area, where 'tab' is used for something else).
-
-
You can also enter the debugger at emulator startup by giving a breakpoint on the command line:
-
- ; will enter the debugger the first time the instruction at "kernel" runs
- stella -break kernel mygame.bin
-
- ; $fffc is the 6502/6507 init vector. This command will break and enter the
- ; debugger before the first 6507 instruction runs, so you can debug the
- ; startup code:
- stella -break "*($fffc)" mygame.bin
-
-
-
-
Using the ` key will always enter the debugger at the end of the
-frame (scanline 262, for NTSC games). This is because Stella only checks
-for keystrokes once per frame. Once in the debugger, you can control
-execution by stepping one instruction, scanline, or frame at a time
-(or more than one at a time, using commands in the prompt). You can
-also set breakpoints or traps, which will cause the emulator to enter
-the debugger when they are triggered, even if it happens in mid-frame.
-
-
Change Tracking
-
-
The debugger tracks changes to the CPU registers and RAM by displaying
-changed locations or registers with a red background after each step,
-trace, scanline, or frame advance. This sounds simple, and it is, but
-it's also amazingly useful.
-
-
One clarification about the change tracking: it only tracks when values
-have changed. If the ROM writes a value into a RAM location that
-already contained the same value, that's not considered a change (old
-value was $whatever, new value is the same, so nothing got tracked). This
-may change in a future version of Stella.
-
-
-
-
(A) Prompt tab
-
-
This is a command-line interface, similar to the DOS DEBUG command
-or Supermon for the C=64.
-
-
Editing keys work about like you'd expect them to in Windows, but many
-Bash-style commands are also supported:
-
-
-
Home
Move cursor to beginning of line
-
End
Move cursor to end of line
-
Delete
Remove character to right of cursor
-
Backspace
Remove character to left of cursor
-
Control-a
Same function as 'Home'
-
Control-e
Same function as 'End'
-
Control-d
Same function as 'Delete'
-
Control-k
Remove all characters from cursor to end of line
-
Control-u
Remove all characters from cursor to beginning of line
-
Control-w
Remove entire word to left of cursor
-
Shift-PgUp
Scroll up through previous commands one screen/page
-
Shift-PgDown
Scroll down through previous commands one screen/page
-
Shift-Up
Scroll up through previous commands one line
-
Shift-Down
Scroll down through previous commands one line
-
Shift-Home
Scroll to beginning of commands
-
Shift-End
Scroll to end of commands
-
-
You can also scroll with the mouse. Copy and paste is not yet supported.
-
-
To see the available commands, enter "help". Bash-style tab completion is
-supported for commands and labels (see below).
-
-
For now, there are some functions that only exist in the prompt. We
-intend to add GUI equivalents for all (or almost all?) of the prompt
-commands in future releases. People who like command prompts will be able to
-use the prompt, but people who hate them will have a fully functional
-debugger without typing (or without typing much, anyway).
-
-
Tab completion
-
-
While entering a command or label, you can type a partial name and
-press the Tab key to attempt to auto-complete it. If you've ever used
-"bash", this will be immediately familiar. If not, try it: load up
-a ROM, go to the debugger, type "print w" (but don't press Enter),
-then hit Tab. The "w" will change to "WSYNC" (since this is the only
-built-in label starting with a "w"). If there are multiple possible
-completions (try with "v" instead of "w"), you'll see a list of them,
-and your partial name will be completed as far as possible.
-
-
Tab completion works on all labels: built-in, loaded from a symbol file,
-or set during debugging with the "define" command. However, it does not
-yet work on functions defined with the "function" command, nor does it
-work on filenames.
-
-
Expressions
-
-
Almost every command takes a value: the "a" command takes a
-byte to stuff into the accumulator, the "break" command
-takes an address to set/clear a breakpoint at. These values
-can be as a hex constant ($ff, $1234), or as complex as
-"the low byte of the 16-bit value located at the address
-pointed to by the binary number 1010010110100101" (which
-would be "@<\1010010110100101"). You can also use registers
-and labels in expressions.
-
-
You can use arithmetic and boolean operators in expressions. The
-syntax is very C-like. The operators supported are:
-
-
- + - * / (add, subtract, multiply, divide: 2+2 is 4)
- % (modulus/remainder: 3%2 is 1)
- & | ^ ~ (bitwise AND, OR, XOR, NOT: 2&3 is 2)
- && || ! (logical AND, OR, NOT: 2&&3 is 1, 2||0 is 0)
- ( ) (parentheses for grouping: (2+2)*3 is 12)
- * @ (byte and word pointer dereference: *$80 is the byte stored
- at location $80)
- [ ] (array-style byte pointer dereference: $80[1] is the byte
- stored at location ($80+1) or $81)
- < > (prefix versions: low and high byte. <$abcd is $cd)
- == < > <= >= !=
- (comparison: equality, less-than, greater-than, less-or-equals,
- greater-or-equals, not-equals)
- << >> (bit shifts, left and right: 1<<1 is 2, 2>>1 is 1)
-
-
-
Division by zero is not an error: it results in zero instead.
-
-
None of the operators change the values of their operands. There
-are no variable-assignment or increment/decrement operators. This
-may change in the future, which is why we used "==" for equality
-instead of just "=".
-
-
The bitwise and logical boolean operators are different in that the
-bitwise operators operate on all the bits of the operand (just like
-AND, ORA, EOR in 6502 asm), while the logical operators treat their
-operands as 0 for false, non-zero for true, and return either 0 or 1.
-So $1234&$5678 results in $1230, whereas $1234&&$5678 results in 1.
-This is just like C or C++...
-
-
Prefixes
-
-
Like some programming languages, the debugger uses prefixed characters
-to change the meaning of an expression. The prefixes are:
-
-
-
Dereference prefixes:
-
-
"*"
- Dereference a byte pointer. "*a" means "the byte at the address that
- the A register points to". If A is 255 (hex $ff), the result will be
- the value currently stored in memory location 255. This operator
- will be very familiar to you if you're a C or C++ programmer. It's
- equivalent to the PEEK() function in most 8-bit BASICs. Also, the
- debugger supports array-like byte dereferences: *address can be
- written as address[0]. *(address+1) can be written as address[1],
- etc.
-
-
"@"
- Dereference a pointer to a word. This is just like the "*" byte deref,
- except it refers to a 16-bit value, occupying 2 locations, in
- low-byte-first format (standard for the 6507).
"<"
- Take the low byte of a 16-bit value. This has no effect on an 8-bit
- value: "a" is equal to "<a". However, "<$1234" equals "$34".
-
-
">"
- Take the high byte of a 16-bit value. For 8-bit values such as
- the Accumulator, this will always result in zero. For 16-bit values,
- "<$1234" = "$12".
-
-
-
Number Base Prefixes:
-
"#"
- Treat the input as a decimal number.
-
-
"$"
- Treat the input as a hex number.
-
-
"\"
- Treat the input as a binary number.
-
-
These only have meaning when they come before a number, not a
- label or a register. "\1010" means 10 decimal. So do "$0a" and
- "#10". "a" by itself is always the Accumulator, no matter what
- the default base is set to.
-
-
If you don't specify any number base prefix, the number is
- assumed to be in the default base. When you first start Stella,
- the default base is 16 (hexadecimal). You can change it with the
- "base" command. If you want to change the default base to decimal permanently,
- you can put a "base #10" command in your "autoexec.stella" file (see
- the section on "Startup").
-
-
Remember, you can use arbitrarily complex expressions with any
- command that takes arguments (except the ones that take filenames,
- like "loadsym").
-
-
-
-
-
Breakpoints, watches and traps, oh my!
-
-
Breakpoints
-
-
A breakpoint is a "hotspot" in your program that causes the emulator
-to stop emulating and jump into the debugger. You can set as many
-breakpoints as you like. The command is "break xx" where xx is any
-expression. If you've created a symbol file, you can use labels.
-
-
Example: you've got a label called "kernel". To break there,
-the command is "break kernel". After you've set the breakpoint,
-exit the debugger ("quit" or click the Exit button). The emulator
-will run until it gets to the breakpoint, then it will enter the
-debugger with the Program Counter pointing to the instruction
-at the breakpoint.
-
-
Breakpoints happen *before* an instruction is executed: the
-instruction at the breakpoint location will be the "next"
-instruction.
-
-
To remove a breakpoint, you just run the same command you used to
-set it. In the example, "break kernel" will remove the breakpoint.
-The "break" command can be thought of as a *toggle*: it turns the
-breakpoint on & off, like a light switch.
-
-
You could also use "clearbreaks" to remove all the breakpoints. Also,
-there is a "listbreaks" command that will list them all.
-
-
Conditional Breaks
-
-
A conditional breakpoint causes the emulator to enter the debugger when
-some arbitrary condition becomes true. "True" means "not zero" here:
-"2+2" is considered true because it's not zero. "2-2" is false, because
-it evaluates to zero. This is exactly how things work in C and lots
-of other languages, but it might take some getting used to if you've
-never used such a language.
-
-
Suppose you want to enter the debugger when the Game Reset switch is
-pressed. Looking at the Stella Programmers' Guide, we see that this
-switch is read at bit 0 of SWCHB. This bit will be 0 if the switch is
-pressed, or 1 otherwise.
-
-
To have an expression read the contents of an address, we use the
-dereference operator "*". Since we're looking at SWCHB, we need
-"*SWCHB".
-
-
We're only wanting to look at bit 0, so let's mask off all the other
-bits: "*SWCHB&1". The expression now evaluates to bit 0 of SWCHB. We're
-almost there: this will be 1 (true) if the switch is NOT pressed. We
-want to break if it IS pressed...
-
-
So we invert the sense of the test with a logical NOT operator (which
-is the "!" operator): !(*SWCHB&1). The parentheses are necessary as
-we want to apply the ! to the result of the &, not just the first term
-(the "*SWCHB").
-
-
"breakif !(*SWCHB&1)" will do the job for us. However, it's an ugly mess
-of letters, numbers, and punctuation. We can do a little better:
-
-
"breakif { !(*SWCHB & 1 ) }" is a lot more readable, isn't it? If
-you're going to use readable expressions with spaces in them,
-enclose the entire expression in curly braces {}.
-
-
Remember that Stella only checks for input once per frame, so a break
-condition that depends on input (like SWCHB) will always happen at the
-end of a frame. This is different from how a real 2600 works, but most
-ROMs only check for input once per frame anyway.
-
-
Conditional breaks appear in "listbreaks", numbered starting from
-zero. You can remove a cond-break with "delbreakif number", where
-the number comes from "listbreaks".
-
-
Any time the debugger is entered due to a trap, breakpoint, or
-conditional break, the reason will be displayed in the status area above
-below the TIA Zoom display.
-
-
Functions
-
-
There is one annoyance about complex expressions: once we
-remove the conditional break with "delbreakif" or "clearbreaks",
-we'd have to retype it (or search backwards with the up-arrow key)
-if we wanted to use it again.
-
-
We can avoid this by defining the expression as a function, then using
-"breakif function_name":
Now we have a meaningful name for the condition, so we can use it again.
-Not only that: we can use the function as part of a bigger expression.
-Suppose we've also defined a gameSelect function that evaluates to true
-if the Game Select switch is pressed. We want to break when the user
-presses both Select and Reset:
-
-
- breakif { gameReset && gameSelect }
-
-
-
If you've defined a lot of complex functions, you probably will
-want to re-use them in future runs of the debugger. You can save all
-your functions, breakpoints, conditional breaks, and watches with the
-"save" command. If you name your saved file the same as the ROM filename
-and place it in the ROM directory, it'll be auto-loaded next time you
-load the same ROM in Stella. The save file is just a plain text file
-called "filename.stella", so you can edit it and add new functions, etc.
-You can also create a file called "autoexec.stella" which will be loaded
-when the debugger starts, no matter what ROM you have loaded. This file
-should live in the "base directory" (which is the current directory on
-Windows or $HOME/.stella on UNIX), not the ROM directory.
-
-
Built-in Functions
-
-
Stella has some pre-defined functions for use with the "breakif"
-command. These allow you to break and enter the debugger on various
-conditions without having to define the conditions yourself.
-
-
Built-in functions and pseudo-registers always start with an _
-(underscore) character. It is suggested that you don't start labels in
-your game's source with underscores, if you plan to use them with the
-Stella debugger.
-
-
-
Function
Definition
Description
-
_joy0left
!(*SWCHA & $40)
Left joystick moved left
-
_joy0right
!(*SWCHA & $80)
Left joystick moved right
-
_joy0up
!(*SWCHA & $10)
Left joystick moved up
-
_joy0down
!(*SWCHA & $20)
Left joystick moved down
-
_joy0button
!(*INPT4 & $80)
Left joystick button pressed
-
_joy1left
!(*SWCHA & $04)
Right joystick moved left
-
_joy1right
!(*SWCHA & $08)
Right joystick moved right
-
_joy1up
!(*SWCHA & $01)
Right joystick moved up
-
_joy1down
!(*SWCHA & $02)
Right joystick moved down
-
_joy1button
!(*INPT5 & $80)
Right joystick button pressed
-
_select
!(*SWCHB & $01)
Game Select pressed
-
_reset
!(*SWCHB & $02)
Game Reset pressed
-
_color
*SWCHB & $08
Color/BW set to Color
-
_bw
!(*SWCHB & $08)
Color/BW set to BW
-
_diff0b
!(*SWCHB & $40)
Left difficulty set to B (easy)
-
_diff0a
*SWCHB & $40
Left difficulty set to A (hard)
-
_diff1b
!(*SWCHB & $80)
Right difficulty set to B (easy)
-
_diff1a
*SWCHB & $80
Right difficulty set to A (hard)
-
-
-
Don't worry about memorizing them all: the Prompt "help" command
-will show you a list of them.
-
-
Pseudo-Registers
-
-
These "registers" are provided for you to use in your conditional breaks.
-They're not registers in the conventional sense, since they don't exist in
-a real system. For example, while the debugger keeps track of the number
-of scanlines in a frame, a real system would not (there is no register
-that holds 'number of scanlines' on an actual console).
-
-
Function
Description
-
_scan
Current scanline count
-
_bank
Currently selected bank
-
_fcount
Number of frames since emulation started
-
_cclocks
Color clocks on a scanline
-
_vsync
Whether vertical sync is enabled (1 or 0)
-
_vblank
Whether vertical blank is enabled (1 or 0)
-
-
-
_scan always contains the current scanline count. You can use
-this to break your program in the middle of your kernel. Example:
-
- breakif _scan==#64
-
-
This will cause Stella to enter the debugger when the TIA reaches the
-beginning of the 64th scanline.
-
-
_bank always contains the currently selected bank. For 2K or 4K
-(non-bankswitched) ROMs, it will always contain 0. One useful use is:
-
-
- breakif { pc==myLabel && _bank==1 }
-
-
-
This is similar to setting a regular breakpoint, but it will only trigger
-when bank 1 is selected.
-
-
Watches
-
-
A watch is an expression that gets evaluated and printed before
-every prompt. This is useful for e.g. tracking the contents of a
-memory location while stepping through code that modifies it.
-
-
You can set up to 10 watches (in future the number will be unlimited).
-Since the expression isn't evaluated until it's used, you can include
-registers: "watch *y" will show you the contents of the location
-pointed to by the Y register, even if the Y register changes.
-
-
The watches are numbered. The numbers are printed along with the
-watches, so you can tell which is which. To delete a watch use the
-"delwatch" command with the watch number (1 to whatever). You can
-also delete them all with the "clearwatches" command.
-
-
Note that there's no real point in watching a label or CPU register
-without dereferencing it: Labels are constants, and CPU registers
-are already visible in the CPU Widget
-
-
Traps
-
-
A trap is similar to a breakpoint, except that it catches
-accesses to a memory address, rather than specific location in the
-program. They're useful for finding code that modifies TIA registers
-or memory.
-
-
An example: you are debugging a game, and you want to stop the
-emulation and enter the debugger whenever RESP0 is strobed. You'd use
-the command "trap RESP0" to set the trap, then exit the debugger. The
-emulator will run until the next time RESP0 is accessed (either read
-or write). Once the trap is hit, you can examine the TIA state to
-see what the actual player 0 position is, in color clocks (or you
-can in the future when we implement that feature in the TIA dump!)
-
-
Unlike breakpoints, traps stop the emulation *after* the instruction
-that triggered the trap. The reason for this is simple: until the
-instruction is executed, the emulator can't know it's going to hit a
-trap. After the trap is hit, the instruction is done executing, and
-whatever effects it may have had on e.g. the TIA state have already
-happened... but we don't have a way to run the emulated VCS in reverse,
-so the best we can do is stop before the next instruction runs.
-
-
Traps come in two varieties: read access traps and write access traps.
-It is possible to set both types of trap on the same address (that's
-what the plain "trap" command does). To set a read or write only trap,
-use "trapread" or "trapwrite". To remove a trap, you just attempt
-to set it again: the commands actually toggle the trap on & off. You
-can also get rid of all traps at once with the "cleartraps" command.
-
-
Use "listtraps" to see all enabled traps.
-
-
Prompt commands:
-
-
Type "help" to see this list in the debugger.
-
-
- a - Set Accumulator to value xx
- bank - Show # of banks (with no args), Switch to bank (with 1 arg)
- base - Set default base (hex, dec, or bin)
- break - Set/clear breakpoint at address (default: current pc)
- breakif - Set breakpoint on condition
- c - Carry Flag: set (to 0 or 1), or toggle (no arg)
- cheetah - Use Cheetah cheat code (see http://members.cox.net/rcolbert/)
- clearbreaks - Clear all breakpoints
- cleartraps - Clear all traps
- clearwatches - Clear all watches
- colortest - Color Test
- d - Decimal Flag: set (to 0 or 1), or toggle (no arg)
- define - Define label
- delbreakif - Delete conditional break created with breakif
- delwatch - Delete watch
- disasm - Disassemble from address (default=pc)
- dump - Dump 128 bytes of memory at address
- exec - Execute script file
- frame - Advance emulation by xx frames (default=1)
- function - Define expression as a function for later use
- height - Change height of debugger window
- help - This cruft
-+ list - List source (if loaded with loadlist)
- listbreaks - List breakpoints
- listtraps - List traps
- listwatches - List watches
- loadstate - Load emulator state (0-9)
-+ loadlist - Load DASM listing file
- loadsym - Load symbol file
- n - Negative Flag: set (to 0 or 1), or toggle (no arg)
- pc - Set Program Counter to address
- poke - Set address to value. Can give multiple values (for address+1, etc)
- print - Evaluate and print expression in hex/dec/binary
- ram - Show RAM contents (no args), or set address xx to value yy
- reload - Reload ROM and symbol file
- reset - Reset 6507 to init vector (does not reset TIA, RIOT)
- riot - Show RIOT timer/input status
- rom - Change ROM contents
- run - Exit debugger, return to emulator
-+ runto - Run until first occurrence of string in disassembly
- s - Set Stack Pointer to value xx
- save - Save breaks, watches, traps as a .stella script file
- saverom - Save (possibly patched) ROM to file
- saveses - Save console session to file
- savestate - Save emulator state (valid args 0-9)
- savesym - Save symbols to file
- scanline - Advance emulation by xx scanlines (default=1)
- step - Single step CPU (optionally, with count)
-+ tia - Show TIA state (NOT FINISHED YET)
- trace - Single step CPU (optionally, with count), subroutines count as one instruction
- trap - Trap read and write accesses to address
- trapread - Trap read accesses to address
- trapwrite - Trap write accesses to address
- undef - Undefine label (if defined)
- v - Overflow Flag: set (to 0 or 1), or toggle (no arg)
- watch - Print contents of address before every prompt
- x - Set X Register to value xx
- y - Set Y Register to value xx
- z - Zero Flag: set (to 0 or 1), or toggle (no arg)
-
-
-
-
Commands marked with a + are partially implemented.
-
-
-
-
-
(B) TIA Tab
-
-
When selected, this tab shows detailed status of all the TIA registers
-(except for audio; use the Audio tab for those).
-
-
-
Most of the values on the TIA tab will be self-explanatory to a 2600
-programmer. The top line (with all the hex values) displays the raw
-values read from the TIA locations, as they would be seen by the CPU.
-
-
Many of the variables inside the TIA can only be written to by the
-6502. The debugger lets you get inside the TIA and see the contents
-of these variables. These include the color registers, player/missile
-graphics and positions, and the playfield.
-
-
You can control almost every aspect of the TIA from here, too: most
-of the displays are editable. You can even toggle individual bits in
-the GRP0/1 and playfield registers (remember to double-click).
-
-
The group of buttons labelled "Strobes" allows you to write to any
-of the strobe registers at any time.
-
-
The collision registers are displayed in decoded format, in a table.
-You can see exactly which objects have hit what. These are read-only
-displays; you can't toggle the bits in the current release of Stella. Of
-course, you can clear all the collisions with the CXCLR Strobe button.
-
-
To the right of each color register, you'll see a small rectangle
-drawn in the current color. Changing a color register will change the
-color of this rectangle.
-
-
-
-
-
(C) I/O Tab
-
-
When selected, this tab shows detailed status of the Input, Output,
-and Timer portion of the RIOT/M6532 chip (the RAM portion is accessed
-in another part of the debugger).
-
-
-
As with the TIA tab, most of the values here will be self-explanatory to a 2600
-programmer, and almost all can be modified. However, the SWCHx registers need
-further explanation:
-
SWCHA(W) can be directly modified; here, the (W) stands for write. Similarly,
-SWACNT can be directly modified. However, the results of reading back from
-the SWCHA register are influenced by SWACNT, and SWCHA(R) is a read-only display
-reflecting this result.
-
SWCHB cannot be directly modified; it will be indirectly modified by setting
-the various difficulty switches, color/BW button, select/reset, etc. SWBCNT
-is hardwired as read-only, and is not shown.
-
-
-
-
-
(D) Audio Tab
-
-
This tab lets you view the contents of the TIA audio registers. In
-the current release of Stella, these are read-only displays. This tab
-will grow some features in a future release.
-
-
-
-
-
(E) TIA Display
-
-
In the upper left of the debugger, you'll see the current frame of
-video as generated by the TIA. If a complete frame hasn't been drawn,
-the partial contents of the current frame will be displayed up to the
-current scanline, with the contents of the old frame (in black &
-white) filling the rest of the display. Note that if 'phosphor mode'
-has been enabled for a ROM, you will see the effect here as well. That
-is, no flicker will be shown for 30Hz display, even though a real
-system would alternate between drawing frames (and hence produce
-flicker).
-
-
You can use the "Scan+1" button, the prompt "scan" command, or the
-Alt-L key-combo to watch the TIA draw the frame one scanline at a time.
-
-
You can also right-click anywhere in this window to show a context menu,
-as illustrated:
-
-
The options are as follows:
-
-
Fill to scanline: If you've already started a partial frame
- draw (ie, the frame is already partially 'greyed' out), selecting this
- option will draw all scanlines up to the vertical position where the
- mouse was clicked. Note that if you weren't in partial-frame mode,
- this option will have no effect.
-
Set breakpoint: Will set a conditional breakpoint at the
- scanline where the mouse was clicked. Currently, you'll need to use
- the Prompt Tab to turn the breakpoint off again.
-
Set zoom position: Influences what is shown in the TIA
- zoom area (further described in part (G). The zoom area will
- contain the area centered at the position where the mouse was
- clicked.
-
-
-
-
-
-
(F) TIA Info
-
To the right of the TIA display (E) there is TIA information, as shown:
-
-
The indicators are as follows:
-
-
Frame: The current frame number, since this ROM was loaded or reset.
-
F. Cyc: The number of CPU cycles that have been executed this frame, since
-VSYNC was cleared at scanline 0.
-
Scanline: The scanline that's currently being drawn. Scanline 0 is the one
-on which VSYNC is cleared (after being set for 3 scanlines, as per the Stella
-Programmer's Guide)
-
S. Cyc: The number of CPU cycles that have been executed since the beginning
-of the current scanline.
-
VSYNC & VBLANK: Self explanatory.
-
Pixel Pos: The current number of visible color clocks that have been displayed on
-the current scanline, starting from the beginning of the Horizontal Blank period.
-During HBLANK, this value will be negative (representing the number of clocks
-until the first visible one). Since there are 68 color clocks per HBLANK and
-160 visible clocks per scanline, the Pixel Position will range from -68 to 159.
-
Color Clk: The current number of total color clocks since the beginning of this
-scanline's HBLANK. This counter starts at zero, but otherwise displays the same
-information as the Pixel Position (so Color Clock will always be 68 more than Pixel
-Position, and will range from 0 to 228).
-
-
-
-
-
-
(G) TIA Zoom
-
Below the TIA Info (F) is the TIA Zoom area. This allows you to enlarge
-part of the TIA display, so you can see fine details. Note that unlike
-the TIA display area, this one does generate frames as the real
-system would. So, if you've enabled 'phosphor mode' for a ROM, it
-won't be honoured here (ie, you'll see alternating frames at 30Hz display,
-just like on a real system).
-
You can also right-click anywhere in this window to show a context menu,
-as illustrated:
-
-
These options allow you to zoom in on the image for even greater detail.
-If you click on the output window, you can scroll around using the cursor,
-PageUp/Dn and Home/End keys. You can also select the zoom position from
-a context menu in the TIA Display.
-
-
-
-
-
(H) Breakpoint/Trap Status
-
Below the TIA Zoom (G), there is a status line that shows the reason the
-debugger was entered (if a breakpoint/trap was hit), as shown:
-
-
The output here will generally be self-explanatory. Due to space concerns,
-conditional breakpoints will be shown as "CBP: ...", normal breakpoints
-as "BP: ...", read traps as "RTrap: ..." and write traps as "WTrap: ...".
-See the "Breakpoints" section for details.
-
-
-
-
-
(I) CPU Registers
-
This displays the current CPU state, as shown:
-
-
All the registers and flags are displayed, and can be changed by
-double-clicking on them. Flags are toggled on double-click. Selected registers
-here can also be changed by using the "Data Operations" buttons, further
-described in (J).
-
There's not much else to say about the CPU widget: if you know 6502
-assembly, it's pretty self-explanatory. If you don't, well, you should
-learn :)
-
-
-
-
-
(J) Data Operations buttons
-
These buttons can be used to change values in either CPU Registers (I), or
-the RIOT RAM (K), depending on which of these widgets is currently active.
-
-
Each of these buttons also have a keyboard shortcut (indicated in square
-brackets). In fact, many of the inputboxes in various parts of the debugger
-respond to these same keyboard shortcuts. If in doubt, give them a try.
-
- 0 [z] - Set the current location/register to zero.
- Inv [i !] - Invert the current location/register [toggle all its bits].
- Neg [n] - Negate the current location/register [twos' complement negative].
- ++ [+ =] - Increment the current location/register
- -- [-] - Decrement the current location/register
- << [< ,] - Shift the current location/register left.
- >> [> .] - Shift the current location/register right.
-
- Any bits shifted out of the location/register with << or >>
- are lost (they will NOT end up in the Carry flag).
-
-
-
-
-
-
(K) M6532/RIOT RAM
-
This is a spreadsheet-like GUI for inspecting and changing the contents
-of the 2600's RAM. All 128 bytes of RAM are visible on the screen at
-once. You can navigate with either the mouse or the keyboard arrow keys.
-To change a RAM location, either double-click on it or press Enter while
-it's highlighted. Enter the new value (hex only for now, sorry), then
-press Enter to make the change. If you change your mind, press Escape
-and the original value will be restored. The currently selected RAM cell
-can also be changed by using the Data operations buttons/associated
-shortcut keys (J).
-
-
The 'Undo' button in the upper right should be self-explanatory; it will
-undo the most previous operation to one cell only. The 'Rev' button is
-more comprehensive. It will undo all operations on all cells
-since you first made a change.
-
The UI objects at the bottom refer to the currently selected RAM cell.
-The 'label' textbox shows the label attached to this RAM location (if any),
-and the other textboxes show the decimal and binary equivalent value.
-The remaining buttons to the right are further explained in section (L).
-
-
-
-
-
(L) M6532/RIOT RAM (search/compare mode)
-
The RIOT RAM widget also lets you search memory for values such as lives or remaining
-energy, but it's also very useful when debugging to determine which
-memory location holds which quantity.
-
-
To search RAM, click 'Srch' and enter a byte value into the search editbox (0-255).
-All matching values will be highlighted in the RAM widget. If 'Search' is clicked
-and the input is empty, all RAM locations are highlighted.
-
-
The 'Cmp' button is used to compare the given value using all
-addresses currently highlighted. This may be an absolute number (such as 2),
-or a comparitive number (such as -1). Using a '+' or '-' operator
-means 'search addresses for values that have changed by that amount'.
-
The 'Rset' button resets the entire operation; it clears the highlighted
-addresses and allows another search.
-
The following is an example of inspecting all addresses that have
-decreased by 1:
-
-
Click 'Srch' with empty input. All 128 address/values are highlighted
-
Exit debugger mode and lose a life, let your energy decrease, or
- do whatever it is you're trying to debug
-
Enter debugger mode again, click 'Cmp' and and enter a '-1' for input.
- This finds all values that have decreased by 1 (as compared to their current
- values)
-
Repeatedly following these steps may help to narrow number of
- addresses under consideration, and eventually you'll find the
- memory address you're looking for
-
Click 'Rset' when you're finished
-
-
-
-
-
-
(M) ROM Listing
-
The ROM Widget is a disassembly of the current bank of ROM. If a symbol
-file is loaded, the disassembly will have labels. Even without a symbol
-file, the standard TIA/RIOT labels will still be present.
-
-
-
Each line of disassembly has four fields:
-
-
Breakpoint - This is the area at the far left, to the left of the
-address. Normally there will be nothing there: this indicates that there's
-no breakpoint set at that address. You can set and clear breakpoints by
-clicking in this area. When a breakpoint is set, there will be a
-red circle in this area. These are the same breakpoints as used
-by the "break" command, not the conditional "breakif" breakpoints
-(which makes sense: cond-breaks can break on any condition, the Program
-Counter isn't necessarily involved).
-
Address (which may be a label or a hex address)
-
Hex bytes. These are the raw machine code bytes for the instruction.
-
Instruction. This is a standard 6502 mnemonic (possibly with operand).
-This field also contains the cycle count for the instruction (separated by a
-semicolon).
-
-
-
The 6502 mnemonic will be UPPERCASE for all standard instructions,
-or lowercase for "illegal" 6502 instructions (like "dcp"). Since there's
-no way to tell code from data, you'll likely see a lot of illegal opcodes
-if you scroll to a data table in ROM.
-
-
Beware: the cycle counts don't take into account any penalty cycles
-for crossing page boundaries. All branches are shown as 2 cycles, which
-is how long they take if the branch isn't taken. Branches that are
-taken will actually take 3 cycles (plus a penalty cycle if they cross
-page boundaries).
-
-
You can scroll through the disassembly with the mouse or keyboard. To
-center the display on the current PC, press the Space bar.
-
-
Any time the Program Counter changes (due to a Step, Trace, Frame
-or Scanline advance, or manually setting the PC), the disassembly will
-scroll to the current PC location.
-
-
Even though ROM is supposed to be Read Only Memory, this is an
-emulator: you can change ROM all you want within the debugger. The hex
-bytes in the ROM Widget are editable. Double-click on them to edit
-them. When you're done, press Enter to accept the changes or Escape to
-cancel them. Any time you edit ROM, there may be a short pause while
-the ROM Widget disassembles the current bank again.
-
-
Speaking of banks: Above the disassembly there's an indicator for the
-current bank and total number of banks. If there's more than one bank,
-you can manually switch banks by double-clicking the bank number and enter
-a new number (or using the shortcuts keys for inputboxes as described
-in section (J). This won't work if the ROM only has one bank, of course.
-
-
The ROM listing also contains a context menu, accessible by right-clicking
-anywhere in the listing:
-
-
Currently, there are two options:
-
-
Save ROM: A textbox will appear for you to enter filename,
-and then the ROM will be saved. Note that the filename is considered
-relative to the current directory, not the ROM or base directory.
-You can enter a full path, though, in which case it doesn't matter.
-
Set PC: Set the Program Counter to the address of the
-disassembly line where the mouse was clicked.
-
-
-
Limitations
-
-
-
-
The ROM Widget only works on ROM. If your game runs code from RAM,
-the ROM Widget will get "confused" while the PC is pointing to RAM. It
-will highlight instructions in ROM instead. If the PC points to (for
-example) $80, the ROM Widget will display the instruction at $F080
-instead. No permanent harm is done: once your RAM routine returns, the
-ROM Widget will work normally again. You can still disassemble RAM with
-the "disasm" command from the Prompt.
-
-
The standard VCS memory map has the cartridge port at locations
-$F000-$FFFF. However, not all the address lines exist on a 6507, so
-the cartridge port is "mirrored" at every other 4K chunk of address
-space ($1000, $3000, up to $D000). Some programmers find it easier
-to think of the different banks of ROM as being at different addresses
-(such as: Bank 0 at $D000 and bank 1 at $F000). When such a ROM runs,
-the Program Counter can point to one of the mirrors instead of the main
-area at $F000. This is perfectly OK, and everything works just fine,
-except that the ROM Widget will show the "real" address instead of the
-mirrored one. For instance, if the PC contains $D010, the ROM Widget
-will highlight the instruction at $F010. This is the same instruction,
-since $D010 reads the same ROM location as $F010. However, the breakpoint
-indicator may be wrong: breakpoints are set on actual addresses. If
-there were a breakpoint set at $F010, it wouldn't be triggered by the
-PC hitting $D010 (but the ROM Widget will show a breakpoint indicator
-if the PC hits $D010, even though it shouldn't)
-
-
-
-
These limitations will be addressed in a future release of Stella.
-
-
-
-
-
Global Buttons
-
-
There are also buttons on the right that always show up no matter which
-tab you're looking at. These are always active. They are: Step, Trace,
-Scan+1, Frame+1 and Exit.
-
-
-
When you use these buttons, the prompt doesn't change. This means the
-status lines with the registers and disassembly will be "stale". You
-can update them just by pressing Enter in the prompt.
-
-
You can also use the Step, Trace, Scan+1 and Frame+1 buttons from anywhere in
-the GUI via the keyboard, with Alt-S, Alt-T, Alt-L and Alt-F.
-
-
-
-
-
Tutorial: How to hack a ROM
-
-
Here is a step-by-step guide that shows you how to use the debugger to
-actually do something useful. No experience with debuggers is necessary,
-but it helps to know at least a little about 6502 programming.
-
-
-
Get the Atari Battlezone ROM image. Make sure you've got the
- regular NTSC version. Load it up in Stella and press TAB to get to
- the main menu. From there, click on "Game Information". For "Name", it
- should say "Battlezone (1983) (Atari)" and for MD5Sum it should say
- "41f252a66c6301f1e8ab3612c19bc5d4". The rest of this tutorial assumes
- you're using this version of the ROM; it may or may not work with the
- PAL version, or with any of the various "hacked" versions floating around
- on the 'net.
-
-
Start the game. You begin the game with 5 lives (count the tank
- symbols at the bottom of the screen).
-
-
Enter the debugger by pressing the ` (backquote) key. Don't get
- killed before you do this, though. You should still have all 5 lives.
-
-
In the RAM display, click the "Search" button (labelled 'Srch') and enter "5" for input.
- This searches RAM for your value and highlights all addresses that match
- the input. You should see two addresses highlighted: "00a5" and "00ba".
- These are the only two addresses that currently have the value 5, so they're
- the most likely candidates for "number of lives" counter. (However, some
- games might actually store one less than the real number of lives, or
- one more, so you might have to experiment a bit. Since this is a "rigged
- demo", I already know Battlezone stores the actual number of lives.
- Most games do, actually).
-
-
Exit the debugger by pressing ` (backquote) again. The game will
- pick up where you left off.
-
-
Get killed! Ram an enemy tank, or let him shoot you. Wait for
- the explosion to finish. You will now have 4 lives.
-
-
Enter the debugger again. Click the "Compare" button (labelled 'Cmp') in RAM widget and enter
- a value of 4. Now the RAM widget should only show one highlighted address:
- "00ba". What we did was search within our previous results (the ones that
- were 5 before) for the new value 4. Address $00ba used to have the value 5,
- but now it has 4. This means that Battlezone (almost certainly) stores the
- current number of lives at address $00ba.
-
-
Test your theory. Go to the RAM display and change address $ba to
- some high number like $ff (you could use the Prompt instead: enter "ram
- $ba $ff"). Exit the debugger again (or advance the frame). You should now see lots of lives
- at the bottom of the screen (of course, there isn't room to display $ff
- (255) of them!)... play the game, get killed a few times, notice that
- you have lots of lives.
-
-
Now it's time to decide what sort of "ROM hack" we want to
- accomplish. We've found the "lives" counter for the game, so we can
- either have the game start with lots of lives, or change the game
- code so we can't get killed (AKA immortality), or change the code
- so we always have the same number of lives (so we never run out, AKA
- infinite lives). Let's go for infinite lives: it's a little harder than
- just starting with lots of lives, but not as difficult as immortality
- (for that, we have to disable the collision checking code, which means
- we have to find and understand it first!)
-
-
Set a Write Trap on the lives counter address: "trapwrite $ba"
- in the Prompt. Exit the debugger and play until you get killed. When
- you die, the trap will cause the emulator to enter the debugger with the
- Program Counter pointing to the instruction *after* the one that wrote
- to location $ba.
-
-
Once in the debugger, look at the ROM display. The PC should be at address
- $f238, instruction "LDA $e1". You want to examine a few instructions before
- the PC, so scroll up using the mouse or arrow keys. Do you see
- the one that affects the lives counter? That's right, it's the "DEC $ba"
- at location $f236.
-
-
Let's stop the DEC $ba from happening. We can't just delete the
- instruction (it would mess up the addressing of everything afterwards,
- if it were even possible), but we can replace it with some other
- instruction(s).
-
-
Since we just want to get rid of the instruction, we can replace it with
- NOP (no operation). From looking at the disassembly, you can see that
- "DEC $ba" is a 2-byte long instruction, so we will need two one-byte
- NOP instructions to replace it. From reading the prompt help (the "help"
- command), you can see that the "rom" command is what we use to patch ROM.
-
-
Unfortunately, Stella doesn't contain an assembler, so we can't just
- type NOP to put a NOP instruction in the code. We'll have to use the
- hex opcode instead.
-
-
Now crack open your 6502 reference manual and look up the NOP
- instruction's opcode... OK, OK, I'll just tell you what it is: it's $EA
- (234 decimal). We need two of them, so the bytes to insert will look like:
-
-
$ea $ea
-
-
Select the line at address $f236 and enter 'ROM patch' mode. This is done
- by either double-clicking the line, or pressing enter. Then delete the bytes
- with backspace key and enter "ea ea". Another way to do this would have been
- to enter "rom $f236 $ea $ea" in the Prompt widget.
-
-
-
Test your patch. First, set location $ba to some number of
- lives that can be displayed on the screen ("poke $ba 3" or enter directly into
- the RAM display). Now exit the debugger and play the game. You should see 3
- lives on the screen.
-
-
The crucial test: get killed again! After the explosion, you
- will *still* see 3 lives: Success! We've hacked Battlezone to give us
- infinite lives.
-
-
Save your work. In the prompt: "saverom bzhack.bin". You now
- have your very own infinite-lives version of Battlezone. The file will
- be saved in the current directory (NOT your ROM directory), so you might
- want to move it to your ROM directory if it isn't the current directory.
- This can also be accomplished by right-clicking on the ROM widget and
- selecting 'Save ROM'.
-
-
Test the new ROM: exit Stella, and re-run it. Open your ROM
- (or give its name on the command line) and play the game. You can play
- forever! It worked.
-
-
-
Now, try the same techniques on some other ROM image (try Pac-Man). Some
-games store (lives+1) or (lives-1) instead of the actual number,
-so try searching for those if you can't seem to make it work. Also,
-some cartridge types include their own RAM. The debugger doesn't (yet)
-know how to access on-cartridge RAM, so you'll have to use the "bank" and
-"ram" commands to manually search the address space for the value you're
-looking for (future versions of the debugger will be smarter about this).
-
-
If you successfully patch a ROM in the debugger, but the saved version
-won't work, or looks funny, you might need to add an entry to the
-stella.pro file, to tell Stella what bankswitch and/or TV type to use.
-That's outside the scope of this tutorial :)
-
-
Of course, the debugger is useful for a lot more than cheating and
-hacking ROMs. Remember, with great power comes great responsibility,
-so you have no excuse to avoid writing that game you've been thinking
-about for so long now :)