[pspplayer commit] r588 - in trunk: Noxa.Emulation.Psp.Cpu.R4000Ultra Noxa.Emulation.Psp.Player Noxa.Emulation.Psp.V...

0 views
Skip to first unread message

codesite...@google.com

unread,
Mar 23, 2008, 11:50:12 PM3/23/08
to psppla...@googlegroups.com
Author: ben.vanik
Date: Sun Mar 23 20:49:40 2008
New Revision: 588

Removed:
trunk/Noxa.Emulation.Psp.Player/Player.Glass.cs
Modified:
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Controller.cpp
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Interrupts.cpp
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_NativeInterface.cpp
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Threading.cpp
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Ctx.h
trunk/Noxa.Emulation.Psp.Player/Noxa.Emulation.Psp.Player.csproj
trunk/Noxa.Emulation.Psp.Player/Player.Designer.cs
trunk/Noxa.Emulation.Psp.Player/Player.cs
trunk/Noxa.Emulation.Psp.Video.ManagedGL/MGLDriver.Worker.cs
trunk/Noxa.Utilities/FastLinkedList.cs

Log:
Fixed a MAJOR bug in the linked list stuff - was causing hangs
Removed glass status bar from player, as it's not really needed and
wasted resources
Now support multiple pending marshal requests (was happening more and
more due to new GE callbacks and such)
StopFlags in CPU context is now used as a flag value, allowing multiple
pending operations (context switch, interrupts, marshals, etc) - not
perfect, but it seems to work

PB works perfectly and yuusha runs to where it did before
EEE is fubar - if the GE interrupt is enabled, it dies on an invalid
memory access

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Controller.cpp
==============================================================================
--- trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Controller.cpp (original)
+++ trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Controller.cpp Sun Mar
23 20:49:40 2008
@@ -465,7 +465,11 @@
byte* start = FindInstructionStart( block, breakpoint->Address, &size );

// Write break jump bytes (see __debugThunk for more info)
- Debug::Assert( start[ 0 ] == 0x90 );
+ if( start[ 0 ] != 0x90 )
+ {
+ Debug::WriteLine( String::Format( "R4000Controller::SetBreakpoint:
breakpoint already set at {0:X8} (attempted bpid {1})",
breakpoint->Address, breakpoint->ID ) );
+ return;
+ }
start[ 0 ] = 0x68;
*( ( int* )( &start[ 1 ] ) ) = breakpoint->ID;
start[ 5 ] = 0xB8;

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Interrupts.cpp
==============================================================================
--- trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Interrupts.cpp (original)
+++ trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Interrupts.cpp Sun
Mar 23 20:49:40 2008
@@ -46,7 +46,9 @@

void PerformInterrupt()
{
- assert( _inIntHandler == false );
+ // Note that we are NOT reentrant - if we get back here somehow, just
ignore the interrupt
+ if( _inIntHandler == true )
+ return;
_inIntHandler = true;
for( int n = 0; n < INTERRUPT_COUNT; n++ )
{
@@ -91,7 +93,7 @@
if( ( value & _pendingInterrupts ) != 0 )
{
// Handle pending interrupts
- _cpuCtx->StopFlag = CtxInterruptPending;
+ _cpuCtx->StopFlag |= CtxInterruptPending;
}
}

@@ -123,5 +125,5 @@
{
_pendingInterrupts |= ( 1 << interruptNumber );
if( _inIntHandler == false )
- _cpuCtx->StopFlag = CtxInterruptPending;
+ _cpuCtx->StopFlag |= CtxInterruptPending;
}

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_NativeInterface.cpp
==============================================================================
---
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_NativeInterface.cpp (original)
+++
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_NativeInterface.cpp
Sun Mar 23 20:49:40 2008
@@ -46,7 +46,7 @@
if( ( newState & _pendingInterrupts ) != 0 )
{
// Handle pending interrupts
- _cpuCtx->StopFlag = CtxInterruptPending;
+ _cpuCtx->StopFlag |= CtxInterruptPending;
}

return old;
@@ -56,7 +56,7 @@
{
_pendingInterrupts |= ( 1 << intNumber );
if( _inIntHandler == false )
- _cpuCtx->StopFlag = CtxInterruptPending;
+ _cpuCtx->StopFlag |= CtxInterruptPending;
}

void niResume()

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Threading.cpp
==============================================================================
--- trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Threading.cpp (original)
+++ trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Threading.cpp Sun
Mar 23 20:49:40 2008
@@ -88,6 +88,7 @@
ThreadContext* _currentTcs;

SwitchRequest _switchRequest;
+LL<SwitchRequest*> _marshalRequests;

// From interrupts file
void PerformInterrupt();
@@ -225,7 +226,7 @@
_switchRequest.MakeCall = false;

// Put the request in
- _cpuCtx->StopFlag = CtxContextSwitch;
+ _cpuCtx->StopFlag |= CtxContextSwitch;
}

