Go Back   Project64 Forums > General Discussion > Open Discussion

Reply
 
Thread Tools Display Modes
  #271  
Old 22nd May 2013, 08:25 PM
shunyuan's Avatar
shunyuan shunyuan is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Apr 2013
Posts: 491
Default

Quote:
Originally Posted by FatCat View Post
Bah, I thought I finished removing the files.
The binaries should be in this thread, not my Git repo.


In the meantime, while you are trying to find internal problems with my RSP emulator, I would advise against using rsp_mle.dll; the only thing to test about that file is to see if an error comes up saying a game tried to use DPC_STATUS_FREEZE, which for some reason zilmar always clears before doing gfx tasks in HLE from the video plugin which is what we're trying to find out why and where it gets used.

But just plain rsp.dll should be enough.
The more things that are HLE'd, the less likely a crash will happen internally within my RSP emulator, and not somebody else's plugin, so just test rsp.dll in those cases.

Now, the GNU build is rsp.dll.
The Microsoft Visual Studio build, compiled as C++, is rsp_free.dll and has no dependencies whatsoever (not even user32.dll/kernel32.dll).

I would suggest comparing between those.
Actually I am not trying to find bugs in your RSP, but try to use your rsp plugin to debug my audio plugin, since your RSP is more accurate.

But the results of Pilotwings 64 and Killer Instinct Gold are weird, and I guess I need to stick on your mingw build.
__________________
---------------------
CPU: Intel U7300 1.3 GHz
GPU: Mobile Intel 4 Series (on board)
AUDIO: Realtek HD Audio (on board)
RAM: 4 GB
OS: Windows 7 - 32 bit
Reply With Quote
  #272  
Old 22nd May 2013, 08:34 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,236
Default

It is also possible that compiler prediction theory has played its part.

You may be using the default "Recompiler" setting of Mupen64 CPU.
If you change this to "Interpreter" there is less unpredictable variation.

So sometimes with a recompiler, a game sends to the CPU to send faulty SP DMA requests to the RSP which will crash an accurate RSP, whereas othertimes, the recompiler does not crash it.

With the interpreter you can debug problems with the CPU that are giving the RSP problems.

With some fundamental exceptions (re-ordered vector WB stage phases, vector divide ROM proper lookup, rather than CRT-dependent calculation) my RSP is only more accurate in zilmar's mostly in the sense just that it takes more advantage of hardware properties similar enough to those of the N64, to send multiple datum contiguously at once, as long as this is possible.
Whereas zilmar's RSP was written only to be very stable and maintainable, not either fast or really accurate. It does things in pure software, byte-iterated reads and writes for example which is much more stable, but not necessarily as accurate.

The Microsoft build crashes but not the MinGW built?
What can I say, it's Microsoft.

I thought once that Microsoft Visual Studio fixed a linker crash I was having with the GNU linker.
It turned out, that my PARALLELIZE_VECTOR_TRANSFERS macro, was causing GCC to generate SSSE3 vector AND/OR/XOR instructions equivalent to the N64 RSP's vector instructions, doing all the writes in parallel, and my hardware does not support those things so that's why GCC build was crashing on my machine but not MS build.

So unintentionally yes, I did add SSSE3 support in my plugin, switched by the macro.
It just doesn't exist in any of the precompiled binaries released here.
I think it did vector ADD/SUB in SSSE3 too or something.

tl;dr, back to RDP
Reply With Quote
  #273  
Old 23rd May 2013, 03:06 PM
Whitelink111 Whitelink111 is offline
Junior Member
 
Join Date: May 2013
Posts: 1
Exclamation Need to know

WHat is the best rsp plugin out there ?


at the same time what an rsp plugin actually really does.



i find code source but how can i make a plugin out of that.

Reply With Quote
  #274  
Old 23rd May 2013, 03:27 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,236
Default

Quote:
Originally Posted by Whitelink111 View Post
WHat is the best rsp plugin out there ?
The one your mom uses at night.

Quote:
Originally Posted by Whitelink111 View Post
at the same time what an rsp plugin actually really does.
Plugs inside things.

Quote:
Originally Posted by Whitelink111 View Post
i find code source but how can i make a plugin out of that.
Not being white always helps.

Quote:
Originally Posted by Whitelink111 View Post
code source get built into plugin by compiler

compiler go do things, optimize many things

turn into dll

Usually best RSP plugin is mine, but can sacrifice some accuracy for speed in the Project64 recompiler RSP around half of the time.
Reply With Quote
  #275  
Old 23rd May 2013, 06:39 PM
shunyuan's Avatar
shunyuan shunyuan is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Apr 2013
Posts: 491
Default

some questions about RSP semaphore register:

(1) after rsp plugin internal set semaphore on and return to emu to let emu retask, what should emu do at this time?
(2) can you give an example for emu retask?
(3) if I want add very basic SP semaphore simulation, to let other emulators such as mupen64 can run World Driver Championship with LLE rsp, what should I do?


