mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
131 lines
5.2 KiB
Text
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
|