void R4000Cpu::MarshalCall( int tcsId, uint address, array<uint>^
arguments, MarshalCompleteDelegate^ resultCallback, int state )
@@ -245,32 +246,29 @@
ThreadContext* targetContext = ( ThreadContext* )_threadContexts[
tcsId ].ToPointer();
UNLOCK;

- // Don't support more than one at a time right now
- Debug::Assert( _switchRequest.MakeCall == false );
- if( _switchRequest.MakeCall == true )
- {
- Log::WriteLine( Verbosity::Critical, Feature::Cpu, "MarshalCall:
attempted to marshal a call while one was already pending - THIS NEEDS
TO BE FIXED" );
- return;
- }
-
+ SwitchRequest* marshalRequest = new SwitchRequest();
+
// Marshal context setup
- _switchRequest.Previous = _currentTcs;
- _switchRequest.PreviousID = _currentTcsId;
- _switchRequest.Target = targetContext;
- _switchRequest.TargetID = tcsId;
+ marshalRequest->Previous = _currentTcs;
+ marshalRequest->PreviousID = _currentTcsId;
+ marshalRequest->Target = targetContext;
+ marshalRequest->TargetID = tcsId;

- _switchRequest.MakeCall = true;
- _switchRequest.CallAddress = address;
- _switchRequest.CallArgumentCount = arguments->Length;
+ marshalRequest->MakeCall = true;
+ marshalRequest->CallAddress = address;
+ marshalRequest->CallArgumentCount = arguments->Length;
for( int n = 0; n < arguments->Length; n++ )
- _switchRequest.CallArguments[ n ] = arguments[ n ];
+ marshalRequest->CallArguments[ n ] = arguments[ n ];

- _switchRequest.ResultCallbackValid = ( resultCallback != nullptr );
- ( *_switchRequest.ResultCallback ) = resultCallback;
- _switchRequest.CallbackState = state;
+ marshalRequest->ResultCallbackValid = ( resultCallback != nullptr );
+ marshalRequest->ResultCallback = new gcref<MarshalCompleteDelegate^>();
+ ( *marshalRequest->ResultCallback ) = resultCallback;
+ marshalRequest->CallbackState = state;
+
+ _marshalRequests.Enqueue( marshalRequest );

// Put the request in
- _cpuCtx->StopFlag = CtxMarshal;
+ _cpuCtx->StopFlag |= CtxMarshal;
}

CodeBlock* BuildBlock( int pc )
@@ -292,10 +290,10 @@
}
}

-bool MakeResultCallback( int v0 )
+bool MakeResultCallback( SwitchRequest* marshalRequest, int v0 )
{
- MarshalCompleteDelegate^ del = ( *_switchRequest.ResultCallback );
- return del( _currentTcsId, _switchRequest.CallbackState, v0 );
+ MarshalCompleteDelegate^ del = ( *marshalRequest->ResultCallback );
+ return del( _currentTcsId, marshalRequest->CallbackState, v0 );
}