Code:
void MFC0(int rt, int rd)
{
        .....
		
        case 0x7:
            SR[rt] = *RSP.SP_SEMAPHORE_REG;
            *RSP.SP_SEMAPHORE_REG = 0x00000001;
            *RSP.SP_STATUS_REG |= 0x00000001; /* temporary bit to break CPU */
            return; /* Break the SP task (zilmar). */

		....
}
I try to trace the code of pj64, but it is not easy to understand, because all mechanisms are working on CPU core emulation.
__________________
---------------------
CPU: Intel U7300 1.3 GHz
GPU: Mobile Intel 4 Series (on board)
AUDIO: Realtek HD Audio (on board)
RAM: 4 GB
OS: Windows 7 - 32 bit

Last edited by shunyuan; 23rd May 2013 at 06:42 PM.
Reply With Quote
  #276  
Old 23rd May 2013, 07:17 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,236
Default

I don't administrate to the sources of Project64.
I have only had a good look at parts of the core source maybe once or twice.

But, so as to attempt to answer your question, I just had another look.
I'm quickly finding that part of your answer may be in CN64System::RunRSP under $project64/Source/Project64/N64 System/N64 Class.cpp. Here you will find what seems to be most of the thread management code for the RSP in the emu.

It is likely that zilmar made revisions there to get it to sync better by knowing when to restart the SP task under certain conditional requests of the RSP plugin system hacks, but I don't understand the C++ language templating to describe exactly how that is so.

Quote:
Originally Posted by suanyuan View Post
(3) if I want add very basic SP semaphore simulation, to let other emulators such as mupen64 can run World Driver Championship with LLE rsp, what should I do?
The CPU-RSP semaphore is not entirely related to the problems with World Driver Championship.
Correct emulation of SP_SEMAPHORE_REG generally fixes accurate audio and the graphics task for Mario no Photopie, Banjo-Tooie boot, maybe some other things.

The real reason behind the problems with Gauntlet Legends, Stunt Racer 64, and World Driver Championship is the external semaphore synchronization bits stored in the SP status register.
The most common, problematic CPU-RSP sync status flag is SP_STATUS_SIG0.
When the SP task was run the first time the CPU did not update this signal to be present yet.
When it is run a second time the up-to-date, synchronized information from the CPU core will have been set by then.

For more details regarding this, see instead my `$rsp/su/cop0/mfc0.h`:
Code:
        case 0x4:
            SR[rt] = *RSP.SP_STATUS_REG;
#ifdef WAIT_FOR_CPU_HOST
            ++MFC0_count[rt];
            if (MFC0_count[rt] > 07)
                *RSP.SP_STATUS_REG |= 0x00000001; /* Let OS restart the task. */
#endif
            return;
Reply With Quote
  #277  
Old 23rd May 2013, 07:24 PM
shunyuan's Avatar
shunyuan shunyuan is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Apr 2013
Posts: 491
Default

Quote:
Originally Posted by FatCat View Post
I don't administrate to the sources of Project64.
I have only had a good look at parts of the core source maybe once or twice.

But, so as to attempt to answer your question, I just had another look.
I'm quickly finding that part of your answer may be in CN64System::RunRSP under $project64/Source/Project64/N64 System/N64 Class.cpp. Here you will find what seems to be most of the thread management code for the RSP in the emu.

It is likely that zilmar made revisions there to get it to sync better by knowing when to restart the SP task under certain conditional requests of the RSP plugin system hacks, but I don't understand the C++ language templating to describe exactly how that is so.



The CPU-RSP semaphore is not entirely related to the problems with World Driver Championship.
Correct emulation of SP_SEMAPHORE_REG generally fixes accurate audio and the graphics task for Mario no Photopie, Banjo-Tooie boot, maybe some other things.

The real reason behind the problems with Gauntlet Legends, Stunt Racer 64, and World Driver Championship is the external semaphore synchronization bits stored in the SP status register.
The most common, problematic CPU-RSP sync status flag is SP_STATUS_SIG0.
When the SP task was run the first time the CPU did not update this signal to be present yet.
When it is run a second time the up-to-date, synchronized information from the CPU core will have been set by then.

For more details regarding this, see instead my `$rsp/su/cop0/mfc0.h`:
Code:
        case 0x4:
            SR[rt] = *RSP.SP_STATUS_REG;
#ifdef WAIT_FOR_CPU_HOST
            ++MFC0_count[rt];
            if (MFC0_count[rt] > 07)
                *RSP.SP_STATUS_REG |= 0x00000001; /* Let OS restart the task. */
#endif
            return;
Thanks, got it.
__________________
---------------------
CPU: Intel U7300 1.3 GHz
GPU: Mobile Intel 4 Series (on board)
AUDIO: Realtek HD Audio (on board)
RAM: 4 GB
OS: Windows 7 - 32 bit
Reply With Quote
  #278  
Old 23rd May 2013, 09:35 PM
shunyuan's Avatar
shunyuan shunyuan is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Apr 2013
Posts: 491
Default

Code:
void run_task(void)
{
	.......
	
	
    while (SR[0] != SR[0])
    {
BRANCH:
        inst = *(unsigned int *)(RSP.IMEM + *RSP.SP_PC_REG);
#ifdef SP_EXECUTE_LOG
        step_SP_commands(inst);
#endif
        *RSP.SP_PC_REG = temp_PC & 0x00000FFC;
        /* temp_PC = 0x00000000 ^ 0xFFFFFFFF; */
        goto EX;
    }
}
I don't understand this line of code.

