[pspplayer commit] r602 - in trunk: Noxa.Emulation.Psp Noxa.Emulation.Psp.Bios.ManagedHLE Noxa.Emulation.Psp.Cpu.R40...

0 views
Skip to first unread message

codesite...@google.com

unread,
Mar 30, 2008, 12:23:30 AM3/30/08
to psppla...@googlegroups.com
Author: ben.vanik
Date: Sat Mar 29 21:22:43 2008
New Revision: 602

Added:
trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.Designer.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.resx
trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.resx
trunk/Noxa.Emulation.Psp/Debugging/DebugModel/ThreadInfo.cs
Modified:
trunk/Noxa.Emulation.Psp.Bios.ManagedHLE/BiosDebugHook.cs
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Cpu_Threading.cpp
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.cpp
trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.h
trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Handlers.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Navigation.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/RegistersControl.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.Designer.cs
trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.cs
trunk/Noxa.Emulation.Psp.Player/Noxa.Emulation.Psp.Player.csproj
trunk/Noxa.Emulation.Psp/Debugging/Hooks/IBiosHook.cs
trunk/Noxa.Emulation.Psp/Debugging/Hooks/ICpuHook.cs
trunk/Noxa.Emulation.Psp/Noxa.Emulation.Psp.csproj

Log:
Thread info exposed in the debugger through the bios debug hook
Thread list shows threads and allows you to jump to their PC and perform some basic operations (like delay, wake, and kill)
Wake is still a little broken, as depend on what it's waiting on things may break later on down the line - have to figure out a nice way to fix it

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:22:43 2008
@@ -22,5 +22,72 @@
{
this.Bios = bios;
}
+
+ public uint ActiveThreadID
+ {
+ get
+ {
+ Kernel kernel = this.Bios._kernel;
+ return ( uint )kernel.ActiveThread.UID;
+ }
+ }
+
+ public ThreadInfo[] GetThreads()
+ {
+ Kernel kernel = this.Bios._kernel;
+ List<ThreadInfo> threadInfos = new List<ThreadInfo>();
+ foreach( KThread thread in kernel.Threads )
+ {
+ ThreadInfo threadInfo = new ThreadInfo();
+ threadInfo.ThreadID = thread.UID;
+ threadInfo.InternalThreadID = thread.ContextID;
+ threadInfo.Name = thread.Name;
+ threadInfo.Attributes = ( ThreadAttributes )thread.Attributes;
+ threadInfo.EntryAddress = thread.EntryAddress;
+ threadInfo.Priority = thread.Priority;
+ threadInfo.State = ( ThreadState )thread.State;
+ threadInfo.IsWaiting = ( thread.State == KThreadState.Waiting ) || ( thread.State == KThreadState.WaitSuspended );
+ if( threadInfo.IsWaiting == true )
+ {
+ // TODO: more descriptive...
+ threadInfo.WaitingDescription = thread.WaitingOn.ToString();
+ }
+
+ threadInfo.CurrentPC = this.Bios.Emulator.Cpu.GetContextRegister( thread.ContextID, -1 );
+ threadInfos.Add( threadInfo );
+ }
+ return threadInfos.ToArray();
+ }
+
+ public void WakeThread( uint threadId )
+ {
+ Kernel kernel = this.Bios._kernel;
+ KThread thread = kernel.GetHandleOrNull<KThread>( ( int )threadId );
+ if( thread == null )
+ return;
+ if( ( thread.State == KThreadState.Suspended ) ||
+ ( thread.State == KThreadState.WaitSuspended ) )
+ thread.Resume();
+ if( thread.State == KThreadState.Waiting )
+ thread.ReleaseWait();
+ }
+
+ public void DelayThread( uint threadId, uint delayMs )
+ {
+ Kernel kernel = this.Bios._kernel;
+ KThread thread = kernel.GetHandleOrNull<KThread>( ( int )threadId );
+ if( thread == null )
+ return;
+ thread.Delay( delayMs * 1000, true );
+ }
+
+ public void KillThread( uint threadId )
+ {
+ Kernel kernel = this.Bios._kernel;
+ KThread thread = kernel.GetHandleOrNull<KThread>( ( int )threadId );
+ if( thread == null )
+ return;
+ thread.Exit( -1 );
+ }
}
}

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 Sat Mar 29 21:22:43 2008
@@ -198,7 +198,10 @@
ThreadContext* context = ( ThreadContext* )_threadContexts[ tcsId ].ToPointer();
UNLOCK;