#pragma unmanaged
@@ -313,37 +311,47 @@
memcpy( _cpuCtx, ctxCopy, sizeof( R4000Ctx ) );
SAFEDELETE( ctxCopy );

- _cpuCtx->StopFlag = CtxContinue;
+ //_cpuCtx->StopFlag = CtxContinue;
}

-void PerformSwitch()
+void PerformSwitch( SwitchRequest* request )
{
- assert( _switchRequest.Target != NULL );
+ //assert( request->Target != NULL );
+ if( request->Target == NULL )
+ {
+ // Bad?
+ return;
+ }

// Save old context
if( _currentTcs != NULL )
{
memcpy( &_currentTcs->Ctx, _cpuCtx, sizeof( R4000Ctx ) );
- _currentTcs->Ctx.StopFlag = CtxContinue;
+ //_currentTcs->Ctx.StopFlag = CtxContinue;
}
int oldIntMask = _cpuCtx->InterruptMask;

// Switch to new context
- _currentTcsId = _switchRequest.TargetID;
- _currentTcs = _switchRequest.Target;
+ _currentTcsId = request->TargetID;
+ _currentTcs = request->Target;

// Restore new context
memcpy( _cpuCtx, &_currentTcs->Ctx, sizeof( R4000Ctx ) );
_cpuCtx->InterruptMask = oldIntMask;

// Clear so that we can't switch badly
- _switchRequest.Target = NULL;
- _switchRequest.TargetID = -1;
+ request->Target = NULL;
+ request->TargetID = -1;
}

-void PerformSwitchBack( SwitchType type )
+void PerformSwitch()
{
- assert( _switchRequest.Previous != NULL );
+ PerformSwitch( &_switchRequest );
+}
+
+void PerformSwitchBack( SwitchRequest* request, SwitchType type )
+{
+ assert( request->Previous != NULL );

// Save new context
if( type == SwitchMinimal )
@@ -359,22 +367,27 @@
// Copy everything (normal case)
memcpy( &_currentTcs->Ctx, _cpuCtx, sizeof( R4000Ctx ) );
}
- _currentTcs->Ctx.StopFlag = CtxContinue;
+ _currentTcs->Ctx.StopFlag |= CtxContinue;

int oldIntMask = _cpuCtx->InterruptMask;

// Switch back to old context
- _currentTcsId = _switchRequest.PreviousID;
- _currentTcs = _switchRequest.Previous;
+ _currentTcsId = request->PreviousID;
+ _currentTcs = request->Previous;

// Restore old context
memcpy( _cpuCtx, &_currentTcs->Ctx, sizeof( R4000Ctx ) );
_cpuCtx->InterruptMask = oldIntMask;

// Clear for safety
- _switchRequest.Previous = NULL;
- _switchRequest.PreviousID = -1;
- _switchRequest.MakeCall = false;
+ request->Previous = NULL;
+ request->PreviousID = -1;
+ request->MakeCall = false;
+}
+
+void PerformSwitchBack( SwitchType type )
+{
+ PerformSwitchBack( &_switchRequest, type );
}