Doesn't SR[0] != SR[0] always return false?
__________________
---------------------
CPU: Intel U7300 1.3 GHz
GPU: Mobile Intel 4 Series (on board)
AUDIO: Realtek HD Audio (on board)
RAM: 4 GB
OS: Windows 7 - 32 bit
Reply With Quote
  #279  
Old 23rd May 2013, 09:40 PM
HatCat's Avatar
HatCat HatCat is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Feb 2007
Location: In my hat.
Posts: 16,236
Default

Quote:
Originally Posted by suanyuan View Post
Code:
void run_task(void)
{
	.......
	
	
    while (SR[0] != SR[0])
    {
BRANCH:
        inst = *(unsigned int *)(RSP.IMEM + *RSP.SP_PC_REG);
#ifdef SP_EXECUTE_LOG
        step_SP_commands(inst);
#endif
        *RSP.SP_PC_REG = temp_PC & 0x00000FFC;
        /* temp_PC = 0x00000000 ^ 0xFFFFFFFF; */
        goto EX;
    }
}
I don't understand this line of code.

Doesn't SR[0] != SR[0] always return false?
It's supposed to be unreachable code to the rest of the program, except by means of using the `goto` keyword in C to branch to that isolated code block.

It was meant to be a workaround for some of the compilers that set up the if-else branch prediction frame disadvantageously to the emulator speed.
Reply With Quote
  #280  
Old 24th May 2013, 08:29 AM
shunyuan's Avatar
shunyuan shunyuan is offline
Alpha Tester
Project Supporter
Senior Member
 
Join Date: Apr 2013
Posts: 491
Default

One question about WAIT_FOR_CPU_HOST:


Code:
void run_task(void)
{
	.....
	
    if (*RSP.SP_SEMAPHORE_REG == 0x00000001) /* SP semaphore lock (zilmar) */
        *RSP.SP_STATUS_REG &= ~0x00000001; /* Guess I need to let emu retask. */
#ifdef WAIT_FOR_CPU_HOST
    else if (MFC0_count != 0)
        *RSP.SP_STATUS_REG &= ~0x00000001; /* CPU restarts with correct SIGs. */
#endif
    else
    {
        message("Halted RSP CPU loop by means of MTC0.", 2); /* not sure */
        *RSP.MI_INTR_REG |= 0x00000001; /* VR4300 SP interrupt */
        RSP.CheckInterrupts();
    }

    .....
}
Is this line of code correct?

Since MFC0_count is an integer array, then the code "else if (MFC0_count != 0)" will always compare the address of MFC0_count to zero.

Code:
#ifdef WAIT_FOR_CPU_HOST
static int MFC0_count[32];
/* Keep one C0 MF status read count for each scalar register. */
#endif
Shouldn't the code to be

Code:
void run_task(void)
{
	.....
	
    if (*RSP.SP_SEMAPHORE_REG == 0x00000001) /* SP semaphore lock (zilmar) */
        *RSP.SP_STATUS_REG &= ~0x00000001; /* Guess I need to let emu retask. */
#ifdef WAIT_FOR_CPU_HOST
    else if (MFC0_count[rt] != 0)
        *RSP.SP_STATUS_REG &= ~0x00000001; /* CPU restarts with correct SIGs. */
#endif
    else
    {
        message("Halted RSP CPU loop by means of MTC0.", 2); /* not sure */
        *RSP.MI_INTR_REG |= 0x00000001; /* VR4300 SP interrupt */
        RSP.CheckInterrupts();
    }

    .....
}
or

Code:
void run_task(void)
{
	.....
	
    if (*RSP.SP_SEMAPHORE_REG == 0x00000001) /* SP semaphore lock (zilmar) */
        *RSP.SP_STATUS_REG &= ~0x00000001; /* Guess I need to let emu retask. */
#ifdef WAIT_FOR_CPU_HOST
    else if (MFC0_count[0] != 0 || ...... || MFC0_count[31] != 0)
        *RSP.SP_STATUS_REG &= ~0x00000001; /* CPU restarts with correct SIGs. */
#endif
    else
    {
        message("Halted RSP CPU loop by means of MTC0.", 2); /* not sure */
        *RSP.MI_INTR_REG |= 0x00000001; /* VR4300 SP interrupt */
        RSP.CheckInterrupts();
    }

    .....
}

And Top Gear Rally (USA) (one of Boss Stuido games) will get stuck in the loop of wait for cpu host (tested with rsp_pj64.dll mingw build without any modification).
__________________
---------------------
CPU: Intel U7300 1.3 GHz
GPU: Mobile Intel 4 Series (on board)
AUDIO: Realtek HD Audio (on board)
RAM: 4 GB
OS: Windows 7 - 32 bit

Last edited by shunyuan; 24th May 2013 at 10:37 AM.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT. The time now is 08:30 PM.


Powered by vBulletin® Version 3.7.3
Copyright ©2000 - 2023, Jelsoft Enterprises Ltd.