- return context->Ctx.Registers[ reg ];
+ if( reg == -1 )
+ return context->Ctx.PC;
+ else
+ return context->Ctx.Registers[ reg ];
}

void R4000Cpu::SetContextRegister( int tcsId, int reg, uint value )

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.cpp
==============================================================================
--- trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.cpp (original)
+++ trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.cpp Sat Mar 29 21:22:43 2008
@@ -204,6 +204,43 @@
{
}

+CoreState^ R4000Hook::GetThreadCoreState( int core, int internalThreadId )
+{
+ Debug::Assert( core == 0 );
+
+ if( core == 0 )
+ {
+ R4000Core^ core = this->Cpu->_core0;
+
+ CoreState^ state = gcnew CoreState();
+
+ /*state->ProgramCounter = *core->PC;
+ state->GeneralRegisters = core->GeneralRegisters;
+ state->Hi = ( uint )*core->HI;
+ state->Lo = ( uint )*core->LO;
+ state->LL = ( *core->LL == 1 ) ? true : false;
+
+ state->Cp0ControlRegisters = core->Cp0->Control;
+ state->Cp0Registers = core->Cp0->Registers;
+ state->Cp0ConditionBit = core->Cp0->ConditionBit;
+
+ state->FpuControlRegister = core->Cp1->Control;
+ state->FpuConditionBit = core->Cp1->ConditionBit;
+ state->FpuRegisters = core->Cp1->Registers;
+
+ state->VfpuRegisters = gcnew array<float>( 128 );
+ for( int n = 0; n < 128; n++ )
+ state->VfpuRegisters[ n ] = _cpuCtx->Cp2Registers[ n ];*/
+ //state->VfpuControlRegister
+
+ return state;
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
generic<typename T>
T R4000Hook::GetRegister( RegisterSet set, int ordinal )
{

Modified: trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.h
==============================================================================
--- trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.h (original)
+++ trunk/Noxa.Emulation.Psp.Cpu.R4000Ultra/R4000Hook.h Sat Mar 29 21:22:43 2008
@@ -45,6 +45,7 @@

virtual CoreState^ GetCoreState( int core );
virtual void SetCoreState( int core, CoreState^ state );
+ virtual CoreState^ GetThreadCoreState( int core, int internalThreadId );

generic<typename T>
virtual T GetRegister( RegisterSet set, int ordinal );

Added: trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.Designer.cs
==============================================================================
--- (empty file)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.Designer.cs Sat Mar 29 21:22:43 2008
@@ -0,0 +1,111 @@
+namespace Noxa.Emulation.Psp.Player.Debugger.Dialogs
+{
+ partial class DelayThreadDialog
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose( bool disposing )
+ {
+ if( disposing && ( components != null ) )
+ {
+ components.Dispose();
+ }
+ base.Dispose( disposing );
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.delayButton = new System.Windows.Forms.Button();
+ this.cancelButton = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ this.timeTextBox = new System.Windows.Forms.TextBox();
+ this.SuspendLayout();
+ //
+ // delayButton
+ //
+ this.delayButton.Anchor = ( ( System.Windows.Forms.AnchorStyles )( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right ) ) );
+ this.delayButton.Location = new System.Drawing.Point( 103, 51 );
+ this.delayButton.Name = "delayButton";
+ this.delayButton.Size = new System.Drawing.Size( 75, 23 );
+ this.delayButton.TabIndex = 2;
+ this.delayButton.Text = "&Delay";
+ this.delayButton.UseVisualStyleBackColor = true;
+ this.delayButton.Click += new System.EventHandler( this.delayButton_Click );
+ //
+ // cancelButton
+ //
+ this.cancelButton.Anchor = ( ( System.Windows.Forms.AnchorStyles )( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right ) ) );
+ this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.cancelButton.Location = new System.Drawing.Point( 184, 51 );
+ this.cancelButton.Name = "cancelButton";
+ this.cancelButton.Size = new System.Drawing.Size( 75, 23 );
+ this.cancelButton.TabIndex = 3;
+ this.cancelButton.Text = "&Cancel";
+ this.cancelButton.UseVisualStyleBackColor = true;
+ this.cancelButton.Click += new System.EventHandler( this.cancelButton_Click );
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point( 12, 9 );
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size( 175, 13 );
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Enter time to delay the thread in ms:";
+ //
+ // timeTextBox
+ //
+ this.timeTextBox.Anchor = ( ( System.Windows.Forms.AnchorStyles )( ( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left )
+ | System.Windows.Forms.AnchorStyles.Right ) ) );
+ this.timeTextBox.Font = new System.Drawing.Font( "Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ( ( byte )( 0 ) ) );
+ this.timeTextBox.Location = new System.Drawing.Point( 15, 25 );
+ this.timeTextBox.Name = "timeTextBox";
+ this.timeTextBox.Size = new System.Drawing.Size( 244, 20 );
+ this.timeTextBox.TabIndex = 1;
+ //
+ // DelayThreadDialog
+ //
+ this.AcceptButton = this.delayButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.cancelButton;
+ this.ClientSize = new System.Drawing.Size( 271, 86 );
+ this.Controls.Add( this.timeTextBox );
+ this.Controls.Add( this.label1 );
+ this.Controls.Add( this.cancelButton );
+ this.Controls.Add( this.delayButton );
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "DelayThreadDialog";
+ this.ShowIcon = false;
+ this.ShowInTaskbar = false;
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Delay Thread";
+ this.Activated += new System.EventHandler( this.DelayThreadDialog_Activated );
+ this.ResumeLayout( false );
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button delayButton;
+ private System.Windows.Forms.Button cancelButton;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TextBox timeTextBox;
+ }
+}
\ No newline at end of file

Added: trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.cs
==============================================================================
--- (empty file)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.cs Sat Mar 29 21:22:43 2008
@@ -0,0 +1,59 @@
+// ----------------------------------------------------------------------------
+// PSP Player Emulation Suite
+// Copyright (C) 2008 Ben Vanik (noxa)
+// Licensed under the LGPL - see License.txt in the project root for details
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Globalization;
+using System.Media;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Noxa.Emulation.Psp.Player.Debugger.Dialogs
+{
+ partial class DelayThreadDialog : Form
+ {
+ public uint Time;
+
+ public DelayThreadDialog()
+ {
+ this.InitializeComponent();
+
+ this.DialogResult = DialogResult.Cancel;
+ this.timeTextBox.Text = "30000";
+ }
+
+ private void delayButton_Click( object sender, EventArgs e )
+ {
+ uint time;
+ if( uint.TryParse( this.timeTextBox.Text, out time ) == true )
+ this.Time = time;
+ else
+ {
+ SystemSounds.Exclamation.Play();
+ this.timeTextBox.Focus();
+ this.timeTextBox.SelectAll();
+ return;
+ }
+ this.DialogResult = DialogResult.OK;
+ this.Close();
+ }
+
+ private void cancelButton_Click( object sender, EventArgs e )
+ {
+ this.DialogResult = DialogResult.Cancel;
+ this.Close();
+ }
+
+ private void DelayThreadDialog_Activated( object sender, EventArgs e )
+ {
+ this.timeTextBox.Focus();
+ this.timeTextBox.SelectAll();
+ }
+ }
+}

Added: trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.resx
==============================================================================
--- (empty file)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/Dialogs/DelayThreadDialog.resx Sat Mar 29 21:22:43 2008
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
\ No newline at end of file

Modified: trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Handlers.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Handlers.cs (original)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Handlers.cs Sat Mar 29 21:22:43 2008
@@ -14,12 +14,19 @@
{
partial class InprocDebugger
{
+ private void DisableAll()
+ {
+ this.CodeTool.Disable();
+ this.CallstackTool.Clear();
+ this.ThreadsTool.Clear();
+ }
+
public void OnContinue( bool steppingForward )
{
DummyDelegate del = delegate
{
if( steppingForward == false )
- this.CodeTool.Disable();
+ this.DisableAll();

this.SetStatusText( "Running..." );

Modified: trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Navigation.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Navigation.cs (original)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.Navigation.cs Sat Mar 29 21:22:43 2008
@@ -56,6 +56,7 @@
this.CodeTool.Activate();
this.CodeTool.SetAddress( address, isCurrentStatement );
this.CallstackTool.RefreshCallstack();
+ this.ThreadsTool.RefreshThreads();
}
break;
case NavigationTarget.Memory:

Modified: trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.cs (original)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/InprocDebugger.cs Sat Mar 29 21:22:43 2008
@@ -69,12 +69,15 @@
this.Tools.Add( this.MemoryTool );
this.StatisticsTool = new StatisticsTool( this );
this.Tools.Add( this.StatisticsTool );
+ this.ThreadsTool = new ThreadsTool( this );
+ this.Tools.Add( this.ThreadsTool );
// ...

this.Window.Show();

this.CodeTool.Show( this.Window.DockPanel );
this.LogTool.Show( this.Window.DockPanel );
+ this.ThreadsTool.Show( this.Window.DockPanel );

WeifenLuo.WinFormsUI.Docking.DockPane dp;
dp = this.Window.DockPanel.DockPaneFactory.CreateDockPane( this.CodeTool, WeifenLuo.WinFormsUI.Docking.DockState.Document, true );

Modified: trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/RegistersControl.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/RegistersControl.cs (original)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/RegistersControl.cs Sat Mar 29 21:22:43 2008
@@ -310,6 +310,8 @@
this.OnPaintBackground( e );
if( _debugger == null )
return;
+ if( _debugger.DebugHost.CpuHook == null )
+ return;

e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;

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:22:43 2008
@@ -29,8 +29,150 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
+ this.threadListView = new Noxa.Utilities.Controls.DoubleBufferedListView();
+ this.idColumnHeader = new System.Windows.Forms.ColumnHeader();
+ this.pcColumnHeader = new System.Windows.Forms.ColumnHeader();
+ this.nameColumnHeader = new System.Windows.Forms.ColumnHeader();
+ this.priorityColumnHeader = new System.Windows.Forms.ColumnHeader();
+ this.stateColumnHeader = new System.Windows.Forms.ColumnHeader();
+ this.threadContextMenuStrip = new System.Windows.Forms.ContextMenuStrip( this.components );
+ 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.threadContextMenuStrip.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // threadListView
+ //
+ this.threadListView.Anchor = ( ( System.Windows.Forms.AnchorStyles )( ( ( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom )
+ | System.Windows.Forms.AnchorStyles.Left )
+ | System.Windows.Forms.AnchorStyles.Right ) ) );
+ this.threadListView.Columns.AddRange( new System.Windows.Forms.ColumnHeader[] {
+ this.idColumnHeader,
+ this.pcColumnHeader,
+ this.nameColumnHeader,
+ this.priorityColumnHeader,
+ this.stateColumnHeader} );
+ this.threadListView.ExtendedStyle = ( ( Noxa.Utilities.Controls.ListViewExtendedStyle )( ( ( ( Noxa.Utilities.Controls.ListViewExtendedStyle.GridLines | Noxa.Utilities.Controls.ListViewExtendedStyle.FullRowSelect )
+ | Noxa.Utilities.Controls.ListViewExtendedStyle.BorderSelect )
+ | Noxa.Utilities.Controls.ListViewExtendedStyle.DoubleBuffer ) ) );
+ this.threadListView.Font = new System.Drawing.Font( "Courier New", 8F );
+ this.threadListView.FullRowSelect = true;
+ this.threadListView.GridLines = true;
+ this.threadListView.Location = new System.Drawing.Point( 4, 4 );
+ this.threadListView.Name = "threadListView";
+ this.threadListView.Size = new System.Drawing.Size( 692, 181 );
+ this.threadListView.TabIndex = 0;
+ this.threadListView.UseCompatibleStateImageBehavior = false;
+ this.threadListView.View = System.Windows.Forms.View.Details;
+ this.threadListView.MouseDown += new System.Windows.Forms.MouseEventHandler( this.threadListView_MouseDown );
+ //
+ // idColumnHeader
+ //
+ this.idColumnHeader.Text = "ID";
+ this.idColumnHeader.Width = 55;
+ //
+ // pcColumnHeader
+ //
+ this.pcColumnHeader.Text = "PC";
+ this.pcColumnHeader.Width = 99;
+ //
+ // nameColumnHeader
+ //
+ this.nameColumnHeader.Text = "Name";
+ this.nameColumnHeader.Width = 152;
+ //
+ // priorityColumnHeader
+ //
+ this.priorityColumnHeader.Text = "Pri";
+ //
+ // stateColumnHeader
+ //
+ this.stateColumnHeader.Text = "State";
+ this.stateColumnHeader.Width = 297;
+ //
+ // threadContextMenuStrip
+ //
+ this.threadContextMenuStrip.Items.AddRange( new System.Windows.Forms.ToolStripItem[] {
+ this.jumpToCurrentPCToolStripMenuItem,
+ this.toolStripMenuItem1,
+ this.wakeToolStripMenuItem,
+ this.delayToolStripMenuItem,
+ this.killToolStripMenuItem} );
+ this.threadContextMenuStrip.Name = "threadContextMenuStrip";
+ this.threadContextMenuStrip.Size = new System.Drawing.Size( 179, 120 );
+ //
+ // jumpToCurrentPCToolStripMenuItem
+ //
+ this.jumpToCurrentPCToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.StatementIcon;
+ this.jumpToCurrentPCToolStripMenuItem.Name = "jumpToCurrentPCToolStripMenuItem";
+ this.jumpToCurrentPCToolStripMenuItem.Size = new System.Drawing.Size( 178, 22 );
+ this.jumpToCurrentPCToolStripMenuItem.Text = "&Jump to Current PC";
+ this.jumpToCurrentPCToolStripMenuItem.Click += new System.EventHandler( this.jumpToCurrentPCToolStripMenuItem_Click );
+ //
+ // toolStripMenuItem1
+ //
+ this.toolStripMenuItem1.Name = "toolStripMenuItem1";
+ this.toolStripMenuItem1.Size = new System.Drawing.Size( 175, 6 );
+ //
+ // 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 );
+ //
+ // killToolStripMenuItem
+ //
+ this.killToolStripMenuItem.Image = global::Noxa.Emulation.Psp.Player.Properties.Resources.StopIcon;
+ this.killToolStripMenuItem.Name = "killToolStripMenuItem";
+ this.killToolStripMenuItem.Size = new System.Drawing.Size( 178, 22 );
+ 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 );
+ this.ClientSize = new System.Drawing.Size( 700, 189 );
+ this.CloseButton = false;
+ this.Controls.Add( this.threadListView );
+ this.DockAreas = ( ( WeifenLuo.WinFormsUI.Docking.DockAreas )( ( ( ( ( WeifenLuo.WinFormsUI.Docking.DockAreas.Float | WeifenLuo.WinFormsUI.Docking.DockAreas.DockLeft )
+ | WeifenLuo.WinFormsUI.Docking.DockAreas.DockRight )
+ | WeifenLuo.WinFormsUI.Docking.DockAreas.DockTop )
+ | WeifenLuo.WinFormsUI.Docking.DockAreas.DockBottom ) ) );
+ this.HideOnClose = true;
+ this.Name = "ThreadsTool";
+ this.ShowHint = WeifenLuo.WinFormsUI.Docking.DockState.DockTopAutoHide;
+ this.TabText = "Threads";
+ this.threadContextMenuStrip.ResumeLayout( false );
+ this.ResumeLayout( false );
+
}

#endregion
+
+ private Noxa.Utilities.Controls.DoubleBufferedListView threadListView;
+ private System.Windows.Forms.ColumnHeader idColumnHeader;
+ private System.Windows.Forms.ColumnHeader nameColumnHeader;
+ private System.Windows.Forms.ColumnHeader pcColumnHeader;
+ private System.Windows.Forms.ColumnHeader priorityColumnHeader;
+ private System.Windows.Forms.ColumnHeader stateColumnHeader;
+ private System.Windows.Forms.ContextMenuStrip threadContextMenuStrip;
+ private System.Windows.Forms.ToolStripMenuItem jumpToCurrentPCToolStripMenuItem;
+ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
+ private System.Windows.Forms.ToolStripMenuItem wakeToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem killToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem delayToolStripMenuItem;
}
}

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:22:43 2008
@@ -11,14 +11,144 @@
using System.Drawing;
using System.Text;
using System.Windows.Forms;
+using Noxa.Emulation.Psp.Debugging.DebugModel;
+using Noxa.Emulation.Psp.Player.Debugger.Dialogs;

