Modified:
   trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/BiosDebugHook.cs
   trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/Kernel Types/KThread.Waiting.cs
   trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.Designer.cs
   trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.cs
   trunk/Noxa.Emulation.Psp/Debugging/Hooks/IBiosHook.cs
Log:
added suspend/resume - much more reliable than delay/wake
fixed a bug in the way waking was done, as well as making it work right
done with thread stuff for now - it's awesome!
now just need to add modules
Modified: trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/BiosDebugHook.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/BiosDebugHook.cs	(original)
+++ trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/BiosDebugHook.cs	Sat Mar 
29 21:45:15 2008
@@ -69,7 +69,7 @@
 				( thread.State == KThreadState.WaitSuspended ) )
 				thread.Resume();
 			if( thread.State == KThreadState.Waiting )
-				thread.ReleaseWait();
+				thread.ReleaseWait( false );
 		}
 		public void DelayThread( uint threadId, uint delayMs )
@@ -78,7 +78,25 @@
 			KThread thread = kernel.GetHandleOrNull<KThread>( ( int )threadId );
 			if( thread == null )
 				return;
-			thread.Delay( delayMs * 1000, true );
+			thread.Delay( delayMs * 1000, false );
+		}
+
+		public void SuspendThread( uint threadId )
+		{
+			Kernel kernel = this.Bios._kernel;
+			KThread thread = kernel.GetHandleOrNull<KThread>( ( int )threadId );
+			if( thread == null )
+				return;
+			thread.Suspend();
+		}
+
+		public void ResumeThread( uint threadId )
+		{
+			Kernel kernel = this.Bios._kernel;
+			KThread thread = kernel.GetHandleOrNull<KThread>( ( int )threadId );
+			if( thread == null )
+				return;
+			thread.Resume();
 		}
