SuperSaiyanWolverine / mupen64plus

Automatically exported from code.google.com/p/mupen64plus
0 stars 0 forks source link

more CPU<>RSP synchronization #311

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
i was just browsing and found this 
http://www.emuxhaven.net/forums/showpost.php?p=81932&postcount=35

I found a way to boot Gauntlet Legends with LLE, using a hack. Just like
World Driver Championship, this game requires more CPU<>RSP synchronization
than the Zilmar's RSP spec and current emulators allow. Like WDC, Gauntlet
Legends also enters an endless loop of RSP opcodes waiting for the CPU to
set the "signal 0" bit. So the hack I applied to WDC may also be applied to
Gauntlet Legends.  

and
http://www.emuxhaven.net/forums/showpost.php?p=81948&postcount=37

It shouldn't break anything, if done properly. Maybe it will even fix
Vigilante 8 - 2nd Offense, which hangs at the main menu with all LLE
implementations (except maybe unreleased Xe emulator). My theory is that
Vigilante 8 - 2nd Offense also needs tighter CPU<>RSP synchronization.
To add support for a new extension, we need a "state machine" approach. So,
CPU execution loops should be amended. This will make modified emus
incompatible with every other RSP plugin, unless we force emus to behave
differently depending on a selected RSP plugin.
Overall it's not impossible but I'm not going to work on this right now. 

Original issue reported on code.google.com by vitbur...@gmail.com on 6 Jan 2010 at 5:04

GoogleCodeExporter commented 9 years ago
I'll take a look at this before the 2.0 release.  If we're going to change the 
API,
now is the time to do it.

Original comment by richard...@gmail.com on 14 Jan 2010 at 5:38

GoogleCodeExporter commented 9 years ago
Angrylion doesn't give enough details in his forum posts or link to any code 
which
documents his proposed changes.  The screenshot appears to show PJ64, which is a
"closed source" emulator, so any changes that he made to this emulator are
essentially lost to the rest of the world.

Original comment by richard...@gmail.com on 2 Feb 2010 at 3:24

GoogleCodeExporter commented 9 years ago
I haven't made any changes into PJ64. Instead I added a hack to the LLE RSP 
plugin 
that compensates for the lack of RSP<>CPU synchronization. The details of the 
hack 
can be found in the source code I posted a year ago:
http://emutalk.net/showpost.php?p=416237&postcount=390
, namely in rsp_execute() function.
What details do you need? As to granularity of synchronization, I think even a 
very 
coarse approach will do the thing for the 3 games that are known to need this: 
WDC, 
Stunt Racer 64, Gauntlet Legends (Vigilante 2, btw, had nothing to do with 
synchronization, as I discovered some time ago). An emulator executes 1000 CPU 
instructions and then orders an RSP plugin to execute 1000 RSP instructions if 
the 
RSP is running. In fact, DoRSPCycles() function from Zilmar's spec is described 
as 
if it supports synchronization. The problem is, no emulator and no low-level 
RSP 
plugin is programmed this way.  

Original comment by angryl...@bk.ru on 3 Feb 2010 at 10:28

GoogleCodeExporter commented 9 years ago
Angrylion, thanks for the explanation and link to the code.  I looked at the 
code
last night and now I see what you're asking for.  I'll take some time to do some
experiments and see if I can make this work.  I'll have to update the RSP 
plugin API
to support 2 different functions: one for HLE plugins to just process an 
AList/DList,
and another for LLE plugins to execute a given number of RSP cycles.

I'm not convinced that this will actually work though.  In particular I think 
there
might be problems with the synchronization between the RSP and CPU, which is 
handled
with some status bits in the mi_intr_reg and sp_status_reg.  Currently the core
resets these bits after calling the DoRspCycles, expecting that the AList/DList 
was
processed and finished.  After adding an 'LLE' RSP interface, the core cannot 
reset
these bits and the emulated RSP must do this itself, which it may not (because 
it
never had to do this with the old API).  If you have any thoughts on this, 
please let
me know.

Anyway I'll do some experiments before the 2.0 release (which is coming very 
soon)
and see if I can make this work.

Original comment by richard...@gmail.com on 4 Feb 2010 at 3:39

GoogleCodeExporter commented 9 years ago
The low-level RSP plugin that I posted reads and writes to these bits, although 
it's 
possible that there are errors in my implementation. Here's a newer version of 
the 
plugin btw:
http://slil.ru/28598303 
It's true that things like
sp_register.sp_status_reg &= ~0x303; //memory.c, 1375
aren't very suitable for custom microcode games. Docs say that microcode 
authors may 
use any "signal bits" of sp_status_reg for any synchronization model. Also, in 
my 
opinion, "broke" and "halt" bits are set after the RSP has stopped running by 
the 
RSP itself, not cleared. It's the CPU that clears these bits later if it wants 
to re-
launch the RSP.
I also don't think that PJ64 does anything arbitrary with sp_status_reg like 
you do 
(see cpu.c, memory.c, PJ64 1.4 sources). Or maybe I missed something.

Original comment by angryl...@bk.ru on 4 Feb 2010 at 11:48

GoogleCodeExporter commented 9 years ago
Okay, I wrote an LLE interface into the core and tested it against wahrhaft's 
Z64
plugin but couldn't make it work right.  There is a lot of flickering and 
missing
polygons.  I played the games you mentioned as needing tighter RSP<-->CPU
synchronization and they still didn't boot.  But they didn't boot with the 
unmodified
Z64 plugin either, so maybe this is a different problem.  If someone else who's 
more
familiar with the N64 system operation can take a look at this implementation, 
maybe
you'll be able to make it work.  I have attached the diffs of my changes 
against the
Hg source code of the core and Z64 RSP plugins.

Original comment by richard...@gmail.com on 13 Feb 2010 at 4:42

Attachments: