pureikyubu/Docs/EMU/TIPS.TXT
ogamespec@gmail.com 7b3118623b
2011-06-29 14:19:07 +00:00

131 lines
5.2 KiB
Text

---------------------------------------------------------------------------
GC Emulation Tips.
---------------------------------------------------------------------------
General Emu Development
-----------------------
Any emulator development includes several stages :
Interpreter
Disassembler -> Memory Emulation -> Debugger -> and/or -> Hardware
Recompiler
Optional feature is HLE. NextGen consoles hardware emulation is often
realized, using plugin technology. There are some nice GAMECUBE plugins
with Dolwin 0.10 ;)
VI emulation tips
-----------------
VI have A LOT of different registers. You dont need to emulate them all.
Here is the list of most important :
CC002002 - for video mode (determining maximum hline value)
CC00201C - for XFB address (if homebrewn VI XFB blitting is enabled)
CC00202C - hline count
CC002030 - To handle VI retrace interrupt.
hline counter can be emulated in two ways :
1. Constantly increase it after some interval, and clear when it reach
its maximum value (depends on video mode).
2. Switch it between some fixed values to cheat game libraries wait vsync
routine. It will be faster, than previous method, but less compatible.
(You dont need counter, but games can use different hline check values).
Practically, VI is not much important to emulate. In Dolphin OS its used
mainly to reschedule active threads and to control PAD sampling rate, and
homebrewn are using it for output and for wait retrace routines. GAMECUBE
GX can be emulated without EFB->XFB copying.
Be careful : VI interrupt is cleared, when INT bit is cleared. Usually
other hardware is clearing interrupt, by setting INT bit. But not VI!
Summary : Your task in VI emulation is to make VIINT generated every
fixed GC time intervals. Approximately 30 ms of GC time. (I use GC time
term for TBR register, which count every 1/12 CPU clocks). Use your
debugger and make sure, that VIINT is generated at constantly rate.
Here is small note for VI frame timing, which may help you :
---------------------------------------------------
| | PAL | NTSC, MPAL, EURGB60 |
| value +---------------------|---------------------|
| | NIN | INT | NIN | INT |
|=======+==========+==========+==========+==========|
| hz | 50 | 25 | 60 | 30 |
|-------+----------+----------+----------+----------|
| lines | 312.5 | 625 | 262.5 | 525 |
|-------+----------+----------+----------+----------|
| active| 262 | 574 | 218 | 480 |
-------+----------+----------+----------+----------
NIN - non-intelaced (double-strike) mode (both odd and even lines in one frame)
INT - interlaced mode (odd and even lines in alternating frames)
I call all NTSC, MPAL and EURGB60 modes, as "NTSC-Like" in emu.
FP FPSCR
--------
Emulating of FPSCR-register is unecessary. The only one interesting field
is RN (rounding control). Affecting of rounding control on emulation
run-flow is unknown.
Note : At least zelda works fine without it.
Fast FP context switching
-------------------------
GCN OS have optimized FP context switching. It doesnt saves FPU context
each time, after exception or interrupt occurs. It switches FP context
only when it was changed. This is possible with using of floating point
exception (vector is 0x800).
So, to avoid context bugs, when using multi-threaded applications, you
should raise floating point exception, every time, after changing of FPR
or PS registers (simply after every floating-point instruction).
MSR bits
--------
Here is the list of important MSR bits :
MSR[EE] - This one is used to mask external interrupts and decrementer
exception. Emulator must check this bit, before rasing interrupt, or
when decrementer reaching zero value, as example :
if(--DEC == 0)
{
if(MSR & 0x8000) // EE bit mask
{
CPUException(DECREMENTER_INTERRUPT);
}
}
MSR[RI] - Always set this bit after any exception! If this bit will be
cleared, OS halts as unexpected exception.
MSR[FP] - See in previous tip.
MSR[DR] and MSR[IR] can be optionally used for MMU emulation.
Other bits shouldn't be used :)
Exceptions
----------
List of most important exceptions for correct emulation :
0x500 External Interrupt. Very important :)
0x800 Floating-point unavailable. For correct OS context switching.
0x900 Decrementer. Used by OS alarm objects.
0xC00 Optionally. You can fake system call opcode, and dont use it.
But GC-Linux is using it, so you cant ignore it for homebrewn.
---------------------------------------------------------------------------
This document is maintaining by Dolwin team.
Last edited by org, 5 Nov 2004