namespace Noxa.Emulation.Psp.Player.Debugger.Tools
{
partial class ThreadsTool : Noxa.Emulation.Psp.Player.Debugger.DebuggerTool
{
+ private DelayThreadDialog _delayThreadDialog;
+
public ThreadsTool()
{
- InitializeComponent();
+ this.InitializeComponent();
+ }
+
+ public ThreadsTool( InprocDebugger debugger )
+ : base( debugger )
+ {
+ this.InitializeComponent();
+
+ Bitmap image = Properties.Resources.ThreadsIcon as Bitmap;
+ this.Icon = Icon.FromHandle( image.GetHicon() );
+
+ this.Clear();
+
+ _delayThreadDialog = new DelayThreadDialog();
+ }
+
+ public void Clear()
+ {
+ this.threadListView.BeginUpdate();
+ this.threadListView.Items.Clear();
+ this.threadListView.EndUpdate();
+ this.threadListView.Enabled = false;
+ }
+
+ public void RefreshThreads()
+ {
+ ThreadInfo[] threadInfos = this.Debugger.DebugHost.BiosHook.GetThreads();
+ uint activeThreadId = this.Debugger.DebugHost.BiosHook.ActiveThreadID;
+
+ this.threadListView.BeginUpdate();
+ this.threadListView.Items.Clear();
+ foreach( ThreadInfo threadInfo in threadInfos )
+ {
+ string ids = threadInfo.ThreadID.ToString( "X" ) + "/" + threadInfo.InternalThreadID;
+ string pc = threadInfo.CurrentPC.ToString( "X8" );
+ string state = threadInfo.State.ToString();
+ if( threadInfo.IsWaiting == true )
+ state += " - " + threadInfo.WaitingDescription;
+ ListViewItem item = new ListViewItem( new string[]{
+ ids, pc, threadInfo.Name, threadInfo.Priority.ToString(), state
+ } );
+ item.Tag = threadInfo;
+ item.UseItemStyleForSubItems = true;
+ if( threadInfo.ThreadID == activeThreadId )
+ item.ForeColor = Color.Green;
+ else if( threadInfo.IsWaiting == true )
+ item.ForeColor = SystemColors.InactiveCaptionText;
+ this.threadListView.Items.Add( item );
+ }
+ this.threadListView.EndUpdate();
+ this.threadListView.Enabled = true;
+ }
+
+ private ListViewItem _currentItem;
+
+ private void threadListView_MouseDown( object sender, MouseEventArgs e )
+ {
+ ListViewItem item = this.threadListView.GetItemAt( e.X, e.Y );
+ _currentItem = item;
+ if( item == null )
+ return;
+ ThreadInfo threadInfo = item.Tag as ThreadInfo;
+ if( threadInfo == null )
+ return;
+ uint activeThreadId = this.Debugger.DebugHost.BiosHook.ActiveThreadID;
+ if( e.Clicks == 2 )
+ {
+ this.Debugger.CodeTool.SetAddress( threadInfo.CurrentPC, ( activeThreadId == threadInfo.ThreadID ) );
+ }
+ else
+ {
+ if( e.Button == MouseButtons.Right )
+ {
+ bool canControl = ( threadInfo.ThreadID != activeThreadId );
+ this.wakeToolStripMenuItem.Enabled = canControl;
+ this.delayToolStripMenuItem.Enabled = canControl;
+ this.killToolStripMenuItem.Enabled = canControl;
+ this.threadContextMenuStrip.Show( this.threadListView, e.Location );
+ }
+ }
+ }
+
+ private void jumpToCurrentPCToolStripMenuItem_Click( object sender, EventArgs e )
+ {
+ if( _currentItem == null )
+ return;
+ ThreadInfo threadInfo = _currentItem.Tag as ThreadInfo;
+ if( threadInfo == null )
+ return;
+ uint activeThreadId = this.Debugger.DebugHost.BiosHook.ActiveThreadID;
+ this.Debugger.CodeTool.SetAddress( threadInfo.CurrentPC, ( activeThreadId == threadInfo.ThreadID ) );
+ }
+
+ private void wakeToolStripMenuItem_Click( object sender, EventArgs e )
+ {
+ if( _currentItem == null )
+ return;
+ ThreadInfo threadInfo = _currentItem.Tag as ThreadInfo;
+ if( threadInfo == null )
+ return;
+ this.Debugger.DebugHost.BiosHook.WakeThread( threadInfo.ThreadID );
+ this.RefreshThreads();
+ }
+
+ private void delayToolStripMenuItem_Click( object sender, EventArgs e )
+ {
+ if( _currentItem == null )
+ return;
+ ThreadInfo threadInfo = _currentItem.Tag as ThreadInfo;
+ if( threadInfo == null )
+ return;
+ if( _delayThreadDialog.ShowDialog( this.FindForm() ) == DialogResult.OK )
+ {
+ this.Debugger.DebugHost.BiosHook.DelayThread( threadInfo.ThreadID, _delayThreadDialog.Time );
+ this.RefreshThreads();
+ }
+ }
+
+ private void killToolStripMenuItem_Click( object sender, EventArgs e )
+ {
+ if( _currentItem == null )
+ return;
+ ThreadInfo threadInfo = _currentItem.Tag as ThreadInfo;
+ if( threadInfo == null )
+ return;
+ this.Debugger.DebugHost.BiosHook.KillThread( threadInfo.ThreadID );
+ this.RefreshThreads();
}
}
}