#ifdef DEBUGBOUNCE
@@ -395,32 +408,39 @@
uint NativeExecute( bool* breakFlag )
{
// If we came in with a switch flag, it's possible we are the first run
- if( _cpuCtx->StopFlag == CtxContextSwitch )
+ if( ( _cpuCtx->StopFlag & CtxContextSwitch ) == CtxContextSwitch )
+ {
PerformSwitch();
- _cpuCtx->StopFlag = CtxContinue;
+ _cpuCtx->StopFlag &= ~CtxContextSwitch;
+ }

// Check for callback end
if( _cpuCtx->PC == CALL_RETURN_DUMMY )
{
+ SwitchRequest* marshalRequest = _marshalRequests.Dequeue();
+
int v0 = _cpuCtx->Registers[ 2 ];
//int v1 = _cpuCtx->Registers[ 3 ];
PopState();

// Switch state back
if( _currentTcs->MarshalSwitchback == true )
- PerformSwitchBack( SwitchNormal );
+ PerformSwitchBack( marshalRequest, SwitchNormal );

// Make callback
- _switchRequest.MakeCall = false;
- if( _switchRequest.ResultCallbackValid == true )
+ if( marshalRequest->ResultCallbackValid == true )
{
- bool exitEarly = MakeResultCallback( v0 );
+ bool exitEarly = MakeResultCallback( marshalRequest, v0 );
if( exitEarly == true )
{
*breakFlag = false;
+ SAFEDELETE( marshalRequest->ResultCallback );
+ delete marshalRequest;
return 0;
}
}
+ SAFEDELETE( marshalRequest->ResultCallback );
+ delete marshalRequest;
}
else if( _cpuCtx->PC == BIOS_SAFETY_DUMMY )
{
@@ -482,45 +502,52 @@
#endif

// See what we need to do now
- CtxStopFlags stopFlag = _cpuCtx->StopFlag;
- _cpuCtx->StopFlag = CtxContinue;
- if( stopFlag != CtxContinue )
+ while( _cpuCtx->StopFlag != CtxContinue )
{
- switch( stopFlag )
+ if( ( _cpuCtx->StopFlag & CtxBreakRequest ) == CtxBreakRequest )
{
- case CtxBreakRequest:
+ _cpuCtx->StopFlag &= ~CtxBreakRequest;
// This happens when the BIOS requests a break
// Not sure when this happens, really ^_^
*breakFlag = true;
- break;
- case CtxContextSwitch:
- // Means that a context switch is pending and we should do it and continue
- PerformSwitch();
- break;
- case CtxMarshal:
+ }
+ else if( ( _cpuCtx->StopFlag & CtxMarshal ) == CtxMarshal )
+ {
+ _cpuCtx->StopFlag &= ~CtxMarshal;
// We need to marshal a callback on to another thread and then handle
// what happens when it ends
- assert( _switchRequest.MakeCall == true );
- _currentTcs->MarshalSwitchback = ( _currentTcsId !=
_switchRequest.TargetID );
+ SwitchRequest* marshalRequest = _marshalRequests.PeekHead();
+ assert( marshalRequest->MakeCall == true );
+ _currentTcs->MarshalSwitchback = ( _currentTcsId !=
marshalRequest->TargetID );
if( _currentTcs->MarshalSwitchback == true )
- PerformSwitch();
+ PerformSwitch( marshalRequest );
PushState();
- _cpuCtx->PC = _switchRequest.CallAddress;
- for( int n = 0; n < _switchRequest.CallArgumentCount; n++ )
- _cpuCtx->Registers[ n + 4 ] = _switchRequest.CallArguments[ n ];
+ _cpuCtx->PC = marshalRequest->CallAddress;
+ for( int n = 0; n < marshalRequest->CallArgumentCount; n++ )
+ _cpuCtx->Registers[ n + 4 ] = marshalRequest->CallArguments[ n ];
_cpuCtx->Registers[ 31 ] = CALL_RETURN_DUMMY;
goto executeStart;
- case CtxInterruptPending:
+ }
+ else if( ( _cpuCtx->StopFlag & CtxContextSwitch ) ==
CtxContextSwitch )
+ {
+ _cpuCtx->StopFlag &= ~CtxContextSwitch;
+ // Means that a context switch is pending and we should do it and continue
+ PerformSwitch();
+ }
+ else if( ( _cpuCtx->StopFlag & CtxInterruptPending ) ==
CtxInterruptPending )
+ {
+ _cpuCtx->StopFlag &= ~CtxInterruptPending;
// An interrupt is pending and we need to redirect to the handler
PerformInterrupt();
- break;
- case CtxBreakAndWait:
+ }
+ else if( ( _cpuCtx->StopFlag & CtxBreakAndWait ) == CtxBreakAndWait )
+ {
+ _cpuCtx->StopFlag &= ~CtxBreakAndWait;
// BreakAndWait request
WaitForSingleObject( _waitHandle, INFINITE );
- break;
}
}
-
+
return instructionCount;
}

@@ -540,8 +567,7 @@
// Don't overwrite a marshal and stuff
if( _cpuCtx == NULL )
return;
- if( _cpuCtx->StopFlag == CtxContinue )
- _cpuCtx->StopFlag = CtxBreakRequest;
+ _cpuCtx->StopFlag |= CtxBreakRequest;
}

