My favorites | Sign in
Logo
                
Search
for
Updated Jan 19, 2009 by hrydgard
DeveloperGuide  
A guide for developers.

(this doc is very much work in progress)

Building Dolphin

Look at the build guide page for your platform:

WindowsBuild Linux_dependencies MacOSX_Build

Test build in Linux

Here's how Windows users can test build their changes in Linux:

  1. Install Linux (for example Ubuntu) in VMware
  2. Add your Windows Dolphin dir as a Shared Folder in VMware so you can easily build the same version in both Windows and Linux. To build the Linux version open a Terminal (command prompt) and go to your Dolphin dir and type "scons", this will read the SConstruct file there and build Dolphin. (Before you do this you have to follow the instructions above to get SCons to work in the first place.)
  3. If you are not familiar with the Linux text editing tools you can use TextPad for Window (that supports Linux line breaks) to edit the SConscript files when you add and remove source files to the build

Code dependencies

It is absolutely forbidden to introduce dependencies on wxWidgets into Core and Common. We want to be able to do a NoGUI build without requiring Wx. Also, optional dependencies (any kind of ALLOW_WX etc) is ABSOLUTELY FORBIDDEN in Core/Common!!!!!!

In general, keep dependencies to a minimum. More code linked in = more bugs.

The Debugger

To start Dolphin in debugger mode, add -d or /d (Windows) to the command line (this can be done in Visual Studio by right-clicking the project, properties, and add this command in debugging/command arguments).

The debugger you see in Dolphin is a complete rewrite (using wxWindows this time, the old one was Win32) of the one we used to have. Some features have been lost, but we try to add them back as we need them.

If you want to see something meaningful in there when games are loaded, choose Symbols/Generate symbol map after you have loaded a game in order to discern functions. This works without the symbol database too, but then you won't get nice function names. (Note: totaldb.dsy is also available under Downloads on this site)

Alternatively, if you have a .map file for a game (Zelda WW and a few others have one on the disc!), then you can load it. There's no GUI to do that in the new debugger yet, but it's coming.

Menu Options

CPU Mode

Interpreter core

This is nessesary to get break points and stepping to work as explained below. But it can be very slow, perhaps slower than 1 fps.

Automatic start

Starts the game directly instead of booting to pause. It also automatically loads the Default ISO when Dolphin starts, or the last game you loaded, if you have not passed Dolphin an elf file with --elf on the command line. This can be convenient if you are bugtesting with a certain game and want to rebuild and retry it several times, either with changes to Dolphin or if you are developing a homebrew game.

Unlimited JIT Cache

Avoid any involuntary JIT cache clearing, this may prevent Zelda TP from crashing.

JIT off (JIT core)

Turn off all JIT functions, but still use the JIT core from Jit.cpp.

Symbols

Save code

Saves the entire disassembled code. This may take a several seconds and may require between 50 and 100 MB of hard drive space. It will only save code that is in the first 4 MB of memory; if you are debugging a game that loads .rel files with code to memory you may want to increase that to perhaps 8 MB, which you can do from SymbolDB::SaveMap().

Breakpoints and Stepping

CPU breakpoints are triggered from CPU.cpp under case CPU_RUNNINGDEBUG. There are many limitations to using breakpoints in JIT mode. To begin with only the first address of a block may be considered for a breakpoint, the PC variable (PowerPC::ppcState.pc) will never have any address from within a block. Also if you use the JIT core multiple blocks will be executed at a time before execution leaves Jit64::Core::SingleStep() and goes back to the case. So breakpoints will often not hit even if you have added the first address of a block. So currently the only way to use breakpoints and stepping reliably is with the interpreter core. Because it can be very slow (less than 1 fps) an idea is to place a PanicAlert() at some function that is executed short before the function you want to break at, and when you get to the Alert, close the Alert window > press pause > change to interpreter. Currently it's important that you close the Alert box before you pause, if you don't Dolphin will exit without any message or DrWatson crash report. At least that's what happened for me with SSBB.

For memory breakpoints (also called memory checks), i.e. breaks that are hit when a certain address outside the executable blocks are read from or written to, JIT mode will also be unreliable. It will only work for non-JITed memory instructions, for example lesser used instructions such as stmw or lmw. More common instructions such as lwz or stw will not trigger any breakpoints. The difference here is that you can still use the JIT core and get all (or almost all?) memory reads and writes to pass by Memmap.cpp so that they trigger a breakpoint.