Added: trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.resx
==============================================================================
--- (empty file)
+++ trunk/Noxa.Emulation.Psp.Player/Debugger/Tools/ThreadsTool.resx Sat Mar 29 21:22:43 2008
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="threadContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>17, 17</value>
+ </metadata>
+</root>
\ No newline at end of file

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 Sat Mar 29 21:22:43 2008
@@ -102,6 +102,12 @@
<Compile Include="Debugger\DebuggerWindow.Designer.cs">
<DependentUpon>DebuggerWindow.cs</DependentUpon>
</Compile>
+ <Compile Include="Debugger\Dialogs\DelayThreadDialog.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="Debugger\Dialogs\DelayThreadDialog.Designer.cs">
+ <DependentUpon>DelayThreadDialog.cs</DependentUpon>
+ </Compile>
<Compile Include="Debugger\Dialogs\JumpToMethodDialog.cs">
<SubType>Form</SubType>
</Compile>
@@ -280,6 +286,10 @@
<DependentUpon>DebuggerWindow.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
+ <EmbeddedResource Include="Debugger\Dialogs\DelayThreadDialog.resx">
+ <DependentUpon>DelayThreadDialog.cs</DependentUpon>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
<EmbeddedResource Include="Debugger\Dialogs\JumpToMethodDialog.resx">
<DependentUpon>JumpToMethodDialog.cs</DependentUpon>
<SubType>Designer</SubType>
@@ -322,6 +332,10 @@
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Tools\StatisticsTool.resx">
<DependentUpon>StatisticsTool.cs</DependentUpon>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Debugger\Tools\ThreadsTool.resx">
+ <DependentUpon>ThreadsTool.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="GamePicker\AdvancedGameListing.resx">