void R4000Cpu::Resume()
@@ -576,7 +602,7 @@

_resumeCallback = nullptr;

- _cpuCtx->StopFlag = CtxBreakAndWait;
+ _cpuCtx->StopFlag |= CtxBreakAndWait;
}

void R4000Cpu::BreakAndWait( int timeoutMs )
@@ -600,7 +626,7 @@
_timerQueue->CreateOneShotTimer( cb, timeoutMs,
TimerExecutionContext::TimerThread, false );
}

- _cpuCtx->StopFlag = CtxBreakAndWait;
+ _cpuCtx->StopFlag |= CtxBreakAndWait;
}

void R4000Cpu::Stop()

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Ctx.h
==============================================================================
--- trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Ctx.h (original)
+++ trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Ctx.h Sun Mar 23
20:49:40 2008
@@ -51,17 +51,17 @@
enum CtxStopFlags
{
// Continue execution (no stop)
- CtxContinue = 0,
+ CtxContinue = 0x00,
// BIOS requested a break
- CtxBreakRequest = 1,
+ CtxBreakRequest = 0x01,
// BIOS wants to make a context switch
- CtxContextSwitch = 2,
+ CtxContextSwitch = 0x02,
// BIOS is marshalling a call
- CtxMarshal = 3,
+ CtxMarshal = 0x04,
// Interrupt pending
- CtxInterruptPending = 4,
+ CtxInterruptPending = 0x08,
// BreakAndWait request
- CtxBreakAndWait = 5,
+ CtxBreakAndWait = 0x10,
};

// Note: for perf, everything should be 32 bit ints
@@ -85,7 +85,7 @@
float Cp1Registers[ 32 * 4 ]; // +160 (512) - large because we
want 16b aligned elements
SSE_ALIGN
float Cp2Registers[ 128 ]; // +672 (512) - not aligned because
we may access as packed
- CtxStopFlags StopFlag; // +1184 - used to detect stop conditions
+ int StopFlag; // +1184 - used to detect stop conditions
int Cp2Pfx[ 3 ]; // +1188 (12) - s, t, d prefixes
int Cp2Wm; // +1200 - write mask (bits 0-3)
int Cp2ConditionBit; // +1204

Modified: trunk/Noxa.Emulation.Psp.Player/Noxa.Emulation.Psp.Player.csproj
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Noxa.Emulation.Psp.Player.csproj (original)
+++ trunk/Noxa.Emulation.Psp.Player/Noxa.Emulation.Psp.Player.csproj
Sun Mar 23 20:49:40 2008
@@ -246,9 +246,6 @@
<Compile Include="Player.Designer.cs">
<DependentUpon>Player.cs</DependentUpon>
</Compile>
- <Compile Include="Player.Glass.cs">
- <SubType>Form</SubType>
- </Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="AttachDebuggerDialog.resx">