As mentioned this is breakpoints for addresses only, there is currently no option to break when a certain value is read or written. However you can do that manually in CheckForBadAddresses() in Memmap.cpp. But even with that there is no way to trigger a break from register-to-register copies of a certain data, it will only trigger from register-to-memory copies. We are looking at a way to add register-to-register breakpoint triggers to that will trigger when a certain value is copied to a register.

Debugging Windows

LogManager window

Verbosity: Show different verbosity levels by changing the verbosity radio boxes. 0 is lowest verbosity and 3 is highest verbosity (high meaning most messages).

Resolve symbols: Checking this will resolve symbols for verbosity level 0 and 1. Higher verbosity levels will not be resolved because of the speed issue.

Write master: Check this to write all selected logs to the master log file.

Show unique: Show only logs that are unique to that verbosity level. I.e. prevent logs from lower verbosity levels to fall through to this higher level (it only applies to what is shown in the window, lower level logs are still saved to the message list and to the files). Naturally it only applies to levels 1, 2 and 3, not 0.

BreakPoints window

Memory checks for the main RAM located at 0x80000000 to 0x817fffff and 0xC0000000 to 0xC17fffff wont work for JITed LoadStore opcodes because they don't use the Memmap.cpp functions where the memory checks are. Memory checks for the hardware registers that are located at 0xCC000000 to 0xcc008004 seems to work even if JITed opcodes update them, but they are mostly unnecessary because all changes to these registers are also picked up by LOG messages.

BPs and MCs buttons: They allow you to load breakpoints and memory checks from a GameIni/BreakPoints.ini and a GameIni/MemoryChecks.ini file. All memory check matches will result in a log message in the MI memmap log, but only selected checks will result in a break. Voluntary comments can be written after a #.

BreakPoints.ini only accept one address per row and should look like this

 802734fc # Starting address of a function
8045dc44 # Starting address of another function
...

MemoryChecks.ini accept different formatting and can look like this

 8037ffac # Only one address checked, and no break will occur
cc000000 cc000080 # A range of memory, and no break will occur
cc000000 cc000080 1 # A range of memory, and a break will occur
...

A PowerPC Primer

The GC and the Wii both have a modified PowerPC as a main CPU.

PowerPC has 32 registers. R1, also known as sp, is the stack pointer. Return addresses are first keps in LR, the link register, and are only if necessary written to the stack.

These are only some basic instructions. There are many more, of course.

PowerPC x86 Description
li MOV load immediate
blr RET "branch to link register", ie, return
b JMP branch (jump)
bl CALL branch and link (branch + put pc+4 in link register)
bne JNE branch if not equal
rlwinm ROR + AND with mask tricky :)
rfi RETI return from interrupt

Optimization

When you work on improving the framerate, work on the difficult cases, such as outdoors in Zelda. A change that improves the framerate indoors, where it's already fast enough, without having any measurable effect outdoors, is probably not worth doing if it complicates the code at all.

Thread Model

Dolphin has a choice of two thread models: "single core" and "dual core". As the name suggests, the "dual core" model is intended to spread the load over two cores on dual core machines.

The "single core" model runs the following threads:

  1. Main Thread
  2. In the GUI version of Dolphin, this thread runs wxWidgets. In the non-GUI version of Dolphin, this thread sleeps most of the time. This thread starts in the main() function of the application executable. In the GUI version, wxWidgets contains the main() though and the Dolphin code is only called through event handlers.
  3. Emu Thread
  4. This thread starts running in the EmuThread() function defined in Source/Core/Core/Src/Core.cpp, created from the Main Thread. On Windows, this thread preprocesses input events. On other platforms, it just sleeps.
  5. Audio Thread
  6. This thread is started by the audio library (libao).
  7. CPU Thread
  8. This thread starts running in the CPUThread() function defined in Source/Core/Core/Src/Core.cpp, created from the Emu Thread. It runs the emulation of all hardware: the CPU (PowerPC), the GPU (GX) and the rest.

In the "dual core" model, the video emulation is done on the Emu Thread instead of on the CPU Thread.

Not useful docs

Read this for your own fun ;)

yacgd and more http://hitmen.c02.at/html/gc_docs.html
random link http://hitmen.c02.at/files/yagcd/yagcd/chap19.html#sec19.1
Command Processor & FIFO discussions US patent 7196710


Comment by nakeee, Jan 19, 2009

It should probably be noted that you can't link Plugins to libcore.

Comment by ALIENDUDE5300, Apr 12, 2009

It may be worth mentioning that if you don't want to pay for a VMWare License, you can use VirtualBox?, which is free, and tends to run faster than VMWare.


Sign in to add a comment
Hosted by Google Code