Added: trunk/Noxa.Emulation.Psp/Debugging/DebugModel/ThreadInfo.cs
==============================================================================
--- (empty file)
+++ trunk/Noxa.Emulation.Psp/Debugging/DebugModel/ThreadInfo.cs Sat Mar 29 21:22:43 2008
@@ -0,0 +1,115 @@
+// ----------------------------------------------------------------------------
+// PSP Player Emulation Suite
+// Copyright (C) 2008 Ben Vanik (noxa)
+// Licensed under the LGPL - see License.txt in the project root for details
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Noxa.Emulation.Psp.Debugging.DebugModel
+{
+ /// <summary>
+ /// Thread info.
+ /// </summary>
+ [Serializable]
+ public class ThreadInfo
+ {
+ /// <summary>
+ /// The BIOS thread ID.
+ /// </summary>
+ public uint ThreadID;
+ /// <summary>
+ /// The CPU thread ID, used for CPU inspection.
+ /// </summary>
+ public int InternalThreadID;
+
+ /// <summary>
+ /// The game-defined name for the thread.
+ /// </summary>
+ public string Name;
+ /// <summary>
+ /// The attributes the thread was created with.
+ /// </summary>
+ public ThreadAttributes Attributes;
+ /// <summary>
+ /// The entry address of the thread.
+ /// </summary>
+ public uint EntryAddress;
+
+ // TODO: Module info
+
+ /// <summary>
+ /// The current PC of the thread.
+ /// </summary>
+ public uint CurrentPC;
+ /// <summary>
+ /// The priority of the thread.
+ /// </summary>
+ public int Priority;
+ /// <summary>
+ /// The current state of the thread.
+ /// </summary>
+ public ThreadState State;
+
+ /// <summary>
+ /// <c>true</c> if the thread is waiting.
+ /// </summary>
+ public bool IsWaiting;
+ /// <summary>
+ /// A human-readable description of what the thread is waiting on if <c>IsWaiting</c> is <c>true</c>.
+ /// </summary>
+ public string WaitingDescription;
+ }
+
+ /// <summary>
+ /// The current state of a thread.
+ /// </summary>
+ public enum ThreadState
+ {
+ Running = 1,
+ Ready = 2,
+ Waiting = 4,
+ Suspended = 8,
+ WaitSuspended = 12,
+ Stopped = 16,
+ Dead = 32,
+ }
+
+ /// <summary>
+ /// Attributes describing the behavior/usage of a thread.
+ /// </summary>
+ [Flags]
+ public enum ThreadAttributes : uint
+ {
+ /// <summary>
+ /// Allow VFPU usage.
+ /// </summary>
+ VFPU = 0x00004000,
+ /// <summary>
+ /// Start thread in user mode.
+ /// </summary>
+ User = 0x80000000,
+ /// <summary>
+ /// Thread is part of USB/WLAN API.
+ /// </summary>
+ UsbWlan = 0xA0000000,
+ /// <summary>
+ /// Thread is part of VSH API.
+ /// </summary>
+ Vsh = 0xC0000000,
+ /// <summary>
+ /// Allow scratchpad usage.
+ /// </summary>
+ ScratchSram = 0x00008000,
+ /// <summary>
+ /// Don't fill stack with 0xFF on create.
+ /// </summary>
+ NoFillStack = 0x00100000,
+ /// <summary>
+ /// Clear stack when thread deleted.
+ /// </summary>
+ ClearStack = 0x00200000,
+ }
+}

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:22:43 2008
@@ -17,5 +17,34 @@
/// </summary>
public interface IBiosHook : IHook
{
+ /// <summary>
+ /// Gets the ID of the active thread.
+ /// </summary>
+ uint ActiveThreadID { get; }
+
+ /// <summary>
+ /// Get the states of all the living threads.
+ /// </summary>
+ /// <returns>The information of all the living threads.</returns>
+ ThreadInfo[] GetThreads();
+
+ /// <summary>
+ /// Force wake the given thread.
+ /// </summary>
+ /// <param name="threadId">The ID of the thread to wake.</param>
+ void WakeThread( uint threadId );
+
+ /// <summary>
+ /// Delay the given thread.
+ /// </summary>
+ /// <param name="threadId">The ID of the thread to delay.</param>
+ /// <param name="delayMs">The time, in milliseconds, to delay the thread.</param>
+ void DelayThread( uint threadId, uint delayMs );
+
+ /// <summary>
+ /// Kill the given thread.
+ /// </summary>
+ /// <param name="threadId">The ID of the thread to kill.</param>
+ void KillThread( uint threadId );
}
}