public void KillThread( uint threadId )
Modified: trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/Kernel Types/KThread.Waiting.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/Kernel  
Types/KThread.Waiting.cs	(original)
+++ trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/Kernel  
Types/KThread.Waiting.cs	Sat Mar 29 21:45:15 2008
@@ -13,6 +13,8 @@
 {
 	partial class KThread
 	{
+		private Timer _waitTimer;
+
 		public void Wake()
 		{
 			State = KThreadState.Ready;
@@ -40,13 +42,52 @@
 		public void ReleaseWait()
 		{
+			this.ReleaseWait( true );
+		}
+
+		public void ReleaseWait( bool clean )
+		{
 			if( ( State == KThreadState.Waiting ) ||
 				( State == KThreadState.WaitSuspended ) )
 			{
-				Debug.Assert( false, "implement nice way to cancel things - need 
to remove from waitingthreads list of whatever it's waiting on" );
-				//switch( this.WaitingOn )
-				//{
-				//}
+				switch( this.WaitingOn )
+				{
+					case KThreadWait.Sleep:
+						// Nothing to do
+						break;
+					case KThreadWait.Delay:
+						if( _waitTimer != null )
+							this.Kernel.CancelTimer( _waitTimer );
+						_waitTimer = null;
+						break;
+					case KThreadWait.Event:
+						{
+							KEvent ev = this.WaitHandle as KEvent;
+							ev.WaitingThreads.Remove( this );
+						}
+						break;
+					case KThreadWait.Semaphore:
+						{
+							KSemaphore sema = this.WaitHandle as KSemaphore;
+							sema.WaitingThreads.Remove( this );
+						}
+						break;
+					case KThreadWait.Fpl:
+						{
+							KFixedPool pool = this.WaitHandle as KFixedPool;
+							pool.WaitingThreads.Remove( this );
+						}
+						break;
+					case KThreadWait.Vpl:
+						{
+							KVariablePool pool = this.WaitHandle as KVariablePool;
+							pool.WaitingThreads.Remove( this );
+						}
+						break;
+					default:
+						Log.WriteLine( Verbosity.Critical, Feature.Bios, "unsupported 
wake wait type " + this.WaitingOn.ToString() + " - ignoring" );
+						return;
+				}
 			}
 			if( State == KThreadState.WaitSuspended )
 				State = KThreadState.Suspended;
@@ -54,7 +95,8 @@
 				State = KThreadState.Ready;
 			ReleaseCount++;
-			Kernel.Cpu.SetContextRegister( ContextID, 2, 0x800201AA );
+			if( clean == true )
+				Kernel.Cpu.SetContextRegister( ContextID, 2, 0x800201AA );
 			if( State == KThreadState.Ready )
 				this.AddToSchedule();
@@ -110,6 +152,9 @@
 		private void DelayCallback( Timer timer, object state )
 		{
+			if( _waitTimer != timer )
+				return;
+			_waitTimer = null;
 			if( this.State == KThreadState.WaitSuspended )
 				this.State = KThreadState.Suspended;
 			else if( ( this.State == KThreadState.Waiting ) &&
@@ -138,7 +183,7 @@
 			// Install timer
 			uint waitTimeMs = Math.Max( 5, waitTimeUs / 1000 );
-			Kernel.AddOneShotTimer( this.DelayCallback, this, waitTimeMs );
+			_waitTimer = Kernel.AddOneShotTimer( this.DelayCallback, this, 
waitTimeMs );
 			if( canHandleCallbacks == true )
 				this.Kernel.CheckCallbacks();
@@ -326,7 +371,7 @@
 			this.WaitAddress = ( uint )message;
 			this.WaitAddressResult = ( uint )outSize;
-			if (canHandleCallbacks == true)
+			if( canHandleCallbacks == true )
 			{
 				this.Kernel.CheckCallbacks();
 			}
@@ -334,25 +379,25 @@
 			this.Kernel.Schedule();
 		}
-		public void Wait(KMessageBox box, int pmessage, int timeout, bool canHandleCallbacks)
+		public void Wait( KMessageBox box, int pmessage, int timeout, bool 
canHandleCallbacks )
 		{
 			this.State = KThreadState.Waiting;
 			this.RemoveFromSchedule();
-			
+
 			this.CanHandleCallbacks = canHandleCallbacks;
-			
-			box.WaitingThreads.Enqueue(this);
-			
+
+			box.WaitingThreads.Enqueue( this );
+
 			this.WaitingOn = KThreadWait.Mbx;
-			this.WaitTimeoutSetup((uint)timeout);
+			this.WaitTimeoutSetup( ( uint )timeout );
 			this.WaitHandle = box;
-			this.WaitAddress = (uint)pmessage;
+			this.WaitAddress = ( uint )pmessage;
-			if (canHandleCallbacks == true)
+			if( canHandleCallbacks == true )
 			{
 				this.Kernel.CheckCallbacks();
 			}
-			
+
 			this.Kernel.Schedule();
 		}
 	}
Modified: trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.Designer.cs
==============================================================================
---  
trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.Designer.cs	(original)
+++  
trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.Designer.cs	
Sat Mar 29 21:45:15 2008
@@ -39,8 +39,12 @@
 			this.jumpToCurrentPCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
 			this.wakeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-			this.killToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.delayToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
+			this.suspendToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.resumeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+			this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+			this.killToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
 			this.threadContextMenuStrip.SuspendLayout();
 			this.SuspendLayout();
 			//
@@ -100,9 +104,13 @@
             this.toolStripMenuItem1,
             this.wakeToolStripMenuItem,
             this.delayToolStripMenuItem,
+            this.toolStripSeparator2,
+            this.suspendToolStripMenuItem,
+            this.resumeToolStripMenuItem,
+            this.toolStripSeparator1,
             this.killToolStripMenuItem} );
 			this.threadContextMenuStrip.Name = "threadContextMenuStrip";
-			this.threadContextMenuStrip.Size = new System.Drawing.Size( 179, 
120 );
+			this.threadContextMenuStrip.Size = new System.Drawing.Size( 179, 
176 );
 			//
 			// jumpToCurrentPCToolStripMenuItem
 			//
@@ -119,12 +127,44 @@
 			//
 			// wakeToolStripMenuItem
 			//
-			this.wakeToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.PlayIcon;
 			this.wakeToolStripMenuItem.Name = "wakeToolStripMenuItem";
 			this.wakeToolStripMenuItem.Size = new System.Drawing.Size( 178, 22 );
 			this.wakeToolStripMenuItem.Text = "&Wake";
  			this.wakeToolStripMenuItem.Click += new System.EventHandler( 
this.wakeToolStripMenuItem_Click );
 			//
+			// delayToolStripMenuItem
+			//
+			this.delayToolStripMenuItem.Name = "delayToolStripMenuItem";
+			this.delayToolStripMenuItem.Size = new System.Drawing.Size( 178, 22 );
+			this.delayToolStripMenuItem.Text = "&Delay";
+			this.delayToolStripMenuItem.Click += new System.EventHandler( 
this.delayToolStripMenuItem_Click );
+			//
+			// toolStripSeparator2
+			//
+			this.toolStripSeparator2.Name = "toolStripSeparator2";
+			this.toolStripSeparator2.Size = new System.Drawing.Size( 175, 6 );
+			//
+			// suspendToolStripMenuItem
+			//
+			this.suspendToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.PauseIcon;
+			this.suspendToolStripMenuItem.Name = "suspendToolStripMenuItem";
+			this.suspendToolStripMenuItem.Size = new System.Drawing.Size( 178, 
22 );
+			this.suspendToolStripMenuItem.Text = "&Suspend";
+			this.suspendToolStripMenuItem.Click += new System.EventHandler( 
this.suspendToolStripMenuItem_Click );
+			//
+			// resumeToolStripMenuItem
+			//
+			this.resumeToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.PlayIcon;
+			this.resumeToolStripMenuItem.Name = "resumeToolStripMenuItem";
+			this.resumeToolStripMenuItem.Size = new System.Drawing.Size( 178, 
22 );
+			this.resumeToolStripMenuItem.Text = "&Resume";
+			this.resumeToolStripMenuItem.Click += new System.EventHandler( 
this.resumeToolStripMenuItem_Click );
+			//
+			// toolStripSeparator1
+			//
+			this.toolStripSeparator1.Name = "toolStripSeparator1";
+			this.toolStripSeparator1.Size = new System.Drawing.Size( 175, 6 );
+			//
 			// killToolStripMenuItem
 			//
 			this.killToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.StopIcon;
@@ -133,14 +173,6 @@
 			this.killToolStripMenuItem.Text = "&Kill";
  			this.killToolStripMenuItem.Click += new System.EventHandler( 
this.killToolStripMenuItem_Click );
 			//
-			// delayToolStripMenuItem
-			//
-			this.delayToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.PauseIcon;
-			this.delayToolStripMenuItem.Name = "delayToolStripMenuItem";
-			this.delayToolStripMenuItem.Size = new System.Drawing.Size( 178, 22 );
-			this.delayToolStripMenuItem.Text = "&Delay";
-			this.delayToolStripMenuItem.Click += new System.EventHandler( 
this.delayToolStripMenuItem_Click );
-			//
 			// ThreadsTool
 			//
 			this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
@@ -174,5 +206,9 @@
 		private System.Windows.Forms.ToolStripMenuItem wakeToolStripMenuItem;
 		private System.Windows.Forms.ToolStripMenuItem killToolStripMenuItem;
 		private System.Windows.Forms.ToolStripMenuItem delayToolStripMenuItem;
+		private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+		private System.Windows.Forms.ToolStripMenuItem suspendToolStripMenuItem;
+		private System.Windows.Forms.ToolStripMenuItem resumeToolStripMenuItem;
+		private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
 	}
 }
Modified: trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.cs	(original)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.cs	Sat 
Mar 29 21:45:15 2008
@@ -98,6 +98,8 @@
 					bool canControl = ( threadInfo.ThreadID != activeThreadId );
 					this.wakeToolStripMenuItem.Enabled = canControl;
 					this.delayToolStripMenuItem.Enabled = canControl;
+					this.suspendToolStripMenuItem.Enabled = ( ( threadInfo.State == 
ThreadState.Ready ) || ( threadInfo.State == ThreadState.Waiting ) );
+					this.resumeToolStripMenuItem.Enabled = ( ( threadInfo.State == 
ThreadState.Suspended ) || ( threadInfo.State == 
ThreadState.WaitSuspended ) );
 					this.killToolStripMenuItem.Enabled = canControl;
 					this.threadContextMenuStrip.Show( this.threadListView, e.Location );
 				}
@@ -138,6 +140,28 @@
  				this.Debugger.DebugHost.BiosHook.DelayThread( threadInfo.ThreadID, 
_delayThreadDialog.Time );
 				this.RefreshThreads();
 			}