Modified: trunk/Noxa.Emulation.Psp.Player/Player.Designer.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Player.Designer.cs (original)
+++ trunk/Noxa.Emulation.Psp.Player/Player.Designer.cs Sun Mar 23
20:49:40 2008
@@ -55,7 +55,6 @@
this.attachToolStripButton = new System.Windows.Forms.ToolStripButton();
this.renderSurface = new RenderControl();
this.splashPicture = new System.Windows.Forms.PictureBox();
- this.statusUpdateTimer = new System.Windows.Forms.Timer(
this.components );
this.toolStrip1.SuspendLayout();
this.renderSurface.SuspendLayout();
( ( System.ComponentModel.ISupportInitialize )( this.splashPicture
) ).BeginInit();
@@ -248,21 +247,15 @@
this.splashPicture.TabIndex = 0;
this.splashPicture.TabStop = false;
//
- // statusUpdateTimer
- //
- this.statusUpdateTimer.Enabled = true;
- this.statusUpdateTimer.Interval = 1000;
- this.statusUpdateTimer.Tick += new System.EventHandler(
this.statusUpdateTimer_Tick );
- //
// Player
//
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size( 480, 319 );
+ this.ClientSize = new System.Drawing.Size( 480, 297 );
this.Controls.Add( this.renderSurface );
this.Controls.Add( this.toolStrip1 );
this.DoubleBuffered = true;
- this.MinimumSize = new System.Drawing.Size( 496, 355 );
+ this.MinimumSize = new System.Drawing.Size( 496, 333 );
this.Name = "Player";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "PSP Player";
@@ -294,7 +287,6 @@
private System.Windows.Forms.ToolStripMenuItem twoXToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem threeXToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem fullscreenToolStripMenuItem;
- private System.Windows.Forms.Timer statusUpdateTimer;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripButton attachToolStripButton;
private System.Windows.Forms.ToolStripButton debugToolStripButton;

Modified: trunk/Noxa.Emulation.Psp.Player/Player.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Player.cs (original)
+++ trunk/Noxa.Emulation.Psp.Player/Player.cs Sun Mar 23 20:49:40 2008
@@ -8,14 +8,13 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
+using System.Diagnostics;
using System.Drawing;
+using System.IO;
using System.Text;
using System.Windows.Forms;
-using Noxa.Emulation.Psp.Player.Configuration;
-using System.Diagnostics;
using Noxa.Emulation.Psp.Media;
-using System.IO;
-//using Noxa.Emulation.Psp.Player.Development;
+using Noxa.Emulation.Psp.Player.Configuration;

namespace Noxa.Emulation.Psp.Player
{
@@ -46,8 +45,6 @@

this.Icon = Properties.Resources.PspIcon;

- this.SetupGlass();
-
_widthPadding = this.Width - 480;
_heightPadding = this.Height - 272;
}
@@ -152,6 +149,7 @@
this.Invalidate( true );
this.Update();
}
+ this.Text = "PSP Player - " + this.GetStatusText();
};

this.Invoke( del );
@@ -323,16 +321,6 @@
return "";
}

- private void UpdateStatusText()
- {
- this.PaintMe();
- }
-
- private void statusUpdateTimer_Tick( object sender, EventArgs e )
- {
- this.UpdateStatusText();
- }
-
#region Display Size

private void sizeToolStripSplitButton_ButtonClick( object sender,
EventArgs e )
@@ -419,8 +407,6 @@
{
_host.CurrentInstance.Video.Resize(
renderSurface.ClientSize.Width, renderSurface.ClientSize.Height );
}
-
- this.GlassResize();

this.Invalidate( false );
}

Modified: trunk/Noxa.Emulation.Psp.Video.ManagedGL/MGLDriver.Worker.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Video.ManagedGL/MGLDriver.Worker.cs (original)
+++ trunk/Noxa.Emulation.Psp.Video.ManagedGL/MGLDriver.Worker.cs Sun
Mar 23 20:49:40 2008
@@ -36,7 +36,8 @@
_vsyncWaiting = true;

// HACK: this should happen in NextFrame()
- this.Emu.Cpu.SetPendingInterrupt( 30 );
+ //lock( this )
+ // this.Emu.Cpu.SetPendingInterrupt( 30 );
}

#region Frame Advancement

Modified: trunk/Noxa.Utilities/FastLinkedList.cs
==============================================================================
--- trunk/Noxa.Utilities/FastLinkedList.cs (original)
+++ trunk/Noxa.Utilities/FastLinkedList.cs Sun Mar 23 20:49:40 2008
@@ -97,6 +97,7 @@
return;
this.Remove( entry );
entry.Next = _head;
+ entry.Previous = null;
if( _head != null )
_head.Previous = entry;
_head = entry;

Reply all
Reply to author
Forward
0 new messages