Modified: trunk/Noxa.Emulation.Psp/Debugging/Hooks/ICpuHook.cs
==============================================================================
--- trunk/Noxa.Emulation.Psp/Debugging/Hooks/ICpuHook.cs (original)
+++ trunk/Noxa.Emulation.Psp/Debugging/Hooks/ICpuHook.cs Sat Mar 29 21:22:43 2008
@@ -104,6 +104,14 @@
/// <param name="state">State information for the given core.</param>
void SetCoreState( int core, CoreState state );

+ /// <summary>
+ /// Get the processor state for the specified thread.
+ /// </summary>
+ /// <param name="core">Core ordinal.</param>
+ /// <param name="internalThreadId">Internal thread ID.</param>
+ /// <returns>State information for the given core on the given thread.</returns>
+ CoreState GetThreadCoreState( int core, int internalThreadId );
+
#region Register Accessors

/// <summary>

Modified: trunk/Noxa.Emulation.Psp/Noxa.Emulation.Psp.csproj
==============================================================================
--- trunk/Noxa.Emulation.Psp/Noxa.Emulation.Psp.csproj (original)
+++ trunk/Noxa.Emulation.Psp/Noxa.Emulation.Psp.csproj Sat Mar 29 21:22:43 2008
@@ -73,6 +73,7 @@
<Compile Include="Debugging\DebugModel\CpuError.cs" />
<Compile Include="Debugging\DebugModel\MemoryError.cs" />
<Compile Include="Debugging\DebugModel\Symbol.cs" />
+ <Compile Include="Debugging\DebugModel\ThreadInfo.cs" />
<Compile Include="Debugging\DebugModel\Variable.cs" />
<Compile Include="Debugging\Hooks\IHook.cs" />
<Compile Include="Debugging\Hooks\IVideoHook.cs" />

Reply all
Reply to author
Forward
0 new messages