----------------------------------------------------------------------------- MEKA - Debugger / Hacking tools ----------------------------------------------------------------------------- Note: this documentation is yet incomplete. ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- 1. Debugger ----------------------------------------------------------------------------- To enable the debugger, set 'debug_mode' to 1 in the configuration file. Else, you can enable the debugger for a session by executing MEKA with the '-DEBUG' command-line parameter. In debug mode, an additionnal menu is added to the top, with access to the debugger and data dumping facilities. The debugger can also be switched on and off using the Scroll Lock key. You can configure some part of the debugger from the configuration file, search for the following variables: debug_mode (enable debug mode) debugger_console_lines (number of console lines) debugger_disassembly_lines (number of disassembly lines) debugger_disassembly_display_labels (enable label display) debugger_log (enable log of debugger output) Use mouse wheel to scroll in disassembly. All debugger output are logged by default. The log is located in the 'DEBUG/DEBUGLOG.TXT' file. Symbols Loading --------------- The debugger support symbols loading in the following format: - NO$GMB format, as generated by the WLA DX linker (-s option): YYYY:XXXX MyLabel - NO$GMB format with banking: XXXX MyLabel - SJASM format: MyLabel: equ XXXXXXXXh - TASM format: MyLabel XXXX When a bank is specified in NO$GMB format, the label is associated to its ROM-space address. Otherwise a CPU-space address is used. The filename must be the same as the ROM image filename, replaced by or post pended with the ".SYM" extension. - eg: ROM is "PsychoFox.sms", -> MEKA will look for symbols in "PsychoFox.sym" or "PsychoFox.sms.sym" If you are using a tool that generate an unsupported symbol format please contact me. Symbols are replaced by their corresponding address in CPU space in the various debugger commands. If you prefix a symbol name with the : character (eg: ":MyLabel") it is replaced by its address in ROM space. This is only functional if the bank number is available from the symbols format (the 'XXXX' in WLA DX output). Completion ---------- Pressing TAB in the debugger command line performs contextual completion. If more than one item matches, possible matches are displayed. History ------- Command are logged into an history buffer. Pressing Up/Down allows navigating in the history buffer. Additionnally, the HI/HISTORY allows listing or searching for a given word in the history buffer. Expression evaluator -------------------- Mathematical expression can be evaluated by the debugger. Supported features are: - Values: - Immediate hexadecimal integer (eg: 1234, or $1234 or 0x1234) - Immediate binary integer (eg: %00101010) - Immediate decimal integer (eg: #256) - Symbols gets replaced by their CPU address. (eg: function_label) - Symbols prefixed by : gets replaced by their ROM address. (eg: :function_label) - Z80 registers names gets replaced by their current value. (eg: PC, SP, AF, A, BC, B, C, DE, D, E, HL, H, L, IX, IY) Pay attention that some registers names are ambiguous with hexadecimal constants ('A' is a 10 in hexadecimal). Z80 registers name are always given priority over hexadecimal constants. Uses the 'Ox' or '$' prefixes to resolve ambiguity. - Operators: - Integer operators: + - / * (eg: 1+2*3 returns 7) (eg: SP-10) - Binary operators: & | ^ (eg: 0xF0 | 0x0F returns 0xFF) - Parenthesis: (), forcing priority (eg: (1+2)*3 returns 9) Any separator among the set of ',' '.' or ' ' (space) is considered as ending the expression. The remaining text will be fed to the next parameters of the current command. M HL+10 ; correct M HL + 10 ; incorrect (will provide 3 parameters to the "M" command) Known problems -------------- - Beware of clashes between Z80 registers names and hexadecimal constants. 'AF','BC','DE','A','B','C','D','E' by default refers to Z80 registers. Uses $ or 0x hexadecimal prefixes to resolve ambiguities. - Reseting or loading save states may result in missing breakpoints for a few Z80 instructions (unconfirmed? is this bug still valid?). - Execution breakpoints only works for the leading byte of the opcode. eg: 1234 - C3 00 20 - JP $2000 Adding an X breakpoint at $1234 will work, but not at $1235 or $1236. However, adding a R breakpoint will work. So usually, you end just adding default RWX or RW breakpoints. Debugger commands summary ------------------------- -- Flow: : Step into S : Step over SO : Step out (to next RET) C : Continue C addr : Continue up to J addr : Jump to -- Breakpoints: B [access] [bus] addr [=value] : Add breakpoint W [access] [bus] addr [=value] : Add watchpoint B LIST : List breakpoints B REMOVE id : Remove breakpoint B ENABLE id ; Enable breakpoint B DISABLE id : Disable breakpoint B CLEAR : Clear breakpoints -- Inspect/Modify: R : Dump Z80 registers P expr : Print evaluated expression M [addr] [cnt] : Memory dump at D [addr] [cnt] : Disassembly at STACK [cnt] : Stack dump TRACE [|all|clear|regs] : Trace past execution RMAP addr : Reverse map Z80 address VARS [name] : Display variables by name VARS @addr : Display variables by address SYM [name] : Find symbols by name SYM @addr : Find symbols by address SET register=value : Set Z80 register CLOCK [RESET] : Display Z80 cycle counter -- Miscellaenous: MEMEDIT [lines] [cols] : Spawn memory editor HISTORY [word] : Print/search history H,? [command] : Help Debugger command - H -------------------- H/HELP: Online help Usage: H ; Get general help H command ; Get detailed help on a command Debugger command - S -------------------- S: Step over Usage: S ; Step over current instruction Examples: 0000: CALL $0100 0003: LD HL, $1FFF S ; Resume execution after the call Debugger command - C -------------------- C/CONT: Continue execution Usage: C ; Continue C address ; Continue up to reaching
Debugger command - CR --------------------- CR/CONTRET: Continue to next RET instruction Debugger command - J -------------------- J/JUMP: Jump Usage: J address ; Jump to
Examples: J 0 ; Jump back to $0000 (reset) J 1000 ; Jump to $1000 Note: Equivalent to SET PC=address Debugger command - B -------------------- B/BREAK: Manage breakpoints Usage: B address [..address2] ; Add CPU breakpoint B [access] [bus] address [=xx] ; Add breakpoint B LIST ; List breakpoints B REMOVE id ; Remove breakpoint B ENABLE id ; Enable breakpoint B DISABLE id ; Disable breakpoint B CLEAR ; Clear breakpoints Parameters: address : breakpoint address, can be a range or label access : access to trap, any from r/w/x (rwx) bus : bus/event, one from cpu/io/vram/pal/rom/line (cpu) xx ; byte to compare to, for conditionnal break id : breakpoint identifier Examples: B 0038 ; break when CPU access $0038 B w io 7f ; break on IO write to $7F B rx e000..ffff ; break on CPU read/exec from $E000+ B x =0,0,C9 ; break on CPU execution of NOP NOP RET B w vram 3f00.. ; break on VRAM write to SAT B w pram 0 =03 ; break on PRAM write of color 0 as $03 B line #13 ; break on display line 13 You can add a description to breakpoints, by ending the command line with a string: B 0038 "interrupt" As a shortcut: B nopnop Is equivalent to: B x=0,0 "NOP NOP" Debugger command - W -------------------- W/WATCH: Manage watchpoints Usage: Same as B/BREAK. Watchpoints will display value but won't break. Examples: W r io dd ; watch and log all IO read from DDh W w pal 0.. ; watch and log all palette write Debugger command - P -------------------- P/PRINT: Print expression Usage: P expr P expr[,expr,...] Examples: P IX,IY ; print IX and IY registers P 1200+34 ; print $1234 P %00101010 ; print 42 P HL+(BC*4) ; print HL+BC*4 P label ; print label Debugger command - SET ---------------------- SET: Set Z80 register Usage: SET register=value [,...] Parameters: register : Z80 register name value : value to assign to register Examples: SET BC=$1234 ; set BC register to $1234 SET DE=HL,HL=0 ; set DE=HL, then zero HL Debugger command - RMAP ----------------------- RMAP: Reverse map Z80 address Usage: RMAP address Parameters: address : address in Z80 space Examples: RMAP $8001 ; eg: print 'ROM $14001 (Page 5 +0001)' RMAP $E001 ; eg: print 'RAM $C001' Debugger command - CLOCK ------------------------ CLOCK: Display Z80 cycle accumulator Usage: CLOCK ; Display cycle accumulator CLOCK R[ESET] ; Reset cycle accumulator Debugger command - VARS ---------------------- VARS: Display variables (Variables are symbols declared within a RAM location.) Usage: VARS [name] VARS @addr Parameters: name : variable/symbol name to search for addr : variable/symbol address to search for Examples: VARS ; display all variables VARS player ; display variables matching 'player' VARS @HL ; display variables at address HL Debugger command - SYM ---------------------- SYM/SYMBOLS: Find symbols Usage: SYM [name] SYM @addr Parameters: name : symbol name to search for addr : symbol address to search for Examples: SYM vdp ; search for symbol matching 'vdp' SYM @HL ; search for symbol at address of HL Debugger command - M -------------------- M/MEM: Dump memory Usage: M [address] [len] Parameters: address : address to dump memory from (PC) len : bytes to dump (128) Examples: M ; dump 128 bytes at PC M HL BC ; dump BC bytes at HL Debugger command - D -------------------- D/DASM: Disassemble instructions Usage: D [address] [cnt] Parameters: address : address to disassemble from (PC) cnt : number of instruction to disassemble (10) Debugger command - STACK ------------------------ ST/STACK: Dump stack Usage: ST [len] Parameters: len : bytes to dump (8) Examples: ST ; dump 8 bytes at SP Notes: Each entry is displayed as a possible 8-bit of 16-bit value. Symbols are resolved. Debugger command - TRACE ------------------------ TR/TRACE: Trace past execution Usage: TR [cnt] TR all ; trace all (since last clear TR clear ; clear trace log TR regs ; toggle dumping extra registers Parameters: cnt : number of previous instruction (16) Notes: If the number of instructions to trace is large, output is redirected to Debug/debuglog.txt and not displayed in the debugger view. Debugger command - R -------------------- R/REGS: Dump Z80 registers Usage: R Debugger command - MEMEDIT -------------------------- MEMEDIT: Spawn memory editor Usage: MEMEDIT [lines] [cols] Parameters: lines : number of lines cols : number of columns Debugger command - HISTORY -------------------------- HI/HISTORY: Print/search history Usage: HISTORY ; Print history HISTORY word ; Search history ----------------------------------------------------------------------------- 2. Palette ----------------------------------------------------------------------------- ... ----------------------------------------------------------------------------- 3. Tile Viewer ----------------------------------------------------------------------------- ... ----------------------------------------------------------------------------- 4. Tilemap Viewer ----------------------------------------------------------------------------- ... ----------------------------------------------------------------------------- 5. Technical Information ----------------------------------------------------------------------------- ... ----------------------------------------------------------------------------- 6. Memory Editor ----------------------------------------------------------------------------- Allows viewing and writing to memory: - Z80 memory map - ROM - RAM - VRAM - VREG - PAL (if any) - SaveRAM (if any) Tips: - Use mouse wheel, arrow keys or cursor to navigate. - Using the address box, you can jump to a given address. - In some case, you may want to pause the game (F12) while editing, in some other case you may want it running. - Z80 memory map is what the Z80 CPU sees and accesses thru its buses. Refer to technical documentation about the machine memory map to know how this works. Understand the difference: - Writing to Z80 $FFFC-$FFFF trigger mapping + write to RAM. But writing to RAM $FFFC-$FFFF only write to RAM. - Writing to Z80 $0000-$3FFF is ignored (by most mappers). But writing to ROM $0000-$3FFF works and modify loaded ROM image. - Beware that pressing "BackSpace" may reset the game. Use the "Delete" key instead. (I should hack a way so that BackSpace is disabled but other controller keys still enabled). ----------------------------------------------------------------------------- 7. Data Dumping ----------------------------------------------------------------------------- ... ----------------------------------------------------------------------------- 8. Patching ----------------------------------------------------------------------------- Refer to MEKA.PAT file. ----------------------------------------------------------------------------- 8. Links ----------------------------------------------------------------------------- SMS Power! Development http://www.smspower.org/dev/ SMS Power! Development Forum http://www.smspower.org/forums/viewforum.php?f=3 WLA DX http://users.tkk.fi/~vhelin/wla.html Maxim's "Getting started with SMS programming" pages http://www.smspower.org/maxim/howtoprogram ----------------------------------------------------------------------------- 9. More ? ----------------------------------------------------------------------------- Please suggest features you may want to help development/hacking activity! Please report bugs! I can also point out that in the absence of a given feature, you can always hack into MEKA source code and add custom code/printing/hacks to help you. :) The TODO.TXT file provided along with the source code list several notes and ideas related to future development of debugging/hacking features. -----------------------------------------------------------------------------