+		}
+
+		private void suspendToolStripMenuItem_Click( object sender, 
EventArgs e )
+		{
+			if( _currentItem == null )
+				return;
+			ThreadInfo threadInfo = _currentItem.Tag as ThreadInfo;
+			if( threadInfo == null )
+				return;
+			this.Debugger.DebugHost.BiosHook.SuspendThread( threadInfo.ThreadID );
+			this.RefreshThreads();
+		}
+
+		private void resumeToolStripMenuItem_Click( object sender, EventArgs 
e )
+		{
+			if( _currentItem == null )
+				return;
+			ThreadInfo threadInfo = _currentItem.Tag as ThreadInfo;
+			if( threadInfo == null )
+				return;
+			this.Debugger.DebugHost.BiosHook.ResumeThread( threadInfo.ThreadID );
+			this.RefreshThreads();
 		}
private void killToolStripMenuItem_Click( object sender, EventArgs e )
Modified: trunk/Noxa.Emulation.Psp/Debugging/Hooks/IBiosHook.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp/Debugging/Hooks/IBiosHook.cs	(original)
+++ trunk/Noxa.Emulation.Psp/Debugging/Hooks/IBiosHook.cs	Sat Mar 29 
21:45:15 2008
@@ -42,6 +42,18 @@
 		void DelayThread( uint threadId, uint delayMs );
 		/// <summary>
+		/// Suspend the given thread.
+		/// </summary>
+		/// <param name="threadId">The ID of the thread to suspend.</param>
+		void SuspendThread( uint threadId );
+
+		/// <summary>
+		/// Resume the given thread.
+		/// </summary>
+		/// <param name="threadId">The ID of the thread to resume.</param>
+		void ResumeThread( uint threadId );
+
+		/// <summary>
 		/// Kill the given thread.
 		/// </summary>
 		/// <param name="threadId">The ID of the thread to kill.</param>