From Final Fantasy Hacktics Wiki
Jump to: navigation, search

pSX is a Playstation emulator with debugging features and without a plugin system. It is abandonware: the latest version, 1.13, was released in 2007, and its author last posted on its message board in 2009.[1]

The final release's executable is named psxfin.exe, while earlier unstable versions were named psxrel.exe.


To open the debugger and memory tools, go to Debug -> Monitor -> r3000.

Note: All values in pSX's tools are interpreted as decimal by default. Prepend the address with "0x" to make it read hexadecimal. For example, use "0x91AF" instead of "91AF".

  • File:
    • Disassemble: Disassembles a block of code and saves it to a file.
    • Save binary: Saves a block of memory to a file.
    • Configuration: Change the font of the disassembly window.
  • Debug:
    • Run (F9): (Only when halted.) Resume normal execution.
    • Break: (Only when not halted.) Stop execution and set disassembly cursor to the current instruction.
    • Step over (F8): (Only when halted.) Execute current instruction. If it is a call (e.g. jal), execute the subroutine.
    • Step into (F7): (Only when halted.) Execute current instruction. If it is a call, follow the jump and go to the subroutine's first instruction.
    • Run to cursor: Run normally until the selected instruction is reached.
    • Set next: ?
    • Reset: Restart the emulation.
    • Exit: Exit the debugger.
  • Window: Manage the various debugger subwindows.
    • Call stack:
    • Breakpoints: Active breakpoints.
    • Registers: Current value of registers. Only updated about every second while emulation is running.
    • Disassembly: Current instruction being executed. Not updated while emulation is running.
    • Memory: Current values in memory. Only updated about every second while emulation is running.
    • GPU:
    • CDROM:

Debugger hotkeys
  • Ctrl+G: Goto. Go to specified address. Available in the Memory and Disassembly subwindows. Uses #Value syntax.


pSX can set two kinds of breakpoints:

  • Execute: Break when the instruction at this location is executed.
  • Memory: Break when an instruction reads/writes/either to this address.

Breakpoint parameters

  • Address: The address to watch. Uses #Value syntax.
  • Size: (memory breakpoint only) Specifies how many bytes after this address will be watched.
  • Condition: Only break if the condition holds true (i.e. is not 0). Uses #Value syntax.
  • Count: Only break after the breakpoint is hit this many times.


  • For execution breakpoints, pSX changes the instruction to an illegal instruction until it is reached. Do not save a state while an execution breakpoint is active, or else the state will remember the illegal instruction even if there is no breakpoint there. Do not dump assembly or RAM while an execution breakpoint is active, or else it will contain the illegal instruction.
  • pSX does not apply breakpoints after loading a state. After loading a state, edit (each of?) your active breakpoints, or they will have no effect.
  • Do not close the debugger window while a breakpoint is active, or else pSX will crash. Delete all breakpoints first.
  • When triggering a memory breakpoint, pSX will stop AFTER the triggering instruction. This means that the arrow in the Disassembly window will point to the instruction after the trigger.
    • If the trigger was in a delay slot after a jump or branch, the cursor in the Disassembly window will point to the instruction after the jump/branch, which won't be close to the trigger.
  • While a breakpoint is active, the immediate value for slti and sltiu is not sign-extended.[2] Normally, all immediate values are sign-extended.

Value syntax

pSX's debugger accepts several syntaxes for entering addresses and values. Everything is case-insensitive.

  • decimal: Any numerical value will be interpreted as decimal.
    • 124 => 0x7C (= 124)
    • 68e142 => 0x44 (= 68)
  • hexadecimal: Values starting with "0x" will be interpreted as hexadecimal.
    • 0x7C => 0x7C (= 124)
  • register: Any name in the "Registers" subwindow can be used as a value.
    • r29
    • pc
    • cop0cr14_epc
  • spaces: Ignored.
  • operators: The value can be calculated.
    • Arithmetic operators: binary + - * / % and unary -. Division is truncating (rounds toward 0).
    • Bitwise operators: binary & | ^ << >> and unary ~.
    • Comparison operators: binary == != < > <= >=.
    • Logical operators: binary && || and unary !. Results in 1 for true and 0 for false.
    • Parentheses and square brackets, for grouping: ( ) [ ].
    • Comma operator: When values are separated by commas, only the last value is taken. Useful when using the write_XXX functions.
    • r29 + (r4 + 0x35)*4
    • (r2==0)*r4 + (r2!=0)*r5 => r4 if r2 is 0 else r5
    • r29, r5, r3 => r3
  • functions:
    WARNING: Misspelling a function name can cause the emulator to crash (circumstances unknown).
    • read_long(ADDR): Read a 32-bit int from ADDR and return it.[3]
    • read_word(ADDR): Read a 16-bit int from ADDR. (Note: "word" here means 16 bits, whereas "word" means 32 bits in MIPS.)
    • read_byte(ADDR): Read an 8-bit int from ADDR.
    • print(VALUE): Print a value to the pSX console, and return the value.
    • write_long(ADDR, VALUE): Write a 32-bit value to ADDR (and return 0).
    • write_word(ADDR, VALUE): Write a 16-bit value to ADDR.
    • write_byte(ADDR, VALUE): Write an 8-bit value to ADDR.

Unrecognized characters may be ignored. If the syntax is wrong, it may evaluate the longest prefix that makes sense.

Cheat Engine

For psxfin.exe 1.13, the base address of the emulated RAM is at [[psxfin.exe+1899BC]+30].