Add debug features
This commit is contained in:
parent
631c471fe1
commit
47fd0632ff
|
@ -54,6 +54,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginRSP", "Source\Android
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JniBridge", "Source\Android\Bridge\Bridge.vcxproj", "{593B00E6-1987-415D-A62C-26533FC3E95C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duktape", "Source\3rdParty\duktape\duktape.vcxproj", "{E8D9A652-A354-4374-B6C5-A51EE62749FD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Project64-video", "Source\Project64-video\Project64-video.vcxproj", "{A4D13408-A794-4199-8FC7-4A9A32505005}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -173,6 +175,14 @@ Global
|
|||
{593B00E6-1987-415D-A62C-26533FC3E95C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{593B00E6-1987-415D-A62C-26533FC3E95C}.Release|Win32.Build.0 = Release|Win32
|
||||
{593B00E6-1987-415D-A62C-26533FC3E95C}.Release|x64.ActiveCfg = Release|Win32
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Debug|x64.Build.0 = Debug|x64
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Release|Win32.Build.0 = Release|Win32
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Release|x64.ActiveCfg = Release|x64
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD}.Release|x64.Build.0 = Release|x64
|
||||
{A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A4D13408-A794-4199-8FC7-4A9A32505005}.Debug|x64.ActiveCfg = Debug|x64
|
||||
|
@ -194,5 +204,6 @@ Global
|
|||
{1133A1CC-A9E5-4026-B20D-6A2987130D4E} = {0E0FCAC2-E128-4886-8EE6-1BCA84551F58}
|
||||
{B685BB34-D700-4FCC-8503-9B6AA1A0C95D} = {0E0FCAC2-E128-4886-8EE6-1BCA84551F58}
|
||||
{593B00E6-1987-415D-A62C-26533FC3E95C} = {0E0FCAC2-E128-4886-8EE6-1BCA84551F58}
|
||||
{E8D9A652-A354-4374-B6C5-A51EE62749FD} = {AA8F7F8E-5377-4911-859D-8A8817B0DB26}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
console.log("Hello world! See apidoc.htm for documentation.");
|
|
@ -0,0 +1,72 @@
|
|||
===============
|
||||
Duktape authors
|
||||
===============
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
Duktape copyrights are held by its authors. Each author has a copyright
|
||||
to their contribution, and agrees to irrevocably license the contribution
|
||||
under the Duktape ``LICENSE.txt``.
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Please include an e-mail address, a link to your GitHub profile, or something
|
||||
similar to allow your contribution to be identified accurately.
|
||||
|
||||
The following people have contributed code, website contents, or Wiki contents,
|
||||
and agreed to irrevocably license their contributions under the Duktape
|
||||
``LICENSE.txt`` (in order of appearance):
|
||||
|
||||
* Sami Vaarala <sami.vaarala@iki.fi>
|
||||
* Niki Dobrev
|
||||
* Andreas Öman <andreas@lonelycoder.com>
|
||||
* László Langó <llango.u-szeged@partner.samsung.com>
|
||||
* Legimet <legimet.calc@gmail.com>
|
||||
* Karl Skomski <karl@skomski.com>
|
||||
* Bruce Pascoe <fatcerberus1@gmail.com>
|
||||
* René Hollander <rene@rene8888.at>
|
||||
* Julien Hamaide (https://github.com/crazyjul)
|
||||
* Sebastian Götte (https://github.com/jaseg)
|
||||
|
||||
Other contributions
|
||||
===================
|
||||
|
||||
The following people have contributed something other than code (e.g. reported
|
||||
bugs, provided ideas, etc; roughly in order of appearance):
|
||||
|
||||
* Greg Burns
|
||||
* Anthony Rabine
|
||||
* Carlos Costa
|
||||
* Aurélien Bouilland
|
||||
* Preet Desai (Pris Matic)
|
||||
* judofyr (http://www.reddit.com/user/judofyr)
|
||||
* Jason Woofenden
|
||||
* Michał Przybyś
|
||||
* Anthony Howe
|
||||
* Conrad Pankoff
|
||||
* Jim Schimpf
|
||||
* Rajaran Gaunker (https://github.com/zimbabao)
|
||||
* Andreas Öman
|
||||
* Doug Sanden
|
||||
* Josh Engebretson (https://github.com/JoshEngebretson)
|
||||
* Remo Eichenberger (https://github.com/remoe)
|
||||
* Mamod Mehyar (https://github.com/mamod)
|
||||
* David Demelier (https://github.com/markand)
|
||||
* Tim Caswell (https://github.com/creationix)
|
||||
* Mitchell Blank Jr (https://github.com/mitchblank)
|
||||
* https://github.com/yushli
|
||||
* Seo Sanghyeon (https://github.com/sanxiyn)
|
||||
* Han ChoongWoo (https://github.com/tunz)
|
||||
* Joshua Peek (https://github.com/josh)
|
||||
* Bruce E. Pascoe (https://github.com/fatcerberus)
|
||||
* https://github.com/Kelledin
|
||||
* https://github.com/sstruchtrup
|
||||
* Michael Drake (https://github.com/tlsa)
|
||||
* https://github.com/chris-y
|
||||
* Laurent Zubiaur (https://github.com/lzubiaur)
|
||||
* Ole André Vadla Ravnås (https://github.com/oleavr)
|
||||
|
||||
If you are accidentally missing from this list, send me an e-mail
|
||||
(``sami.vaarala@iki.fi``) and I'll fix the omission.
|
|
@ -0,0 +1,25 @@
|
|||
===============
|
||||
Duktape license
|
||||
===============
|
||||
|
||||
(http://opensource.org/licenses/MIT)
|
||||
|
||||
Copyright (c) 2013-2016 by Duktape authors (see AUTHORS.rst)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,110 @@
|
|||
=======
|
||||
Duktape
|
||||
=======
|
||||
|
||||
Duktape is a small and portable Ecmascript E5/E5.1 implementation. It is
|
||||
intended to be easily embeddable into C programs, with a C API similar in
|
||||
spirit to Lua's.
|
||||
|
||||
Duktape supports the full E5/E5.1 feature set including errors, Unicode
|
||||
strings, and regular expressions, a subset of E6 features (e.g. Proxy
|
||||
objects), Khronos/ES6 ArrayBuffer/TypedView, and Node.js Buffer bindings.
|
||||
|
||||
Duktape also provides a number of custom features such as error tracebacks,
|
||||
additional data types for better C integration, combined reference counting
|
||||
and mark-and sweep garbage collector, object finalizers, co-operative
|
||||
threads a.k.a. coroutines, tail calls, built-in logging and module frameworks,
|
||||
a built-in debugger protocol, function bytecode dump/load, and so on.
|
||||
|
||||
You can browse Duktape programmer's API and other documentation at:
|
||||
|
||||
* http://duktape.org/
|
||||
|
||||
In particular, you should read the getting started section:
|
||||
|
||||
* http://duktape.org/guide.html#gettingstarted
|
||||
|
||||
More examples and how-to articles are in the Duktape Wiki:
|
||||
|
||||
* http://wiki.duktape.org/
|
||||
|
||||
Building and integrating Duktape into your project is very straightforward:
|
||||
|
||||
* http://duktape.org/guide.html#compiling
|
||||
|
||||
See Makefile.hello for a concrete example::
|
||||
|
||||
$ cd <dist_root>
|
||||
$ make -f Makefile.hello
|
||||
[...]
|
||||
$ ./hello
|
||||
Hello world!
|
||||
2+3=5
|
||||
|
||||
To build an example command line tool, use the following::
|
||||
|
||||
$ cd <dist_root>
|
||||
$ make -f Makefile.cmdline
|
||||
[...]
|
||||
|
||||
$ ./duk
|
||||
((o) Duktape
|
||||
duk> print('Hello world!');
|
||||
Hello world!
|
||||
= undefined
|
||||
|
||||
$ ./duk mandel.js
|
||||
[...]
|
||||
|
||||
This distributable contains:
|
||||
|
||||
* ``src/``: main Duktape library in a "single source file" format (duktape.c,
|
||||
duktape.h, and duk_config.h).
|
||||
|
||||
* ``src-noline/``: contains a variant of ``src/duktape.c`` with no ``#line``
|
||||
directives which is preferable for some users. See discussion in
|
||||
https://github.com/svaarala/duktape/pull/363.
|
||||
|
||||
* ``src-separate/``: main Duktape library in multiple files format.
|
||||
|
||||
* ``config/``: genconfig utility for creating duk_config.h configuration
|
||||
files, see: http://wiki.duktape.org/Configuring.html.
|
||||
|
||||
* ``examples/``: further examples for using Duktape. Although Duktape
|
||||
itself is widely portable, some of the examples are Linux only.
|
||||
For instance the ``eventloop`` example illustrates how ``setTimeout()``
|
||||
and other standard timer functions could be implemented on Unix/Linux.
|
||||
|
||||
* ``extras/``: utilities and modules which don't comfortably fit into the
|
||||
main Duktape library because of footprint or portability concerns.
|
||||
Extras are maintained and bug fixed code, but don't have the same version
|
||||
guarantees as the main Duktape library.
|
||||
|
||||
* ``polyfills/``: a few replacement suggestions for non-standard Javascript
|
||||
functions provided by other implementations.
|
||||
|
||||
* ``debugger/``: a debugger with a web UI, see ``debugger/README.rst`` and
|
||||
https://github.com/svaarala/duktape/blob/master/doc/debugger.rst for
|
||||
details on Duktape debugger support. Also contains a JSON debug proxy
|
||||
(one written in Node.js and another in DukLuv) to make talking to the
|
||||
debug target easier.
|
||||
|
||||
* ``licenses/``: licensing information.
|
||||
|
||||
You can find release notes at:
|
||||
|
||||
* https://github.com/svaarala/duktape/blob/master/RELEASES.rst
|
||||
|
||||
This distributable contains Duktape version 1.5.1, created from git
|
||||
commit 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e (v1.5.1).
|
||||
|
||||
Duktape is copyrighted by its authors (see ``AUTHORS.rst``) and licensed
|
||||
under the MIT license (see ``LICENSE.txt``). String hashing algorithms are
|
||||
based on the algorithm from Lua (MIT license), djb2 hash, and Murmurhash2
|
||||
(MIT license). Duktape module loader is based on the CommonJS module
|
||||
loading specification (without sharing any code), CommonJS is under the
|
||||
MIT license.
|
||||
|
||||
Have fun!
|
||||
|
||||
Sami Vaarala (sami.vaarala@iki.fi)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,150 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="duktape"
|
||||
ProjectGUID=""
|
||||
RootNamespace="duktape"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\PropertySheets\Win32.Debug.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\PropertySheets\Win32.Release.vsprops"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;fi;fd"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Minizip"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{E8D9A652-A354-4374-B6C5-A51EE62749FD}</ProjectGuid>
|
||||
<RootNamespace>duktape</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(SolutionDir)PropertySheets\Platform.$(Configuration).props" />
|
||||
</ImportGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader />
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DisableSpecificWarnings>
|
||||
</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="duktape.h" />
|
||||
<ClInclude Include="duk_config.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="duktape.c" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{20a593ff-2e3f-48c3-89ef-81cd7bdd8898}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{a3b93770-ecab-40a0-93dc-ace6e58b2384}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="duk_config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="duktape.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="duktape.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -48,10 +48,10 @@ static bool TranslateToMemProtect(int OsMemProtection, MEM_PROTECTION & memProte
|
|||
}
|
||||
#endif
|
||||
|
||||
void* AllocateAddressSpace(size_t size)
|
||||
void* AllocateAddressSpace(size_t size, LPVOID lpAddress)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_TOP_DOWN, PAGE_NOACCESS);
|
||||
return VirtualAlloc(lpAddress, size, MEM_RESERVE | MEM_TOP_DOWN, PAGE_NOACCESS);
|
||||
#else
|
||||
void * ptr = mmap((void*)0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
|
|
|
@ -8,7 +8,7 @@ enum MEM_PROTECTION
|
|||
MEM_EXECUTE_READWRITE,
|
||||
};
|
||||
|
||||
void* AllocateAddressSpace(size_t size);
|
||||
void* AllocateAddressSpace(size_t size, LPVOID lpAddress = NULL);
|
||||
bool FreeAddressSpace(void* addr, size_t size);
|
||||
void* CommitMemory(void* addr, size_t size, MEM_PROTECTION memProtection);
|
||||
bool DecommitMemory(void* addr, size_t size);
|
||||
|
|
|
@ -34,6 +34,8 @@ Source: "{#BaseDir}\Plugin\GFX\Jabo_Direct3D8.dll"; DestDir: "{app}\Plugin\GFX"
|
|||
Source: "{#BaseDir}\Plugin\GFX\Project64-Video.dll"; DestDir: "{app}\Plugin\GFX"
|
||||
Source: "{#BaseDir}\Plugin\Input\PJ64_NRage.dll"; DestDir: "{app}\Plugin\Input"
|
||||
Source: "{#BaseDir}\Plugin\RSP\RSP 1.7.dll"; DestDir: "{app}\Plugin\RSP"
|
||||
Source: "{#BaseDir}\Scripts\example.js"; DestDir: "{app}\Scripts"
|
||||
Source: "{#BaseDir}\apidoc.htm"; DestDir: "{app}\apidoc.htm"
|
||||
|
||||
[Dirs]
|
||||
Name: "{app}\Config"; Permissions: everyone-full
|
||||
|
|
|
@ -13,4 +13,7 @@
|
|||
__interface CDebugger
|
||||
{
|
||||
virtual void TLBChanged(void) = 0;
|
||||
virtual bool CPUStepStarted(void) = 0;
|
||||
virtual void CPUStep(void) = 0;
|
||||
virtual void FrameDrawn(void) = 0;
|
||||
};
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "InterpreterCPU.h"
|
||||
#include "Debugger.h"
|
||||
|
||||
#include <Project64-core/N64System/SystemGlobals.h>
|
||||
#include <Project64-core/N64System/N64Class.h>
|
||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
||||
|
@ -295,15 +298,26 @@ void CInterpreterCPU::ExecuteCPU()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!g_Debugger->CPUStepStarted())
|
||||
{
|
||||
// Skip command if instructed by the debugger
|
||||
PROGRAM_COUNTER += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
g_Debugger->CPUStep();
|
||||
|
||||
/* if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER < 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER));
|
||||
// WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
// WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
} */
|
||||
|
||||
|
||||
m_R4300i_Opcode[Opcode.op]();
|
||||
NextTimer -= CountPerOp;
|
||||
|
||||
|
||||
PROGRAM_COUNTER += 4;
|
||||
switch (R4300iOp::m_NextInstruction)
|
||||
{
|
||||
|
@ -354,6 +368,8 @@ void CInterpreterCPU::ExecuteCPU()
|
|||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CInterpreterCPU::ExecuteOps(int32_t Cycles)
|
||||
{
|
||||
bool & Done = g_System->m_EndEmulation;
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
static void ExecuteCPU();
|
||||
static void ExecuteOps(int32_t Cycles);
|
||||
static void InPermLoop();
|
||||
|
||||
|
||||
private:
|
||||
CInterpreterCPU(); // Disable default constructor
|
||||
CInterpreterCPU(const CInterpreterCPU&); // Disable copy constructor
|
||||
|
|
|
@ -2094,6 +2094,18 @@ void R4300iOp::REGIMM_BGEZAL()
|
|||
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
|
||||
{
|
||||
if (g_Settings->LoadBool(Debugger_Enabled))
|
||||
{
|
||||
if (g_Reg->m_PROGRAM_COUNTER < 0x80000400)
|
||||
{
|
||||
// Break out of possible checksum halt
|
||||
g_Notify->DisplayMessage(5, "Broke out of permanent loop! Invalid checksum?");
|
||||
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
|
||||
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
|
||||
R4300iOp::m_NextInstruction = DELAY_SLOT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
|
|
|
@ -1302,6 +1302,18 @@ void R4300iOp32::REGIMM_BGEZAL()
|
|||
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
|
||||
if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
|
||||
{
|
||||
if (g_Settings->LoadBool(Debugger_Enabled))
|
||||
{
|
||||
if (g_Reg->m_PROGRAM_COUNTER < 0x80000400)
|
||||
{
|
||||
// Break out of possible checksum halt
|
||||
g_Notify->DisplayMessage(5, "Broke out of permanent loop! Invalid checksum?");
|
||||
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
|
||||
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
|
||||
R4300iOp::m_NextInstruction = DELAY_SLOT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
|
||||
{
|
||||
CInterpreterCPU::InPermLoop();
|
||||
|
|
|
@ -59,6 +59,13 @@ union OPCODE
|
|||
unsigned fmt : 5;
|
||||
unsigned : 6;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned : 6;
|
||||
unsigned code : 20;
|
||||
unsigned : 6;
|
||||
};
|
||||
};
|
||||
#pragma warning(pop)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,34 +14,34 @@
|
|||
#include <Project64-core/N64System/SystemGlobals.h>
|
||||
#include <Project64-core/Logging.h>
|
||||
|
||||
const char * CRegName::GPR[32] = { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
||||
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" };
|
||||
const char * CRegName::GPR[32] = { "R0", "AT", "V0", "V1", "A0", "A1", "A2", "A3",
|
||||
"T0", "T1", "T2", "T3", "T4", "T5", "T6", "T7",
|
||||
"S0", "S1", "S2", "S3", "S4", "S5", "S6", "S7",
|
||||
"T8", "T9", "K0", "K1", "GP", "SP", "FP", "RA" };
|
||||
|
||||
const char *CRegName::GPR_Hi[32] = { "r0.HI", "at.HI", "v0.HI", "v1.HI", "a0.HI", "a1.HI",
|
||||
"a2.HI", "a3.HI", "t0.HI", "t1.HI", "t2.HI", "t3.HI",
|
||||
"t4.HI", "t5.HI", "t6.HI", "t7.HI", "s0.HI", "s1.HI",
|
||||
"s2.HI", "s3.HI", "s4.HI", "s5.HI", "s6.HI", "s7.HI",
|
||||
"t8.HI", "t9.HI", "k0.HI", "k1.HI", "gp.HI", "sp.HI",
|
||||
"s8.HI", "ra.HI" };
|
||||
"fp.HI", "ra.HI" };
|
||||
|
||||
const char *CRegName::GPR_Lo[32] = { "r0.LO", "at.LO", "v0.LO", "v1.LO", "a0.LO", "a1.LO",
|
||||
"a2.LO", "a3.LO", "t0.LO", "t1.LO", "t2.LO", "t3.LO",
|
||||
"t4.LO", "t5.LO", "t6.LO", "t7.LO", "s0.LO", "s1.LO",
|
||||
"s2.LO", "s3.LO", "s4.LO", "s5.LO", "s6.LO", "s7.LO",
|
||||
"t8.LO", "t9.LO", "k0.LO", "k1.LO", "gp.LO", "sp.LO",
|
||||
"s8.LO", "ra.LO" };
|
||||
"fp.LO", "ra.LO" };
|
||||
|
||||
const char * CRegName::Cop0[32] = { "Index", "Random", "EntryLo0", "EntryLo1", "Context", "PageMask", "Wired", "",
|
||||
"BadVAddr", "Count", "EntryHi", "Compare", "Status", "Cause", "EPC", "PRId",
|
||||
"Config", "LLAddr", "WatchLo", "WatchHi", "XContext", "", "", "",
|
||||
"", "", "ECC", "CacheErr", "TagLo", "TagHi", "ErrEPC", "" };
|
||||
|
||||
const char * CRegName::FPR[32] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
||||
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
||||
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" };
|
||||
const char * CRegName::FPR[32] = { "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
|
||||
"F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
|
||||
"F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
|
||||
"F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31" };
|
||||
|
||||
const char * CRegName::FPR_Ctrl[32] = { "Revision", "Unknown", "Unknown", "Unknown", "Unknown",
|
||||
"Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
|
||||
|
@ -574,4 +574,4 @@ void CRegisters::DoSysCallException(bool DelaySlot)
|
|||
}
|
||||
STATUS_REGISTER |= STATUS_EXL;
|
||||
m_PROGRAM_COUNTER = 0x80000180;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1006,7 +1006,18 @@ void CN64System::ExecuteCPU()
|
|||
_controlfp(_PC_53, _MCW_PC);
|
||||
#endif
|
||||
|
||||
switch ((CPU_TYPE)g_Settings->LoadDword(Game_CpuType))
|
||||
CPU_TYPE cpuType;
|
||||
|
||||
if (g_Settings->LoadBool(Setting_ForceInterpreterCPU))
|
||||
{
|
||||
cpuType = CPU_Interpreter;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpuType = (CPU_TYPE)g_Settings->LoadDword(Game_CpuType);
|
||||
}
|
||||
|
||||
switch (cpuType)
|
||||
{
|
||||
case CPU_Recompiler: ExecuteRecompiler(); break;
|
||||
case CPU_SyncCores: ExecuteSyncCPU(); break;
|
||||
|
@ -2128,6 +2139,7 @@ void CN64System::RefreshScreen()
|
|||
{
|
||||
WriteTrace(TraceGFXPlugin, TraceDebug, "UpdateScreen Starting");
|
||||
g_Plugins->Gfx()->UpdateScreen();
|
||||
g_Debugger->FrameDrawn();
|
||||
WriteTrace(TraceGFXPlugin, TraceDebug, "UpdateScreen Done");
|
||||
}
|
||||
__except_catch()
|
||||
|
@ -2201,4 +2213,4 @@ void CN64System::TLB_Changed()
|
|||
{
|
||||
g_Debugger->TLBChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
<ClInclude Include="3rdParty\7zip.h" />
|
||||
<ClInclude Include="3rdParty\zip.h" />
|
||||
<ClInclude Include="AppInit.h" />
|
||||
<ClInclude Include="Debugger.h" />
|
||||
<ClInclude Include="ExceptionHandler.h" />
|
||||
<ClInclude Include="Logging.h" />
|
||||
<ClInclude Include="Multilanguage.h" />
|
||||
|
@ -235,4 +236,8 @@
|
|||
</ProjectReference>
|
||||
<ProjectReference Include="..\Common\Common.vcxproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ClassDiagram.cd" />
|
||||
<None Include="ClassDiagram1.cd" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -539,6 +539,9 @@
|
|||
<ClInclude Include="N64System\Recompiler\SectionInfo.h">
|
||||
<Filter>Header Files\N64 System\Recompiler</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Recompiler\X86ops.h">
|
||||
<Filter>Header Files\N64 System\Recompiler</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Mips\Audio.h">
|
||||
<Filter>Header Files\N64 System\Mips</Filter>
|
||||
</ClInclude>
|
||||
|
@ -653,5 +656,12 @@
|
|||
<ClInclude Include="N64System\Recompiler\x64-86\x64RegInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debugger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ClassDiagram.cd" />
|
||||
<None Include="ClassDiagram1.cd" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -48,6 +48,7 @@ enum SettingID
|
|||
Setting_AutoStart,
|
||||
Setting_CheckEmuRunning,
|
||||
Setting_EraseGameDefaults,
|
||||
Setting_ForceInterpreterCPU,
|
||||
|
||||
Setting_AutoZipInstantSave,
|
||||
Setting_RememberCheats,
|
||||
|
|
|
@ -112,6 +112,8 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
|
|||
AddHandler(Setting_AutoZipInstantSave, new CSettingTypeApplication("", "Auto Zip Saves", (uint32_t)true));
|
||||
AddHandler(Setting_EraseGameDefaults, new CSettingTypeApplication("", "Erase on default", (uint32_t)true));
|
||||
AddHandler(Setting_CheckEmuRunning, new CSettingTypeApplication("", "Check Running", (uint32_t)true));
|
||||
AddHandler(Setting_ForceInterpreterCPU, new CSettingTypeApplication("", "Force Interpreter CPU", false));
|
||||
|
||||
|
||||
AddHandler(Setting_RememberCheats, new CSettingTypeApplication("", "Remember Cheats", (uint32_t)false));
|
||||
#ifdef ANDROID
|
||||
|
@ -1277,4 +1279,4 @@ void CSettings::UnregisterChangeCB(SettingID Type, void * Data, SettingChangedFu
|
|||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,343 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Assembler.h"
|
||||
#include "Project64-core\N64System\Mips\OpCode.h"
|
||||
|
||||
REGISTER* lookup_register(char* name);
|
||||
|
||||
static int parse_error = 0;
|
||||
static uint32_t m_Address = 0x00000000;
|
||||
|
||||
void to_lower(char* str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str >= 'A' && *str <= 'Z')
|
||||
{
|
||||
*str |= 0x20;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pop_reg()
|
||||
{
|
||||
char* r = strtok(NULL, " \t,()");
|
||||
|
||||
if (r == NULL)
|
||||
{
|
||||
parse_error = ERR_EXPECTED_REG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
REGISTER* reg = lookup_register(r);
|
||||
|
||||
if (reg == NULL)
|
||||
{
|
||||
parse_error = ERR_INVALID_REG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reg->val;
|
||||
}
|
||||
|
||||
uint32_t pop_val()
|
||||
{
|
||||
char* v = strtok(NULL, " \t,()");
|
||||
|
||||
if (isalpha(*v))
|
||||
{
|
||||
// todo lookup label value
|
||||
return 0;
|
||||
}
|
||||
|
||||
int base = 0; // hex or dec
|
||||
|
||||
if (*v == '$')
|
||||
{
|
||||
base = 16; // hex
|
||||
v++;
|
||||
}
|
||||
|
||||
char* endptr;
|
||||
|
||||
uint32_t val = strtoul(v, &endptr, base);
|
||||
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
parse_error = ERR_EXPECTED_VAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t base_op(uint32_t val)
|
||||
{
|
||||
return val << 26;
|
||||
}
|
||||
|
||||
uint32_t base_spec(uint32_t val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t base_regimm(uint32_t val)
|
||||
{
|
||||
return (R4300i_REGIMM << 26) | (val << 16);
|
||||
}
|
||||
|
||||
void arg_reg_s(uint32_t* opcode)
|
||||
{
|
||||
*opcode |= pop_reg() << 21;
|
||||
}
|
||||
|
||||
void arg_reg_t(uint32_t* opcode)
|
||||
{
|
||||
*opcode |= pop_reg() << 16;
|
||||
}
|
||||
|
||||
void arg_reg_d(uint32_t* opcode)
|
||||
{
|
||||
*opcode |= pop_reg() << 11;
|
||||
}
|
||||
|
||||
void arg_jump(uint32_t* opcode)
|
||||
{
|
||||
*opcode |= (pop_val() / 4) & 0x3FFFFFF;
|
||||
}
|
||||
|
||||
void arg_imm16(uint32_t* opcode)
|
||||
{
|
||||
*opcode |= (pop_val() & 0xFFFF);
|
||||
}
|
||||
|
||||
void arg_bra_target(uint32_t* opcode)
|
||||
{
|
||||
uint16_t relTarget = (((pop_val() - m_Address) / 4) & 0xFFFF) - 1;
|
||||
*opcode |= relTarget;
|
||||
}
|
||||
|
||||
void arg_shamt(uint32_t* opcode)
|
||||
{
|
||||
*opcode |= (pop_val() & 0x1F) << 6;
|
||||
}
|
||||
|
||||
SYNTAX syn_jump[] = { arg_jump, NULL };
|
||||
SYNTAX syn_loadstore[] = { arg_reg_t, arg_imm16, arg_reg_s, NULL };
|
||||
SYNTAX syn_arith[] = { arg_reg_d, arg_reg_s, arg_reg_t, NULL };
|
||||
SYNTAX syn_arith_i[] = { arg_reg_t, arg_reg_s, arg_imm16, NULL };
|
||||
SYNTAX syn_load_i[] = { arg_reg_t, arg_imm16, NULL };
|
||||
|
||||
SYNTAX syn_branch_z[] = { arg_reg_s, arg_bra_target, NULL };
|
||||
SYNTAX syn_branch[] = { arg_reg_s, arg_reg_t, arg_bra_target, NULL };
|
||||
SYNTAX syn_branch_unc[] = { arg_bra_target, NULL };
|
||||
|
||||
SYNTAX syn_trap_i[] = { arg_reg_s, arg_imm16, NULL };
|
||||
|
||||
SYNTAX syn_shift[] = { arg_reg_d, arg_reg_t, arg_shamt, NULL };
|
||||
|
||||
SYNTAX syn_mf[] = { arg_reg_d, NULL };
|
||||
SYNTAX syn_jr[] = { arg_reg_s, NULL };
|
||||
|
||||
INSTRUCTION instructions[] =
|
||||
{
|
||||
{ "j", R4300i_J, base_op, syn_jump },
|
||||
{ "jal", R4300i_JAL, base_op, syn_jump },
|
||||
{ "beq", R4300i_BEQ, base_op, syn_branch },
|
||||
{ "beqz", R4300i_BEQ, base_op, syn_branch_z },
|
||||
{ "b", R4300i_BEQ, base_op, syn_branch_unc },
|
||||
{ "bne", R4300i_BNE, base_op, syn_branch },
|
||||
{ "bnez", R4300i_BNE, base_op, syn_branch_z },
|
||||
{ "blez", R4300i_BLEZ, base_op, syn_branch_z },
|
||||
{ "bgtz", R4300i_BGTZ, base_op, syn_branch_z },
|
||||
{ "addi", R4300i_ADDI, base_op, syn_arith_i },
|
||||
{ "addiu", R4300i_ADDIU, base_op, syn_arith_i },
|
||||
{ "slti", R4300i_SLTI, base_op, syn_arith_i },
|
||||
{ "sltiu", R4300i_SLTIU, base_op, syn_arith_i },
|
||||
{ "andi", R4300i_ANDI, base_op, syn_arith_i },
|
||||
{ "ori", R4300i_ORI, base_op, syn_arith_i },
|
||||
{ "xori", R4300i_XORI, base_op, syn_arith_i },
|
||||
{ "lui", R4300i_LUI, base_op, syn_load_i },
|
||||
// cp0 cp1
|
||||
{ "beql", R4300i_BEQL, base_op, syn_branch },
|
||||
{ "beqzl", R4300i_BEQL, base_op, syn_branch_z },
|
||||
{ "bnel", R4300i_BNEL, base_op, syn_branch },
|
||||
{ "bnezl", R4300i_BNEL, base_op, syn_branch_z },
|
||||
{ "blezl", R4300i_BLEZL, base_op, syn_branch_z },
|
||||
{ "bgtzl", R4300i_BGTZL, base_op, syn_branch_z },
|
||||
{ "daddi", R4300i_DADDI, base_op, syn_arith_i },
|
||||
{ "daddiu", R4300i_DADDI, base_op, syn_arith_i },
|
||||
{ "ldl", R4300i_LDL, base_op, syn_loadstore },
|
||||
{ "ldr", R4300i_LDR, base_op, syn_loadstore },
|
||||
{ "lb", R4300i_LB, base_op, syn_loadstore },
|
||||
{ "lh", R4300i_LH, base_op, syn_loadstore },
|
||||
{ "lwl", R4300i_LWL, base_op, syn_loadstore },
|
||||
{ "lw", R4300i_LW, base_op, syn_loadstore },
|
||||
{ "lbu", R4300i_LBU, base_op, syn_loadstore },
|
||||
{ "lhu", R4300i_LHU, base_op, syn_loadstore },
|
||||
{ "lwr", R4300i_LWR, base_op, syn_loadstore },
|
||||
{ "lwu", R4300i_LWU, base_op, syn_loadstore },
|
||||
{ "sb", R4300i_SB, base_op, syn_loadstore },
|
||||
{ "sh", R4300i_SH, base_op, syn_loadstore },
|
||||
{ "swl", R4300i_SWL, base_op, syn_loadstore },
|
||||
{ "sw", R4300i_SW, base_op, syn_loadstore },
|
||||
{ "sdl", R4300i_SDL, base_op, syn_loadstore },
|
||||
{ "sdr", R4300i_SDR, base_op, syn_loadstore },
|
||||
{ "swr", R4300i_SWR, base_op, syn_loadstore },
|
||||
//{ "cache", R4300i_CACHE, base_op, },
|
||||
{ "ll", R4300i_LL, base_op, syn_loadstore },
|
||||
{ "lwc1", R4300i_LWC1, base_op, syn_loadstore },
|
||||
{ "ldc1", R4300i_LDC1, base_op, syn_loadstore },
|
||||
{ "ld", R4300i_LD, base_op, syn_loadstore },
|
||||
{ "sc", R4300i_SC, base_op, syn_loadstore },
|
||||
{ "swc1", R4300i_SWC1, base_op, syn_loadstore },
|
||||
{ "sdc1", R4300i_SDC1, base_op, syn_loadstore },
|
||||
{ "sdc2", R4300i_SDC2, base_op, syn_loadstore },
|
||||
{ "sd", R4300i_SD, base_op, syn_loadstore },
|
||||
|
||||
{ "bltz", R4300i_REGIMM_BLTZ, base_regimm, syn_branch_z },
|
||||
{ "bgez", R4300i_REGIMM_BGEZ, base_regimm, syn_branch_z },
|
||||
{ "bltzl", R4300i_REGIMM_BLTZL, base_regimm, syn_branch_z },
|
||||
{ "bgezl", R4300i_REGIMM_BGEZL, base_regimm, syn_branch_z },
|
||||
{ "tgei", R4300i_REGIMM_TGEI, base_regimm, syn_trap_i },
|
||||
{ "tgeiu", R4300i_REGIMM_TGEIU, base_regimm, syn_trap_i },
|
||||
{ "tlti", R4300i_REGIMM_TLTIU, base_regimm, syn_trap_i },
|
||||
{ "tltiu", R4300i_REGIMM_TLTIU, base_regimm, syn_trap_i },
|
||||
{ "teqi", R4300i_REGIMM_TEQI, base_regimm, syn_trap_i },
|
||||
{ "tnei", R4300i_REGIMM_TNEI, base_regimm, syn_trap_i },
|
||||
{ "bltzal", R4300i_REGIMM_BLTZAL, base_regimm, syn_branch_z },
|
||||
{ "bgezal", R4300i_REGIMM_BGEZAL, base_regimm, syn_branch_z },
|
||||
{ "bal", R4300i_REGIMM_BGEZAL, base_regimm, syn_branch_unc },
|
||||
{ "bltzall", R4300i_REGIMM_BLTZALL, base_regimm, syn_branch_z },
|
||||
{ "bgezall", R4300i_REGIMM_BGEZALL, base_regimm, syn_branch_z },
|
||||
|
||||
{ "sll", R4300i_SPECIAL_SLL, base_spec, syn_shift },
|
||||
{ "nop", R4300i_SPECIAL_SLL, base_spec, NULL },
|
||||
{ "srl", R4300i_SPECIAL_SRL, base_spec, syn_shift },
|
||||
{ "sra", R4300i_SPECIAL_SRA, base_spec, syn_shift },
|
||||
|
||||
{ "jr", R4300i_SPECIAL_JR, base_spec, syn_jr },
|
||||
{ "syscall", R4300i_SPECIAL_SYSCALL, base_spec, NULL },
|
||||
{ "break", R4300i_SPECIAL_BREAK, base_spec, NULL },
|
||||
{ "sync", R4300i_SPECIAL_SYNC, base_spec, NULL },
|
||||
|
||||
{ "mfhi", R4300i_SPECIAL_MFHI, base_spec, syn_mf },
|
||||
{ "mthi", R4300i_SPECIAL_MTHI, base_spec, syn_mf },
|
||||
{ "mflo", R4300i_SPECIAL_MFLO, base_spec, syn_mf },
|
||||
{ "mtlo", R4300i_SPECIAL_MTLO, base_spec, syn_mf },
|
||||
|
||||
{ "add", R4300i_SPECIAL_ADD, base_spec, syn_arith },
|
||||
{ "addu", R4300i_SPECIAL_ADDU, base_spec, syn_arith },
|
||||
{ "sub", R4300i_SPECIAL_SUB, base_spec, syn_arith },
|
||||
{ "subu", R4300i_SPECIAL_SUBU, base_spec, syn_arith },
|
||||
{ "and", R4300i_SPECIAL_AND, base_spec, syn_arith },
|
||||
{ "or", R4300i_SPECIAL_OR, base_spec, syn_arith },
|
||||
{ "xor", R4300i_SPECIAL_XOR, base_spec, syn_arith },
|
||||
{ "nor", R4300i_SPECIAL_NOR, base_spec, syn_arith },
|
||||
{ "slt", R4300i_SPECIAL_SLT, base_spec, syn_arith },
|
||||
{ "sltu", R4300i_SPECIAL_SLTU, base_spec, syn_arith },
|
||||
{ "dadd", R4300i_SPECIAL_DADD, base_spec, syn_arith },
|
||||
{ "daddu", R4300i_SPECIAL_DADDU, base_spec, syn_arith },
|
||||
{ "dsub", R4300i_SPECIAL_DSUB, base_spec, syn_arith },
|
||||
{ "dsubu", R4300i_SPECIAL_DSUBU, base_spec, syn_arith },
|
||||
|
||||
{ "dsll", R4300i_SPECIAL_DSLL, base_spec, syn_shift },
|
||||
{ "dsrl", R4300i_SPECIAL_DSRL, base_spec, syn_shift },
|
||||
{ "dsra", R4300i_SPECIAL_DSRA, base_spec, syn_shift },
|
||||
{ "dsll32", R4300i_SPECIAL_DSLL32, base_spec, syn_shift },
|
||||
{ "dsrl32", R4300i_SPECIAL_DSRL32, base_spec, syn_shift },
|
||||
{ "dsra32", R4300i_SPECIAL_DSRA32, base_spec, syn_shift },
|
||||
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
REGISTER registers[] =
|
||||
{
|
||||
{ "r0", 0 },{ "at", 1 },{ "v0", 2 },{ "v1", 3 },{ "a0", 4 },{ "a1", 5 },{ "a2", 6 },{ "a3", 7 },
|
||||
{ "t0", 8 },{ "t1", 9 },{ "t2", 10 },{ "t3", 11 },{ "t4", 12 },{ "t5", 13 },{ "t6", 14 },{ "t7", 15 },
|
||||
{ "s0", 16 },{ "s1", 17 },{ "s2", 18 },{ "s3", 19 },{ "s4", 20 },{ "s5", 21 },{ "s6", 22 },{ "s7", 23 },
|
||||
{ "t8", 24 },{ "t9", 25 },{ "k0", 26 },{ "k1", 27 },{ "gp", 28 },{ "sp", 29 },{ "s8", 30 },{ "ra", 31 },
|
||||
|
||||
{ "fp", 30 },
|
||||
|
||||
{ "f0", 0 },{ "f1", 1 },{ "f2", 2 },{ "f3", 3 },{ "f4", 4 },{ "f5", 5 },{ "f6", 6 },{ "f7", 7 },
|
||||
{ "f8", 8 },{ "f9", 9 },{ "f10", 10 },{ "f11", 11 },{ "f12", 12 },{ "f13", 13 },{ "f14", 14 },{ "f15", 15 },
|
||||
{ "f16", 16 },{ "f17", 17 },{ "f18", 18 },{ "f19", 19 },{ "f20", 20 },{ "f21", 21 },{ "f22", 22 },{ "f23", 23 },
|
||||
{ "f24", 24 },{ "f25", 25 },{ "f26", 26 },{ "f27", 27 },{ "f28", 28 },{ "f29", 29 },{ "f30", 30 },{ "f31", 31 },
|
||||
|
||||
{ "r0", 0 },{ "r1", 1 },{ "r2", 2 },{ "r3", 3 },{ "r4", 4 },{ "r5", 5 },{ "r6", 6 },{ "r7", 7 },
|
||||
{ "r8", 8 },{ "r9", 9 },{ "r10", 10 },{ "r11", 11 },{ "r12", 12 },{ "r13", 13 },{ "r14", 14 },{ "r15", 15 },
|
||||
{ "r16", 16 },{ "r17", 17 },{ "r18", 18 },{ "r19", 19 },{ "r20", 20 },{ "r21", 21 },{ "r22", 22 },{ "r23", 23 },
|
||||
{ "r24", 24 },{ "r25", 25 },{ "r26", 26 },{ "r27", 27 },{ "r28", 28 },{ "r29", 29 },{ "r30", 30 },{ "r31", 31 },
|
||||
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
INSTRUCTION* lookup_instruction(char* name)
|
||||
{
|
||||
for (int i = 0; instructions[i].name != NULL; i++)
|
||||
{
|
||||
if (strcmp(name, instructions[i].name) == 0)
|
||||
{
|
||||
return &instructions[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
REGISTER* lookup_register(char* name)
|
||||
{
|
||||
for (int i = 0; registers[i].name != NULL; i++)
|
||||
{
|
||||
if (strcmp(name, registers[i].name) == 0)
|
||||
{
|
||||
return ®isters[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CAssembler::AssembleLine(char* line, uint32_t* opcode, uint32_t address)
|
||||
{
|
||||
m_Address = address;
|
||||
char line_c[128];
|
||||
strncpy(line_c, line, 128);
|
||||
|
||||
to_lower(line_c);
|
||||
|
||||
if (line_c[0] == '\0')
|
||||
{
|
||||
*opcode = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
char* name = strtok(line_c, " \t");
|
||||
|
||||
INSTRUCTION* instruction = lookup_instruction(name);
|
||||
|
||||
if (instruction == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*opcode = instruction->base(instruction->val);
|
||||
|
||||
if (instruction->syntax == NULL)
|
||||
{
|
||||
// No parameters
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; instruction->syntax[i]; i++)
|
||||
{
|
||||
instruction->syntax[i](opcode);
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef void(*SYNTAX)(uint32_t* opcode);
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
uint32_t val;
|
||||
uint32_t(*base)(uint32_t val); // value shift
|
||||
SYNTAX* syntax; // arguments
|
||||
} INSTRUCTION;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
uint32_t val;
|
||||
} REGISTER;
|
||||
|
||||
enum ParseError
|
||||
{
|
||||
ERR_NONE,
|
||||
ERR_EXPECTED_REG,
|
||||
ERR_INVALID_REG,
|
||||
ERR_EXPECTED_VAL
|
||||
};
|
||||
|
||||
class CAssembler {
|
||||
public:
|
||||
static bool AssembleLine(char* line, uint32_t* opcode, uint32_t address = 0x00000000);
|
||||
};
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Breakpoints.h"
|
||||
|
||||
#include <Project64-core/N64System/Mips/RegisterClass.h>
|
||||
#include <Project64-core/N64System/SystemGlobals.h>
|
||||
#include <Project64-core/N64System/Mips/OpcodeName.h>
|
||||
#include <Project64-core/N64System/N64Class.h>
|
||||
|
||||
//BOOL CBreakpoints::m_Debugging = FALSE;
|
||||
//BOOL CBreakpoints::m_Skipping = FALSE;
|
||||
//
|
||||
//std::vector<uint32_t> CBreakpoints::m_RBP;
|
||||
//std::vector<uint32_t> CBreakpoints::m_WBP;
|
||||
//std::vector<uint32_t> CBreakpoints::m_EBP;
|
||||
//
|
||||
//int CBreakpoints::m_nRBP = 0;
|
||||
//int CBreakpoints::m_nWBP = 0;
|
||||
//int CBreakpoints::m_nEBP = 0;
|
||||
|
||||
CBreakpoints::CBreakpoints()
|
||||
{
|
||||
m_Debugging = FALSE;
|
||||
m_Skipping = FALSE;
|
||||
m_nRBP = 0;
|
||||
m_nWBP = 0;
|
||||
m_nEBP = 0;
|
||||
}
|
||||
|
||||
void CBreakpoints::Pause()
|
||||
{
|
||||
KeepDebugging();
|
||||
g_System->Pause();
|
||||
}
|
||||
|
||||
void CBreakpoints::Resume()
|
||||
{
|
||||
g_System->ExternalEvent(SysEvent_ResumeCPU_FromMenu);
|
||||
}
|
||||
|
||||
BOOL CBreakpoints::isDebugging()
|
||||
{
|
||||
return m_Debugging;
|
||||
}
|
||||
|
||||
void CBreakpoints::KeepDebugging()
|
||||
{
|
||||
m_Debugging = TRUE;
|
||||
}
|
||||
|
||||
void CBreakpoints::StopDebugging()
|
||||
{
|
||||
m_Debugging = FALSE;
|
||||
}
|
||||
|
||||
void CBreakpoints::Skip()
|
||||
{
|
||||
m_Skipping = TRUE;
|
||||
}
|
||||
|
||||
bool CBreakpoints::RBPAdd(uint32_t address, bool bTemporary)
|
||||
{
|
||||
if (!RBPExists(address))
|
||||
{
|
||||
m_RBP.push_back({ address, bTemporary });
|
||||
m_nRBP = m_RBP.size();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBreakpoints::WBPAdd(uint32_t address, bool bTemporary)
|
||||
{
|
||||
if (!WBPExists(address))
|
||||
{
|
||||
m_WBP.push_back({ address, bTemporary });
|
||||
m_nWBP = m_WBP.size();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBreakpoints::EBPAdd(uint32_t address, bool bTemporary)
|
||||
{
|
||||
if (!EBPExists(address))
|
||||
{
|
||||
m_EBP.push_back({ address, bTemporary });
|
||||
m_nEBP = m_EBP.size();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBreakpoints::RBPRemove(uint32_t address)
|
||||
{
|
||||
for (int i = 0; i < m_nRBP; i++)
|
||||
{
|
||||
if (m_RBP[i].address == address)
|
||||
{
|
||||
m_RBP.erase(m_RBP.begin() + i);
|
||||
m_nRBP = m_RBP.size();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBreakpoints::WBPRemove(uint32_t address)
|
||||
{
|
||||
for (int i = 0; i < m_nWBP; i++)
|
||||
{
|
||||
if (m_WBP[i].address == address)
|
||||
{
|
||||
m_WBP.erase(m_WBP.begin() + i);
|
||||
m_nWBP = m_WBP.size();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBreakpoints::EBPRemove(uint32_t address)
|
||||
{
|
||||
for (int i = 0; i < m_nEBP; i++)
|
||||
{
|
||||
if (m_EBP[i].address == address)
|
||||
{
|
||||
m_EBP.erase(m_EBP.begin() + i);
|
||||
m_nEBP = m_EBP.size();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBreakpoints::RBPToggle(uint32_t address, bool bTemporary)
|
||||
{
|
||||
if (RBPAdd(address, bTemporary) == false)
|
||||
{
|
||||
RBPRemove(address);
|
||||
}
|
||||
}
|
||||
|
||||
void CBreakpoints::WBPToggle(uint32_t address, bool bTemporary)
|
||||
{
|
||||
if (WBPAdd(address, bTemporary) == false)
|
||||
{
|
||||
WBPRemove(address);
|
||||
}
|
||||
}
|
||||
|
||||
void CBreakpoints::EBPToggle(uint32_t address, bool bTemporary)
|
||||
{
|
||||
if (EBPAdd(address, bTemporary) == false)
|
||||
{
|
||||
EBPRemove(address);
|
||||
}
|
||||
}
|
||||
|
||||
void CBreakpoints::RBPClear()
|
||||
{
|
||||
m_RBP.clear();
|
||||
m_nRBP = 0;
|
||||
}
|
||||
|
||||
void CBreakpoints::WBPClear()
|
||||
{
|
||||
m_WBP.clear();
|
||||
m_nWBP = 0;
|
||||
}
|
||||
|
||||
void CBreakpoints::EBPClear()
|
||||
{
|
||||
m_EBP.clear();
|
||||
m_nEBP = 0;
|
||||
}
|
||||
|
||||
void CBreakpoints::BPClear()
|
||||
{
|
||||
RBPClear();
|
||||
WBPClear();
|
||||
EBPClear();
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class CBreakpoints {
|
||||
private:
|
||||
|
||||
public:
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
bool bTemporary;
|
||||
} BREAKPOINT;
|
||||
|
||||
enum BPSTATE {
|
||||
BP_NOT_SET = FALSE,
|
||||
BP_SET,
|
||||
BP_SET_TEMP
|
||||
};
|
||||
|
||||
CBreakpoints();
|
||||
|
||||
BOOL m_Debugging;
|
||||
BOOL m_Skipping;
|
||||
|
||||
std::vector<BREAKPOINT> m_RBP;
|
||||
std::vector<BREAKPOINT> m_WBP;
|
||||
std::vector<BREAKPOINT> m_EBP;
|
||||
|
||||
int m_nRBP;
|
||||
int m_nWBP;
|
||||
int m_nEBP;
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Skip();
|
||||
|
||||
BOOL isDebugging();
|
||||
void KeepDebugging();
|
||||
void StopDebugging();
|
||||
inline BOOL isSkipping()
|
||||
{
|
||||
BOOL ret = m_Skipping;
|
||||
m_Skipping = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RBPAdd(uint32_t address, bool bTemporary = false);
|
||||
void RBPRemove(uint32_t address);
|
||||
void RBPToggle(uint32_t address, bool bTemporary = false);
|
||||
void RBPClear();
|
||||
|
||||
bool WBPAdd(uint32_t address, bool bTemporary = false);
|
||||
void WBPRemove(uint32_t address);
|
||||
void WBPToggle(uint32_t address, bool bTemporary = false);
|
||||
void WBPClear();
|
||||
|
||||
bool EBPAdd(uint32_t address, bool bTemporary = false);
|
||||
void EBPRemove(uint32_t address);
|
||||
void EBPToggle(uint32_t address, bool bTemporary = false);
|
||||
void EBPClear();
|
||||
|
||||
void BPClear();
|
||||
|
||||
// inlines
|
||||
|
||||
inline BPSTATE RBPExists(uint32_t address, bool bRemoveTemp = false)
|
||||
{
|
||||
for (int i = 0; i < m_nRBP; i++)
|
||||
{
|
||||
if (m_RBP[i].address != address)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_RBP[i].bTemporary)
|
||||
{
|
||||
if (bRemoveTemp)
|
||||
{
|
||||
RBPRemove(address);
|
||||
}
|
||||
return BP_SET_TEMP;
|
||||
}
|
||||
return BP_SET;
|
||||
}
|
||||
return BP_NOT_SET;
|
||||
}
|
||||
|
||||
inline BPSTATE WBPExists(uint32_t address, bool bRemoveTemp = false)
|
||||
{
|
||||
for (int i = 0; i < m_nWBP; i++)
|
||||
{
|
||||
if (m_WBP[i].address != address)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_WBP[i].bTemporary)
|
||||
{
|
||||
if (bRemoveTemp)
|
||||
{
|
||||
WBPRemove(address);
|
||||
}
|
||||
return BP_SET_TEMP;
|
||||
}
|
||||
return BP_SET;
|
||||
}
|
||||
return BP_NOT_SET;
|
||||
}
|
||||
|
||||
inline BPSTATE EBPExists(uint32_t address, bool bRemoveTemp = false)
|
||||
{
|
||||
for (int i = 0; i < m_nEBP; i++)
|
||||
{
|
||||
if (m_EBP[i].address != address)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_EBP[i].bTemporary)
|
||||
{
|
||||
if (bRemoveTemp)
|
||||
{
|
||||
EBPRemove(address);
|
||||
}
|
||||
return BP_SET_TEMP;
|
||||
}
|
||||
return BP_SET;
|
||||
}
|
||||
return BP_NOT_SET;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,111 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#include "stdafx.h"
|
||||
#include "DMALog.h"
|
||||
|
||||
void CDMALog::AddEntry(uint32_t romAddr, uint32_t ramAddr, uint32_t length)
|
||||
{
|
||||
DMALOGENTRY entry = { romAddr, ramAddr, length };
|
||||
m_Log.push_back(entry);
|
||||
}
|
||||
|
||||
void CDMALog::ClearEntries()
|
||||
{
|
||||
m_Log.clear();
|
||||
}
|
||||
|
||||
size_t CDMALog::GetNumEntries()
|
||||
{
|
||||
return m_Log.size();
|
||||
}
|
||||
|
||||
DMALOGENTRY* CDMALog::GetEntryByIndex(uint32_t index)
|
||||
{
|
||||
if (index < m_Log.size())
|
||||
{
|
||||
return &m_Log[index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DMALOGENTRY* CDMALog::GetEntryByRamAddress(uint32_t ramAddr)
|
||||
{
|
||||
uint32_t nEntries = GetNumEntries();
|
||||
|
||||
if (nEntries == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint32_t i = nEntries - 1; i-- > 0;)
|
||||
{
|
||||
uint32_t min = m_Log[i].ramAddr;
|
||||
uint32_t max = min + m_Log[i].length - 1;
|
||||
|
||||
if (ramAddr >= min && ramAddr <= max)
|
||||
{
|
||||
return &m_Log[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DMALOGENTRY* CDMALog::GetEntryByRamAddress(uint32_t ramAddr, uint32_t* lpRomAddr, uint32_t* lpOffset)
|
||||
{
|
||||
DMALOGENTRY* lpEntry = GetEntryByRamAddress(ramAddr);
|
||||
|
||||
if (lpEntry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*lpOffset = ramAddr - lpEntry->ramAddr;
|
||||
*lpRomAddr = lpEntry->romAddr + *lpOffset;
|
||||
|
||||
return lpEntry;
|
||||
}
|
||||
|
||||
DMALOGENTRY* CDMALog::GetEntryByRomAddress(uint32_t romAddr)
|
||||
{
|
||||
uint32_t nEntries = GetNumEntries();
|
||||
|
||||
if (nEntries == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint32_t i = nEntries - 1; i-- > 0; )
|
||||
{
|
||||
uint32_t min = m_Log[i].romAddr;
|
||||
uint32_t max = min + m_Log[i].length - 1;
|
||||
|
||||
if (romAddr >= min && romAddr <= max)
|
||||
{
|
||||
return &m_Log[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DMALOGENTRY* CDMALog::GetEntryByRomAddress(uint32_t romAddr, uint32_t* lpRamAddr, uint32_t* lpOffset)
|
||||
{
|
||||
DMALOGENTRY* lpEntry = GetEntryByRomAddress(romAddr);
|
||||
|
||||
if (lpEntry == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*lpOffset = romAddr - lpEntry->romAddr;
|
||||
*lpRamAddr = lpEntry->ramAddr + *lpOffset;
|
||||
|
||||
return lpEntry;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdafx.h>
|
||||
|
||||
struct DMALOGENTRY
|
||||
{
|
||||
uint32_t romAddr;
|
||||
uint32_t ramAddr;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
class CDMALog
|
||||
{
|
||||
private:
|
||||
vector<DMALOGENTRY> m_Log;
|
||||
|
||||
public:
|
||||
void AddEntry(uint32_t romAddr, uint32_t ramAddr, uint32_t length);
|
||||
void ClearEntries();
|
||||
size_t GetNumEntries();
|
||||
DMALOGENTRY* GetEntryByIndex(uint32_t index);
|
||||
DMALOGENTRY* GetEntryByRamAddress(uint32_t ramAddr);
|
||||
DMALOGENTRY* GetEntryByRamAddress(uint32_t ramAddr, uint32_t* lpRomAddr, uint32_t* lpOffset);
|
||||
DMALOGENTRY* GetEntryByRomAddress(uint32_t romAddr);
|
||||
DMALOGENTRY* GetEntryByRomAddress(uint32_t romAddr, uint32_t* lpRamAddr, uint32_t* lpOffset);
|
||||
};
|
|
@ -0,0 +1,58 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
LRESULT CAddBreakpointDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
CenterWindow();
|
||||
m_AddressEdit.Attach(GetDlgItem(IDC_ADDR_EDIT));
|
||||
m_ReadCheck.Attach(GetDlgItem(IDC_CHK_READ));
|
||||
m_WriteCheck.Attach(GetDlgItem(IDC_CHK_WRITE));
|
||||
m_ExecuteCheck.Attach(GetDlgItem(IDC_CHK_EXEC));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CAddBreakpointDlg::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
char addrStr[9];
|
||||
m_AddressEdit.GetWindowTextA(addrStr, 9);
|
||||
uint32_t address = strtoul(addrStr, NULL, 16);
|
||||
|
||||
CBreakpoints* breakpoints = m_Debugger->Breakpoints();
|
||||
|
||||
if (m_ReadCheck.GetCheck())
|
||||
{
|
||||
breakpoints->RBPAdd(address);
|
||||
}
|
||||
if (m_WriteCheck.GetCheck())
|
||||
{
|
||||
breakpoints->WBPAdd(address);
|
||||
}
|
||||
if (m_ExecuteCheck.GetCheck())
|
||||
{
|
||||
breakpoints->EBPAdd(address);
|
||||
}
|
||||
EndDialog(0);
|
||||
break;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Modal add breakpoint dialog
|
||||
|
||||
class CAddBreakpointDlg : public CDialogImpl<CAddBreakpointDlg>
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_AddBreakpoint };
|
||||
|
||||
INT_PTR CAddBreakpointDlg::DoModal(CDebuggerUI* debugger)
|
||||
{
|
||||
m_Debugger = debugger;
|
||||
return CDialogImpl<CAddBreakpointDlg>::DoModal();
|
||||
}
|
||||
|
||||
private:
|
||||
CDebuggerUI* m_Debugger;
|
||||
|
||||
CButton m_ReadCheck;
|
||||
CButton m_WriteCheck;
|
||||
CButton m_ExecuteCheck;
|
||||
CEdit m_AddressEdit;
|
||||
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnDestroy(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_MSG_MAP_EX(CAddBreakpointDlg)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
END_MSG_MAP()
|
||||
};
|
|
@ -0,0 +1,131 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "DebuggerUI.h"
|
||||
#include "Symbols.h"
|
||||
|
||||
LRESULT CAddSymbolDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
CenterWindow();
|
||||
|
||||
m_AddressEdit.Attach(GetDlgItem(IDC_ADDR_EDIT));
|
||||
m_AddressEdit.SetDisplayType(CEditNumber::DisplayHex);
|
||||
m_TypeComboBox.Attach(GetDlgItem(IDC_TYPE_COMBOBOX));
|
||||
m_NameEdit.Attach(GetDlgItem(IDC_NAME_EDIT));
|
||||
m_DescriptionEdit.Attach(GetDlgItem(IDC_DESC_EDIT));
|
||||
|
||||
for (int i = 0;; i++)
|
||||
{
|
||||
char* type = CSymbols::SymbolTypes[i];
|
||||
if (type == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
m_TypeComboBox.AddString(type);
|
||||
}
|
||||
|
||||
m_AddressEdit.SetWindowTextA("");
|
||||
m_AddressEdit.SetFocus();
|
||||
|
||||
if (m_bHaveAddress)
|
||||
{
|
||||
m_AddressEdit.SetValue(m_InitAddress, false, true);
|
||||
m_TypeComboBox.SetFocus();
|
||||
}
|
||||
|
||||
if(m_bHaveType)
|
||||
{
|
||||
m_TypeComboBox.SetCurSel(m_InitType);
|
||||
m_NameEdit.SetFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TypeComboBox.SetCurSel(CSymbols::TYPE_DATA);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CAddSymbolDlg::OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
case IDOK:
|
||||
int addrLen = m_AddressEdit.GetWindowTextLengthA();
|
||||
|
||||
if (!addrLen)
|
||||
{
|
||||
MessageBox("Address required", "Error", MB_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t address = m_AddressEdit.GetValue();
|
||||
int type = m_TypeComboBox.GetCurSel();
|
||||
|
||||
int nameLen = m_NameEdit.GetWindowTextLengthA();
|
||||
int descLen = m_DescriptionEdit.GetWindowTextLengthA();
|
||||
|
||||
if (!nameLen && !descLen)
|
||||
{
|
||||
MessageBox("Name and/or description required", "Error", MB_OK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char name[128];
|
||||
char description[256];
|
||||
|
||||
m_NameEdit.GetWindowTextA(name, nameLen + 1);
|
||||
m_DescriptionEdit.GetWindowTextA(description, descLen + 1);
|
||||
|
||||
CSymbols::EnterCriticalSection();
|
||||
CSymbols::Add(type, address, name, description);
|
||||
CSymbols::Save();
|
||||
CSymbols::LeaveCriticalSection();
|
||||
|
||||
m_Debugger->Debug_RefreshSymbolsWindow();
|
||||
|
||||
EndDialog(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR CAddSymbolDlg::DoModal(CDebuggerUI* debugger)
|
||||
{
|
||||
m_Debugger = debugger;
|
||||
m_bHaveAddress = false;
|
||||
m_bHaveType = false;
|
||||
return CDialogImpl<CAddSymbolDlg>::DoModal();
|
||||
}
|
||||
|
||||
INT_PTR CAddSymbolDlg::DoModal(CDebuggerUI* debugger, uint32_t initAddress)
|
||||
{
|
||||
m_Debugger = debugger;
|
||||
m_bHaveAddress = true;
|
||||
m_bHaveType = false;
|
||||
m_InitAddress = initAddress;
|
||||
return CDialogImpl<CAddSymbolDlg>::DoModal();
|
||||
}
|
||||
|
||||
INT_PTR CAddSymbolDlg::DoModal(CDebuggerUI* debugger, uint32_t initAddress, int initType)
|
||||
{
|
||||
m_Debugger = debugger;
|
||||
m_bHaveAddress = true;
|
||||
m_bHaveType = true;
|
||||
m_InitAddress = initAddress;
|
||||
m_InitType = initType;
|
||||
return CDialogImpl<CAddSymbolDlg>::DoModal();
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Modal add symbol dialog
|
||||
|
||||
class CAddSymbolDlg : public CDialogImpl<CAddSymbolDlg>
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_AddSymbol };
|
||||
|
||||
INT_PTR DoModal(CDebuggerUI* debugger);
|
||||
INT_PTR DoModal(CDebuggerUI* debugger, uint32_t initAddress);
|
||||
INT_PTR DoModal(CDebuggerUI* debugger, uint32_t initAddress, int initType);
|
||||
|
||||
private:
|
||||
CDebuggerUI* m_Debugger;
|
||||
|
||||
bool m_bHaveAddress;
|
||||
bool m_bHaveType;
|
||||
uint32_t m_InitAddress;
|
||||
int m_InitType;
|
||||
|
||||
CEditNumber m_AddressEdit;
|
||||
CComboBox m_TypeComboBox;
|
||||
CEdit m_NameEdit;
|
||||
CEdit m_DescriptionEdit;
|
||||
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnDestroy(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_MSG_MAP_EX(CAddSymbolDlg)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
END_MSG_MAP()
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,271 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OpInfo.h"
|
||||
#include "Breakpoints.h"
|
||||
#include "Debugger-AddBreakpoint.h"
|
||||
#include "Debugger-RegisterTabs.h"
|
||||
|
||||
#include <Project64/UserInterface/WTLControls/TooltipDialog.h>
|
||||
|
||||
class CCommandList : public CWindowImpl<CCommandList, CListViewCtrl>
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
COL_ARROWS,
|
||||
COL_ADDRESS,
|
||||
COL_COMMAND,
|
||||
COL_PARAMETERS,
|
||||
COL_SYMBOL
|
||||
};
|
||||
|
||||
enum {
|
||||
ROW_HEIGHT = 13,
|
||||
};
|
||||
|
||||
void Attach(HWND hWndNew)
|
||||
{
|
||||
CListViewCtrl::Attach(hWndNew);
|
||||
ModifyStyle(LVS_OWNERDRAWFIXED, 0, 0);
|
||||
SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_LABELTIP);
|
||||
AddColumn("", COL_ARROWS);
|
||||
AddColumn("Address", COL_ADDRESS);
|
||||
AddColumn("Command", COL_COMMAND);
|
||||
AddColumn("Parameters", COL_PARAMETERS);
|
||||
AddColumn("Symbol", COL_SYMBOL);
|
||||
SetColumnWidth(COL_ARROWS, 30);
|
||||
SetColumnWidth(COL_ADDRESS, 65);
|
||||
SetColumnWidth(COL_COMMAND, 60);
|
||||
SetColumnWidth(COL_PARAMETERS, 120);
|
||||
SetColumnWidth(COL_SYMBOL, 140);
|
||||
}
|
||||
|
||||
BEGIN_MSG_MAP_EX(CCommandsList)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
class CEditOp;
|
||||
class CDebugCommandsView;
|
||||
|
||||
class CEditOp : public CWindowImpl<CEditOp, CEdit>
|
||||
{
|
||||
private:
|
||||
CDebugCommandsView* m_CommandsWindow;
|
||||
|
||||
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (wParam == VK_RETURN || wParam == VK_ESCAPE)
|
||||
{
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
bHandled = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEGIN_MSG_MAP_EX(CEditOp)
|
||||
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
|
||||
MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
|
||||
MESSAGE_HANDLER(WM_CHAR, OnKeyUp)
|
||||
END_MSG_MAP()
|
||||
|
||||
public:
|
||||
void SetCommandsWindow(CDebugCommandsView* commandsWindow);
|
||||
BOOL Attach(HWND hWndNew);
|
||||
};
|
||||
|
||||
class CDebugCommandsView :
|
||||
public CDebugDialog<CDebugCommandsView>,
|
||||
public CDialogResize<CDebugCommandsView>,
|
||||
public CToolTipDialog<CDebugCommandsView>
|
||||
{
|
||||
friend class CEditOp;
|
||||
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_Commands };
|
||||
|
||||
CDebugCommandsView(CDebuggerUI * debugger);
|
||||
virtual ~CDebugCommandsView(void);
|
||||
|
||||
void ShowAddress(DWORD address, BOOL top);
|
||||
void ShowPIRegTab();
|
||||
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
CBreakpoints* m_Breakpoints;
|
||||
vector<uint32_t> m_History;
|
||||
int m_HistoryIndex;
|
||||
|
||||
CAddBreakpointDlg m_AddBreakpointDlg;
|
||||
CAddSymbolDlg m_AddSymbolDlg;
|
||||
|
||||
DWORD m_StartAddress;
|
||||
CRect m_DefaultWindowRect;
|
||||
|
||||
CEditNumber m_PCEdit;
|
||||
bool m_bIgnorePCChange;
|
||||
|
||||
CEditNumber m_AddressEdit;
|
||||
bool m_bIgnoreAddrChange;
|
||||
|
||||
CCommandList m_CommandList;
|
||||
int m_CommandListRows;
|
||||
CListBox m_BreakpointList;
|
||||
CScrollBar m_Scrollbar;
|
||||
|
||||
CRegisterTabs m_RegisterTabs;
|
||||
|
||||
CButton m_BackButton;
|
||||
CButton m_ForwardButton;
|
||||
|
||||
CButton m_ViewPCButton;
|
||||
CButton m_StepButton;
|
||||
CButton m_SkipButton;
|
||||
CButton m_GoButton;
|
||||
|
||||
bool m_bEditing;
|
||||
CEditOp m_OpEdit;
|
||||
|
||||
uint32_t m_SelectedAddress;
|
||||
COpInfo m_SelectedOpInfo;
|
||||
OPCODE& m_SelectedOpCode = m_SelectedOpInfo.m_OpCode;
|
||||
|
||||
uint32_t m_FollowAddress;
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
uint32_t originalOp;
|
||||
} EditedOp;
|
||||
|
||||
vector<EditedOp> m_EditedOps;
|
||||
|
||||
typedef struct {
|
||||
int startPos;
|
||||
int endPos;
|
||||
int startMargin;
|
||||
int endMargin;
|
||||
int margin;
|
||||
} BRANCHARROW;
|
||||
|
||||
vector<BRANCHARROW> m_BranchArrows;
|
||||
void AddBranchArrow(int startPos, int endPos);
|
||||
void ClearBranchArrows();
|
||||
void DrawBranchArrows(HDC listDC);
|
||||
|
||||
vector<bool> m_bvAnnotatedLines;
|
||||
|
||||
void ClearEditedOps();
|
||||
void EditOp(uint32_t address, uint32_t op);
|
||||
void RestoreOp(uint32_t address);
|
||||
void RestoreAllOps();
|
||||
BOOL IsOpEdited(uint32_t address);
|
||||
void BeginOpEdit(uint32_t address);
|
||||
void EndOpEdit();
|
||||
|
||||
void GotoEnteredAddress();
|
||||
void CheckCPUType();
|
||||
void RefreshBreakpointList();
|
||||
void RemoveSelectedBreakpoints();
|
||||
|
||||
bool AddressSafe(uint32_t vaddr);
|
||||
|
||||
void HistoryPushState();
|
||||
void ToggleHistoryButtons();
|
||||
|
||||
static CDebugCommandsView* _this;
|
||||
static HHOOK hWinMessageHook;
|
||||
static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
void InterceptKeyDown(WPARAM wParam, LPARAM lParam);
|
||||
void InterceptMouseWheel(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static const char* GetCodeAddressNotes(uint32_t vAddr);
|
||||
static const char* GetDataAddressNotes(uint32_t vAddr);
|
||||
|
||||
void CPUSkip();
|
||||
void CPUStepInto();
|
||||
void CPUResume();
|
||||
|
||||
LRESULT OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnActivate (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnSizing (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnScroll (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnMeasureItem (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnAddrChanged (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnPCChanged (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnListBoxClicked (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnClicked (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
|
||||
LRESULT OnOpKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
LRESULT OnCommandListClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnCommandListDblClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnCommandListRightClicked (NMHDR* pNMHDR);
|
||||
LRESULT OnRegisterTabChange (NMHDR* pNMHDR);
|
||||
LRESULT OnCustomDrawList (NMHDR* pNMHDR);
|
||||
LRESULT OnDestroy (void);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDebugCommandsView)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
|
||||
MESSAGE_HANDLER(WM_SIZING, OnSizing)
|
||||
MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
|
||||
MESSAGE_HANDLER(WM_VSCROLL, OnScroll)
|
||||
MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
|
||||
COMMAND_HANDLER(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged)
|
||||
COMMAND_HANDLER(IDC_PC_EDIT, EN_CHANGE, OnPCChanged)
|
||||
COMMAND_CODE_HANDLER(LBN_DBLCLK, OnListBoxClicked)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_CLICK, OnCommandListClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_DBLCLK, OnCommandListDblClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_RCLICK, OnCommandListRightClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_REG_TABS, TCN_SELCHANGE, OnRegisterTabChange)
|
||||
NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_CUSTOMDRAW, OnCustomDrawList)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
CHAIN_MSG_MAP(CDialogResize<CDebugCommandsView>)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DLGRESIZE_MAP(CDebugCommandsView)
|
||||
DLGRESIZE_CONTROL(IDC_GO_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_STEP_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_SKIP_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_ADDR_EDIT, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_SYMBOLS_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_OPCODE_BOX, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_BP_LIST, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_ADDBP_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_RMBP_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_CLEARBP_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_REG_TABS, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_BACK_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_FORWARD_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_PC_STATIC, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_PC_EDIT, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_VIEWPC_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_CMD_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_SCRL_BAR, DLSZ_MOVE_X | DLSZ_SIZE_Y)
|
||||
END_DLGRESIZE_MAP()
|
||||
|
||||
BEGIN_TOOLTIP_MAP()
|
||||
TOOLTIP(IDC_SKIP_BTN, "Skip (F1)")
|
||||
TOOLTIP(IDC_STEP_BTN, "Step (F2)")
|
||||
TOOLTIP(IDC_GO_BTN, "Go (F4)")
|
||||
TOOLTIP(IDC_ADDBP_BTN, "Add breakpoint...")
|
||||
TOOLTIP(IDC_RMBP_BTN, "Remove selected breakpoint")
|
||||
TOOLTIP(IDC_CLEARBP_BTN, "Remove all breakpoints")
|
||||
TOOLTIP(IDC_VIEWPC_BTN, "Jump to program counter")
|
||||
TOOLTIP(IDC_BP_LIST, "Active breakpoints")
|
||||
TOOLTIP(IDC_SYMBOLS_BTN, "Symbols...")
|
||||
END_TOOLTIP_MAP()
|
||||
};
|
|
@ -0,0 +1,338 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DebuggerUI.h"
|
||||
#include "DMALog.h"
|
||||
|
||||
CDebugDMALogView::CDebugDMALogView(CDebuggerUI* debugger) :
|
||||
CDebugDialog<CDebugDMALogView>(debugger)
|
||||
{
|
||||
m_DMALog = debugger->DMALog();
|
||||
m_bFilterChanged = false;
|
||||
m_bUniqueRomAddresses = true;
|
||||
m_bCustomDrawClrNext = false;
|
||||
}
|
||||
|
||||
CDebugDMALogView::~CDebugDMALogView()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
bool CDebugDMALogView::FilterEntry(int dmaLogIndex)
|
||||
{
|
||||
DMALogEntry entry = m_Debugger->DMALog()->at(dmaLogIndex);
|
||||
|
||||
for (int i = 0; i < dmaLogIndex; i++)
|
||||
{
|
||||
DMALogEntry testEntry = m_Debugger->DMALog()->at(i);
|
||||
|
||||
// Don't show if another entry has the same ROM address
|
||||
if (entry.romAddr == testEntry.romAddr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
void CDebugDMALogView::RefreshList()
|
||||
{
|
||||
if (g_Rom == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* rom = g_Rom->GetRomAddress();
|
||||
|
||||
// Get scrollbar state
|
||||
SCROLLINFO scroll;
|
||||
scroll.cbSize = sizeof(SCROLLINFO);
|
||||
scroll.fMask = SIF_ALL;
|
||||
m_DMAList.GetScrollInfo(SB_VERT, &scroll);
|
||||
|
||||
bool bScrolledDown = false;
|
||||
|
||||
if ((scroll.nPage + scroll.nPos) - 1 == scroll.nMax)
|
||||
{
|
||||
bScrolledDown = true;
|
||||
}
|
||||
|
||||
int startIndex;
|
||||
int dmaLogSize = m_Debugger->DMALog()->GetNumEntries();
|
||||
|
||||
if (dmaLogSize == 0)
|
||||
{
|
||||
// Reset
|
||||
m_DMAList.DeleteAllItems();
|
||||
startIndex = 0;
|
||||
m_bFilterChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Continue from last index
|
||||
startIndex = m_nLastStartIndex;
|
||||
}
|
||||
|
||||
m_DMAList.SetRedraw(FALSE);
|
||||
|
||||
int itemIndex = m_DMAList.GetItemCount();
|
||||
|
||||
for (int i = startIndex; i < dmaLogSize; i++)
|
||||
{
|
||||
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByIndex(i);
|
||||
|
||||
//if (!FilterEntry(i))
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
|
||||
m_DMAList.AddItem(itemIndex, 0, stdstr_f("%08X", lpEntry->romAddr).c_str());
|
||||
m_DMAList.AddItem(itemIndex, 1, stdstr_f("%08X", lpEntry->ramAddr).c_str());
|
||||
m_DMAList.AddItem(itemIndex, 2, stdstr_f("%08X (%d)", lpEntry->length, lpEntry->length).c_str());
|
||||
|
||||
uint32_t sig = *(uint32_t*)&rom[lpEntry->romAddr];
|
||||
sig = _byteswap_ulong(sig);
|
||||
|
||||
char sigc[5];
|
||||
memcpy(sigc, &sig, 4);
|
||||
sigc[4] = '\0';
|
||||
|
||||
// Todo checkbox to display all in hex
|
||||
if (isalnum(sigc[0]) && isalnum(sigc[1]) && isalnum(sigc[2]) && isalnum(sigc[3]))
|
||||
{
|
||||
m_DMAList.AddItem(itemIndex, 4, sigc);
|
||||
}
|
||||
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
if (bScrolledDown)
|
||||
{
|
||||
m_DMAList.EnsureVisible(m_DMAList.GetItemCount() - 1, FALSE);
|
||||
}
|
||||
|
||||
m_DMAList.SetRedraw(TRUE);
|
||||
|
||||
m_nLastStartIndex = dmaLogSize;
|
||||
}
|
||||
|
||||
DWORD WINAPI CDebugDMALogView::AutoRefreshProc(void* _this)
|
||||
{
|
||||
CDebugDMALogView* self = (CDebugDMALogView*)_this;
|
||||
while (true)
|
||||
{
|
||||
self->RefreshList();
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CDebugDMALogView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
//RefreshList();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugDMALogView::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
DlgResize_Init(false, true);
|
||||
|
||||
m_bConvertingAddress = false;
|
||||
m_nLastStartIndex = 0;
|
||||
|
||||
m_DMAList.Attach(GetDlgItem(IDC_DMA_LIST));
|
||||
|
||||
m_DMAList.ModifyStyle(LVS_OWNERDRAWFIXED, 0, 0);
|
||||
|
||||
m_DMAList.AddColumn("ROM", 0);
|
||||
m_DMAList.AddColumn("RAM", 1);
|
||||
m_DMAList.AddColumn("Length", 2);
|
||||
m_DMAList.AddColumn("Symbol (RAM)", 3);
|
||||
m_DMAList.AddColumn("Signature", 4);
|
||||
|
||||
m_DMAList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
|
||||
|
||||
m_DMAList.SetColumnWidth(0, 65);
|
||||
m_DMAList.SetColumnWidth(1, 65);
|
||||
m_DMAList.SetColumnWidth(2, 120);
|
||||
//m_DMAList.SetColumnWidth(3, 50);
|
||||
//m_DMAList.SetColumnWidth(4, 50);
|
||||
//m_DMAList.SetColumnWidth(5, 50);
|
||||
|
||||
m_DMARamEdit.Attach(GetDlgItem(IDC_DMA_RAM_EDIT));
|
||||
m_DMARamEdit.SetLimitText(8);
|
||||
|
||||
m_DMARomEdit.Attach(GetDlgItem(IDC_DMA_ROM_EDIT));
|
||||
m_DMARomEdit.SetLimitText(8);
|
||||
|
||||
m_BlockInfo.Attach(GetDlgItem(IDC_BLOCK_INFO));
|
||||
|
||||
RefreshList();
|
||||
|
||||
WindowCreated();
|
||||
|
||||
m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT CDebugDMALogView::OnDestroy(void)
|
||||
{
|
||||
if (m_AutoRefreshThread != NULL)
|
||||
{
|
||||
TerminateThread(m_AutoRefreshThread, 0);
|
||||
CloseHandle(m_AutoRefreshThread);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugDMALogView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDOK:
|
||||
EndDialog(0);
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
case IDC_CLEAR_BTN:
|
||||
m_DMALog->ClearEntries();
|
||||
RefreshList();
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugDMALogView::OnRamAddrChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
||||
{
|
||||
if (m_bConvertingAddress)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char szRamAddr[9];
|
||||
char szRomAddr[9];
|
||||
|
||||
m_DMARamEdit.GetWindowTextA(szRamAddr, 9);
|
||||
uint32_t ramAddr = strtoul(szRamAddr, NULL, 16);
|
||||
uint32_t romAddr, offset;
|
||||
|
||||
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByRamAddress(ramAddr, &romAddr, &offset);
|
||||
|
||||
if (lpEntry != NULL)
|
||||
{
|
||||
sprintf(szRomAddr, "%08X", romAddr);
|
||||
stdstr blockInfo = stdstr_f("Block: %08X -> %08X [%X] +%X", romAddr, ramAddr, lpEntry->length, offset);
|
||||
m_BlockInfo.SetWindowTextA(blockInfo.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(szRomAddr, "????????");
|
||||
m_BlockInfo.SetWindowTextA("Block: ?");
|
||||
}
|
||||
|
||||
m_bConvertingAddress = true;
|
||||
m_DMARomEdit.SetWindowTextA(szRomAddr);
|
||||
m_bConvertingAddress = false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugDMALogView::OnRomAddrChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
||||
{
|
||||
if (m_bConvertingAddress)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char szRamAddr[9];
|
||||
char szRomAddr[9];
|
||||
|
||||
m_DMARomEdit.GetWindowTextA(szRomAddr, 9);
|
||||
uint32_t romAddr = strtoul(szRomAddr, NULL, 16);
|
||||
uint32_t ramAddr, offset;
|
||||
|
||||
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByRomAddress(romAddr, &ramAddr, &offset);
|
||||
|
||||
if (lpEntry != NULL)
|
||||
{
|
||||
sprintf(szRamAddr, "%08X", ramAddr);
|
||||
stdstr blockInfo = stdstr_f("Block: %08X -> %08X [%X] +%X", romAddr, ramAddr, lpEntry->length, offset);
|
||||
m_BlockInfo.SetWindowTextA(blockInfo.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(szRamAddr, "????????");
|
||||
m_BlockInfo.SetWindowTextA("Block: ?");
|
||||
}
|
||||
|
||||
m_bConvertingAddress = true;
|
||||
m_DMARamEdit.SetWindowTextA(szRamAddr);
|
||||
m_bConvertingAddress = false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
LRESULT CDebugDMALogView::OnCustomDrawList(NMHDR* pNMHDR)
|
||||
{
|
||||
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
|
||||
DWORD drawStage = pLVCD->nmcd.dwDrawStage;
|
||||
|
||||
switch (drawStage)
|
||||
{
|
||||
case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW;
|
||||
case CDDS_ITEMPREPAINT: return CDRF_NOTIFYSUBITEMDRAW;
|
||||
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): break;
|
||||
default: return CDRF_DODEFAULT;
|
||||
}
|
||||
|
||||
DWORD nItem = pLVCD->nmcd.dwItemSpec;
|
||||
DWORD nSubItem = pLVCD->iSubItem;
|
||||
|
||||
if (nSubItem != 0)
|
||||
{
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
|
||||
size_t nEntries = m_DMALog->GetNumEntries();
|
||||
|
||||
if (nEntries == 0)
|
||||
{
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
|
||||
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByIndex(nItem);
|
||||
|
||||
if (nItem >= 1) // continuation
|
||||
{
|
||||
DMALOGENTRY* lpPrevEntry = m_DMALog->GetEntryByIndex(nItem - 1);
|
||||
|
||||
if (lpEntry->romAddr == lpPrevEntry->romAddr + lpPrevEntry->length)
|
||||
{
|
||||
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0xCC);
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
if (nEntries >= 2 && nItem <= nEntries - 2) // head
|
||||
{
|
||||
DMALOGENTRY* lpNextEntry = m_DMALog->GetEntryByIndex(nItem + 1);
|
||||
|
||||
if (lpNextEntry->romAddr == lpEntry->romAddr + lpEntry->length)
|
||||
{
|
||||
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0x88);
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdafx.h>
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
class CDebugDMALogView :
|
||||
public CDebugDialog<CDebugDMALogView>,
|
||||
public CDialogResize<CDebugDMALogView>
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_DMALog };
|
||||
|
||||
CDebugDMALogView(CDebuggerUI * debugger);
|
||||
virtual ~CDebugDMALogView(void);
|
||||
|
||||
void RefreshList();
|
||||
|
||||
private:
|
||||
CDMALog* m_DMALog;
|
||||
|
||||
int m_nLastStartIndex;
|
||||
bool m_bConvertingAddress;
|
||||
|
||||
bool m_bUniqueRomAddresses;
|
||||
bool m_bFilterChanged;
|
||||
|
||||
HANDLE m_AutoRefreshThread;
|
||||
static DWORD WINAPI AutoRefreshProc(void* _this);
|
||||
|
||||
// Return true if entry meets requirements
|
||||
bool FilterEntry(int dmaLogIndex);
|
||||
|
||||
CListViewCtrl m_DMAList;
|
||||
CEdit m_DMARamEdit;
|
||||
CEdit m_DMARomEdit;
|
||||
CStatic m_BlockInfo;
|
||||
|
||||
bool m_bCustomDrawClrNext;
|
||||
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
|
||||
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnRamAddrChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnRomAddrChanged(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
LRESULT OnCustomDrawList(NMHDR* pNMHDR);
|
||||
LRESULT OnDestroy(void);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDebugDMALogView)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
|
||||
COMMAND_HANDLER(IDC_DMA_RAM_EDIT, EN_CHANGE, OnRamAddrChanged)
|
||||
COMMAND_HANDLER(IDC_DMA_ROM_EDIT, EN_CHANGE, OnRomAddrChanged)
|
||||
NOTIFY_HANDLER_EX(IDC_DMA_LIST, NM_CUSTOMDRAW, OnCustomDrawList)
|
||||
CHAIN_MSG_MAP(CDialogResize<CDebugDMALogView>)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DLGRESIZE_MAP(CDebugDMALogView)
|
||||
DLGRESIZE_CONTROL(IDC_DMA_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_TRACE_STATIC, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_BLOCK_INFO, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_RAM_STATIC, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_ROM_STATIC, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_DMA_ROM_EDIT, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_DMA_RAM_EDIT, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_CLEAR_BTN, DLSZ_MOVE_X | DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_BUTTON1, DLSZ_MOVE_X | DLSZ_MOVE_Y)
|
||||
END_DLGRESIZE_MAP()
|
||||
};
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
#include <Project64-core/N64System/Mips/OpCodeName.h>
|
||||
|
||||
CDumpMemory::CDumpMemory(CDebuggerUI * debugger) :
|
||||
CDebugDialog<CDumpMemory>(debugger)
|
||||
{
|
||||
|
@ -26,18 +28,27 @@ LRESULT CDumpMemory::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa
|
|||
m_StartAddress.Attach(GetDlgItem(IDC_E_START_ADDR));
|
||||
m_EndAddress.Attach(GetDlgItem(IDC_E_END_ADDR));
|
||||
m_PC.Attach(GetDlgItem(IDC_E_ALT_PC));
|
||||
m_FormatList.Attach(GetDlgItem(IDC_FORMAT));
|
||||
m_FileName.Attach(GetDlgItem(IDC_FILENAME));
|
||||
|
||||
m_StartAddress.SetDisplayType(CEditNumber::DisplayHex);
|
||||
m_EndAddress.SetDisplayType(CEditNumber::DisplayHex);
|
||||
m_PC.SetDisplayType(CEditNumber::DisplayHex);
|
||||
|
||||
m_StartAddress.SetValue(0x80000000, true, true);
|
||||
m_EndAddress.SetValue(0x803FFFF0, true, true);
|
||||
m_PC.SetValue(0x80000000);
|
||||
HWND hFormatList = GetDlgItem(IDC_FORMAT);
|
||||
int pos = ::SendMessage(hFormatList, CB_ADDSTRING, (WPARAM)0, (LPARAM)"TEXT - Disassembly + PC");
|
||||
::SendMessage(hFormatList, CB_SETITEMDATA, (WPARAM)pos, (LPARAM)DisassemblyWithPC);
|
||||
::SendMessage(hFormatList, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
|
||||
uint32_t startAddress = 0x80000000;
|
||||
uint32_t endAddress = startAddress + (g_MMU ? g_MMU->RdramSize() : 0x400000);
|
||||
|
||||
m_StartAddress.SetValue(startAddress, true, true);
|
||||
m_EndAddress.SetValue(endAddress, true, true);
|
||||
m_PC.SetValue(startAddress);
|
||||
|
||||
int nIndex = m_FormatList.AddString("TEXT - Disassembly + PC");
|
||||
m_FormatList.SetItemData(nIndex, (DWORD_PTR)DisassemblyWithPC);
|
||||
|
||||
nIndex = m_FormatList.AddString("RAW - Big Endian (N64)");
|
||||
m_FormatList.SetItemData(nIndex, (LPARAM)RawBigEndian);
|
||||
|
||||
m_FormatList.SetCurSel(0);
|
||||
|
||||
WindowCreated();
|
||||
return TRUE;
|
||||
|
@ -54,13 +65,28 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
|
|||
{
|
||||
g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_DumpMemory);
|
||||
|
||||
int CurrentFormatSel = m_FormatList.GetCurSel();
|
||||
DumpFormat Format = (DumpFormat)m_FormatList.GetItemData(CurrentFormatSel);
|
||||
|
||||
const char* FileFilter;
|
||||
|
||||
if (Format == RawBigEndian)
|
||||
{
|
||||
FileFilter = "Binary file (*.bin)\0*.bin;\0All files (*.*)\0*.*\0";
|
||||
}
|
||||
else if (Format == DisassemblyWithPC)
|
||||
{
|
||||
FileFilter = "Text file (*.txt)\0*.txt;\0All files (*.*)\0*.*\0";
|
||||
}
|
||||
|
||||
CPath FileName;
|
||||
if (FileName.SelectFile(m_hWnd, CPath(CPath::MODULE_DIRECTORY), "Text file (*.txt)\0*.txt;\0All files (*.*)\0*.*\0", false))
|
||||
|
||||
if (FileName.SelectFile(m_hWnd, CPath(CPath::MODULE_DIRECTORY), FileFilter, false))
|
||||
{
|
||||
if (FileName.GetExtension().length() == 0)
|
||||
{
|
||||
FileName.SetExtension("txt");
|
||||
SetDlgItemText(IDC_FILENAME, FileName);
|
||||
FileName.SetExtension(Format == RawBigEndian ? "bin" : "txt");
|
||||
m_FileName.SetWindowTextA(FileName);
|
||||
}
|
||||
}
|
||||
g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory);
|
||||
|
@ -69,8 +95,9 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
|
|||
case IDOK:
|
||||
{
|
||||
TCHAR FileName[MAX_PATH];
|
||||
int CurrentFormatSel = SendDlgItemMessage(IDC_FORMAT, CB_GETCURSEL, 0, 0);
|
||||
DumpFormat Format = (DumpFormat)SendDlgItemMessage(IDC_FORMAT, CB_GETITEMDATA, CurrentFormatSel, 0);
|
||||
int CurrentFormatSel = m_FormatList.GetCurSel();
|
||||
DumpFormat Format = (DumpFormat) m_FormatList.GetItemData(CurrentFormatSel);
|
||||
|
||||
DWORD StartPC = m_StartAddress.GetValue();
|
||||
DWORD EndPC = m_EndAddress.GetValue();
|
||||
DWORD DumpPC = m_PC.GetValue();
|
||||
|
@ -83,7 +110,7 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
|
|||
}
|
||||
if (SendDlgItemMessage(IDC_USE_ALT_PC, BM_GETSTATE, 0, 0) != BST_CHECKED)
|
||||
{
|
||||
DumpPC = g_Reg->m_PROGRAM_COUNTER;
|
||||
DumpPC = StartPC;
|
||||
}
|
||||
//disable buttons
|
||||
::EnableWindow(GetDlgItem(IDC_E_START_ADDR), FALSE);
|
||||
|
@ -110,35 +137,71 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD /*DumpPC*/)
|
||||
bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD DumpPC)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case DisassemblyWithPC:
|
||||
{
|
||||
CLog LogFile;
|
||||
if (!LogFile.Open(FileName))
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
|
||||
return false;
|
||||
}
|
||||
LogFile.SetFlush(false);
|
||||
LogFile.SetTruncateFile(false);
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
#ifdef legacycode
|
||||
char Command[200];
|
||||
for (COpcode OpCode(StartPC); OpCode.PC() < EndPC; OpCode.Next())
|
||||
{
|
||||
const char * szOpName = OpCode.OpcodeName();
|
||||
OpCode.OpcodeParam(Command);
|
||||
LogFile.LogF("%X: %-15s%s\r\n",OpCode.PC(),szOpName,Command);
|
||||
}
|
||||
#endif
|
||||
m_StartAddress.SetValue(StartPC, true, true);
|
||||
m_EndAddress.SetValue(EndPC, true, true);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (Format == DisassemblyWithPC)
|
||||
{
|
||||
CLog LogFile;
|
||||
if (!LogFile.Open(FileName))
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
|
||||
return false;
|
||||
}
|
||||
LogFile.SetFlush(false);
|
||||
LogFile.SetTruncateFile(false);
|
||||
|
||||
for (uint32_t pc = StartPC; pc < EndPC; pc += 4, DumpPC += 4)
|
||||
{
|
||||
OPCODE opcode;
|
||||
g_MMU->LW_VAddr(pc, opcode.Hex);
|
||||
|
||||
const char* command = R4300iOpcodeName(opcode.Hex, DumpPC);
|
||||
|
||||
char* cmdName = strtok((char*)command, "\t");
|
||||
char* cmdArgs = strtok(NULL, "\t");
|
||||
cmdArgs = cmdArgs ? cmdArgs : "";
|
||||
|
||||
LogFile.LogF("%X: %-15s%s\r\n", DumpPC, cmdName, cmdArgs);
|
||||
}
|
||||
|
||||
m_StartAddress.SetValue(StartPC, true, true);
|
||||
m_EndAddress.SetValue(EndPC, true, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Format == RawBigEndian)
|
||||
{
|
||||
CFile dumpFile;
|
||||
|
||||
if (!dumpFile.Open(FileName, CFile::modeCreate | CFile::modeWrite))
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t dumpLen = EndPC - StartPC;
|
||||
uint8_t* dumpBuf = (uint8_t*)malloc(dumpLen);
|
||||
uint32_t dumpIdx = 0;
|
||||
|
||||
for (uint32_t pc = StartPC; pc < EndPC; pc++, dumpIdx++)
|
||||
{
|
||||
bool bReadable = g_MMU->LB_VAddr(pc, dumpBuf[dumpIdx]);
|
||||
|
||||
if (!bReadable)
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Address error\n%s", FileName).c_str());
|
||||
dumpFile.Close();
|
||||
free(dumpBuf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
dumpFile.SeekToBegin();
|
||||
dumpFile.Write(dumpBuf, dumpLen);
|
||||
dumpFile.Close();
|
||||
free(dumpBuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -26,7 +26,8 @@ private:
|
|||
|
||||
enum DumpFormat
|
||||
{
|
||||
DisassemblyWithPC
|
||||
DisassemblyWithPC,
|
||||
RawBigEndian
|
||||
};
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDumpMemory)
|
||||
|
@ -39,5 +40,7 @@ private:
|
|||
|
||||
bool DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD DumpPC);
|
||||
|
||||
CComboBox m_FormatList;
|
||||
CEdit m_FileName;
|
||||
CEditNumber m_StartAddress, m_EndAddress, m_PC;
|
||||
};
|
||||
|
|
|
@ -188,6 +188,20 @@ LRESULT CDebugMemorySearch::OnResultRClick(LPNMHDR /*lpnmh*/)
|
|||
return true;
|
||||
}
|
||||
|
||||
LRESULT CDebugMemorySearch::OnResultDblClick(LPNMHDR)
|
||||
{
|
||||
LONG iItem = m_SearchResults.GetNextItem(-1, LVNI_SELECTED);
|
||||
if (iItem == -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// view in memory
|
||||
int ItemId = m_SearchResults.GetItemData(iItem);
|
||||
SearchResultItem & Result = m_SearchResult[ItemId];
|
||||
m_Debugger->Debug_ShowMemoryLocation(Result.PAddr, false);
|
||||
}
|
||||
|
||||
void CDebugMemorySearch::EnableValueOptions(bool Enable)
|
||||
{
|
||||
if (Enable)
|
||||
|
@ -261,6 +275,8 @@ void CDebugMemorySearch::SearchForValue(void)
|
|||
DisplayStr = "0x%04X";
|
||||
}
|
||||
|
||||
m_SearchResults.SetRedraw(FALSE);
|
||||
|
||||
if (!m_HaveResults)
|
||||
{
|
||||
m_HaveResults = true;
|
||||
|
@ -268,7 +284,7 @@ void CDebugMemorySearch::SearchForValue(void)
|
|||
FixUnknownOptions(false);
|
||||
m_SearchResults.DeleteAllItems();
|
||||
DWORD ItemsAdded = 0;
|
||||
|
||||
|
||||
while (SearchForValue(Value, Size, StartAddress, Len))
|
||||
{
|
||||
SearchResultItem Result;
|
||||
|
@ -294,6 +310,7 @@ void CDebugMemorySearch::SearchForValue(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
::SetWindowText(GetDlgItem(IDC_BTN_SEARCH), "Search Results");
|
||||
::ShowWindow(GetDlgItem(IDC_RESET_BUTTON), SW_SHOW);
|
||||
::EnableWindow(GetDlgItem(IDC_VALUE_ALIGN), false);
|
||||
|
@ -347,6 +364,9 @@ void CDebugMemorySearch::SearchForValue(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_SearchResults.SetRedraw(TRUE);
|
||||
|
||||
::SetWindowText(GetDlgItem(IDC_BORDER_RESULTS), stdstr_f("Results (%d)", m_SearchResults.GetItemCount()).c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -53,11 +53,13 @@ private:
|
|||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_LST_RESULTS, NM_RCLICK, OnResultRClick)
|
||||
NOTIFY_HANDLER_EX(IDC_LST_RESULTS, NM_DBLCLK, OnResultDblClick)
|
||||
END_MSG_MAP()
|
||||
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
|
||||
LRESULT OnResultRClick(LPNMHDR lpnmh);
|
||||
LRESULT OnResultDblClick(LPNMHDR lpnmh);
|
||||
|
||||
void EnableUnknownOptions(bool Enable);
|
||||
void EnableValueOptions(bool Enable);
|
||||
|
|
|
@ -0,0 +1,803 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Debugger-RegisterTabs.h"
|
||||
#include "OpInfo.h"
|
||||
|
||||
bool CRegisterTabs::m_bColorsEnabled = false;
|
||||
|
||||
void CRegisterTabs::Attach(HWND hWndNew)
|
||||
{
|
||||
m_TabWindows.clear();
|
||||
|
||||
CTabCtrl::Attach(hWndNew);
|
||||
|
||||
HFONT monoFont = CreateFont(-11, 0, 0, 0,
|
||||
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
|
||||
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
CLEARTYPE_QUALITY, FF_DONTCARE, "Consolas"
|
||||
);
|
||||
|
||||
m_GPRTab = AddTab("GPR", IDD_Debugger_RegGPR, TabProcGPR);
|
||||
m_FPRTab = AddTab("FPR", IDD_Debugger_RegFPR, TabProcFPR);
|
||||
m_COP0Tab = AddTab("COP0", IDD_Debugger_RegCOP0, TabProcDefault);
|
||||
m_RDRAMTab = AddTab("RDRAM", IDD_Debugger_RegRDRAM, TabProcDefault);
|
||||
m_SPTab = AddTab("SP", IDD_Debugger_RegSP, TabProcDefault);
|
||||
m_DPCTab = AddTab("DPC", IDD_Debugger_RegDPC, TabProcDefault);
|
||||
m_MITab = AddTab("MI", IDD_Debugger_RegMI, TabProcDefault);
|
||||
m_VITab = AddTab("VI", IDD_Debugger_RegVI, TabProcDefault);
|
||||
m_AITab = AddTab("AI", IDD_Debugger_RegAI, TabProcDefault);
|
||||
m_PITab = AddTab("PI", IDD_Debugger_RegPI, TabProcDefault);
|
||||
m_RITab = AddTab("RI", IDD_Debugger_RegRI, TabProcDefault);
|
||||
m_SITab = AddTab("SI", IDD_Debugger_RegSI, TabProcDefault);
|
||||
m_DDTab = AddTab("DD", IDD_Debugger_RegDD, TabProcDefault);
|
||||
|
||||
InitRegisterEdits64(m_GPRTab, m_GPREdits, GPREditIds, monoFont);
|
||||
InitRegisterEdit64(m_GPRTab, m_HIEdit, IDC_HI_EDIT, monoFont);
|
||||
InitRegisterEdit64(m_GPRTab, m_LOEdit, IDC_LO_EDIT, monoFont);
|
||||
|
||||
InitRegisterEdits(m_FPRTab, m_FPREdits, FPREditIds, monoFont);
|
||||
InitRegisterEdit(m_FPRTab, m_FCSREdit, IDC_FCSR_EDIT, monoFont);
|
||||
|
||||
InitRegisterEdits(m_COP0Tab, m_COP0Edits, COP0EditIds, monoFont);
|
||||
m_CauseTip.Attach(m_COP0Tab.GetDlgItem(IDC_CAUSE_TIP));
|
||||
|
||||
InitRegisterEdits(m_RDRAMTab, m_RDRAMEdits, RDRAMEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_SPTab, m_SPEdits, SPEditIds, monoFont);
|
||||
InitRegisterEdit(m_SPTab, m_SPPCEdit, IDC_SP_PC_EDIT, monoFont);
|
||||
|
||||
InitRegisterEdits(m_DPCTab, m_DPCEdits, DPCEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_MITab, m_MIEdits, MIEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_VITab, m_VIEdits, VIEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_AITab, m_AIEdits, AIEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_PITab, m_PIEdits, PIEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_RITab, m_RIEdits, RIEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_SITab, m_SIEdits, SIEditIds, monoFont);
|
||||
|
||||
InitRegisterEdits(m_DDTab, m_DDEdits, DDEditIds, monoFont);
|
||||
|
||||
SetColorsEnabled(false);
|
||||
RefreshEdits();
|
||||
RedrawCurrentTab();
|
||||
}
|
||||
|
||||
void CRegisterTabs::RefreshEdits()
|
||||
{
|
||||
if (g_Reg == NULL)
|
||||
{
|
||||
ZeroRegisterEdits64(m_GPREdits, GPREditIds);
|
||||
ZeroRegisterEdit64(m_HIEdit);
|
||||
ZeroRegisterEdit64(m_LOEdit);
|
||||
|
||||
ZeroRegisterEdits(m_FPREdits, FPREditIds);
|
||||
ZeroRegisterEdit(m_FCSREdit);
|
||||
|
||||
ZeroRegisterEdits(m_COP0Edits, COP0EditIds);
|
||||
|
||||
ZeroRegisterEdits(m_RDRAMEdits, RDRAMEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_SPEdits, SPEditIds);
|
||||
ZeroRegisterEdit(m_SPPCEdit);
|
||||
|
||||
ZeroRegisterEdits(m_DPCEdits, DPCEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_MIEdits, MIEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_VIEdits, VIEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_AIEdits, AIEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_PIEdits, PIEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_RIEdits, RIEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_SIEdits, SIEditIds);
|
||||
|
||||
ZeroRegisterEdits(m_DDEdits, DDEditIds);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
m_GPREdits[i].SetValue(g_Reg->m_GPR[i].UDW);
|
||||
m_FPREdits[i].SetValue(*(uint32_t *)g_Reg->m_FPR_S[i], false, true);
|
||||
}
|
||||
m_HIEdit.SetValue(g_Reg->m_HI.UDW);
|
||||
m_LOEdit.SetValue(g_Reg->m_LO.UDW);
|
||||
|
||||
m_FCSREdit.SetValue(g_Reg->m_FPCR[31], false, true);
|
||||
|
||||
m_COP0Edits[0].SetValue(g_Reg->INDEX_REGISTER, false, true);
|
||||
m_COP0Edits[1].SetValue(g_Reg->RANDOM_REGISTER, false, true);
|
||||
m_COP0Edits[2].SetValue(g_Reg->ENTRYLO0_REGISTER, false, true);
|
||||
m_COP0Edits[3].SetValue(g_Reg->ENTRYLO1_REGISTER, false, true);
|
||||
m_COP0Edits[4].SetValue(g_Reg->CONTEXT_REGISTER, false, true);
|
||||
m_COP0Edits[5].SetValue(g_Reg->PAGE_MASK_REGISTER, false, true);
|
||||
m_COP0Edits[6].SetValue(g_Reg->WIRED_REGISTER, false, true);
|
||||
m_COP0Edits[7].SetValue(g_Reg->BAD_VADDR_REGISTER, false, true);
|
||||
m_COP0Edits[8].SetValue(g_Reg->COUNT_REGISTER, false, true);
|
||||
m_COP0Edits[9].SetValue(g_Reg->ENTRYHI_REGISTER, false, true);
|
||||
m_COP0Edits[10].SetValue(g_Reg->COMPARE_REGISTER, false, true);
|
||||
m_COP0Edits[11].SetValue(g_Reg->STATUS_REGISTER, false, true);
|
||||
m_COP0Edits[12].SetValue(g_Reg->CAUSE_REGISTER, false, true);
|
||||
m_COP0Edits[13].SetValue(g_Reg->EPC_REGISTER, false, true);
|
||||
m_COP0Edits[14].SetValue(g_Reg->CONFIG_REGISTER, false, true);
|
||||
m_COP0Edits[15].SetValue(g_Reg->TAGLO_REGISTER, false, true);
|
||||
m_COP0Edits[16].SetValue(g_Reg->TAGHI_REGISTER, false, true);
|
||||
m_COP0Edits[17].SetValue(g_Reg->ERROREPC_REGISTER, false, true);
|
||||
m_COP0Edits[18].SetValue(g_Reg->FAKE_CAUSE_REGISTER, false, true);
|
||||
|
||||
CAUSE cause;
|
||||
cause.intval = g_Reg->CAUSE_REGISTER;
|
||||
|
||||
const char* szExceptionCode = ExceptionCodes[cause.exceptionCode];
|
||||
m_CauseTip.SetWindowTextA(szExceptionCode);
|
||||
|
||||
m_RDRAMEdits[0].SetValue(g_Reg->RDRAM_CONFIG_REG, false, true); // or device type
|
||||
m_RDRAMEdits[1].SetValue(g_Reg->RDRAM_DEVICE_ID_REG, false, true);
|
||||
m_RDRAMEdits[2].SetValue(g_Reg->RDRAM_DELAY_REG, false, true);
|
||||
m_RDRAMEdits[3].SetValue(g_Reg->RDRAM_MODE_REG, false, true);
|
||||
m_RDRAMEdits[4].SetValue(g_Reg->RDRAM_REF_INTERVAL_REG, false, true);
|
||||
m_RDRAMEdits[5].SetValue(g_Reg->RDRAM_REF_ROW_REG, false, true);
|
||||
m_RDRAMEdits[6].SetValue(g_Reg->RDRAM_RAS_INTERVAL_REG, false, true);
|
||||
m_RDRAMEdits[7].SetValue(g_Reg->RDRAM_MIN_INTERVAL_REG, false, true);
|
||||
m_RDRAMEdits[8].SetValue(g_Reg->RDRAM_ADDR_SELECT_REG, false, true);
|
||||
m_RDRAMEdits[9].SetValue(g_Reg->RDRAM_DEVICE_MANUF_REG, false, true);
|
||||
|
||||
m_SPEdits[0].SetValue(g_Reg->SP_MEM_ADDR_REG, false, true);
|
||||
m_SPEdits[1].SetValue(g_Reg->SP_DRAM_ADDR_REG, false, true);
|
||||
m_SPEdits[2].SetValue(g_Reg->SP_RD_LEN_REG, false, true);
|
||||
m_SPEdits[3].SetValue(g_Reg->SP_WR_LEN_REG, false, true);
|
||||
m_SPEdits[4].SetValue(g_Reg->SP_STATUS_REG, false, true);
|
||||
m_SPEdits[5].SetValue(g_Reg->SP_DMA_FULL_REG, false, true);
|
||||
m_SPEdits[6].SetValue(g_Reg->SP_DMA_BUSY_REG, false, true);
|
||||
m_SPEdits[7].SetValue(g_Reg->SP_SEMAPHORE_REG, false, true);
|
||||
m_SPPCEdit.SetValue(g_Reg->SP_PC_REG, false, true);
|
||||
|
||||
m_DPCEdits[0].SetValue(g_Reg->DPC_START_REG, false, true);
|
||||
m_DPCEdits[1].SetValue(g_Reg->DPC_END_REG, false, true);
|
||||
m_DPCEdits[2].SetValue(g_Reg->DPC_CURRENT_REG, false, true);
|
||||
m_DPCEdits[3].SetValue(g_Reg->DPC_STATUS_REG, false, true);
|
||||
m_DPCEdits[4].SetValue(g_Reg->DPC_CLOCK_REG, false, true);
|
||||
m_DPCEdits[5].SetValue(g_Reg->DPC_BUFBUSY_REG, false, true);
|
||||
m_DPCEdits[6].SetValue(g_Reg->DPC_PIPEBUSY_REG, false, true);
|
||||
m_DPCEdits[7].SetValue(g_Reg->DPC_TMEM_REG, false, true);
|
||||
|
||||
m_MIEdits[0].SetValue(g_Reg->MI_INIT_MODE_REG, false, true);
|
||||
m_MIEdits[1].SetValue(g_Reg->MI_VERSION_REG, false, true);
|
||||
m_MIEdits[2].SetValue(g_Reg->MI_INTR_REG, false, true);
|
||||
m_MIEdits[3].SetValue(g_Reg->MI_INTR_MASK_REG, false, true);
|
||||
|
||||
m_VIEdits[0].SetValue(g_Reg->VI_STATUS_REG, false, true);
|
||||
m_VIEdits[1].SetValue(g_Reg->VI_ORIGIN_REG, false, true);
|
||||
m_VIEdits[2].SetValue(g_Reg->VI_WIDTH_REG, false, true);
|
||||
m_VIEdits[3].SetValue(g_Reg->VI_INTR_REG, false, true);
|
||||
m_VIEdits[4].SetValue(g_Reg->VI_CURRENT_REG, false, true);
|
||||
m_VIEdits[5].SetValue(g_Reg->VI_BURST_REG, false, true);
|
||||
m_VIEdits[6].SetValue(g_Reg->VI_V_SYNC_REG, false, true);
|
||||
m_VIEdits[7].SetValue(g_Reg->VI_H_SYNC_REG, false, true);
|
||||
m_VIEdits[8].SetValue(g_Reg->VI_LEAP_REG, false, true);
|
||||
m_VIEdits[9].SetValue(g_Reg->VI_H_START_REG, false, true);
|
||||
m_VIEdits[10].SetValue(g_Reg->VI_V_START_REG, false, true);
|
||||
m_VIEdits[11].SetValue(g_Reg->VI_V_BURST_REG, false, true);
|
||||
m_VIEdits[12].SetValue(g_Reg->VI_X_SCALE_REG, false, true);
|
||||
m_VIEdits[13].SetValue(g_Reg->VI_Y_SCALE_REG, false, true);
|
||||
|
||||
m_AIEdits[0].SetValue(g_Reg->AI_DRAM_ADDR_REG, false, true);
|
||||
m_AIEdits[1].SetValue(g_Reg->AI_LEN_REG, false, true);
|
||||
m_AIEdits[2].SetValue(g_Reg->AI_CONTROL_REG, false, true);
|
||||
m_AIEdits[3].SetValue(g_Reg->AI_STATUS_REG, false, true);
|
||||
m_AIEdits[4].SetValue(g_Reg->AI_DACRATE_REG, false, true);
|
||||
m_AIEdits[5].SetValue(g_Reg->AI_BITRATE_REG, false, true);
|
||||
|
||||
m_PIEdits[0].SetValue(g_Reg->PI_DRAM_ADDR_REG, false, true);
|
||||
m_PIEdits[1].SetValue(g_Reg->PI_CART_ADDR_REG, false, true);
|
||||
m_PIEdits[2].SetValue(g_Reg->PI_RD_LEN_REG, false, true);
|
||||
m_PIEdits[3].SetValue(g_Reg->PI_WR_LEN_REG, false, true);
|
||||
m_PIEdits[4].SetValue(g_Reg->PI_STATUS_REG, false, true);
|
||||
m_PIEdits[5].SetValue(g_Reg->PI_BSD_DOM1_LAT_REG, false, true);
|
||||
m_PIEdits[6].SetValue(g_Reg->PI_BSD_DOM1_PWD_REG, false, true);
|
||||
m_PIEdits[7].SetValue(g_Reg->PI_BSD_DOM1_PGS_REG, false, true);
|
||||
m_PIEdits[8].SetValue(g_Reg->PI_BSD_DOM1_RLS_REG, false, true);
|
||||
m_PIEdits[9].SetValue(g_Reg->PI_BSD_DOM2_LAT_REG, false, true);
|
||||
m_PIEdits[10].SetValue(g_Reg->PI_BSD_DOM2_PWD_REG, false, true);
|
||||
m_PIEdits[11].SetValue(g_Reg->PI_BSD_DOM2_PGS_REG, false, true);
|
||||
m_PIEdits[12].SetValue(g_Reg->PI_BSD_DOM2_RLS_REG, false, true);
|
||||
|
||||
m_RIEdits[0].SetValue(g_Reg->RI_MODE_REG, false, true);
|
||||
m_RIEdits[1].SetValue(g_Reg->RI_CONFIG_REG, false, true);
|
||||
m_RIEdits[2].SetValue(g_Reg->RI_CURRENT_LOAD_REG, false, true);
|
||||
m_RIEdits[3].SetValue(g_Reg->RI_SELECT_REG, false, true);
|
||||
m_RIEdits[4].SetValue(g_Reg->RI_REFRESH_REG, false, true); // or ri count
|
||||
m_RIEdits[5].SetValue(g_Reg->RI_LATENCY_REG, false, true);
|
||||
m_RIEdits[6].SetValue(g_Reg->RI_RERROR_REG, false, true);
|
||||
m_RIEdits[7].SetValue(g_Reg->RI_WERROR_REG, false, true);
|
||||
|
||||
m_SIEdits[0].SetValue(g_Reg->SI_DRAM_ADDR_REG, false, true);
|
||||
m_SIEdits[1].SetValue(g_Reg->SI_PIF_ADDR_RD64B_REG, false, true);
|
||||
m_SIEdits[2].SetValue(g_Reg->SI_PIF_ADDR_WR64B_REG, false, true);
|
||||
m_SIEdits[3].SetValue(g_Reg->SI_STATUS_REG, false, true);
|
||||
|
||||
m_DDEdits[0].SetValue(g_Reg->ASIC_DATA, false, true);
|
||||
m_DDEdits[1].SetValue(g_Reg->ASIC_MISC_REG, false, true);
|
||||
m_DDEdits[2].SetValue(g_Reg->ASIC_STATUS, false, true);
|
||||
m_DDEdits[3].SetValue(g_Reg->ASIC_CUR_TK, false, true);
|
||||
m_DDEdits[4].SetValue(g_Reg->ASIC_BM_STATUS, false, true);
|
||||
m_DDEdits[5].SetValue(g_Reg->ASIC_ERR_SECTOR, false, true);
|
||||
m_DDEdits[6].SetValue(g_Reg->ASIC_SEQ_STATUS, false, true);
|
||||
m_DDEdits[7].SetValue(g_Reg->ASIC_CUR_SECTOR, false, true);
|
||||
m_DDEdits[8].SetValue(g_Reg->ASIC_HARD_RESET, false, true);
|
||||
m_DDEdits[9].SetValue(g_Reg->ASIC_C1_S0, false, true);
|
||||
m_DDEdits[10].SetValue(g_Reg->ASIC_HOST_SECBYTE, false, true);
|
||||
m_DDEdits[11].SetValue(g_Reg->ASIC_C1_S2, false, true);
|
||||
m_DDEdits[12].SetValue(g_Reg->ASIC_SEC_BYTE, false, true);
|
||||
m_DDEdits[13].SetValue(g_Reg->ASIC_C1_S4, false, true);
|
||||
m_DDEdits[14].SetValue(g_Reg->ASIC_C1_S6, false, true);
|
||||
m_DDEdits[15].SetValue(g_Reg->ASIC_CUR_ADDR, false, true);
|
||||
m_DDEdits[16].SetValue(g_Reg->ASIC_ID_REG, false, true);
|
||||
m_DDEdits[17].SetValue(g_Reg->ASIC_TEST_REG, false, true);
|
||||
m_DDEdits[18].SetValue(g_Reg->ASIC_TEST_PIN_SEL, false, true);
|
||||
}
|
||||
|
||||
void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam)
|
||||
{
|
||||
CBreakpoints* breakpoints = ((CDebuggerUI*)g_Debugger)->Breakpoints();
|
||||
|
||||
if (g_Reg == NULL || !breakpoints->isDebugging())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int ctrlId = LOWORD(wParam);
|
||||
|
||||
CWindow editCtrl = ::GetDlgItem(hDlg, ctrlId);
|
||||
char text[20];
|
||||
editCtrl.GetWindowText(text, 20);
|
||||
|
||||
if (srcTabId == TabGPR)
|
||||
{
|
||||
uint64_t value = CEditReg64::ParseValue(text);
|
||||
if (ctrlId == IDC_HI_EDIT)
|
||||
{
|
||||
g_Reg->m_HI.UDW = value;
|
||||
}
|
||||
else if (ctrlId == IDC_LO_EDIT)
|
||||
{
|
||||
g_Reg->m_LO.UDW = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nReg = MapEditRegNum(ctrlId, GPREditIds);
|
||||
g_Reg->m_GPR[nReg].UDW = value;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t value = strtoul(text, NULL, 16);
|
||||
sprintf(text, "%08X", value);
|
||||
editCtrl.SetWindowText(text); // reformat text
|
||||
|
||||
if (srcTabId == TabFPR)
|
||||
{
|
||||
if (ctrlId == IDC_FCSR_EDIT)
|
||||
{
|
||||
g_Reg->m_FPCR[31] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
int nReg = MapEditRegNum(ctrlId, FPREditIds);
|
||||
*(uint32_t*)g_Reg->m_FPR_S[nReg] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ctrlId)
|
||||
{
|
||||
case IDC_COP0_0_EDIT: g_Reg->INDEX_REGISTER = value; break;
|
||||
case IDC_COP0_1_EDIT: g_Reg->RANDOM_REGISTER = value; break;
|
||||
case IDC_COP0_2_EDIT: g_Reg->ENTRYLO0_REGISTER = value; break;
|
||||
case IDC_COP0_3_EDIT: g_Reg->ENTRYLO1_REGISTER = value; break;
|
||||
case IDC_COP0_4_EDIT: g_Reg->CONTEXT_REGISTER = value; break;
|
||||
case IDC_COP0_5_EDIT: g_Reg->PAGE_MASK_REGISTER = value; break;
|
||||
case IDC_COP0_6_EDIT: g_Reg->WIRED_REGISTER = value; break;
|
||||
case IDC_COP0_7_EDIT: g_Reg->BAD_VADDR_REGISTER = value; break;
|
||||
case IDC_COP0_8_EDIT: g_Reg->COUNT_REGISTER = value; break;
|
||||
case IDC_COP0_9_EDIT: g_Reg->ENTRYHI_REGISTER = value; break;
|
||||
case IDC_COP0_10_EDIT: g_Reg->COMPARE_REGISTER = value; break;
|
||||
case IDC_COP0_11_EDIT: g_Reg->STATUS_REGISTER = value; break;
|
||||
case IDC_COP0_12_EDIT: g_Reg->CAUSE_REGISTER = value; break;
|
||||
case IDC_COP0_13_EDIT: g_Reg->EPC_REGISTER = value; break;
|
||||
case IDC_COP0_14_EDIT: g_Reg->CONFIG_REGISTER = value; break;
|
||||
case IDC_COP0_15_EDIT: g_Reg->TAGLO_REGISTER = value; break;
|
||||
case IDC_COP0_16_EDIT: g_Reg->TAGHI_REGISTER = value; break;
|
||||
case IDC_COP0_17_EDIT: g_Reg->ERROREPC_REGISTER = value; break;
|
||||
case IDC_COP0_18_EDIT: g_Reg->FAKE_CAUSE_REGISTER = value; break;
|
||||
|
||||
case IDC_RDRAM00_EDIT: g_Reg->RDRAM_CONFIG_REG = value; break; // or device_type
|
||||
case IDC_RDRAM04_EDIT: g_Reg->RDRAM_DEVICE_ID_REG = value; break;
|
||||
case IDC_RDRAM08_EDIT: g_Reg->RDRAM_DELAY_REG = value; break;
|
||||
case IDC_RDRAM0C_EDIT: g_Reg->RDRAM_MODE_REG = value; break;
|
||||
case IDC_RDRAM10_EDIT: g_Reg->RDRAM_REF_INTERVAL_REG = value; break;
|
||||
case IDC_RDRAM14_EDIT: g_Reg->RDRAM_REF_ROW_REG = value; break;
|
||||
case IDC_RDRAM18_EDIT: g_Reg->RDRAM_RAS_INTERVAL_REG = value; break;
|
||||
case IDC_RDRAM1C_EDIT: g_Reg->RDRAM_MIN_INTERVAL_REG = value; break;
|
||||
case IDC_RDRAM20_EDIT: g_Reg->RDRAM_ADDR_SELECT_REG = value; break;
|
||||
case IDC_RDRAM24_EDIT: g_Reg->RDRAM_DEVICE_MANUF_REG = value; break;
|
||||
|
||||
case IDC_SP00_EDIT: g_Reg->SP_MEM_ADDR_REG = value; break;
|
||||
case IDC_SP04_EDIT: g_Reg->SP_DRAM_ADDR_REG = value; break;
|
||||
case IDC_SP08_EDIT: g_Reg->SP_RD_LEN_REG = value; break;
|
||||
case IDC_SP0C_EDIT: g_Reg->SP_WR_LEN_REG = value; break;
|
||||
case IDC_SP10_EDIT: g_Reg->SP_STATUS_REG = value; break;
|
||||
case IDC_SP14_EDIT: g_Reg->SP_DMA_FULL_REG = value; break;
|
||||
case IDC_SP18_EDIT: g_Reg->SP_DMA_BUSY_REG = value; break;
|
||||
case IDC_SP1C_EDIT: g_Reg->SP_SEMAPHORE_REG = value; break;
|
||||
case IDC_SP_PC_EDIT: g_Reg->SP_PC_REG = value; break;
|
||||
|
||||
case IDC_DPC00_EDIT: g_Reg->DPC_START_REG = value; break;
|
||||
case IDC_DPC04_EDIT: g_Reg->DPC_END_REG = value; break;
|
||||
case IDC_DPC08_EDIT: g_Reg->DPC_CURRENT_REG = value; break;
|
||||
case IDC_DPC0C_EDIT: g_Reg->DPC_STATUS_REG = value; break;
|
||||
case IDC_DPC10_EDIT: g_Reg->DPC_CLOCK_REG = value; break;
|
||||
case IDC_DPC14_EDIT: g_Reg->DPC_BUFBUSY_REG = value; break;
|
||||
case IDC_DPC18_EDIT: g_Reg->DPC_PIPEBUSY_REG = value; break;
|
||||
case IDC_DPC1C_EDIT: g_Reg->DPC_TMEM_REG = value; break;
|
||||
|
||||
case IDC_MI00_EDIT: g_Reg->MI_INIT_MODE_REG = value; break; // or MI_MODE ?
|
||||
case IDC_MI04_EDIT: g_Reg->MI_VERSION_REG = value; break; // or MI_NOOP ?
|
||||
case IDC_MI08_EDIT: g_Reg->MI_INTR_REG = value; break; // or MI_INTR ?
|
||||
case IDC_MI0C_EDIT: g_Reg->MI_INTR_MASK_REG = value; break; // or MI_INTR_MASK ?
|
||||
|
||||
case IDC_VI00_EDIT: g_Reg->VI_STATUS_REG = value; break;
|
||||
case IDC_VI04_EDIT: g_Reg->VI_ORIGIN_REG = value; break;
|
||||
case IDC_VI08_EDIT: g_Reg->VI_WIDTH_REG = value; break;
|
||||
case IDC_VI0C_EDIT: g_Reg->VI_INTR_REG = value; break;
|
||||
case IDC_VI10_EDIT: g_Reg->VI_CURRENT_REG = value; break;
|
||||
case IDC_VI14_EDIT: g_Reg->VI_BURST_REG = value; break;
|
||||
case IDC_VI18_EDIT: g_Reg->VI_V_SYNC_REG = value; break;
|
||||
case IDC_VI1C_EDIT: g_Reg->VI_H_SYNC_REG = value; break;
|
||||
case IDC_VI20_EDIT: g_Reg->VI_LEAP_REG = value; break;
|
||||
case IDC_VI24_EDIT: g_Reg->VI_H_START_REG = value; break;
|
||||
case IDC_VI28_EDIT: g_Reg->VI_V_START_REG = value; break;
|
||||
case IDC_VI2C_EDIT: g_Reg->VI_V_BURST_REG = value; break;
|
||||
case IDC_VI30_EDIT: g_Reg->VI_X_SCALE_REG = value; break;
|
||||
case IDC_VI34_EDIT: g_Reg->VI_Y_SCALE_REG = value; break;
|
||||
|
||||
case IDC_AI00_EDIT: g_Reg->AI_DRAM_ADDR_REG = value; break;
|
||||
case IDC_AI04_EDIT: g_Reg->AI_LEN_REG = value; break;
|
||||
case IDC_AI08_EDIT: g_Reg->AI_CONTROL_REG = value; break;
|
||||
case IDC_AI0C_EDIT: g_Reg->AI_STATUS_REG = value; break;
|
||||
case IDC_AI10_EDIT: g_Reg->AI_DACRATE_REG = value; break;
|
||||
case IDC_AI14_EDIT: g_Reg->AI_BITRATE_REG = value; break;
|
||||
|
||||
case IDC_PI00_EDIT: g_Reg->PI_DRAM_ADDR_REG = value; break;
|
||||
case IDC_PI04_EDIT: g_Reg->PI_CART_ADDR_REG = value; break;
|
||||
case IDC_PI08_EDIT: g_Reg->PI_RD_LEN_REG = value; break;
|
||||
case IDC_PI0C_EDIT: g_Reg->PI_WR_LEN_REG = value; break;
|
||||
case IDC_PI10_EDIT: g_Reg->PI_STATUS_REG = value; break;
|
||||
case IDC_PI14_EDIT: g_Reg->PI_BSD_DOM1_LAT_REG = value; break;
|
||||
case IDC_PI18_EDIT: g_Reg->PI_BSD_DOM1_PWD_REG = value; break;
|
||||
case IDC_PI1C_EDIT: g_Reg->PI_BSD_DOM1_PGS_REG = value; break;
|
||||
case IDC_PI20_EDIT: g_Reg->PI_BSD_DOM1_RLS_REG = value; break;
|
||||
case IDC_PI24_EDIT: g_Reg->PI_BSD_DOM2_LAT_REG = value; break;
|
||||
case IDC_PI28_EDIT: g_Reg->PI_BSD_DOM2_PWD_REG = value; break;
|
||||
case IDC_PI2C_EDIT: g_Reg->PI_BSD_DOM2_PGS_REG = value; break;
|
||||
case IDC_PI30_EDIT: g_Reg->PI_BSD_DOM2_RLS_REG = value; break;
|
||||
|
||||
case IDC_RI00_EDIT: g_Reg->RI_MODE_REG = value; break;
|
||||
case IDC_RI04_EDIT: g_Reg->RI_CONFIG_REG = value; break;
|
||||
case IDC_RI08_EDIT: g_Reg->RI_CURRENT_LOAD_REG = value; break;
|
||||
case IDC_RI0C_EDIT: g_Reg->RI_SELECT_REG = value; break;
|
||||
case IDC_RI10_EDIT: g_Reg->RI_REFRESH_REG = value; break;
|
||||
case IDC_RI14_EDIT: g_Reg->RI_LATENCY_REG = value; break;
|
||||
case IDC_RI18_EDIT: g_Reg->RI_RERROR_REG = value; break;
|
||||
case IDC_RI1C_EDIT: g_Reg->RI_WERROR_REG = value; break;
|
||||
|
||||
case IDC_SI00_EDIT: g_Reg->SI_DRAM_ADDR_REG = value; break;
|
||||
case IDC_SI04_EDIT: g_Reg->SI_PIF_ADDR_RD64B_REG = value; break;
|
||||
case IDC_SI08_EDIT: g_Reg->SI_PIF_ADDR_WR64B_REG = value; break;
|
||||
case IDC_SI0C_EDIT: g_Reg->SI_STATUS_REG = value; break;
|
||||
|
||||
case IDC_DD00_EDIT: g_Reg->ASIC_DATA = value; break;
|
||||
case IDC_DD04_EDIT: g_Reg->ASIC_MISC_REG = value; break;
|
||||
case IDC_DD08_EDIT: g_Reg->ASIC_STATUS = value; break;
|
||||
case IDC_DD0C_EDIT: g_Reg->ASIC_CUR_TK = value; break;
|
||||
case IDC_DD10_EDIT: g_Reg->ASIC_BM_STATUS = value; break;
|
||||
case IDC_DD14_EDIT: g_Reg->ASIC_ERR_SECTOR = value; break;
|
||||
case IDC_DD18_EDIT: g_Reg->ASIC_SEQ_STATUS = value; break;
|
||||
case IDC_DD1C_EDIT: g_Reg->ASIC_CUR_SECTOR = value; break;
|
||||
case IDC_DD20_EDIT: g_Reg->ASIC_HARD_RESET = value; break;
|
||||
case IDC_DD24_EDIT: g_Reg->ASIC_C1_S0 = value; break;
|
||||
case IDC_DD28_EDIT: g_Reg->ASIC_HOST_SECBYTE = value; break;
|
||||
case IDC_DD2C_EDIT: g_Reg->ASIC_C1_S2 = value; break;
|
||||
case IDC_DD30_EDIT: g_Reg->ASIC_SEC_BYTE = value; break;
|
||||
case IDC_DD34_EDIT: g_Reg->ASIC_C1_S4 = value; break;
|
||||
case IDC_DD38_EDIT: g_Reg->ASIC_C1_S6 = value; break;
|
||||
case IDC_DD3C_EDIT: g_Reg->ASIC_CUR_ADDR = value; break;
|
||||
case IDC_DD40_EDIT: g_Reg->ASIC_ID_REG = value; break;
|
||||
case IDC_DD44_EDIT: g_Reg->ASIC_TEST_REG = value; break;
|
||||
case IDC_DD48_EDIT: g_Reg->ASIC_TEST_PIN_SEL = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK CRegisterTabs::TabProcDefault(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_INITDIALOG)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (msg != WM_COMMAND)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WORD notification = HIWORD(wParam);
|
||||
|
||||
if (notification == EN_KILLFOCUS)
|
||||
{
|
||||
RegisterChanged(hDlg, TabDefault, wParam);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_INITDIALOG)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (msg == WM_CTLCOLOREDIT)
|
||||
{
|
||||
HDC hdc = (HDC)wParam;
|
||||
COLORREF colorBg = RGB(255, 255, 255);
|
||||
|
||||
COLORREF colorRead = RGB(200, 200, 255);
|
||||
COLORREF colorWrite = RGB(255, 200, 200);
|
||||
COLORREF colorBoth = RGB(255, 200, 255);
|
||||
|
||||
if (!m_bColorsEnabled || g_Reg == NULL || g_MMU == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HWND hWnd = (HWND)lParam;
|
||||
int ctrlId = ::GetWindowLong(hWnd, GWL_ID);
|
||||
|
||||
COpInfo opInfo;
|
||||
g_MMU->LW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);
|
||||
|
||||
bool bOpReads = false;
|
||||
bool bOpWrites = false;
|
||||
|
||||
if (ctrlId == IDC_LO_EDIT)
|
||||
{
|
||||
bOpReads = opInfo.ReadsLO();
|
||||
bOpWrites = !bOpReads && opInfo.WritesLO();
|
||||
}
|
||||
else if (ctrlId == IDC_HI_EDIT)
|
||||
{
|
||||
bOpReads = opInfo.ReadsHI();
|
||||
bOpWrites = !bOpReads && opInfo.WritesHI();
|
||||
}
|
||||
else
|
||||
{
|
||||
int nReg = MapEditRegNum(ctrlId, GPREditIds);
|
||||
bOpReads = opInfo.ReadsGPR(nReg);
|
||||
bOpWrites = opInfo.WritesGPR(nReg);
|
||||
}
|
||||
|
||||
if (bOpReads && bOpWrites)
|
||||
{
|
||||
colorBg = colorBoth;
|
||||
}
|
||||
else if(bOpReads)
|
||||
{
|
||||
colorBg = colorRead;
|
||||
}
|
||||
else if (bOpWrites)
|
||||
{
|
||||
colorBg = colorWrite;
|
||||
}
|
||||
|
||||
SetBkColor(hdc, colorBg);
|
||||
SetDCBrushColor(hdc, colorBg);
|
||||
return (LRESULT)GetStockObject(DC_BRUSH);
|
||||
}
|
||||
|
||||
if (msg != WM_COMMAND)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WORD notification = HIWORD(wParam);
|
||||
|
||||
if (notification == EN_KILLFOCUS)
|
||||
{
|
||||
RegisterChanged(hDlg, TabGPR, wParam);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK CRegisterTabs::TabProcFPR(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_INITDIALOG)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (msg != WM_COMMAND)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WORD notification = HIWORD(wParam);
|
||||
|
||||
if (notification == EN_KILLFOCUS)
|
||||
{
|
||||
RegisterChanged(hDlg, TabFPR, wParam);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CRect CRegisterTabs::GetPageRect()
|
||||
{
|
||||
CWindow parentWin = GetParent();
|
||||
CRect pageRect;
|
||||
GetWindowRect(&pageRect);
|
||||
parentWin.ScreenToClient(&pageRect);
|
||||
AdjustRect(FALSE, &pageRect);
|
||||
return pageRect;
|
||||
}
|
||||
|
||||
CWindow CRegisterTabs::AddTab(char* caption, int dialogId, DLGPROC dlgProc)
|
||||
{
|
||||
AddItem(caption);
|
||||
|
||||
CWindow parentWin = GetParent();
|
||||
CWindow tabWin = ::CreateDialog(NULL, MAKEINTRESOURCE(dialogId), parentWin, dlgProc);
|
||||
|
||||
CRect pageRect = GetPageRect();
|
||||
|
||||
::SetParent(tabWin, parentWin);
|
||||
|
||||
::SetWindowPos(
|
||||
tabWin,
|
||||
m_hWnd,
|
||||
pageRect.left,
|
||||
pageRect.top,
|
||||
pageRect.Width(),
|
||||
pageRect.Height(),
|
||||
SWP_HIDEWINDOW
|
||||
);
|
||||
|
||||
m_TabWindows.push_back(tabWin);
|
||||
|
||||
int index = m_TabWindows.size() - 1;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
ShowTab(0);
|
||||
}
|
||||
|
||||
return tabWin;
|
||||
}
|
||||
|
||||
void CRegisterTabs::ShowTab(int nPage)
|
||||
{
|
||||
for (int i = 0; i < m_TabWindows.size(); i++)
|
||||
{
|
||||
::ShowWindow(m_TabWindows[i], SW_HIDE);
|
||||
}
|
||||
|
||||
CRect pageRect = GetPageRect();
|
||||
|
||||
::SetWindowPos(
|
||||
m_TabWindows[nPage],
|
||||
HWND_TOP,
|
||||
pageRect.left,
|
||||
pageRect.top,
|
||||
pageRect.Width(),
|
||||
pageRect.Height(),
|
||||
SWP_SHOWWINDOW
|
||||
);
|
||||
}
|
||||
|
||||
void CRegisterTabs::RedrawCurrentTab()
|
||||
{
|
||||
int nPage = GetCurSel();
|
||||
CRect pageRect = GetPageRect();
|
||||
|
||||
::SetWindowPos(
|
||||
m_TabWindows[nPage],
|
||||
HWND_TOP,
|
||||
pageRect.left,
|
||||
pageRect.top,
|
||||
pageRect.Width(),
|
||||
pageRect.Height(),
|
||||
SWP_SHOWWINDOW
|
||||
);
|
||||
}
|
||||
|
||||
void CRegisterTabs::SetColorsEnabled(bool bColorsEnabled)
|
||||
{
|
||||
m_bColorsEnabled = bColorsEnabled;
|
||||
}
|
||||
|
||||
void CRegisterTabs::InitRegisterEdit(CWindow& tab, CEditNumber& edit, WORD ctrlId, HFONT font)
|
||||
{
|
||||
edit.Attach(tab.GetDlgItem(ctrlId));
|
||||
edit.SetDisplayType(CEditNumber::DisplayHex);
|
||||
edit.SetFont(font);
|
||||
}
|
||||
|
||||
void CRegisterTabs::InitRegisterEdits(CWindow& tab, CEditNumber* edits, const DWORD* ctrlIds, HFONT font)
|
||||
{
|
||||
for (int i = 0; i < ctrlIds[i] != 0; i++)
|
||||
{
|
||||
InitRegisterEdit(tab, edits[i], ctrlIds[i], font);
|
||||
}
|
||||
}
|
||||
|
||||
void CRegisterTabs::InitRegisterEdit64(CWindow& tab, CEditReg64& edit, WORD ctrlId, HFONT font)
|
||||
{
|
||||
edit.Attach(tab.GetDlgItem(ctrlId));
|
||||
edit.SetFont(font);
|
||||
}
|
||||
|
||||
void CRegisterTabs::InitRegisterEdits64(CWindow& tab, CEditReg64* edits, const DWORD* ctrlIds, HFONT font)
|
||||
{
|
||||
for (int i = 0; i < ctrlIds[i] != 0; i++)
|
||||
{
|
||||
InitRegisterEdit64(tab, edits[i], ctrlIds[i], font);
|
||||
}
|
||||
}
|
||||
|
||||
void CRegisterTabs::ZeroRegisterEdit(CEditNumber& edit)
|
||||
{
|
||||
edit.SetValue(0, false, true);
|
||||
}
|
||||
|
||||
void CRegisterTabs::ZeroRegisterEdits(CEditNumber* edits, const DWORD* ctrlIds)
|
||||
{
|
||||
for (int i = 0; ctrlIds[i] != 0; i++)
|
||||
{
|
||||
ZeroRegisterEdit(edits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CRegisterTabs::ZeroRegisterEdit64(CEditReg64& edit)
|
||||
{
|
||||
edit.SetValue(0);
|
||||
}
|
||||
|
||||
void CRegisterTabs::ZeroRegisterEdits64(CEditReg64* edits, const DWORD* ctrlIds)
|
||||
{
|
||||
for (int i = 0; ctrlIds[i] != 0; i++)
|
||||
{
|
||||
ZeroRegisterEdit64(edits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// CEditReg64 for GPR
|
||||
|
||||
uint64_t CEditReg64::ParseValue(char* wordPair)
|
||||
{
|
||||
uint32_t a, b;
|
||||
uint64_t ret;
|
||||
a = strtoul(wordPair, &wordPair, 16);
|
||||
if (*wordPair == ' ')
|
||||
{
|
||||
wordPair++;
|
||||
b = strtoul(wordPair, NULL, 16);
|
||||
ret = (uint64_t)a << 32;
|
||||
ret |= b;
|
||||
return ret;
|
||||
}
|
||||
return (uint64_t)a;
|
||||
}
|
||||
|
||||
BOOL CEditReg64::Attach(HWND hWndNew)
|
||||
{
|
||||
return SubclassWindow(hWndNew);
|
||||
}
|
||||
|
||||
LRESULT CEditReg64::OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
CBreakpoints* breakpoints = ((CDebuggerUI*)g_Debugger)->Breakpoints();
|
||||
if (!breakpoints->isDebugging())
|
||||
{
|
||||
goto canceled;
|
||||
}
|
||||
|
||||
char charCode = wParam;
|
||||
|
||||
if (!isxdigit(charCode) && charCode != ' ')
|
||||
{
|
||||
if (!isalnum(charCode))
|
||||
{
|
||||
goto unhandled;
|
||||
}
|
||||
goto canceled;
|
||||
}
|
||||
|
||||
if (isalpha(charCode) && !isupper(charCode))
|
||||
{
|
||||
SendMessage(uMsg, toupper(wParam), lParam);
|
||||
goto canceled;
|
||||
}
|
||||
|
||||
char text[20];
|
||||
GetWindowText(text, 20);
|
||||
int textLen = strlen(text);
|
||||
|
||||
if (textLen >= 17)
|
||||
{
|
||||
int selStart, selEnd;
|
||||
GetSel(selStart, selEnd);
|
||||
if (selEnd - selStart == 0)
|
||||
{
|
||||
goto canceled;
|
||||
}
|
||||
}
|
||||
|
||||
if (charCode == ' ' && strchr(text, ' ') != NULL)
|
||||
{
|
||||
goto canceled;
|
||||
}
|
||||
|
||||
unhandled:
|
||||
bHandled = FALSE;
|
||||
return 0;
|
||||
|
||||
canceled:
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t CEditReg64::GetValue()
|
||||
{
|
||||
char text[20];
|
||||
GetWindowText(text, 20);
|
||||
return ParseValue(text);
|
||||
}
|
||||
|
||||
LRESULT CEditReg64::OnLostFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
SetValue(GetValue()); // clean up
|
||||
bHandled = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CEditReg64::SetValue(uint32_t h, uint32_t l)
|
||||
{
|
||||
char text[20];
|
||||
sprintf(text, "%08X %08X", h, l);
|
||||
SetWindowText(text);
|
||||
}
|
||||
|
||||
void CEditReg64::SetValue(uint64_t value)
|
||||
{
|
||||
uint32_t h = (value & 0xFFFFFFFF00000000LL) >> 32;
|
||||
uint32_t l = (value & 0x00000000FFFFFFFFLL);
|
||||
SetValue(h, l);
|
||||
}
|
|
@ -0,0 +1,282 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Breakpoints.h"
|
||||
|
||||
#ifndef COUNT_OF
|
||||
#define COUNT_OF(a) (sizeof(a) / sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
class CEditReg64 : public CWindowImpl<CEditReg64, CEdit>
|
||||
{
|
||||
public:
|
||||
static uint64_t ParseValue(char* wordPair);
|
||||
BOOL Attach(HWND hWndNew);
|
||||
LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnLostFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
uint64_t GetValue();
|
||||
void SetValue(uint32_t h, uint32_t l);
|
||||
void SetValue(uint64_t value);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CRegEdit64)
|
||||
MESSAGE_HANDLER(WM_CHAR, OnChar)
|
||||
MESSAGE_HANDLER(WM_KILLFOCUS, OnLostFocus)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
class CRegisterTabs : public CTabCtrl
|
||||
{
|
||||
private:
|
||||
typedef union
|
||||
{
|
||||
uint32_t intval;
|
||||
|
||||
struct {
|
||||
unsigned : 2;
|
||||
unsigned exceptionCode : 5;
|
||||
unsigned : 1;
|
||||
unsigned pendingInterrupts : 8;
|
||||
unsigned : 12;
|
||||
unsigned coprocessor : 2;
|
||||
unsigned : 1;
|
||||
unsigned fromDelaySlot : 1;
|
||||
};
|
||||
|
||||
} CAUSE;
|
||||
|
||||
enum TAB_ID {
|
||||
TabDefault,
|
||||
TabGPR,
|
||||
TabFPR
|
||||
};
|
||||
|
||||
static constexpr DWORD GPREditIds[] = {
|
||||
IDC_R0_EDIT, IDC_R1_EDIT, IDC_R2_EDIT, IDC_R3_EDIT,
|
||||
IDC_R4_EDIT, IDC_R5_EDIT, IDC_R6_EDIT, IDC_R7_EDIT,
|
||||
IDC_R8_EDIT, IDC_R9_EDIT, IDC_R10_EDIT, IDC_R11_EDIT,
|
||||
IDC_R12_EDIT, IDC_R13_EDIT, IDC_R14_EDIT, IDC_R15_EDIT,
|
||||
IDC_R16_EDIT, IDC_R17_EDIT, IDC_R18_EDIT, IDC_R19_EDIT,
|
||||
IDC_R20_EDIT, IDC_R21_EDIT, IDC_R22_EDIT, IDC_R23_EDIT,
|
||||
IDC_R24_EDIT, IDC_R25_EDIT, IDC_R26_EDIT, IDC_R27_EDIT,
|
||||
IDC_R28_EDIT, IDC_R29_EDIT, IDC_R30_EDIT, IDC_R31_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD FPREditIds[] = {
|
||||
IDC_F0_EDIT, IDC_F1_EDIT, IDC_F2_EDIT, IDC_F3_EDIT,
|
||||
IDC_F4_EDIT, IDC_F5_EDIT, IDC_F6_EDIT, IDC_F7_EDIT,
|
||||
IDC_F8_EDIT, IDC_F9_EDIT, IDC_F10_EDIT, IDC_F11_EDIT,
|
||||
IDC_F12_EDIT, IDC_F13_EDIT, IDC_F14_EDIT, IDC_F15_EDIT,
|
||||
IDC_F16_EDIT, IDC_F17_EDIT, IDC_F18_EDIT, IDC_F19_EDIT,
|
||||
IDC_F20_EDIT, IDC_F21_EDIT, IDC_F22_EDIT, IDC_F23_EDIT,
|
||||
IDC_F24_EDIT, IDC_F25_EDIT, IDC_F26_EDIT, IDC_F27_EDIT,
|
||||
IDC_F28_EDIT, IDC_F29_EDIT, IDC_F30_EDIT, IDC_F31_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD COP0EditIds[] = {
|
||||
IDC_COP0_0_EDIT, IDC_COP0_1_EDIT, IDC_COP0_2_EDIT, IDC_COP0_3_EDIT,
|
||||
IDC_COP0_4_EDIT, IDC_COP0_5_EDIT, IDC_COP0_6_EDIT, IDC_COP0_7_EDIT,
|
||||
IDC_COP0_8_EDIT, IDC_COP0_9_EDIT, IDC_COP0_10_EDIT, IDC_COP0_11_EDIT,
|
||||
IDC_COP0_12_EDIT, IDC_COP0_13_EDIT, IDC_COP0_14_EDIT, IDC_COP0_15_EDIT,
|
||||
IDC_COP0_16_EDIT, IDC_COP0_17_EDIT, IDC_COP0_18_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD RDRAMEditIds[] = {
|
||||
IDC_RDRAM00_EDIT, IDC_RDRAM04_EDIT, IDC_RDRAM08_EDIT, IDC_RDRAM0C_EDIT,
|
||||
IDC_RDRAM10_EDIT, IDC_RDRAM14_EDIT, IDC_RDRAM18_EDIT, IDC_RDRAM1C_EDIT,
|
||||
IDC_RDRAM20_EDIT, IDC_RDRAM24_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD SPEditIds[] = {
|
||||
IDC_SP00_EDIT, IDC_SP04_EDIT, IDC_SP08_EDIT, IDC_SP0C_EDIT,
|
||||
IDC_SP10_EDIT, IDC_SP14_EDIT, IDC_SP18_EDIT, IDC_SP1C_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD DPCEditIds[] = {
|
||||
IDC_DPC00_EDIT, IDC_DPC04_EDIT, IDC_DPC08_EDIT, IDC_DPC0C_EDIT,
|
||||
IDC_DPC10_EDIT, IDC_DPC14_EDIT, IDC_DPC18_EDIT, IDC_DPC1C_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD MIEditIds[] = {
|
||||
IDC_MI00_EDIT, IDC_MI04_EDIT, IDC_MI08_EDIT, IDC_MI0C_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD VIEditIds[] = {
|
||||
IDC_VI00_EDIT, IDC_VI04_EDIT, IDC_VI08_EDIT, IDC_VI0C_EDIT,
|
||||
IDC_VI10_EDIT, IDC_VI14_EDIT, IDC_VI18_EDIT, IDC_VI1C_EDIT,
|
||||
IDC_VI20_EDIT, IDC_VI24_EDIT, IDC_VI28_EDIT, IDC_VI2C_EDIT,
|
||||
IDC_VI30_EDIT, IDC_VI34_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD AIEditIds[] = {
|
||||
IDC_AI00_EDIT, IDC_AI04_EDIT, IDC_AI08_EDIT, IDC_AI0C_EDIT,
|
||||
IDC_AI10_EDIT, IDC_AI14_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD PIEditIds[] = {
|
||||
IDC_PI00_EDIT, IDC_PI04_EDIT, IDC_PI08_EDIT, IDC_PI0C_EDIT,
|
||||
IDC_PI10_EDIT, IDC_PI14_EDIT, IDC_PI18_EDIT, IDC_PI1C_EDIT,
|
||||
IDC_PI20_EDIT, IDC_PI24_EDIT, IDC_PI28_EDIT, IDC_PI2C_EDIT,
|
||||
IDC_PI30_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD RIEditIds[] = {
|
||||
IDC_RI00_EDIT, IDC_RI04_EDIT, IDC_RI08_EDIT, IDC_RI0C_EDIT,
|
||||
IDC_RI10_EDIT, IDC_RI14_EDIT, IDC_RI18_EDIT, IDC_RI1C_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD SIEditIds[] = {
|
||||
IDC_SI00_EDIT, IDC_SI04_EDIT, IDC_SI08_EDIT, IDC_SI0C_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static constexpr DWORD DDEditIds[] = {
|
||||
IDC_DD00_EDIT, IDC_DD04_EDIT, IDC_DD08_EDIT, IDC_DD0C_EDIT,
|
||||
IDC_DD10_EDIT, IDC_DD14_EDIT, IDC_DD18_EDIT, IDC_DD1C_EDIT,
|
||||
IDC_DD20_EDIT, IDC_DD24_EDIT, IDC_DD28_EDIT, IDC_DD2C_EDIT,
|
||||
IDC_DD30_EDIT, IDC_DD34_EDIT, IDC_DD38_EDIT, IDC_DD3C_EDIT,
|
||||
IDC_DD40_EDIT, IDC_DD44_EDIT, IDC_DD48_EDIT,
|
||||
0
|
||||
};
|
||||
|
||||
static int MapEditRegNum(DWORD controlId, const DWORD* edits)
|
||||
{
|
||||
for (int i = 0; edits[i] != 0; i++)
|
||||
{
|
||||
if (edits[i] == controlId)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static constexpr char* ExceptionCodes[] = {
|
||||
"Interrupt",
|
||||
"TLB mod",
|
||||
"TLB load/fetch",
|
||||
"TLB store",
|
||||
"Address error (load/fetch)",
|
||||
"Address error (store)",
|
||||
"Bus error (instruction fetch)",
|
||||
"Bus error (data load/store)",
|
||||
"Syscall",
|
||||
"Breakpoint",
|
||||
"Reserved instruction",
|
||||
"Coprocessor unusable",
|
||||
"Arithmetic overflow",
|
||||
"Trap",
|
||||
"Virtual coherency (instruction)",
|
||||
"Floating-point",
|
||||
"? 16",
|
||||
"? 17",
|
||||
"? 18",
|
||||
"? 19",
|
||||
"? 20",
|
||||
"? 21",
|
||||
"? 22",
|
||||
"Watch",
|
||||
"? 24",
|
||||
"? 25",
|
||||
"? 26",
|
||||
"? 27",
|
||||
"? 28",
|
||||
"? 29",
|
||||
"? 30",
|
||||
"Virtual coherency (data)"
|
||||
};
|
||||
|
||||
// for static dlgprocs, assumes single instance
|
||||
static bool m_bColorsEnabled;
|
||||
|
||||
vector<CWindow> m_TabWindows;
|
||||
|
||||
CWindow m_GPRTab;
|
||||
CEditReg64 m_GPREdits[COUNT_OF(GPREditIds) - 1];
|
||||
CEditReg64 m_HIEdit;
|
||||
CEditReg64 m_LOEdit;
|
||||
|
||||
CWindow m_FPRTab;
|
||||
CEditNumber m_FPREdits[COUNT_OF(FPREditIds) - 1];
|
||||
CEditNumber m_FCSREdit;
|
||||
|
||||
CWindow m_COP0Tab;
|
||||
CEditNumber m_COP0Edits[COUNT_OF(COP0EditIds) - 1];
|
||||
CStatic m_CauseTip;
|
||||
|
||||
CWindow m_RDRAMTab;
|
||||
CEditNumber m_RDRAMEdits[COUNT_OF(RDRAMEditIds) - 1];
|
||||
|
||||
CWindow m_SPTab;
|
||||
CEditNumber m_SPEdits[COUNT_OF(SPEditIds) - 1];
|
||||
CEditNumber m_SPPCEdit;
|
||||
|
||||
CWindow m_DPCTab;
|
||||
CEditNumber m_DPCEdits[COUNT_OF(DPCEditIds) - 1];
|
||||
|
||||
CWindow m_MITab;
|
||||
CEditNumber m_MIEdits[COUNT_OF(MIEditIds) - 1];
|
||||
|
||||
CWindow m_VITab;
|
||||
CEditNumber m_VIEdits[COUNT_OF(VIEditIds) - 1];
|
||||
|
||||
CWindow m_AITab;
|
||||
CEditNumber m_AIEdits[COUNT_OF(AIEditIds) - 1];
|
||||
|
||||
CWindow m_PITab;
|
||||
CEditNumber m_PIEdits[COUNT_OF(PIEditIds) - 1];
|
||||
|
||||
CWindow m_RITab;
|
||||
CEditNumber m_RIEdits[COUNT_OF(RIEditIds) - 1];
|
||||
|
||||
CWindow m_SITab;
|
||||
CEditNumber m_SIEdits[COUNT_OF(SIEditIds) - 1];
|
||||
|
||||
CWindow m_DDTab;
|
||||
CEditNumber m_DDEdits[COUNT_OF(DDEditIds) - 1];
|
||||
|
||||
static void RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam);
|
||||
|
||||
static INT_PTR CALLBACK TabProcDefault(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static INT_PTR CALLBACK TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static INT_PTR CALLBACK TabProcFPR(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static void InitRegisterEdit(CWindow& tab, CEditNumber& edit, WORD ctrlId, HFONT font);
|
||||
static void InitRegisterEdits(CWindow& tab, CEditNumber* edits, const DWORD* ctrlIds, HFONT font);
|
||||
static void InitRegisterEdit64(CWindow& tab, CEditReg64& edit, WORD ctrlId, HFONT font);
|
||||
static void InitRegisterEdits64(CWindow& tab, CEditReg64* edits, const DWORD* ctrlIds, HFONT font);
|
||||
static void ZeroRegisterEdit(CEditNumber& edit);
|
||||
static void ZeroRegisterEdits(CEditNumber* edits, const DWORD* ctrlIds);
|
||||
static void ZeroRegisterEdit64(CEditReg64& edit);
|
||||
static void ZeroRegisterEdits64(CEditReg64* edits, const DWORD* ctrlIds);
|
||||
|
||||
public:
|
||||
void Attach(HWND hWndNew);
|
||||
CWindow AddTab(char* caption, int dialogId, DLGPROC dlgProc);
|
||||
void ShowTab(int nPage);
|
||||
CRect GetPageRect();
|
||||
void RedrawCurrentTab();
|
||||
void RefreshEdits();
|
||||
void SetColorsEnabled(bool bColorsEnabled);
|
||||
};
|
|
@ -0,0 +1,396 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
//char* CEditEval::m_EvalString;
|
||||
|
||||
CDebugScripts::CDebugScripts(CDebuggerUI* debugger) :
|
||||
CDebugDialog<CDebugScripts>(debugger)
|
||||
{
|
||||
m_SelectedScriptName = (char*)malloc(MAX_PATH);
|
||||
//CScriptSystem::SetScriptsWindow(this);
|
||||
}
|
||||
|
||||
CDebugScripts::~CDebugScripts(void)
|
||||
{
|
||||
free(m_SelectedScriptName);
|
||||
}
|
||||
|
||||
LRESULT CDebugScripts::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
DlgResize_Init(false, true);
|
||||
|
||||
HFONT monoFont = CreateFont(-11, 0, 0, 0,
|
||||
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
|
||||
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
CLEARTYPE_QUALITY, FF_DONTCARE, "Consolas"
|
||||
);
|
||||
|
||||
m_InstanceInfoEdit.Attach(GetDlgItem(IDC_CTX_INFO_EDIT));
|
||||
|
||||
m_ScriptList.Attach(GetDlgItem(IDC_SCRIPT_LIST));
|
||||
m_ScriptList.AddColumn("Script", 0, 0);
|
||||
m_ScriptList.SetColumnWidth(0, 100);
|
||||
m_ScriptList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
|
||||
m_ScriptList.ModifyStyle(LVS_OWNERDRAWFIXED, 0, 0);
|
||||
|
||||
m_EvalEdit.Attach(GetDlgItem(IDC_EVAL_EDIT));
|
||||
m_EvalEdit.SetScriptWindow(this);
|
||||
m_EvalEdit.SetFont(monoFont);
|
||||
m_EvalEdit.EnableWindow(FALSE);
|
||||
|
||||
m_ConsoleEdit.Attach(GetDlgItem(IDC_CONSOLE_EDIT));
|
||||
m_ConsoleEdit.SetLimitText(0);
|
||||
m_ConsoleEdit.SetFont(monoFont);
|
||||
|
||||
RefreshList();
|
||||
|
||||
WindowCreated();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDebugScripts::ConsolePrint(const char* text)
|
||||
{
|
||||
::ShowWindow(*this, SW_SHOWNOACTIVATE);
|
||||
int textPos = m_ConsoleEdit.GetWindowTextLengthA();
|
||||
|
||||
// Get scrollbar state
|
||||
SCROLLINFO scroll;
|
||||
scroll.cbSize = sizeof(SCROLLINFO);
|
||||
scroll.fMask = SIF_ALL;
|
||||
m_ConsoleEdit.GetScrollInfo(SB_VERT, &scroll);
|
||||
|
||||
m_ConsoleEdit.SetRedraw(FALSE);
|
||||
|
||||
m_ConsoleEdit.AppendText(text);
|
||||
|
||||
m_ConsoleEdit.SetRedraw(TRUE);
|
||||
|
||||
if ((scroll.nPage + scroll.nPos) - 1 == scroll.nMax)
|
||||
{
|
||||
m_ConsoleEdit.ScrollCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void CDebugScripts::RefreshConsole()
|
||||
{
|
||||
m_Debugger->Debug_ShowScriptsWindow();
|
||||
CScriptSystem* scriptSystem = m_Debugger->ScriptSystem();
|
||||
vector<char*>* logData = scriptSystem->LogData();
|
||||
|
||||
while(logData->size() != 0)
|
||||
{
|
||||
ConsolePrint((*logData)[0]);
|
||||
free((*logData)[0]);
|
||||
logData->erase(logData->begin() + 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CDebugScripts::ConsoleClear()
|
||||
{
|
||||
m_ConsoleEdit.SetWindowTextA("");
|
||||
}
|
||||
|
||||
void CDebugScripts::ConsoleCopy()
|
||||
{
|
||||
if (!OpenClipboard())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EmptyClipboard();
|
||||
|
||||
size_t nChars = m_ConsoleEdit.GetWindowTextLengthA() + 1;
|
||||
|
||||
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, nChars);
|
||||
|
||||
char* memBuf = (char*) GlobalLock(hMem);
|
||||
m_ConsoleEdit.GetWindowTextA(memBuf, nChars);
|
||||
|
||||
GlobalUnlock(hMem);
|
||||
HANDLE hRes = SetClipboardData(CF_TEXT, hMem);
|
||||
|
||||
GlobalFree(hMem);
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
void CDebugScripts::RefreshList()
|
||||
{
|
||||
int nIndex = m_ScriptList.GetSelectedIndex();
|
||||
|
||||
CPath SearchPath("Scripts", "*");
|
||||
|
||||
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_ScriptList.SetRedraw(false);
|
||||
m_ScriptList.DeleteAllItems();
|
||||
|
||||
do
|
||||
{
|
||||
stdstr scriptFileName = SearchPath.GetNameExtension();
|
||||
m_ScriptList.AddItem(0, 0, scriptFileName.c_str());
|
||||
} while (SearchPath.FindNext());
|
||||
|
||||
m_ScriptList.SetRedraw(true);
|
||||
m_ScriptList.Invalidate();
|
||||
|
||||
if (nIndex >= 0)
|
||||
{
|
||||
m_ScriptList.SelectItem(nIndex);
|
||||
RefreshStatus();
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CDebugScripts::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
case ID_POPUP_RUN:
|
||||
RunSelected();
|
||||
break;
|
||||
case ID_POPUP_STOP:
|
||||
StopSelected();
|
||||
break;
|
||||
case IDC_CLEAR_BTN:
|
||||
ConsoleClear();
|
||||
break;
|
||||
case IDC_COPY_BTN:
|
||||
ConsoleCopy();
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugScripts::OnScriptListDblClicked(NMHDR* pNMHDR)
|
||||
{
|
||||
// Run script on double click
|
||||
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
|
||||
int nItem = pIA->iItem;
|
||||
|
||||
m_ScriptList.SelectItem(nItem);
|
||||
|
||||
RunSelected();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDebugScripts::RefreshStatus()
|
||||
{
|
||||
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
|
||||
|
||||
char* szState;
|
||||
switch (state)
|
||||
{
|
||||
case STATE_RUNNING: szState = "Running"; break;
|
||||
case STATE_STARTED: szState = "Started"; break;
|
||||
case STATE_STOPPED: szState = "Stopped"; break;
|
||||
case STATE_INVALID: szState = "Not running"; break;
|
||||
}
|
||||
|
||||
stdstr instanceInfo = stdstr_f("%s (%s)", m_SelectedScriptName, szState);
|
||||
|
||||
m_InstanceInfoEdit.SetWindowTextA(instanceInfo.c_str());
|
||||
|
||||
if (state == STATE_RUNNING)
|
||||
{
|
||||
m_EvalEdit.EnableWindow(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EvalEdit.EnableWindow(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR)
|
||||
{
|
||||
// Select instance for console input
|
||||
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
|
||||
int nItem = pIA->iItem;
|
||||
|
||||
m_ScriptList.GetItemText(nItem, 0, m_SelectedScriptName, MAX_PATH);
|
||||
|
||||
RefreshStatus();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugScripts::OnScriptListRClicked(NMHDR* pNMHDR)
|
||||
{
|
||||
OnScriptListClicked(pNMHDR);
|
||||
|
||||
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_SCRIPT_POPUP));
|
||||
HMENU hPopupMenu = GetSubMenu(hMenu, 0);
|
||||
|
||||
/*
|
||||
if (m_Breakpoints->m_RBP.size() == 0 && m_Breakpoints->m_WBP.size() == 0)
|
||||
{
|
||||
EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARALLBPS, MF_DISABLED | MF_GRAYED);
|
||||
}
|
||||
*/
|
||||
|
||||
POINT mouse;
|
||||
GetCursorPos(&mouse);
|
||||
|
||||
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, mouse.x, mouse.y, 0, m_hWnd, NULL);
|
||||
|
||||
DestroyMenu(hMenu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugScripts::OnScriptListCustomDraw(NMHDR* pNMHDR)
|
||||
{
|
||||
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
|
||||
DWORD drawStage = pLVCD->nmcd.dwDrawStage;
|
||||
|
||||
switch (drawStage)
|
||||
{
|
||||
case CDDS_PREPAINT:
|
||||
return CDRF_NOTIFYITEMDRAW;
|
||||
case CDDS_ITEMPREPAINT:
|
||||
return CDRF_NOTIFYSUBITEMDRAW;
|
||||
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
|
||||
break;
|
||||
default:
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
|
||||
DWORD nItem = pLVCD->nmcd.dwItemSpec;
|
||||
|
||||
char scriptName[MAX_PATH];
|
||||
m_ScriptList.GetItemText(nItem, 0, scriptName, MAX_PATH);
|
||||
|
||||
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(scriptName);
|
||||
|
||||
if (state == STATE_STARTED)
|
||||
{
|
||||
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0xAA);
|
||||
}
|
||||
else if (state == STATE_RUNNING)
|
||||
{
|
||||
pLVCD->clrTextBk = RGB(0xAA, 0xFF, 0xAA);
|
||||
}
|
||||
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
|
||||
void CDebugScripts::EvaluateInSelectedInstance(char* code)
|
||||
{
|
||||
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
|
||||
|
||||
if (state == STATE_RUNNING || state == STATE_STARTED)
|
||||
{
|
||||
CScriptInstance* instance = m_Debugger->ScriptSystem()->GetInstance(m_SelectedScriptName);
|
||||
//instance->EvalAsync(code);
|
||||
instance->Eval(code);
|
||||
}
|
||||
}
|
||||
|
||||
// Console input
|
||||
LRESULT CEditEval::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (wParam == VK_UP)
|
||||
{
|
||||
if (m_HistoryIdx > 0)
|
||||
{
|
||||
char* code = m_History[--m_HistoryIdx];
|
||||
SetWindowTextA(code);
|
||||
int selEnd = strlen(code);
|
||||
SetSel(selEnd, selEnd);
|
||||
}
|
||||
}
|
||||
else if (wParam == VK_DOWN)
|
||||
{
|
||||
int size = m_History.size();
|
||||
if (m_HistoryIdx < size - 1)
|
||||
{
|
||||
char* code = m_History[++m_HistoryIdx];
|
||||
SetWindowTextA(code);
|
||||
int selEnd = strlen(code);
|
||||
SetSel(selEnd, selEnd);
|
||||
}
|
||||
else if (m_HistoryIdx < size)
|
||||
{
|
||||
SetWindowTextA("");
|
||||
m_HistoryIdx++;
|
||||
}
|
||||
}
|
||||
else if (wParam == VK_RETURN)
|
||||
{
|
||||
if (m_ScriptWindow == NULL)
|
||||
{
|
||||
bHandled = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t codeLength = GetWindowTextLength() + 1;
|
||||
char* code = (char*)malloc(codeLength);
|
||||
GetWindowTextA(code, codeLength);
|
||||
|
||||
m_ScriptWindow->EvaluateInSelectedInstance(code);
|
||||
|
||||
SetWindowTextA("");
|
||||
int historySize = m_History.size();
|
||||
|
||||
// remove duplicate
|
||||
for (int i = 0; i < historySize; i++)
|
||||
{
|
||||
if (strcmp(code, m_History[i]) == 0)
|
||||
{
|
||||
free(m_History[i]);
|
||||
m_History.erase(m_History.begin() + i);
|
||||
historySize--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove oldest if maxed
|
||||
if (historySize >= HISTORY_MAX_ENTRIES)
|
||||
{
|
||||
m_History.erase(m_History.begin() + 0);
|
||||
historySize--;
|
||||
}
|
||||
|
||||
m_History.push_back(code);
|
||||
m_HistoryIdx = ++historySize;
|
||||
}
|
||||
bHandled = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CDebugScripts::RunSelected()
|
||||
{
|
||||
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
|
||||
|
||||
if (state == STATE_INVALID || state == STATE_STOPPED)
|
||||
{
|
||||
m_Debugger->ScriptSystem()->RunScript(m_SelectedScriptName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Debugger->Debug_LogScriptsWindow("[Error: Script is already running]\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CDebugScripts::StopSelected()
|
||||
{
|
||||
m_Debugger->ScriptSystem()->StopScript(m_SelectedScriptName);
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "DebuggerUI.h"
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
class CScriptList : public CListViewCtrl
|
||||
{
|
||||
public:
|
||||
BEGIN_MSG_MAP_EX(CScriptList)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
class CEditEval : public CWindowImpl<CEditEval, CEdit>
|
||||
{
|
||||
private:
|
||||
//static char* m_EvalString;
|
||||
static const int HISTORY_MAX_ENTRIES = 20;
|
||||
vector<char*> m_History;
|
||||
int m_HistoryIdx;
|
||||
CDebugScripts* m_ScriptWindow;
|
||||
|
||||
public:
|
||||
CEditEval()
|
||||
{
|
||||
m_HistoryIdx = 0;
|
||||
}
|
||||
|
||||
void SetScriptWindow(CDebugScripts* scriptWindow)
|
||||
{
|
||||
m_ScriptWindow = scriptWindow;
|
||||
}
|
||||
|
||||
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
BOOL Attach(HWND hWndNew)
|
||||
{
|
||||
return SubclassWindow(hWndNew);
|
||||
}
|
||||
|
||||
BEGIN_MSG_MAP_EX(CEditEval)
|
||||
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
class CEditConsole : public CWindowImpl<CEditEval, CEdit>
|
||||
{
|
||||
private:
|
||||
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (GetKeyState(VK_CONTROL) < 0)
|
||||
{
|
||||
if (wParam == 'A')
|
||||
{
|
||||
this->SetSelAll();
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
public:
|
||||
BOOL Attach(HWND hWndNew)
|
||||
{
|
||||
return SubclassWindow(hWndNew);
|
||||
}
|
||||
|
||||
BEGIN_MSG_MAP_EX(CEditEval)
|
||||
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
|
||||
END_MSG_MAP()
|
||||
};
|
||||
|
||||
class CDebugScripts :
|
||||
public CDebugDialog < CDebugScripts >,
|
||||
public CDialogResize<CDebugScripts>
|
||||
{
|
||||
private:
|
||||
CEdit m_InstanceInfoEdit;
|
||||
CEditEval m_EvalEdit;
|
||||
CEditConsole m_ConsoleEdit;
|
||||
CScriptList m_ScriptList;
|
||||
char* m_SelectedScriptName;
|
||||
|
||||
void RefreshStatus();
|
||||
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_Scripts };
|
||||
|
||||
CDebugScripts(CDebuggerUI * debugger);
|
||||
virtual ~CDebugScripts(void);
|
||||
|
||||
void ConsolePrint(const char* text);
|
||||
void ConsoleClear();
|
||||
void ConsoleCopy();
|
||||
|
||||
void RefreshList();
|
||||
void RefreshConsole();
|
||||
|
||||
void EvaluateInSelectedInstance(char* code);
|
||||
void RunSelected();
|
||||
void StopSelected();
|
||||
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnDestroy(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnScriptListDblClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnScriptListClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnScriptListRClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnScriptListCustomDraw(NMHDR* pNMHDR);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDebugScripts)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
NOTIFY_HANDLER_EX(IDC_SCRIPT_LIST, NM_DBLCLK, OnScriptListDblClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_SCRIPT_LIST, NM_CLICK, OnScriptListClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_SCRIPT_LIST, NM_RCLICK, OnScriptListRClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_SCRIPT_LIST, NM_CUSTOMDRAW, OnScriptListCustomDraw)
|
||||
CHAIN_MSG_MAP_MEMBER(m_ScriptList)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
CHAIN_MSG_MAP(CDialogResize<CDebugScripts>)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DLGRESIZE_MAP(CDebugScripts)
|
||||
DLGRESIZE_CONTROL(IDC_CTX_INFO_EDIT, DLSZ_SIZE_X)
|
||||
DLGRESIZE_CONTROL(IDC_EVAL_EDIT, DLSZ_SIZE_X | DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_CONSOLE_EDIT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_SCRIPT_LIST, DLSZ_SIZE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_CLEAR_BTN, DLSZ_MOVE_X)
|
||||
DLGRESIZE_CONTROL(IDC_COPY_BTN, DLSZ_MOVE_X)
|
||||
END_DLGRESIZE_MAP()
|
||||
|
||||
};
|
|
@ -0,0 +1,104 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
CDebugStackTrace::CDebugStackTrace(CDebuggerUI* debugger) :
|
||||
CDebugDialog<CDebugStackTrace>(debugger)
|
||||
{
|
||||
}
|
||||
|
||||
CDebugStackTrace::~CDebugStackTrace()
|
||||
{
|
||||
}
|
||||
|
||||
LRESULT CDebugStackTrace::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
DlgResize_Init();
|
||||
|
||||
m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, 0);
|
||||
|
||||
m_List.Attach(GetDlgItem(IDC_STACKTRACE_LIST));
|
||||
m_List.AddColumn("Routine", 0);
|
||||
m_List.AddColumn("Name", 1);
|
||||
|
||||
m_List.SetColumnWidth(0, 60);
|
||||
m_List.SetColumnWidth(1, 100);
|
||||
|
||||
WindowCreated();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT CDebugStackTrace::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
RefreshList();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugStackTrace::OnDestroy(void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugStackTrace::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugStackTrace::OnListDblClicked(NMHDR* pNMHDR)
|
||||
{
|
||||
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
|
||||
int nItem = pIA->iItem;
|
||||
|
||||
uint32_t address = m_List.GetItemData(nItem);
|
||||
|
||||
m_Debugger->Debug_ShowCommandsLocation(address, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDebugStackTrace::RefreshList()
|
||||
{
|
||||
vector<uint32_t>* stackTrace = m_Debugger->StackTrace();
|
||||
|
||||
m_List.SetRedraw(FALSE);
|
||||
m_List.DeleteAllItems();
|
||||
|
||||
int count = stackTrace->size();
|
||||
|
||||
if (count > 4000)
|
||||
{
|
||||
count = 4000;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t address = stackTrace->at(i);
|
||||
|
||||
char szAddress[9];
|
||||
sprintf(szAddress, "%08X", address);
|
||||
|
||||
m_List.AddItem(i, 0, szAddress);
|
||||
m_List.AddItem(i, 1, "symbol");
|
||||
|
||||
m_List.SetItemData(i, address);
|
||||
}
|
||||
|
||||
m_List.SetRedraw(TRUE);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
class CDebugStackTrace :
|
||||
public CDebugDialog<CDebugStackTrace>,
|
||||
public CDialogResize<CDebugStackTrace>
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_StackTrace };
|
||||
|
||||
CDebugStackTrace(CDebuggerUI * debugger);
|
||||
virtual ~CDebugStackTrace(void);
|
||||
|
||||
void RefreshList();
|
||||
|
||||
private:
|
||||
|
||||
HANDLE m_AutoRefreshThread;
|
||||
static DWORD WINAPI AutoRefreshProc(void* _this);
|
||||
|
||||
CListViewCtrl m_List;
|
||||
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnListDblClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnDestroy(void);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDebugStackTrace)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_STACKTRACE_LIST, NM_DBLCLK, OnListDblClicked)
|
||||
CHAIN_MSG_MAP(CDialogResize<CDebugStackTrace>)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DLGRESIZE_MAP(CDebugStackTrace)
|
||||
DLGRESIZE_CONTROL(IDC_STACKTRACE_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
|
||||
END_DLGRESIZE_MAP()
|
||||
};
|
|
@ -0,0 +1,108 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
CDebugStackView::CDebugStackView(CDebuggerUI * debugger) :
|
||||
CDebugDialog<CDebugStackView>(debugger)
|
||||
{
|
||||
}
|
||||
|
||||
CDebugStackView::~CDebugStackView(void)
|
||||
{
|
||||
}
|
||||
|
||||
LRESULT CDebugStackView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
DlgResize_Init(false, true);
|
||||
|
||||
m_StackList.Attach(GetDlgItem(IDC_STACK_LIST));
|
||||
m_StackList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
|
||||
m_StackList.AddColumn("#", 0);
|
||||
m_StackList.AddColumn("00", 1);
|
||||
m_StackList.AddColumn("04", 2);
|
||||
m_StackList.AddColumn("08", 3);
|
||||
m_StackList.AddColumn("0C", 4);
|
||||
|
||||
m_StackList.SetColumnWidth(0, 22);
|
||||
m_StackList.SetColumnWidth(1, 64);
|
||||
m_StackList.SetColumnWidth(2, 64);
|
||||
m_StackList.SetColumnWidth(3, 64);
|
||||
m_StackList.SetColumnWidth(4, 64);
|
||||
|
||||
m_SPStatic.Attach(GetDlgItem(IDC_SP_STATIC));
|
||||
|
||||
WindowCreated();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugStackView::OnDestroy(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugStackView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDC_MEM_BTN:
|
||||
if (g_Reg != NULL)
|
||||
{
|
||||
m_Debugger->Debug_ShowMemoryLocation(g_Reg->m_GPR[29].UW[0], true);
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDebugStackView::Refresh()
|
||||
{
|
||||
m_StackList.SetRedraw(FALSE);
|
||||
m_StackList.DeleteAllItems();
|
||||
|
||||
uint32_t spBase;
|
||||
|
||||
if (g_Reg != NULL)
|
||||
{
|
||||
spBase = g_Reg->m_GPR[29].UW[0];
|
||||
m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str());
|
||||
}
|
||||
|
||||
for (int i = 0; i < 0x10; i++)
|
||||
{
|
||||
char t[4];
|
||||
sprintf(t, "%02X", i * 0x10);
|
||||
m_StackList.AddItem(i, 0, t);
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (g_MMU == NULL)
|
||||
{
|
||||
m_StackList.AddItem(i, j + 1, "????????");
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t val;
|
||||
g_MMU->LW_VAddr(spBase + i * 0x10 + j * 4, val);
|
||||
|
||||
char valStr[9];
|
||||
sprintf(valStr, "%08X", val);
|
||||
m_StackList.AddItem(i, j + 1, valStr);
|
||||
}
|
||||
}
|
||||
|
||||
m_StackList.SetRedraw(TRUE);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class CDebugStackView :
|
||||
public CDebugDialog<CDebugStackView>,
|
||||
public CDialogResize<CDebugStackView>
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_Stack };
|
||||
|
||||
CDebugStackView(CDebuggerUI * debugger);
|
||||
virtual ~CDebugStackView(void);
|
||||
|
||||
void Refresh();
|
||||
|
||||
private:
|
||||
CListViewCtrl m_StackList;
|
||||
CStatic m_SPStatic;
|
||||
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnDestroy(void);
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDebugStackView)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
CHAIN_MSG_MAP(CDialogResize<CDebugStackView>)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DLGRESIZE_MAP(CDebugStackView)
|
||||
DLGRESIZE_CONTROL(IDC_STACK_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
|
||||
END_DLGRESIZE_MAP()
|
||||
};
|
|
@ -0,0 +1,176 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Common/path.h>
|
||||
|
||||
#include "Symbols.h"
|
||||
|
||||
CDebugSymbols::CDebugSymbols(CDebuggerUI * debugger) :
|
||||
CDebugDialog<CDebugSymbols>(debugger)
|
||||
{
|
||||
}
|
||||
|
||||
LRESULT CDebugSymbols::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
DlgResize_Init(false, true);
|
||||
|
||||
m_SymbolsListView.Attach(GetDlgItem(IDC_SYMBOLS_LIST));
|
||||
m_SymbolsListView.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
|
||||
|
||||
m_SymbolsListView.AddColumn("Address", 0);
|
||||
m_SymbolsListView.AddColumn("Type", 1);
|
||||
m_SymbolsListView.AddColumn("Name", 2);
|
||||
m_SymbolsListView.AddColumn("Value", 3);
|
||||
m_SymbolsListView.AddColumn("Description", 4);
|
||||
|
||||
m_SymbolsListView.SetColumnWidth(0, 70);
|
||||
m_SymbolsListView.SetColumnWidth(1, 40);
|
||||
m_SymbolsListView.SetColumnWidth(2, 120);
|
||||
m_SymbolsListView.SetColumnWidth(3, 100);
|
||||
m_SymbolsListView.SetColumnWidth(4, 120);
|
||||
|
||||
Refresh();
|
||||
|
||||
m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL);
|
||||
|
||||
WindowCreated();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugSymbols::OnDestroy(void)
|
||||
{
|
||||
if (m_AutoRefreshThread != NULL)
|
||||
{
|
||||
TerminateThread(m_AutoRefreshThread, 0);
|
||||
CloseHandle(m_AutoRefreshThread);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI CDebugSymbols::AutoRefreshProc(void* _this)
|
||||
{
|
||||
CDebugSymbols* self = (CDebugSymbols*)_this;
|
||||
while (true)
|
||||
{
|
||||
self->RefreshValues();
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CDebugSymbols::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
switch (wID)
|
||||
{
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
case IDC_ADDSYMBOL_BTN:
|
||||
m_AddSymbolDlg.DoModal(m_Debugger);
|
||||
break;
|
||||
case IDC_REMOVESYMBOL_BTN:
|
||||
{
|
||||
int id = m_SymbolsListView.GetItemData(m_SymbolsListView.GetSelectedIndex());
|
||||
CSymbols::EnterCriticalSection();
|
||||
CSymbols::RemoveEntryById(id);
|
||||
CSymbols::Save();
|
||||
CSymbols::LeaveCriticalSection();
|
||||
Refresh();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugSymbols::OnListDblClicked(NMHDR* pNMHDR)
|
||||
{
|
||||
// Open it in memory viewer/commands viewer
|
||||
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
|
||||
int nItem = pIA->iItem;
|
||||
|
||||
int id = m_SymbolsListView.GetItemData(nItem);
|
||||
CSymbolEntry* symbol = CSymbols::GetEntryById(id);
|
||||
|
||||
if (symbol->m_Type == 0) // code
|
||||
{
|
||||
m_Debugger->Debug_ShowCommandsLocation(symbol->m_Address, true);
|
||||
}
|
||||
else // data/number
|
||||
{
|
||||
m_Debugger->Debug_ShowMemoryLocation(symbol->m_Address, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDebugSymbols::Refresh()
|
||||
{
|
||||
m_SymbolsListView.SetRedraw(FALSE);
|
||||
m_SymbolsListView.DeleteAllItems();
|
||||
|
||||
CSymbols::EnterCriticalSection();
|
||||
|
||||
int count = CSymbols::GetCount();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
CSymbolEntry* lpSymbol = CSymbols::GetEntryByIndex(i);
|
||||
|
||||
stdstr addrStr = stdstr_f("%08X", lpSymbol->m_Address);
|
||||
|
||||
m_SymbolsListView.AddItem(i, 0, addrStr.c_str());
|
||||
m_SymbolsListView.AddItem(i, 1, lpSymbol->TypeName());
|
||||
m_SymbolsListView.AddItem(i, 2, lpSymbol->m_Name);
|
||||
m_SymbolsListView.AddItem(i, 4, lpSymbol->m_Description);
|
||||
|
||||
m_SymbolsListView.SetItemData(i, lpSymbol->m_Id);
|
||||
|
||||
if (g_MMU)
|
||||
{
|
||||
char szValue[64];
|
||||
CSymbols::GetValueString(szValue, lpSymbol);
|
||||
m_SymbolsListView.AddItem(i, 3, szValue);
|
||||
}
|
||||
}
|
||||
|
||||
CSymbols::LeaveCriticalSection();
|
||||
|
||||
m_SymbolsListView.SetRedraw(TRUE);
|
||||
}
|
||||
|
||||
void CDebugSymbols::RefreshValues()
|
||||
{
|
||||
if (g_MMU == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int count = m_SymbolsListView.GetItemCount();
|
||||
|
||||
CSymbols::EnterCriticalSection();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int symbolId = m_SymbolsListView.GetItemData(i);
|
||||
|
||||
CSymbolEntry* lpSymbol = CSymbols::GetEntryById(symbolId);
|
||||
|
||||
char szValue[64];
|
||||
CSymbols::GetValueString(szValue, lpSymbol);
|
||||
|
||||
m_SymbolsListView.SetItemText(i, 3, szValue);
|
||||
}
|
||||
|
||||
CSymbols::LeaveCriticalSection();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DebuggerUI.h"
|
||||
|
||||
// todo maybe add char* ownerName and use a TreeView
|
||||
|
||||
|
||||
class CDebugSymbols :
|
||||
public CDebugDialog<CDebugSymbols>,
|
||||
public CDialogResize<CDebugSymbols>
|
||||
{
|
||||
private:
|
||||
CListViewCtrl m_SymbolsListView;
|
||||
CAddSymbolDlg m_AddSymbolDlg;
|
||||
|
||||
HANDLE m_AutoRefreshThread;
|
||||
static DWORD WINAPI CDebugSymbols::AutoRefreshProc(void* _this);
|
||||
|
||||
public:
|
||||
enum { IDD = IDD_Debugger_Symbols };
|
||||
|
||||
CDebugSymbols(CDebuggerUI * debugger);
|
||||
//virtual ~CDebugScripts(void);
|
||||
|
||||
void Refresh();
|
||||
void RefreshValues();
|
||||
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnListDblClicked(NMHDR* pNMHDR);
|
||||
LRESULT OnDestroy(void);
|
||||
|
||||
BEGIN_MSG_MAP_EX(CDebugSymbols)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
NOTIFY_HANDLER_EX(IDC_SYMBOLS_LIST, NM_DBLCLK, OnListDblClicked)
|
||||
//NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_RCLICK, OnListClicked)
|
||||
CHAIN_MSG_MAP(CDialogResize<CDebugSymbols>)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DLGRESIZE_MAP(CDebugSymbols)
|
||||
DLGRESIZE_CONTROL(IDC_FILTER_EDIT, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_FILTER_STATIC, DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_REMOVESYMBOL_BTN, DLSZ_MOVE_X | DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_ADDSYMBOL_BTN, DLSZ_MOVE_X | DLSZ_MOVE_Y)
|
||||
DLGRESIZE_CONTROL(IDC_SYMBOLS_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
|
||||
END_DLGRESIZE_MAP()
|
||||
};
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "DebuggerUI.h"
|
||||
#include "Symbols.h"
|
||||
#include "DMALog.h"
|
||||
|
||||
CDebugMemoryView::CDebugMemoryView(CDebuggerUI * debugger) :
|
||||
CDebugDialog<CDebugMemoryView>(debugger),
|
||||
|
@ -21,6 +23,9 @@ m_MemoryList(NULL)
|
|||
m_MemoryList = new CListCtrl;
|
||||
m_MemoryList->RegisterClass();
|
||||
}
|
||||
|
||||
m_Breakpoints = m_Debugger->Breakpoints();
|
||||
|
||||
}
|
||||
|
||||
CDebugMemoryView::~CDebugMemoryView()
|
||||
|
@ -29,6 +34,8 @@ CDebugMemoryView::~CDebugMemoryView()
|
|||
|
||||
LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
m_SymbolColorStride = 0;
|
||||
m_SymbolColorPhase = 0;
|
||||
m_DataStartLoc = (DWORD)-1;
|
||||
m_CompareStartLoc = (DWORD)-1;
|
||||
memset(m_CompareData, 0, sizeof(m_CompareData));
|
||||
|
@ -50,7 +57,7 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
|
|||
|
||||
m_MemAddr.Attach(GetDlgItem(IDC_ADDR_EDIT));
|
||||
m_MemAddr.SetDisplayType(CEditNumber::DisplayHex);
|
||||
m_MemAddr.SetValue(0x80000000, true, true);
|
||||
m_MemAddr.SetValue(0x80000000, false, true);
|
||||
|
||||
SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, BST_CHECKED, 0);
|
||||
|
||||
|
@ -97,8 +104,6 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
|
|||
SetWindowPos(NULL, 0, 0, MemoryListWindow.right - MemoryListWindow.left, (MemoryListWindow.bottom - MemoryListWindow.top) + (height - MemoryListRect.bottom), SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER);
|
||||
|
||||
RECT DlgItemRect = { 0 };
|
||||
::GetWindowRect(GetDlgItem(IDC_BORDER), &DlgItemRect);
|
||||
::SetWindowPos(GetDlgItem(IDC_BORDER), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE);
|
||||
|
||||
::GetWindowRect(GetDlgItem(IDC_MEM_DETAILS), &DlgItemRect);
|
||||
::SetWindowPos(GetDlgItem(IDC_MEM_DETAILS), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE);
|
||||
|
@ -106,12 +111,34 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
|
|||
::GetWindowRect(GetDlgItem(IDC_SCRL_BAR), &DlgItemRect);
|
||||
::SetWindowPos(GetDlgItem(IDC_SCRL_BAR), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE);
|
||||
}
|
||||
|
||||
m_SymInfo.Attach(GetDlgItem(IDC_SYM_INFO));
|
||||
m_DMAInfo.Attach(GetDlgItem(IDC_DMA_INFO));
|
||||
|
||||
WindowCreated();
|
||||
|
||||
m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD WINAPI CDebugMemoryView::AutoRefreshProc(void* _this)
|
||||
{
|
||||
CDebugMemoryView* self = (CDebugMemoryView*)_this;
|
||||
while (true)
|
||||
{
|
||||
self->RefreshMemory(true);
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CDebugMemoryView::OnDestroy(void)
|
||||
{
|
||||
if (m_AutoRefreshThread != NULL)
|
||||
{
|
||||
TerminateThread(m_AutoRefreshThread, 0);
|
||||
CloseHandle(m_AutoRefreshThread);
|
||||
}
|
||||
if (m_MemoryList)
|
||||
{
|
||||
m_MemoryList->UnsubclassWindow();
|
||||
|
@ -137,60 +164,138 @@ LRESULT CDebugMemoryView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL&
|
|||
case IDC_SEARCH_MEM:
|
||||
m_Debugger->Debug_ShowMemorySearch();
|
||||
break;
|
||||
case IDC_SYMBOLS_BTN:
|
||||
m_Debugger->Debug_ShowSymbolsWindow();
|
||||
break;
|
||||
case IDCANCEL:
|
||||
EndDialog(0);
|
||||
break;
|
||||
case ID_POPUPMENU_TOGGLERBP:
|
||||
m_Breakpoints->RBPToggle(m_CtxMenuAddr);
|
||||
RefreshMemory(true);
|
||||
break;
|
||||
case ID_POPUPMENU_TOGGLEWBP:
|
||||
m_Breakpoints->WBPToggle(m_CtxMenuAddr);
|
||||
RefreshMemory(true);
|
||||
break;
|
||||
case ID_POPUPMENU_CLEARALLBPS:
|
||||
m_Breakpoints->RBPClear();
|
||||
m_Breakpoints->WBPClear();
|
||||
RefreshMemory(true);
|
||||
break;
|
||||
case ID_POPUPMENU_VIEWDISASM:
|
||||
m_Debugger->Debug_ShowCommandsLocation(m_CtxMenuAddr, true);
|
||||
break;
|
||||
case ID_POPUPMENU_ADDSYMBOL:
|
||||
m_AddSymbolDlg.DoModal(m_Debugger, m_CtxMenuAddr);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LRESULT CDebugMemoryView::OnMemoryRightClicked(LPNMHDR lpNMHDR)
|
||||
{
|
||||
uint32_t address;
|
||||
bool bData = GetItemAddress(lpNMHDR, address);
|
||||
|
||||
if (!bData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_CtxMenuAddr = address;
|
||||
|
||||
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MEM_BP_POPUP));
|
||||
HMENU hPopupMenu = GetSubMenu(hMenu, 0);
|
||||
|
||||
if (m_Breakpoints->m_RBP.size() == 0 && m_Breakpoints->m_WBP.size() == 0)
|
||||
{
|
||||
EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARALLBPS, MF_DISABLED | MF_GRAYED);
|
||||
}
|
||||
|
||||
POINT mouse;
|
||||
GetCursorPos(&mouse);
|
||||
|
||||
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, mouse.x, mouse.y, 0, m_hWnd, NULL);
|
||||
|
||||
DestroyMenu(hMenu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugMemoryView::OnHotItemChanged(LPNMHDR lpNMHDR)
|
||||
{
|
||||
uint32_t address;
|
||||
bool bData = GetItemAddress(lpNMHDR, address);
|
||||
|
||||
if (!bData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSymbols::EnterCriticalSection();
|
||||
|
||||
CSymbolEntry* lpSymbol = CSymbols::GetEntryByAddress(address);
|
||||
|
||||
stdstr symbolInfo;
|
||||
|
||||
if (lpSymbol != NULL)
|
||||
{
|
||||
char* desc = lpSymbol->m_Description;
|
||||
desc = desc ? desc : "";
|
||||
symbolInfo = stdstr_f("%08X: %s %s // %s", address, lpSymbol->TypeName(), lpSymbol->m_Name, desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolInfo = stdstr_f("%08X", address);
|
||||
}
|
||||
|
||||
CSymbols::LeaveCriticalSection();
|
||||
|
||||
m_SymInfo.SetWindowTextA(symbolInfo.c_str());
|
||||
|
||||
uint32_t romAddr, offset;
|
||||
DMALOGENTRY* lpEntry = m_Debugger->DMALog()->GetEntryByRamAddress(address, &romAddr, &offset);
|
||||
|
||||
stdstr dmaInfo;
|
||||
|
||||
if (lpEntry != NULL)
|
||||
{
|
||||
dmaInfo = stdstr_f("Last DMA: %08X -> %08X [%X] (%08X, +%X) ", lpEntry->romAddr, lpEntry->ramAddr, lpEntry->length, romAddr, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
dmaInfo = stdstr_f("Last DMA: ?");
|
||||
}
|
||||
|
||||
m_DMAInfo.SetWindowTextA(dmaInfo.c_str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CDebugMemoryView::OnMemoryModified(LPNMHDR lpNMHDR)
|
||||
{
|
||||
uint32_t Pos = 0;
|
||||
bool bData = GetItemOffset(lpNMHDR, Pos);
|
||||
|
||||
if (!bData)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CListNotify *pListNotify = reinterpret_cast<CListNotify *>(lpNMHDR);
|
||||
int LineNumber = pListNotify->m_nItem;
|
||||
int Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 1));
|
||||
if (pListNotify->m_nSubItem >= 6 && pListNotify->m_nSubItem < 10)
|
||||
{
|
||||
Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 2));
|
||||
}
|
||||
if (pListNotify->m_nSubItem >= 11 && pListNotify->m_nSubItem < 15)
|
||||
{
|
||||
Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 3));
|
||||
}
|
||||
if (pListNotify->m_nSubItem >= 16 && pListNotify->m_nSubItem < 20)
|
||||
{
|
||||
Pos = ((LineNumber << 4) + (pListNotify->m_nSubItem - 4));
|
||||
}
|
||||
|
||||
|
||||
LPCSTR strValue = m_MemoryList->GetItemText(pListNotify->m_nItem, pListNotify->m_nSubItem);
|
||||
int Finish = strlen(strValue);
|
||||
if (Finish > 8)
|
||||
{
|
||||
Finish = 8;
|
||||
}
|
||||
DWORD Value = 0;
|
||||
for (int i = 0; i < Finish; i++)
|
||||
{
|
||||
Value = (Value << 4);
|
||||
if (strValue[i] <= '9' && strValue[i] >= '0')
|
||||
{
|
||||
Value |= strValue[i] - '0';
|
||||
}
|
||||
else if (strValue[i] <= 'f' && strValue[i] >= 'a')
|
||||
{
|
||||
Value |= strValue[i] - 'a' + 10;
|
||||
}
|
||||
else if (strValue[i] <= 'F' && strValue[i] >= 'A')
|
||||
{
|
||||
Value |= strValue[i] - 'A' + 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DWORD Value = strtoull(strValue, NULL, 16);
|
||||
|
||||
if (m_CurrentData[Pos] == Value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (m_CompareStartLoc != m_DataStartLoc ||
|
||||
m_CompareVAddrr != m_DataVAddrr)
|
||||
{
|
||||
|
@ -200,10 +305,10 @@ LRESULT CDebugMemoryView::OnMemoryModified(LPNMHDR lpNMHDR)
|
|||
memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData));
|
||||
memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid));
|
||||
}
|
||||
|
||||
|
||||
m_CompareData[Pos] = m_CurrentData[Pos];
|
||||
m_CurrentData[Pos] = (BYTE)Value;
|
||||
|
||||
|
||||
//sb
|
||||
if (m_DataVAddrr)
|
||||
{
|
||||
|
@ -224,6 +329,54 @@ LRESULT CDebugMemoryView::OnMemoryModified(LPNMHDR lpNMHDR)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/)
|
||||
{
|
||||
RefreshMemory(false);
|
||||
}
|
||||
|
||||
void CDebugMemoryView::OnVScroll(int request, short Pos, HWND ctrl)
|
||||
{
|
||||
if (ctrl != GetDlgItem(IDC_SCRL_BAR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
DWORD Location = m_MemAddr.GetValue();
|
||||
switch (request)
|
||||
{
|
||||
case SB_LINEDOWN:
|
||||
m_MemAddr.SetValue(Location < 0xFFFFFFEF ? Location + 0x10 : 0xFFFFFFFF, false, true);
|
||||
break;
|
||||
case SB_LINEUP:
|
||||
m_MemAddr.SetValue(Location > 0x10 ? Location - 0x10 : 0, false, true);
|
||||
break;
|
||||
case SB_PAGEDOWN:
|
||||
m_MemAddr.SetValue(Location < 0xFFFFFEFF ? Location + 0x100 : 0xFFFFFFFF, false, true);
|
||||
break;
|
||||
case SB_PAGEUP:
|
||||
m_MemAddr.SetValue(Location > 0x100 ? Location - 0x100 : 0, false, true);
|
||||
break;
|
||||
case SB_THUMBPOSITION:
|
||||
m_MemAddr.SetValue((DWORD)Pos << 0x10, false, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CDebugMemoryView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
WORD type = LOWORD(wParam);
|
||||
|
||||
if (type == WA_INACTIVE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RefreshMemory(false);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CDebugMemoryView::ShowAddress(DWORD Address, bool VAddr)
|
||||
{
|
||||
if (m_hWnd == NULL)
|
||||
|
@ -232,7 +385,7 @@ void CDebugMemoryView::ShowAddress(DWORD Address, bool VAddr)
|
|||
}
|
||||
|
||||
SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, VAddr ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
m_MemAddr.SetValue(Address, true, true);
|
||||
m_MemAddr.SetValue(Address, false, true);
|
||||
RefreshMemory(true);
|
||||
}
|
||||
|
||||
|
@ -284,15 +437,22 @@ void CDebugMemoryView::Insert_MemoryLineDump(int LineNumber)
|
|||
{
|
||||
Changed = true;
|
||||
}
|
||||
|
||||
sprintf(Hex, "%02X", m_CurrentData[Pos]);
|
||||
m_MemoryList->SetItemText(LineNumber, col, Hex);
|
||||
|
||||
m_MemoryList->SetItemText(LineNumber, col, Hex);
|
||||
m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_EDIT, ITEM_FLAGS_EDIT_HEX);
|
||||
m_MemoryList->SetItemMaxEditLen(LineNumber, col, 2);
|
||||
m_MemoryList->SetItemColours(LineNumber, col, GetSysColor(COLOR_WINDOW),
|
||||
Changed ? RGB(255, 0, 0) : GetSysColor(COLOR_WINDOWTEXT));
|
||||
m_MemoryList->SetItemHighlightColours(LineNumber, col,
|
||||
Changed ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
if (m_CurrentData[Pos] < 30)
|
||||
|
||||
uint32_t vaddr = 0x80000000 | (m_DataStartLoc + Pos);
|
||||
|
||||
COLORREF bgColor, fgColor, fgHiColor;
|
||||
SelectColors(vaddr, Changed, bgColor, fgColor, fgHiColor);
|
||||
|
||||
m_MemoryList->SetItemColours(LineNumber, col, bgColor, fgColor);
|
||||
m_MemoryList->SetItemHighlightColours(LineNumber, col, fgHiColor);
|
||||
|
||||
if (m_CurrentData[Pos] < 30)
|
||||
{
|
||||
strcat(Ascii, ".");
|
||||
}
|
||||
|
@ -324,42 +484,15 @@ void CDebugMemoryView::Insert_MemoryLineDump(int LineNumber)
|
|||
}
|
||||
}
|
||||
|
||||
void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/)
|
||||
{
|
||||
RefreshMemory(false);
|
||||
}
|
||||
|
||||
void CDebugMemoryView::OnVScroll(int request, short Pos, HWND ctrl)
|
||||
{
|
||||
if (ctrl != GetDlgItem(IDC_SCRL_BAR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
DWORD Location = m_MemAddr.GetValue();
|
||||
switch (request)
|
||||
{
|
||||
case SB_LINEDOWN:
|
||||
m_MemAddr.SetValue(Location < 0xFFFFFFEF ? Location + 0x10 : 0xFFFFFFFF, true, true);
|
||||
break;
|
||||
case SB_LINEUP:
|
||||
m_MemAddr.SetValue(Location > 0x10 ? Location - 0x10 : 0, true, true);
|
||||
break;
|
||||
case SB_PAGEDOWN:
|
||||
m_MemAddr.SetValue(Location < 0xFFFFFEFF ? Location + 0x100 : 0xFFFFFFFF, true, true);
|
||||
break;
|
||||
case SB_PAGEUP:
|
||||
m_MemAddr.SetValue(Location > 0x100 ? Location - 0x100 : 0, true, true);
|
||||
break;
|
||||
case SB_THUMBPOSITION:
|
||||
m_MemAddr.SetValue((DWORD)Pos << 0x10, true, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CDebugMemoryView::RefreshMemory(bool ResetCompare)
|
||||
{
|
||||
m_SymbolColorPhase = 0;
|
||||
|
||||
if (g_MMU == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_MemoryList && m_MemoryList->GetHasEditItem())
|
||||
{
|
||||
m_MemoryList->SetFocus();
|
||||
|
@ -402,14 +535,22 @@ void CDebugMemoryView::RefreshMemory(bool ResetCompare)
|
|||
|
||||
if (m_DataVAddrr)
|
||||
{
|
||||
if (!g_MMU->LW_VAddr(m_DataStartLoc & ~3, word.UW))
|
||||
if (!AddressSafe(m_DataStartLoc & ~3))
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
else if (!g_MMU->LW_VAddr(m_DataStartLoc & ~3, word.UW))
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_MMU->LW_PAddr(m_DataStartLoc & ~3, word.UW))
|
||||
if ((m_DataStartLoc & ~3) >= g_MMU->RdramSize())
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
else if (!g_MMU->LW_PAddr(m_DataStartLoc & ~3, word.UW))
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
|
@ -438,14 +579,22 @@ void CDebugMemoryView::RefreshMemory(bool ResetCompare)
|
|||
|
||||
if (m_DataVAddrr)
|
||||
{
|
||||
if (!g_MMU->LW_VAddr(Pos, word.UW))
|
||||
if (!AddressSafe(Pos))
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
else if (!g_MMU->LW_VAddr(Pos, word.UW))
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_MMU->LW_PAddr(Pos, word.UW))
|
||||
if (Pos >= g_MMU->RdramSize())
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
else if (!g_MMU->LW_PAddr(Pos, word.UW))
|
||||
{
|
||||
ValidData = false;
|
||||
}
|
||||
|
@ -469,4 +618,102 @@ void CDebugMemoryView::RefreshMemory(bool ResetCompare)
|
|||
{
|
||||
Insert_MemoryLineDump(count);
|
||||
}
|
||||
}
|
||||
|
||||
bool CDebugMemoryView::GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset)
|
||||
{
|
||||
CListNotify *pListNotify = reinterpret_cast<CListNotify *>(lpNMHDR);
|
||||
|
||||
int nRow = pListNotify->m_nItem;
|
||||
int nCol = pListNotify->m_nSubItem - 1;
|
||||
|
||||
if (nCol < 0 || (nCol % 5) == 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = (nRow * 0x10) + (nCol / 5) * 4 + (nCol % 5);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDebugMemoryView::GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address)
|
||||
{
|
||||
uint32_t offset;
|
||||
bool bData = GetItemOffset(lpNMHDR, offset);
|
||||
|
||||
if (!bData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
address = 0x80000000 | (m_DataStartLoc + offset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDebugMemoryView::SelectColors(uint32_t vaddr, bool changed, COLORREF& bgColor, COLORREF& fgColor, COLORREF& fgHiColor)
|
||||
{
|
||||
CSymbols::EnterCriticalSection();
|
||||
CSymbolEntry* lpSymbol = CSymbols::GetEntryByAddress(vaddr);
|
||||
|
||||
if (lpSymbol != NULL)
|
||||
{
|
||||
m_SymbolColorStride = lpSymbol->TypeSize();
|
||||
m_SymbolColorPhase = m_SymbolColorPhase ? 0 : 1;
|
||||
}
|
||||
|
||||
CSymbols::LeaveCriticalSection();
|
||||
|
||||
bool bHaveReadBP = m_Breakpoints->RBPExists(vaddr);
|
||||
bool bHaveWriteBP = m_Breakpoints->WBPExists(vaddr);
|
||||
|
||||
fgHiColor = RGB(0x00, 0x00, 0x00);
|
||||
|
||||
if (bHaveReadBP && bHaveWriteBP)
|
||||
{
|
||||
bgColor = RGB(0xAA, 0xDD, 0xDD);
|
||||
}
|
||||
else if (bHaveReadBP)
|
||||
{
|
||||
bgColor = RGB(0xDD, 0xDD, 0xAA);
|
||||
}
|
||||
else if (bHaveWriteBP)
|
||||
{
|
||||
bgColor = RGB(0xAA, 0xAA, 0xDD);
|
||||
}
|
||||
else if (m_SymbolColorStride > 0)
|
||||
{
|
||||
bgColor = m_SymbolColorPhase ? RGB(0xD0, 0xF0, 0xD0) : RGB(0xAA, 0xCC, 0xAA);
|
||||
}
|
||||
else
|
||||
{
|
||||
bgColor = GetSysColor(COLOR_WINDOW);
|
||||
fgHiColor = (changed ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHTTEXT));
|
||||
fgColor = (changed ? RGB(255, 0, 0) : GetSysColor(COLOR_WINDOWTEXT));
|
||||
}
|
||||
|
||||
if (m_SymbolColorStride > 0)
|
||||
{
|
||||
m_SymbolColorStride--;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if KSEG0 addr is out of bounds
|
||||
bool CDebugMemoryView::AddressSafe(uint32_t vaddr)
|
||||
{
|
||||
if (g_MMU == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vaddr >= 0x80000000 && vaddr <= 0x9FFFFFFF)
|
||||
{
|
||||
if ((vaddr & 0x1FFFFFFF) >= g_MMU->RdramSize())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -10,6 +10,8 @@
|
|||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "Debugger-AddSymbol.h"
|
||||
|
||||
class CDebugMemoryView :
|
||||
public CDebugDialog < CDebugMemoryView >
|
||||
{
|
||||
|
@ -22,29 +24,53 @@ public:
|
|||
void ShowAddress(DWORD Address, bool VAddr);
|
||||
|
||||
private:
|
||||
BEGIN_MSG_MAP_EX(CDebugMemoryView)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
COMMAND_HANDLER_EX(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged)
|
||||
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_MODIFIED, OnMemoryModified)
|
||||
BEGIN_MSG_MAP_EX(CDebugMemoryView)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
|
||||
COMMAND_HANDLER_EX(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged)
|
||||
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_MODIFIED, OnMemoryModified)
|
||||
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_RIGHTCLICK, OnMemoryRightClicked)
|
||||
NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_HOTITEMCHANGED, OnHotItemChanged)
|
||||
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
MSG_WM_VSCROLL(OnVScroll)
|
||||
END_MSG_MAP()
|
||||
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
|
||||
void OnAddrChanged(UINT Code, int id, HWND ctl);
|
||||
void OnVScroll(int request, short Pos, HWND ctrl);
|
||||
LRESULT OnMemoryModified(LPNMHDR lpNMHDR);
|
||||
LRESULT OnDestroy(void);
|
||||
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
|
||||
void OnAddrChanged(UINT Code, int id, HWND ctl);
|
||||
void OnVScroll(int request, short Pos, HWND ctrl);
|
||||
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnMemoryModified(LPNMHDR lpNMHDR);
|
||||
LRESULT OnMemoryRightClicked(LPNMHDR lpNMHDR);
|
||||
LRESULT OnHotItemChanged(LPNMHDR lpNMHDR);
|
||||
LRESULT OnDestroy(void);
|
||||
|
||||
void Insert_MemoryLineDump(int LineNumber);
|
||||
void RefreshMemory(bool ResetCompare);
|
||||
|
||||
enum { MemoryToDisplay = 0x100 };
|
||||
HANDLE m_AutoRefreshThread;
|
||||
static DWORD WINAPI AutoRefreshProc(void* _this);
|
||||
|
||||
void SelectColors(uint32_t address, bool changed, COLORREF& bgColor, COLORREF& fgColor, COLORREF& fgHiColor);
|
||||
bool GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset);
|
||||
bool GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address);
|
||||
|
||||
bool AddressSafe(uint32_t vaddr);
|
||||
|
||||
enum { MemoryToDisplay = 0x100 };
|
||||
|
||||
CEditNumber m_MemAddr;
|
||||
CListCtrl * m_MemoryList;
|
||||
CAddSymbolDlg m_AddSymbolDlg;
|
||||
CStatic m_SymInfo;
|
||||
CStatic m_DMAInfo;
|
||||
|
||||
CBreakpoints* m_Breakpoints;
|
||||
|
||||
int m_SymbolColorStride;
|
||||
int m_SymbolColorPhase;
|
||||
DWORD m_CtxMenuAddr;
|
||||
|
||||
DWORD m_DataStartLoc;
|
||||
bool m_DataVAddrr;
|
||||
|
@ -55,4 +81,4 @@ private:
|
|||
bool m_CompareVAddrr;
|
||||
BYTE m_CompareData[MemoryToDisplay];
|
||||
bool m_CompareValid[MemoryToDisplay];
|
||||
};
|
||||
};
|
|
@ -10,6 +10,10 @@
|
|||
****************************************************************************/
|
||||
#include "stdafx.h"
|
||||
#include "DebuggerUI.h"
|
||||
#include "ScriptHook.h"
|
||||
|
||||
#include "DMALog.h"
|
||||
#include "Symbols.h"
|
||||
|
||||
CPj64Module _Module;
|
||||
|
||||
|
@ -17,8 +21,28 @@ CDebuggerUI::CDebuggerUI() :
|
|||
m_MemoryDump(NULL),
|
||||
m_MemoryView(NULL),
|
||||
m_MemorySearch(NULL),
|
||||
m_DebugTLB(NULL)
|
||||
m_DebugTLB(NULL),
|
||||
m_CommandsView(NULL),
|
||||
m_Scripts(NULL),
|
||||
m_Symbols(NULL),
|
||||
m_Breakpoints(NULL),
|
||||
m_ScriptSystem(NULL),
|
||||
m_DMALogView(NULL),
|
||||
m_StackTraceView(NULL),
|
||||
m_StackView(NULL),
|
||||
m_DMALog(NULL)
|
||||
{
|
||||
g_Debugger = this;
|
||||
|
||||
//m_DMALog = new vector<DMALogEntry>;
|
||||
m_StackTrace = new vector<uint32_t>;
|
||||
|
||||
m_Breakpoints = new CBreakpoints();
|
||||
m_ScriptSystem = new CScriptSystem(this);
|
||||
|
||||
m_DMALog = new CDMALog();
|
||||
|
||||
CSymbols::InitializeCriticalSection();
|
||||
g_Settings->RegisterChangeCB(GameRunning_InReset, this, (CSettings::SettingChangedFunc)GameReset);
|
||||
}
|
||||
|
||||
|
@ -26,15 +50,48 @@ CDebuggerUI::~CDebuggerUI(void)
|
|||
{
|
||||
g_Settings->UnregisterChangeCB(GameRunning_InReset, this, (CSettings::SettingChangedFunc)GameReset);
|
||||
Debug_Reset();
|
||||
delete m_MemoryView;
|
||||
delete m_CommandsView;
|
||||
delete m_Scripts;
|
||||
delete m_ScriptSystem;
|
||||
delete m_Breakpoints;
|
||||
delete m_Symbols;
|
||||
delete m_DMALogView;
|
||||
delete m_MemorySearch;
|
||||
delete m_DMALog;
|
||||
|
||||
CSymbols::DeleteCriticalSection();
|
||||
|
||||
m_StackTrace->clear();
|
||||
}
|
||||
|
||||
void CDebuggerUI::GameReset(CDebuggerUI * _this)
|
||||
{
|
||||
if (!g_Settings->LoadBool(GameRunning_InReset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_this->Debug_Reset();
|
||||
if (!g_Settings->LoadBool(GameRunning_InReset))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_this->m_CommandsView)
|
||||
{
|
||||
_this->m_CommandsView->Reset();
|
||||
}
|
||||
|
||||
if (_this->m_DMALog)
|
||||
{
|
||||
_this->m_DMALog->ClearEntries();
|
||||
}
|
||||
|
||||
CSymbols::EnterCriticalSection();
|
||||
CSymbols::Load();
|
||||
CSymbols::LeaveCriticalSection();
|
||||
|
||||
if (_this->m_Symbols)
|
||||
{
|
||||
CSymbols::EnterCriticalSection();
|
||||
_this->m_Symbols->Refresh();
|
||||
CSymbols::LeaveCriticalSection();
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_Reset(void)
|
||||
|
@ -45,12 +102,6 @@ void CDebuggerUI::Debug_Reset(void)
|
|||
delete m_MemoryDump;
|
||||
m_MemoryDump = NULL;
|
||||
}
|
||||
if (m_MemoryView)
|
||||
{
|
||||
m_MemoryView->HideWindow();
|
||||
delete m_MemoryView;
|
||||
m_MemoryView = NULL;
|
||||
}
|
||||
if (m_MemorySearch)
|
||||
{
|
||||
m_MemorySearch->HideWindow();
|
||||
|
@ -63,6 +114,48 @@ void CDebuggerUI::Debug_Reset(void)
|
|||
delete m_DebugTLB;
|
||||
m_DebugTLB = NULL;
|
||||
}
|
||||
if (m_MemoryView)
|
||||
{
|
||||
m_MemoryView->HideWindow();
|
||||
delete m_MemoryView;
|
||||
m_MemoryView = NULL;
|
||||
}
|
||||
if (m_CommandsView)
|
||||
{
|
||||
m_CommandsView->HideWindow();
|
||||
delete m_CommandsView;
|
||||
m_CommandsView = NULL;
|
||||
}
|
||||
if (m_Scripts)
|
||||
{
|
||||
m_Scripts->HideWindow();
|
||||
delete m_Scripts;
|
||||
m_Scripts = NULL;
|
||||
}
|
||||
if (m_Symbols)
|
||||
{
|
||||
m_Symbols->HideWindow();
|
||||
delete m_Symbols;
|
||||
m_Symbols = NULL;
|
||||
}
|
||||
if (m_DMALogView)
|
||||
{
|
||||
m_DMALogView->HideWindow();
|
||||
delete m_DMALogView;
|
||||
m_DMALogView = NULL;
|
||||
}
|
||||
if (m_StackTraceView)
|
||||
{
|
||||
m_StackTraceView->HideWindow();
|
||||
delete m_StackTraceView;
|
||||
m_StackTraceView = NULL;
|
||||
}
|
||||
if (m_StackView)
|
||||
{
|
||||
m_StackView->HideWindow();
|
||||
delete m_StackView;
|
||||
m_StackView = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowMemoryDump()
|
||||
|
@ -142,7 +235,289 @@ void CDebuggerUI::Debug_ShowMemorySearch()
|
|||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowCommandsWindow()
|
||||
{
|
||||
if (m_CommandsView == NULL)
|
||||
{
|
||||
m_CommandsView = new CDebugCommandsView(this);
|
||||
}
|
||||
m_CommandsView->ShowWindow();
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowCommandsLocation(uint32_t address, bool top)
|
||||
{
|
||||
Debug_ShowCommandsWindow();
|
||||
if (m_CommandsView)
|
||||
{
|
||||
m_CommandsView->ShowAddress(address, top);
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowScriptsWindow()
|
||||
{
|
||||
if (m_Scripts == NULL)
|
||||
{
|
||||
m_Scripts = new CDebugScripts(this);
|
||||
}
|
||||
m_Scripts->ShowWindow();
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_RefreshScriptsWindow()
|
||||
{
|
||||
if (m_Scripts != NULL)
|
||||
{
|
||||
m_Scripts->RefreshList();
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_LogScriptsWindow(const char* text)
|
||||
{
|
||||
if (m_Scripts != NULL)
|
||||
{
|
||||
m_Scripts->ConsolePrint(text);
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ClearScriptsWindow()
|
||||
{
|
||||
if (m_Scripts != NULL)
|
||||
{
|
||||
m_Scripts->ConsoleClear();
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowSymbolsWindow()
|
||||
{
|
||||
if (m_Symbols == NULL)
|
||||
{
|
||||
m_Symbols = new CDebugSymbols(this);
|
||||
}
|
||||
m_Symbols->ShowWindow();
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_RefreshSymbolsWindow()
|
||||
{
|
||||
if (m_Symbols != NULL)
|
||||
{
|
||||
m_Symbols->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowDMALogWindow(void)
|
||||
{
|
||||
if (m_DMALogView == NULL)
|
||||
{
|
||||
m_DMALogView = new CDebugDMALogView(this);
|
||||
}
|
||||
m_DMALogView->ShowWindow();
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowStackTrace(void)
|
||||
{
|
||||
if (m_StackTraceView == NULL)
|
||||
{
|
||||
m_StackTraceView = new CDebugStackTrace(this);
|
||||
}
|
||||
m_StackTraceView->ShowWindow();
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_ShowStackWindow(void)
|
||||
{
|
||||
if (m_StackView == NULL)
|
||||
{
|
||||
m_StackView = new CDebugStackView(this);
|
||||
}
|
||||
m_StackView->ShowWindow();
|
||||
}
|
||||
|
||||
void CDebuggerUI::Debug_RefreshStackWindow(void)
|
||||
{
|
||||
if (m_StackView != NULL)
|
||||
{
|
||||
m_StackView->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
CBreakpoints* CDebuggerUI::Breakpoints()
|
||||
{
|
||||
return m_Breakpoints;
|
||||
}
|
||||
|
||||
CScriptSystem* CDebuggerUI::ScriptSystem()
|
||||
{
|
||||
return m_ScriptSystem;
|
||||
}
|
||||
|
||||
CDebugScripts* CDebuggerUI::ScriptConsole()
|
||||
{
|
||||
return m_Scripts;
|
||||
}
|
||||
|
||||
CDMALog* CDebuggerUI::DMALog()
|
||||
{
|
||||
return m_DMALog;
|
||||
}
|
||||
|
||||
vector<uint32_t> * CDebuggerUI::StackTrace()
|
||||
{
|
||||
return m_StackTrace;
|
||||
}
|
||||
|
||||
|
||||
void CDebuggerUI::BreakpointHit()
|
||||
{
|
||||
m_Breakpoints->KeepDebugging();
|
||||
Debug_ShowCommandsLocation(g_Reg->m_PROGRAM_COUNTER, false);
|
||||
m_Breakpoints->Pause();
|
||||
}
|
||||
|
||||
|
||||
// CDebugger implementation
|
||||
|
||||
void CDebuggerUI::TLBChanged()
|
||||
{
|
||||
Debug_RefreshTLBWindow();
|
||||
Debug_RefreshTLBWindow();
|
||||
}
|
||||
|
||||
// Called from the interpreter core at the beginning of every CPU step
|
||||
// Returns false when the instruction should be skipped
|
||||
bool CDebuggerUI::CPUStepStarted()
|
||||
{
|
||||
uint32_t PROGRAM_COUNTER = g_Reg->m_PROGRAM_COUNTER;
|
||||
uint32_t JumpToLocation = R4300iOp::m_JumpToLocation;
|
||||
|
||||
m_ScriptSystem->HookCPUExec()->InvokeByParamInRange(PROGRAM_COUNTER);
|
||||
|
||||
// PC breakpoints
|
||||
|
||||
if (m_Breakpoints->EBPExists(PROGRAM_COUNTER, true))
|
||||
{
|
||||
goto breakpoint_hit;
|
||||
}
|
||||
|
||||
// Memory breakpoints
|
||||
|
||||
OPCODE Opcode = R4300iOp::m_Opcode;
|
||||
uint32_t op = Opcode.op;
|
||||
|
||||
if (op >= R4300i_LDL && op <= R4300i_SD && op != R4300i_CACHE) // Read and write instructions
|
||||
{
|
||||
uint32_t memoryAddress = g_Reg->m_GPR[Opcode.base].UW[0] + (int16_t)Opcode.offset;
|
||||
|
||||
if ((op <= R4300i_LWU || (op >= R4300i_LL && op <= R4300i_LD))) // Read instructions
|
||||
{
|
||||
m_ScriptSystem->HookCPURead()->InvokeByParamInRange(memoryAddress);
|
||||
|
||||
if (m_Breakpoints->RBPExists(memoryAddress))
|
||||
{
|
||||
goto breakpoint_hit;
|
||||
}
|
||||
}
|
||||
else // Write instructions
|
||||
{
|
||||
m_ScriptSystem->HookCPUWrite()->InvokeByParamInRange(memoryAddress);
|
||||
|
||||
if (m_Breakpoints->WBPExists(memoryAddress))
|
||||
{
|
||||
goto breakpoint_hit;
|
||||
}
|
||||
|
||||
// Catch cart -> rdram dma
|
||||
if (memoryAddress == 0xA460000C) // PI_WR_LEN_REG
|
||||
{
|
||||
uint32_t dmaRomAddr = g_Reg->PI_CART_ADDR_REG & 0x0FFFFFFF;
|
||||
uint32_t dmaRamAddr = g_Reg->PI_DRAM_ADDR_REG | 0x80000000;
|
||||
uint32_t dmaLen = g_Reg->m_GPR[Opcode.rt].UW[0] + 1;
|
||||
uint32_t endAddr = dmaRamAddr + dmaLen;
|
||||
|
||||
m_DMALog->AddEntry(dmaRomAddr, dmaRamAddr, dmaLen);
|
||||
|
||||
for (int i = 0; i < m_Breakpoints->m_nWBP; i++)
|
||||
{
|
||||
uint32_t wbpAddr = m_Breakpoints->m_WBP[i].address;
|
||||
if (wbpAddr >= dmaRamAddr && wbpAddr < endAddr)
|
||||
{
|
||||
goto breakpoint_hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_Breakpoints->isDebugging())
|
||||
{
|
||||
return !m_Breakpoints->isSkipping();
|
||||
}
|
||||
|
||||
if (R4300iOp::m_NextInstruction != JUMP)
|
||||
{
|
||||
goto breakpoint_hit;
|
||||
}
|
||||
|
||||
if (JumpToLocation == PROGRAM_COUNTER + 4)
|
||||
{
|
||||
// Only pause on delay slots when branch isn't taken
|
||||
goto breakpoint_hit;
|
||||
}
|
||||
|
||||
return !m_Breakpoints->isSkipping();
|
||||
|
||||
breakpoint_hit:
|
||||
BreakpointHit();
|
||||
return !m_Breakpoints->isSkipping();
|
||||
}
|
||||
|
||||
void CDebuggerUI::CPUStep()
|
||||
{
|
||||
OPCODE Opcode = R4300iOp::m_Opcode;
|
||||
uint32_t op = Opcode.op;
|
||||
uint32_t funct = Opcode.funct;
|
||||
|
||||
if (op == R4300i_JAL || funct == R4300i_SPECIAL_JALR) // JAL or JALR
|
||||
{
|
||||
//m_StackTrace->push_back(R4300iOp::m_JumpToLocation);
|
||||
}
|
||||
else if (funct == R4300i_SPECIAL_JR && Opcode.rs == 31) // JR RA
|
||||
{
|
||||
//m_StackTrace->pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void CDebuggerUI::FrameDrawn()
|
||||
{
|
||||
static HWND hMainWnd = NULL;
|
||||
|
||||
static HFONT monoFont = CreateFont(-11, 0, 0, 0,
|
||||
FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
|
||||
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
PROOF_QUALITY, FF_DONTCARE, "Consolas"
|
||||
);
|
||||
|
||||
if (hMainWnd == NULL)
|
||||
{
|
||||
RenderWindow* mainWindow = g_Plugins->MainWindow();
|
||||
|
||||
if (mainWindow == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hMainWnd = (HWND)mainWindow->GetWindowHandle();
|
||||
}
|
||||
|
||||
HDC hdc = GetDC(hMainWnd);
|
||||
|
||||
CRect rt;
|
||||
|
||||
GetClientRect(hMainWnd, &rt);
|
||||
SetBkColor(hdc, RGB(0, 0, 0));
|
||||
|
||||
SelectObject(hdc, monoFont);
|
||||
SetTextColor(hdc, RGB(255, 255, 255));
|
||||
SetBkColor(hdc, RGB(0, 0, 0));
|
||||
|
||||
m_ScriptSystem->SetScreenDC(hdc);
|
||||
m_ScriptSystem->HookFrameDrawn()->InvokeAll();
|
||||
|
||||
ReleaseDC(hMainWnd, hdc);
|
||||
}
|
|
@ -7,3 +7,11 @@
|
|||
#include "Debugger-ViewMemory.h"
|
||||
#include "Debugger-MemoryDump.h"
|
||||
#include "Debugger-TLB.h"
|
||||
#include "Debugger-Commands.h"
|
||||
#include "Debugger-Scripts.h"
|
||||
#include "Debugger-Symbols.h"
|
||||
#include "Debugger-AddBreakpoint.h"
|
||||
#include "Debugger-AddSymbol.h"
|
||||
#include "Debugger-DMALogView.h"
|
||||
#include "Debugger-StackView.h"
|
||||
#include "Debugger-StackTrace.h"
|
|
@ -0,0 +1,322 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <stdafx.h>
|
||||
|
||||
#include <Project64-core\N64System\Mips\OpCode.h>
|
||||
|
||||
class COpInfo
|
||||
{
|
||||
public:
|
||||
|
||||
OPCODE m_OpCode;
|
||||
|
||||
bool IsStaticJump()
|
||||
{
|
||||
// j, jal
|
||||
|
||||
uint32_t op = m_OpCode.op;
|
||||
|
||||
if (op == R4300i_J || op == R4300i_JAL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsJump()
|
||||
{
|
||||
// j, jal, jr, jalr, exception
|
||||
|
||||
uint32_t op = m_OpCode.op;
|
||||
|
||||
if (op == R4300i_J || op == R4300i_JAL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (op == R4300i_SPECIAL)
|
||||
{
|
||||
uint32_t fn = m_OpCode.funct;
|
||||
|
||||
if (fn >= R4300i_SPECIAL_JR && fn <= R4300i_SPECIAL_BREAK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == R4300i_REGIMM)
|
||||
{
|
||||
uint32_t rt = m_OpCode.rt;
|
||||
|
||||
if (rt >= R4300i_REGIMM_TGEI && rt <= R4300i_REGIMM_TNEI)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == R4300i_CP0)
|
||||
{
|
||||
if ((m_OpCode.rs & 0x10) != 0)
|
||||
{
|
||||
uint32_t fn = m_OpCode.funct;
|
||||
if (fn == R4300i_COP0_CO_ERET)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsBranch()
|
||||
{
|
||||
uint32_t op = m_OpCode.op;
|
||||
|
||||
if (op >= R4300i_BEQ && op <= R4300i_BGTZ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (op >= R4300i_BEQL && op <= R4300i_BGTZL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (op == R4300i_REGIMM)
|
||||
{
|
||||
uint32_t rt = m_OpCode.rt;
|
||||
|
||||
if (rt >= R4300i_REGIMM_BLTZ && rt <= R4300i_REGIMM_BGEZL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rt >= R4300i_REGIMM_BLTZAL && rt <= R4300i_REGIMM_BGEZALL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == R4300i_CP1 && m_OpCode.fmt == R4300i_COP1_BC)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsNOP()
|
||||
{
|
||||
if (m_OpCode.Hex == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsLoadStore()
|
||||
{
|
||||
return (m_OpCode.op >= R4300i_LDL && m_OpCode.op <= R4300i_SD && m_OpCode.op != R4300i_CACHE);
|
||||
}
|
||||
|
||||
bool IsStackShift()
|
||||
{
|
||||
return (m_OpCode.op == R4300i_ADDIU || m_OpCode.op == R4300i_ADDI) && m_OpCode.rt == 29;
|
||||
}
|
||||
|
||||
bool IsStackAlloc()
|
||||
{
|
||||
if (!IsStackShift())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (short)m_OpCode.immediate < 0;
|
||||
}
|
||||
|
||||
bool IsStackFree()
|
||||
{
|
||||
if (!IsStackShift())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (short)m_OpCode.immediate > 0;
|
||||
}
|
||||
|
||||
bool ReadsGPR(int nReg)
|
||||
{
|
||||
uint32_t op = m_OpCode.op;
|
||||
|
||||
if (op >= R4300i_LDL && op <= R4300i_LWU ||
|
||||
op >= R4300i_ADDI && op <= R4300i_XORI ||
|
||||
op == R4300i_LD ||
|
||||
op == R4300i_BGTZ || op == R4300i_BGTZL ||
|
||||
op == R4300i_BLEZ || op == R4300i_BLEZL)
|
||||
{
|
||||
if (m_OpCode.rs == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op >= R4300i_SB && op <= R4300i_SWR ||
|
||||
op >= R4300i_SC && op <= R4300i_SD ||
|
||||
op == R4300i_BEQ || op == R4300i_BEQL ||
|
||||
op == R4300i_BNE || op == R4300i_BNEL)
|
||||
{
|
||||
// stores read value and index
|
||||
if (m_OpCode.rs == nReg || m_OpCode.rt == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == R4300i_SPECIAL)
|
||||
{
|
||||
uint32_t fn = m_OpCode.funct;
|
||||
|
||||
switch (fn)
|
||||
{
|
||||
case R4300i_SPECIAL_MTLO:
|
||||
case R4300i_SPECIAL_MTHI:
|
||||
case R4300i_SPECIAL_JR:
|
||||
case R4300i_SPECIAL_JALR:
|
||||
if (m_OpCode.rs == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case R4300i_SPECIAL_SLL:
|
||||
case R4300i_SPECIAL_SRL:
|
||||
case R4300i_SPECIAL_SRA:
|
||||
if (m_OpCode.rt == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (fn >= R4300i_SPECIAL_SLLV && fn <= R4300i_SPECIAL_SRAV ||
|
||||
fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV ||
|
||||
fn >= R4300i_SPECIAL_DIVU && fn <= R4300i_SPECIAL_DSUBU)
|
||||
{
|
||||
// two register operands
|
||||
if (m_OpCode.rt == nReg || m_OpCode.rs == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WritesGPR(int nReg)
|
||||
{
|
||||
uint32_t op = m_OpCode.op;
|
||||
|
||||
if (op >= R4300i_LDL && op <= R4300i_LWU ||
|
||||
op >= R4300i_ADDI && op <= R4300i_XORI ||
|
||||
op == R4300i_LUI || op == R4300i_LD)
|
||||
{
|
||||
// loads write value
|
||||
if (m_OpCode.rt == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == R4300i_JAL)
|
||||
{
|
||||
if (nReg == 31) // RA
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == R4300i_SPECIAL)
|
||||
{
|
||||
uint32_t fn = m_OpCode.funct;
|
||||
|
||||
switch (fn)
|
||||
{
|
||||
case R4300i_SPECIAL_MFLO:
|
||||
case R4300i_SPECIAL_MFHI:
|
||||
case R4300i_SPECIAL_SLL:
|
||||
case R4300i_SPECIAL_SRL:
|
||||
case R4300i_SPECIAL_SRA:
|
||||
if (m_OpCode.rd == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (fn >= R4300i_SPECIAL_SLLV && fn <= R4300i_SPECIAL_SRAV ||
|
||||
fn >= R4300i_SPECIAL_DSLLV && fn <= R4300i_SPECIAL_DSRAV ||
|
||||
fn >= R4300i_SPECIAL_DIVU && fn <= R4300i_SPECIAL_DSUBU ||
|
||||
fn == R4300i_SPECIAL_JALR)
|
||||
{
|
||||
// result register
|
||||
if (m_OpCode.rd == nReg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadsLO()
|
||||
{
|
||||
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFLO)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WritesLO()
|
||||
{
|
||||
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MTLO)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo add mult, div etc
|
||||
|
||||
bool ReadsHI()
|
||||
{
|
||||
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MFHI)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WritesHI()
|
||||
{
|
||||
if (m_OpCode.op == R4300i_SPECIAL && m_OpCode.funct == R4300i_SPECIAL_MTHI)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,126 @@
|
|||
#include <stdafx.h>
|
||||
|
||||
#include "ScriptHook.h"
|
||||
#include "ScriptInstance.h"
|
||||
#include "ScriptSystem.h"
|
||||
|
||||
int CScriptHook::Add(CScriptInstance* scriptInstance, void* heapptr, uint32_t param, uint32_t param2, bool bOnce)
|
||||
{
|
||||
JSCALLBACK jsCallback;
|
||||
jsCallback.scriptInstance = scriptInstance;
|
||||
jsCallback.heapptr = heapptr;
|
||||
jsCallback.callbackId = m_ScriptSystem->GetNextCallbackId();
|
||||
jsCallback.param = param;
|
||||
jsCallback.param2 = param2;
|
||||
jsCallback.bOnce = bOnce;
|
||||
m_Callbacks.push_back(jsCallback);
|
||||
return jsCallback.callbackId;
|
||||
}
|
||||
|
||||
void CScriptHook::InvokeById(int callbackId)
|
||||
{
|
||||
int nCallbacks = m_Callbacks.size();
|
||||
for (int i = 0; i < nCallbacks; i++)
|
||||
{
|
||||
if (m_Callbacks[i].callbackId == callbackId)
|
||||
{
|
||||
m_Callbacks[i].scriptInstance->Invoke(m_Callbacks[i].heapptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHook::InvokeByParam(uint32_t param)
|
||||
{
|
||||
int nCallbacks = m_Callbacks.size();
|
||||
for (int i = 0; i < nCallbacks; i++)
|
||||
{
|
||||
if (m_Callbacks[i].param == param)
|
||||
{
|
||||
m_Callbacks[i].scriptInstance->Invoke(m_Callbacks[i].heapptr, param);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHook::InvokeByParamInRange(uint32_t param)
|
||||
{
|
||||
int nCallbacks = m_Callbacks.size();
|
||||
for (int i = 0; i < nCallbacks; i++)
|
||||
{
|
||||
if (param == m_Callbacks[i].param || (param >= m_Callbacks[i].param && param < m_Callbacks[i].param2))
|
||||
{
|
||||
m_Callbacks[i].scriptInstance->Invoke(m_Callbacks[i].heapptr, param);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHook::InvokeAll()
|
||||
{
|
||||
int nCallbacks = m_Callbacks.size();
|
||||
for (int i = 0; i < nCallbacks; i++)
|
||||
{
|
||||
m_Callbacks[i].scriptInstance->Invoke(m_Callbacks[i].heapptr);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHook::RemoveById(int callbackId)
|
||||
{
|
||||
int nCallbacks = m_Callbacks.size();
|
||||
for (int i = 0; i < nCallbacks; i++)
|
||||
{
|
||||
if (m_Callbacks[i].callbackId == callbackId)
|
||||
{
|
||||
m_Callbacks.erase(m_Callbacks.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHook::RemoveByParam(uint32_t param)
|
||||
{
|
||||
int nCallbacks = m_Callbacks.size();
|
||||
for (int i = 0; i < nCallbacks; i++)
|
||||
{
|
||||
if (m_Callbacks[i].param == param)
|
||||
{
|
||||
m_Callbacks.erase(m_Callbacks.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptHook::RemoveByInstance(CScriptInstance* scriptInstance)
|
||||
{
|
||||
int lastIndex = m_Callbacks.size() - 1;
|
||||
for (int i = lastIndex; i >= 0; i--)
|
||||
{
|
||||
if (m_Callbacks[i].scriptInstance == scriptInstance)
|
||||
{
|
||||
m_Callbacks.erase(m_Callbacks.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CScriptHook::HasContext(CScriptInstance* scriptInstance)
|
||||
{
|
||||
for (int i = 0; i < m_Callbacks.size(); i++)
|
||||
{
|
||||
if (m_Callbacks[i].scriptInstance == scriptInstance)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CScriptHook::CScriptHook(CScriptSystem* scriptSystem)
|
||||
{
|
||||
m_ScriptSystem = scriptSystem;
|
||||
}
|
||||
|
||||
CScriptHook::~CScriptHook()
|
||||
{
|
||||
m_Callbacks.clear();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdafx.h>
|
||||
|
||||
class CScriptInstance;
|
||||
class CScriptSystem;
|
||||
|
||||
class CScriptHook
|
||||
{
|
||||
private:
|
||||
typedef struct {
|
||||
CScriptInstance* scriptInstance;
|
||||
void* heapptr;
|
||||
uint32_t param;
|
||||
uint32_t param2;
|
||||
int callbackId;
|
||||
bool bOnce;
|
||||
} JSCALLBACK;
|
||||
|
||||
CScriptSystem* m_ScriptSystem;
|
||||
|
||||
//int m_NextCallbackId;
|
||||
vector<JSCALLBACK> m_Callbacks;
|
||||
|
||||
public:
|
||||
CScriptHook(CScriptSystem* scriptSystem);
|
||||
~CScriptHook();
|
||||
int Add(CScriptInstance* scriptInstance, void* heapptr, uint32_t param = 0, uint32_t param2 = 0, bool bOnce = false);
|
||||
void InvokeAll();
|
||||
void InvokeById(int callbackId);
|
||||
void InvokeByParam(uint32_t param);
|
||||
/* invoke if param >= cb.param && param < cb.param2*/
|
||||
void InvokeByParamInRange(uint32_t param);
|
||||
void RemoveById(int callbackId);
|
||||
void RemoveByParam(uint32_t tag);
|
||||
void RemoveByInstance(CScriptInstance* scriptInstance);
|
||||
bool HasContext(CScriptInstance* scriptInstance);
|
||||
//bool HasTag(uint32_t tag);
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,206 @@
|
|||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <3rdParty/duktape/duktape.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <mswsock.h>
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#pragma comment(lib, "Mswsock.lib")
|
||||
|
||||
class CScriptSystem;
|
||||
|
||||
typedef enum {
|
||||
STATE_STARTED, // initial evaluation & execution
|
||||
STATE_RUNNING, // event loop running with pending events
|
||||
STATE_STOPPED, // no pending events
|
||||
STATE_INVALID
|
||||
} INSTANCE_STATE;
|
||||
|
||||
class CScriptInstance
|
||||
{
|
||||
typedef enum {
|
||||
EVENT_READ,
|
||||
EVENT_WRITE,
|
||||
EVENT_ACCEPT,
|
||||
EVENT_CONNECT
|
||||
} IOEVENTTYPE;
|
||||
|
||||
typedef struct {
|
||||
OVERLAPPED ovl;
|
||||
IOEVENTTYPE eventType;
|
||||
HANDLE fd;
|
||||
HANDLE childFd; // accepted socket
|
||||
bool bSocket;
|
||||
UINT id;
|
||||
void* data;
|
||||
DWORD dataLen; // changed to bytes transferred after event is fired
|
||||
void* callback;
|
||||
} IOLISTENER;
|
||||
|
||||
// Wrapper for file/socket descriptor and completion port
|
||||
typedef struct {
|
||||
HANDLE fd;
|
||||
HANDLE iocp;
|
||||
bool bSocket;
|
||||
} IOFD;
|
||||
|
||||
typedef enum {
|
||||
EVENT_STATUS_OK,
|
||||
EVENT_STATUS_INTERRUPTED,
|
||||
EVENT_STATUS_ERROR
|
||||
} EVENT_STATUS;
|
||||
|
||||
public:
|
||||
|
||||
CScriptInstance(CDebuggerUI* debugger);
|
||||
~CScriptInstance();
|
||||
|
||||
void Start(char* path);
|
||||
void ForceStop();
|
||||
void Invoke(void* heapptr, uint32_t param = 0);
|
||||
INSTANCE_STATE GetState();
|
||||
|
||||
friend class PendingEval;
|
||||
void EvalAsync(const char* jsCode);
|
||||
const char* Eval(const char* jsCode);
|
||||
|
||||
private:
|
||||
duk_context* m_Ctx;
|
||||
duk_context* DukContext();
|
||||
char* m_TempPath;
|
||||
|
||||
HANDLE m_hThread;
|
||||
HANDLE m_hIOCompletionPort;
|
||||
CRITICAL_SECTION m_CriticalSection;
|
||||
|
||||
vector<IOFD> m_Files;
|
||||
vector<IOLISTENER*> m_Listeners;
|
||||
UINT m_NextListenerId;
|
||||
|
||||
CDebuggerUI* m_Debugger;
|
||||
|
||||
CScriptSystem* m_ScriptSystem;
|
||||
|
||||
INSTANCE_STATE m_State;
|
||||
|
||||
static DWORD CALLBACK StartThread(CScriptInstance* _this);
|
||||
void StartScriptProc();
|
||||
void StartEventLoop();
|
||||
bool HaveEvents();
|
||||
EVENT_STATUS WaitForEvent(IOLISTENER** lpListener);
|
||||
|
||||
void SetState(INSTANCE_STATE state);
|
||||
void StateChanged();
|
||||
|
||||
void QueueAPC(PAPCFUNC userProc, ULONG_PTR param = 0);
|
||||
|
||||
void AddFile(HANDLE fd, bool bSocket = false);
|
||||
void CloseFile(HANDLE fd);
|
||||
void CloseAllFiles();
|
||||
void RemoveFile(HANDLE fd);
|
||||
HANDLE CreateSocket();
|
||||
|
||||
IOLISTENER* AddListener(HANDLE fd, IOEVENTTYPE evt, void* jsCallback, void* data = NULL, int dataLen = 0);
|
||||
void RemoveListener(IOLISTENER* lpListener);
|
||||
void RemoveListenerByIndex(UINT index);
|
||||
void RemoveListenersByFd(HANDLE fd);
|
||||
void InvokeListenerCallback(IOLISTENER* lpListener);
|
||||
|
||||
static void CALLBACK EvalAsyncCallback(ULONG_PTR evalWait);
|
||||
|
||||
const char* EvalFile(const char* jsPath);
|
||||
|
||||
// Lookup list of CScriptInstance instances for static js_* functions
|
||||
static vector<CScriptInstance*> Cache;
|
||||
static void CacheInstance(CScriptInstance* _this);
|
||||
static void UncacheInstance(CScriptInstance* _this);
|
||||
static CScriptInstance* FetchInstance(duk_context* ctx);
|
||||
|
||||
// Bound functions (_native object)
|
||||
static duk_ret_t js_ioSockCreate (duk_context*);
|
||||
static duk_ret_t js_ioSockListen (duk_context*);
|
||||
static duk_ret_t js_ioSockAccept (duk_context*); // async
|
||||
static duk_ret_t js_ioSockConnect (duk_context*); // async
|
||||
static duk_ret_t js_ioRead (duk_context*); // async
|
||||
static duk_ret_t js_ioWrite (duk_context*); // async
|
||||
static duk_ret_t js_ioClose (duk_context*); // (fd) ; file or socket
|
||||
static duk_ret_t js_MsgBox (duk_context*); // (message, caption)
|
||||
static duk_ret_t js_AddCallback (duk_context*); // (hookId, callback, tag) ; external events
|
||||
static duk_ret_t js_RemoveCallback (duk_context*); // (callbackId)
|
||||
static duk_ret_t js_GetPCVal (duk_context*); // ()
|
||||
static duk_ret_t js_SetPCVal (duk_context*); // (value)
|
||||
static duk_ret_t js_GetHIVal (duk_context*); // (bUpper)
|
||||
static duk_ret_t js_SetHIVal (duk_context*); // (bUpper, value)
|
||||
static duk_ret_t js_GetLOVal (duk_context*); // (bUpper)
|
||||
static duk_ret_t js_SetLOVal (duk_context*); // (bUpper, value)
|
||||
static duk_ret_t js_GetGPRVal (duk_context*); // (regNum, bUpper)
|
||||
static duk_ret_t js_SetGPRVal (duk_context*); // (regNum, bUpper, value)
|
||||
static duk_ret_t js_GetFPRVal (duk_context*); // (regNum, bDouble)
|
||||
static duk_ret_t js_SetFPRVal (duk_context*); // (regNum, bDouble, value)
|
||||
static duk_ret_t js_GetROMInt (duk_context*); // (address, bitwidth, signed)
|
||||
static duk_ret_t js_GetROMFloat (duk_context*); // (address, bDouble)
|
||||
static duk_ret_t js_GetROMBlock (duk_context*); // (address, nBytes) ; returns Buffer
|
||||
static duk_ret_t js_GetROMString (duk_context*); // (address[, maxLen]) ; fetch zero terminated string from memory
|
||||
|
||||
static duk_ret_t js_GetRDRAMInt (duk_context*); // (address, bitwidth, signed)
|
||||
static duk_ret_t js_SetRDRAMInt (duk_context*); // (address, bitwidth, signed, newValue)
|
||||
static duk_ret_t js_GetRDRAMFloat (duk_context*); // (address, bDouble)
|
||||
static duk_ret_t js_SetRDRAMFloat (duk_context*); // (address, bDouble, newValue)
|
||||
static duk_ret_t js_GetRDRAMBlock (duk_context*); // (address, nBytes) ; returns Buffer
|
||||
static duk_ret_t js_GetRDRAMString (duk_context*); // (address[, maxLen]) ; fetch zero terminated string from memory
|
||||
static duk_ret_t js_ConsolePrint (duk_context*);
|
||||
static duk_ret_t js_ConsoleClear (duk_context*);
|
||||
|
||||
static duk_ret_t js_Pause(duk_context*); // () ; pauses emulation
|
||||
static duk_ret_t js_ShowCommands(duk_context*); // ([address]) ; shows commands window
|
||||
|
||||
static duk_ret_t js_ScreenPrint(duk_context*); // (x, y, text)
|
||||
|
||||
static constexpr duk_function_list_entry NativeFunctions[] =
|
||||
{
|
||||
{ "addCallback", js_AddCallback, DUK_VARARGS },
|
||||
{ "removeCallback", js_RemoveCallback, DUK_VARARGS },
|
||||
|
||||
{ "setPCVal", js_SetPCVal, DUK_VARARGS },
|
||||
{ "getPCVal", js_GetPCVal, DUK_VARARGS },
|
||||
{ "setHIVal", js_SetHIVal, DUK_VARARGS },
|
||||
{ "getHIVal", js_GetHIVal, DUK_VARARGS },
|
||||
{ "setLOVal", js_SetLOVal, DUK_VARARGS },
|
||||
{ "getLOVal", js_GetLOVal, DUK_VARARGS },
|
||||
{ "setGPRVal", js_SetGPRVal, DUK_VARARGS },
|
||||
{ "getGPRVal", js_GetGPRVal, DUK_VARARGS },
|
||||
{ "setFPRVal", js_SetFPRVal, DUK_VARARGS },
|
||||
{ "getFPRVal", js_GetFPRVal, DUK_VARARGS },
|
||||
|
||||
{ "getROMInt", js_GetROMInt, DUK_VARARGS },
|
||||
{ "getROMFloat", js_GetROMFloat, DUK_VARARGS },
|
||||
{ "getROMString", js_GetROMString, DUK_VARARGS },
|
||||
{ "getROMBlock", js_GetROMBlock, DUK_VARARGS },
|
||||
|
||||
{ "getRDRAMInt", js_GetRDRAMInt, DUK_VARARGS },
|
||||
{ "setRDRAMInt", js_SetRDRAMInt, DUK_VARARGS },
|
||||
{ "getRDRAMFloat", js_GetRDRAMFloat, DUK_VARARGS },
|
||||
{ "setRDRAMFloat", js_SetRDRAMFloat, DUK_VARARGS },
|
||||
{ "getRDRAMBlock", js_GetRDRAMBlock, DUK_VARARGS },
|
||||
{ "getRDRAMString", js_GetRDRAMString, DUK_VARARGS },
|
||||
|
||||
{ "sockCreate", js_ioSockCreate, DUK_VARARGS },
|
||||
{ "sockListen", js_ioSockListen, DUK_VARARGS },
|
||||
{ "sockAccept", js_ioSockAccept, DUK_VARARGS },
|
||||
{ "sockConnect", js_ioSockConnect, DUK_VARARGS },
|
||||
{ "close", js_ioClose, DUK_VARARGS },
|
||||
{ "write", js_ioWrite, DUK_VARARGS },
|
||||
{ "read", js_ioRead, DUK_VARARGS },
|
||||
{ "msgBox", js_MsgBox, DUK_VARARGS },
|
||||
{ "consolePrint", js_ConsolePrint, DUK_VARARGS },
|
||||
{ "consoleClear", js_ConsoleClear, DUK_VARARGS },
|
||||
{ "pause", js_Pause, DUK_VARARGS },
|
||||
{ "showCommands", js_ShowCommands, DUK_VARARGS },
|
||||
|
||||
{ "screenPrint", js_ScreenPrint, DUK_VARARGS },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
};
|
|
@ -0,0 +1,183 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#include <stdafx.h>
|
||||
#include "ScriptSystem.h"
|
||||
#include "Debugger-Scripts.h"
|
||||
|
||||
#include "ScriptInstance.h"
|
||||
#include "ScriptHook.h"
|
||||
|
||||
CScriptSystem::CScriptSystem(CDebuggerUI* debugger)
|
||||
{
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
|
||||
m_NextCallbackId = 0;
|
||||
|
||||
m_Debugger = debugger;
|
||||
|
||||
m_HookCPUExec = new CScriptHook(this);
|
||||
m_HookCPURead = new CScriptHook(this);
|
||||
m_HookCPUWrite = new CScriptHook(this);
|
||||
m_HookFrameDrawn = new CScriptHook(this);
|
||||
|
||||
RegisterHook("exec", m_HookCPUExec);
|
||||
RegisterHook("read", m_HookCPURead);
|
||||
RegisterHook("write", m_HookCPUWrite);
|
||||
RegisterHook("draw", m_HookFrameDrawn);
|
||||
|
||||
HMODULE hInst = GetModuleHandle(NULL);
|
||||
HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(IDR_JSAPI_TEXT), "TEXT");
|
||||
|
||||
HGLOBAL hGlob = LoadResource(hInst, hRes);
|
||||
DWORD resSize = SizeofResource(hInst, hRes);
|
||||
m_APIScript = (char*) malloc(resSize + 1);
|
||||
|
||||
void* resData = LockResource(hGlob);
|
||||
memcpy(m_APIScript, resData, resSize);
|
||||
m_APIScript[resSize] = '\0';
|
||||
FreeResource(hGlob);
|
||||
}
|
||||
|
||||
CScriptSystem::~CScriptSystem()
|
||||
{
|
||||
for (int i = 0; i < m_Hooks.size(); i++)
|
||||
{
|
||||
delete m_Hooks[i].cbList;
|
||||
}
|
||||
|
||||
UnregisterHooks();
|
||||
free(m_APIScript);
|
||||
}
|
||||
|
||||
const char* CScriptSystem::APIScript()
|
||||
{
|
||||
return m_APIScript;
|
||||
}
|
||||
|
||||
void CScriptSystem::RunScript(char* path)
|
||||
{
|
||||
CScriptInstance* scriptInstance = new CScriptInstance(m_Debugger);
|
||||
char* pathSaved = (char*)malloc(strlen(path)); // freed via DeleteStoppedInstances
|
||||
strcpy(pathSaved, path);
|
||||
m_RunningInstances.push_back({ pathSaved, scriptInstance });
|
||||
scriptInstance->Start(pathSaved);
|
||||
}
|
||||
|
||||
void CScriptSystem::StopScript(char* path)
|
||||
{
|
||||
int nInstances = m_RunningInstances.size();
|
||||
|
||||
CScriptInstance* scriptInstance = GetInstance(path);
|
||||
|
||||
if (scriptInstance == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scriptInstance->ForceStop();
|
||||
}
|
||||
|
||||
void CScriptSystem::DeleteStoppedInstances()
|
||||
{
|
||||
int lastIndex = m_RunningInstances.size() - 1;
|
||||
for (int i = lastIndex; i >= 0; i--)
|
||||
{
|
||||
if (m_RunningInstances[i].scriptInstance->GetState() == STATE_STOPPED)
|
||||
{
|
||||
free(m_RunningInstances[i].path);
|
||||
CScriptInstance* instance = m_RunningInstances[i].scriptInstance;
|
||||
delete instance;
|
||||
m_RunningInstances.erase(m_RunningInstances.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INSTANCE_STATE CScriptSystem::GetInstanceState(char* path)
|
||||
{
|
||||
for (int i = 0; i < m_RunningInstances.size(); i++)
|
||||
{
|
||||
if (strcmp(m_RunningInstances[i].path, path) == 0)
|
||||
{
|
||||
return m_RunningInstances[i].scriptInstance->GetState();
|
||||
}
|
||||
}
|
||||
return STATE_INVALID;
|
||||
}
|
||||
|
||||
CScriptInstance* CScriptSystem::GetInstance(char* path)
|
||||
{
|
||||
for (int i = 0; i < m_RunningInstances.size(); i++)
|
||||
{
|
||||
if (strcmp(m_RunningInstances[i].path, path) == 0)
|
||||
{
|
||||
return m_RunningInstances[i].scriptInstance;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CScriptSystem::HasCallbacksForInstance(CScriptInstance* scriptInstance)
|
||||
{
|
||||
for (int i = 0; i < m_Hooks.size(); i++)
|
||||
{
|
||||
if (m_Hooks[i].cbList->HasContext(scriptInstance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CScriptSystem::ClearCallbacksForInstance(CScriptInstance* scriptInstance)
|
||||
{
|
||||
for (int i = 0; i < m_Hooks.size(); i++)
|
||||
{
|
||||
m_Hooks[i].cbList->RemoveByInstance(scriptInstance);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptSystem::RemoveCallbackById(int callbackId)
|
||||
{
|
||||
for (int i = 0; i < m_Hooks.size(); i++)
|
||||
{
|
||||
m_Hooks[i].cbList->RemoveById(callbackId);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptSystem::RegisterHook(const char* hookId, CScriptHook* cbList)
|
||||
{
|
||||
HOOKENTRY hook = { hookId, cbList };
|
||||
m_Hooks.push_back(hook);
|
||||
}
|
||||
|
||||
void CScriptSystem::UnregisterHooks()
|
||||
{
|
||||
m_Hooks.clear();
|
||||
}
|
||||
|
||||
CScriptHook* CScriptSystem::GetHook(const char* hookId)
|
||||
{
|
||||
int size = m_Hooks.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (strcmp(m_Hooks[i].hookId, hookId) == 0)
|
||||
{
|
||||
return m_Hooks[i].cbList;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int CScriptSystem::GetNextCallbackId()
|
||||
{
|
||||
return m_NextCallbackId++;
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
/****************************************************************************
|
||||
* *
|
||||
* Project64 - A Nintendo 64 emulator. *
|
||||
* http://www.pj64-emu.com/ *
|
||||
* Copyright (C) 2012 Project64. All rights reserved. *
|
||||
* *
|
||||
* License: *
|
||||
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdafx.h>
|
||||
#include <3rdParty/duktape/duktape.h>
|
||||
|
||||
#include "ScriptInstance.h"
|
||||
|
||||
class CScriptHook;
|
||||
|
||||
class CScriptSystem
|
||||
{
|
||||
public:
|
||||
CScriptSystem(CDebuggerUI* debugger);
|
||||
~CScriptSystem();
|
||||
// Run a script in its own context/thread
|
||||
void RunScript(char* path);
|
||||
|
||||
// Kill a script context/thread by its path
|
||||
void StopScript(char* path);
|
||||
|
||||
const char* APIScript();
|
||||
|
||||
private:
|
||||
typedef struct {
|
||||
const char* hookId;
|
||||
CScriptHook* cbList;
|
||||
} HOOKENTRY;
|
||||
|
||||
typedef struct {
|
||||
char* path;
|
||||
CScriptInstance* scriptInstance;
|
||||
} INSTANCE_ENTRY;
|
||||
|
||||
CDebuggerUI* m_Debugger;
|
||||
|
||||
char* m_APIScript;
|
||||
|
||||
vector<HOOKENTRY> m_Hooks;
|
||||
vector<INSTANCE_ENTRY> m_RunningInstances;
|
||||
|
||||
vector<char*> m_LogData;
|
||||
|
||||
CScriptHook* m_HookCPUExec;
|
||||
CScriptHook* m_HookCPURead;
|
||||
CScriptHook* m_HookCPUWrite;
|
||||
|
||||
CScriptHook* m_HookFrameDrawn;
|
||||
|
||||
void RegisterHook(const char* hookId, CScriptHook* cbList); // associate string id with callback list
|
||||
void UnregisterHooks();
|
||||
|
||||
HDC m_ScreenDC;
|
||||
|
||||
int m_NextCallbackId;
|
||||
|
||||
public:
|
||||
// Returns true if any of the script hooks have callbacks for scriptInstance
|
||||
|
||||
|
||||
void SetScreenDC(HDC hdc)
|
||||
{
|
||||
m_ScreenDC = hdc;
|
||||
}
|
||||
|
||||
HDC GetScreenDC()
|
||||
{
|
||||
return m_ScreenDC;
|
||||
}
|
||||
|
||||
inline vector<char*>* LogData()
|
||||
{
|
||||
return &m_LogData;
|
||||
}
|
||||
|
||||
inline void LogText(const char* text)
|
||||
{
|
||||
char* newStr = (char*)malloc(strlen(text));
|
||||
strcpy(newStr, text);
|
||||
m_LogData.push_back(newStr);
|
||||
m_Debugger->Debug_RefreshScriptsWindow();
|
||||
}
|
||||
|
||||
bool HasCallbacksForInstance(CScriptInstance* scriptInstance);
|
||||
|
||||
// Remove all hooked callbacks for an instance
|
||||
void ClearCallbacksForInstance(CScriptInstance* scriptInstance);
|
||||
|
||||
void RemoveCallbackById(int callbackId);
|
||||
|
||||
CScriptHook* GetHook(const char* hookId);
|
||||
|
||||
int GetNextCallbackId();
|
||||
|
||||
void DeleteStoppedInstances();
|
||||
INSTANCE_STATE GetInstanceState(char* scriptName);
|
||||
CScriptInstance* GetInstance(char* scriptName);
|
||||
|
||||
CScriptHook* HookCPUExec()
|
||||
{
|
||||
return m_HookCPUExec;
|
||||
}
|
||||
|
||||
CScriptHook* HookCPURead()
|
||||
{
|
||||
return m_HookCPURead;
|
||||
}
|
||||
|
||||
CScriptHook* HookCPUWrite()
|
||||
{
|
||||
return m_HookCPUWrite;
|
||||
}
|
||||
|
||||
CScriptHook* HookFrameDrawn()
|
||||
{
|
||||
return m_HookFrameDrawn;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,469 @@
|
|||
#include "stdafx.h"
|
||||
#include "Symbols.h"
|
||||
|
||||
bool CSymbols::m_bInitialized = false;
|
||||
vector<CSymbolEntry*> CSymbols::m_Symbols;
|
||||
int CSymbols::m_NextSymbolId;
|
||||
|
||||
CFile CSymbols::m_SymFileHandle;
|
||||
char* CSymbols::m_SymFileBuffer;
|
||||
size_t CSymbols::m_SymFileSize;
|
||||
|
||||
char CSymbols::m_ParserDelimeter;
|
||||
char* CSymbols::m_ParserToken;
|
||||
size_t CSymbols::m_ParserTokenLength;
|
||||
bool CSymbols::m_bHaveFirstToken;
|
||||
char* CSymbols::m_SymFileParseBuffer;
|
||||
|
||||
CRITICAL_SECTION CSymbols::m_CriticalSection = {0};
|
||||
|
||||
int CSymbols::GetTypeNumber(char* typeName)
|
||||
{
|
||||
const char* name;
|
||||
for (int i = 0; (name = SymbolTypes[i]) != NULL; i++)
|
||||
{
|
||||
if (strcmp(typeName, name) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* CSymbols::GetTypeName(int typeNumber)
|
||||
{
|
||||
if (typeNumber > 11)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return SymbolTypes[typeNumber];
|
||||
}
|
||||
|
||||
// Open symbols file for game and parse into list
|
||||
|
||||
CPath CSymbols::GetSymFilePath()
|
||||
{
|
||||
stdstr symFileName;
|
||||
symFileName.Format("%s.sym", g_Settings->LoadStringVal(Game_GameName).c_str());
|
||||
|
||||
CPath symFilePath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), symFileName.c_str());
|
||||
|
||||
if (g_Settings->LoadBool(Setting_UniqueSaveDir))
|
||||
{
|
||||
symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
|
||||
}
|
||||
if (!symFilePath.DirectoryExists())
|
||||
{
|
||||
symFilePath.DirectoryCreate();
|
||||
}
|
||||
|
||||
return symFilePath;
|
||||
}
|
||||
|
||||
void CSymbols::ParserInit()
|
||||
{
|
||||
m_SymFileParseBuffer = (char*)malloc(m_SymFileSize + 1);
|
||||
strcpy(m_SymFileParseBuffer, m_SymFileBuffer);
|
||||
m_bHaveFirstToken = false;
|
||||
}
|
||||
|
||||
void CSymbols::ParserDone()
|
||||
{
|
||||
free(m_SymFileParseBuffer);
|
||||
}
|
||||
|
||||
void CSymbols::ParserFetchToken(const char* delim)
|
||||
{
|
||||
if (!m_bHaveFirstToken)
|
||||
{
|
||||
m_ParserToken = strtok(m_SymFileParseBuffer, delim);
|
||||
m_bHaveFirstToken = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ParserToken = strtok(NULL, delim);
|
||||
}
|
||||
|
||||
if (m_ParserToken != NULL)
|
||||
{
|
||||
m_ParserTokenLength = strlen(m_ParserToken);
|
||||
m_ParserDelimeter = m_SymFileBuffer[m_ParserToken - m_SymFileParseBuffer + m_ParserTokenLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ParserTokenLength = 0;
|
||||
m_ParserDelimeter = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void CSymbols::Load()
|
||||
{
|
||||
m_NextSymbolId = 0;
|
||||
Reset();
|
||||
|
||||
if (g_Settings->LoadStringVal(Game_GameName).length() == 0)
|
||||
{
|
||||
MessageBox(NULL, "Game must be loaded", "Symbols", MB_ICONWARNING | MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
CPath symFilePath = GetSymFilePath();
|
||||
|
||||
bool bOpened = m_SymFileHandle.Open(symFilePath, CFileBase::modeRead);
|
||||
|
||||
if (!bOpened)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_SymFileSize = m_SymFileHandle.GetLength();
|
||||
m_SymFileBuffer = (char*)malloc(m_SymFileSize + 1);
|
||||
m_SymFileHandle.Read(m_SymFileBuffer, m_SymFileSize);
|
||||
m_SymFileHandle.Close();
|
||||
m_SymFileBuffer[m_SymFileSize] = '\0';
|
||||
|
||||
ParseError errorCode = ERR_SUCCESS;
|
||||
int lineNumber = 1;
|
||||
|
||||
ParserInit();
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t address = 0;
|
||||
int type = 0;
|
||||
char* name = NULL;
|
||||
char* description = NULL;
|
||||
|
||||
// Address
|
||||
ParserFetchToken(",\n\0");
|
||||
|
||||
if (m_ParserToken == NULL || m_ParserTokenLength == 0)
|
||||
{
|
||||
// Empty line @EOF
|
||||
errorCode = ERR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
char* endptr;
|
||||
address = strtoull(m_ParserToken, &endptr, 16);
|
||||
|
||||
if (endptr == m_ParserToken)
|
||||
{
|
||||
errorCode = ERR_INVALID_ADDR;
|
||||
break;
|
||||
}
|
||||
|
||||
// Type
|
||||
if (m_ParserDelimeter != ',')
|
||||
{
|
||||
errorCode = ERR_MISSING_FIELDS;
|
||||
break;
|
||||
}
|
||||
|
||||
ParserFetchToken(",\n\0");
|
||||
type = GetTypeNumber(m_ParserToken);
|
||||
|
||||
if (type == -1)
|
||||
{
|
||||
errorCode = ERR_INVALID_TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Name
|
||||
if (m_ParserDelimeter != ',')
|
||||
{
|
||||
errorCode = ERR_MISSING_FIELDS;
|
||||
break;
|
||||
}
|
||||
|
||||
ParserFetchToken(",\n\0");
|
||||
name = m_ParserToken;
|
||||
|
||||
// Optional description
|
||||
if (m_ParserDelimeter == ',')
|
||||
{
|
||||
ParserFetchToken("\n\0");
|
||||
description = m_ParserToken;
|
||||
}
|
||||
|
||||
// Add symbol object to the vector
|
||||
Add(type, address, name, description);
|
||||
|
||||
if (m_ParserDelimeter == '\0')
|
||||
{
|
||||
errorCode = ERR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
lineNumber++;
|
||||
}
|
||||
|
||||
ParserDone();
|
||||
free(m_SymFileBuffer);
|
||||
|
||||
switch (errorCode)
|
||||
{
|
||||
case ERR_SUCCESS:
|
||||
break;
|
||||
case ERR_INVALID_ADDR:
|
||||
ParseErrorAlert("Invalid address", lineNumber);
|
||||
break;
|
||||
case ERR_INVALID_TYPE:
|
||||
ParseErrorAlert("Invalid type", lineNumber);
|
||||
break;
|
||||
case ERR_INVALID_NAME:
|
||||
ParseErrorAlert("Invalid name", lineNumber);
|
||||
break;
|
||||
case ERR_MISSING_FIELDS:
|
||||
ParseErrorAlert("Missing required field(s)", lineNumber);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSymbols::Save()
|
||||
{
|
||||
int nSymbols = m_Symbols.size();
|
||||
|
||||
char* symfile;
|
||||
int symfile_size = 0;
|
||||
int symfile_idx = 0;
|
||||
|
||||
// Determine file size
|
||||
for (int i = 0; i < nSymbols; i++)
|
||||
{
|
||||
CSymbolEntry* symbol = m_Symbols[i];
|
||||
|
||||
symfile_size += 11; // address 8, required commas 2, newline 1
|
||||
symfile_size += strlen(symbol->m_Name);
|
||||
symfile_size += strlen(symbol->TypeName());
|
||||
|
||||
if (symbol->m_Description != NULL && strlen(symbol->m_Description) != 0)
|
||||
{
|
||||
symfile_size += 1; // comma
|
||||
symfile_size += strlen(symbol->m_Description);
|
||||
}
|
||||
}
|
||||
|
||||
if (symfile_size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
symfile = (char*) malloc(symfile_size + 1);
|
||||
symfile[symfile_size] = '\0';
|
||||
|
||||
// Write out
|
||||
for (int i = 0; i < nSymbols; i++)
|
||||
{
|
||||
CSymbolEntry* symbol = m_Symbols[i];
|
||||
symfile_idx += sprintf(&symfile[symfile_idx], "%08X,%s,%s", symbol->m_Address, symbol->TypeName(), symbol->m_Name);
|
||||
if (symbol->m_Description != NULL)
|
||||
{
|
||||
symfile_idx += sprintf(&symfile[symfile_idx], ",%s", symbol->m_Description);
|
||||
}
|
||||
symfile_idx += sprintf(&symfile[symfile_idx], "\n");
|
||||
}
|
||||
|
||||
m_SymFileHandle.Open(GetSymFilePath(), CFileBase::modeCreate | CFileBase::modeReadWrite);
|
||||
m_SymFileHandle.SeekToBegin();
|
||||
m_SymFileHandle.Write(symfile, symfile_size);
|
||||
m_SymFileHandle.SetEndOfFile();
|
||||
m_SymFileHandle.Close();
|
||||
|
||||
free(symfile);
|
||||
}
|
||||
|
||||
void CSymbols::GetValueString(char* dest, CSymbolEntry* lpSymbol)
|
||||
{
|
||||
uint8_t v8;
|
||||
uint16_t v16;
|
||||
uint32_t v32;
|
||||
uint64_t v64;
|
||||
float vf;
|
||||
double vd;
|
||||
|
||||
uint32_t address = lpSymbol->m_Address;
|
||||
|
||||
switch (lpSymbol->m_Type)
|
||||
{
|
||||
case TYPE_CODE:
|
||||
case TYPE_DATA:
|
||||
sprintf(dest, "");
|
||||
break;
|
||||
case TYPE_U8:
|
||||
g_MMU->LB_VAddr(address, v8);
|
||||
sprintf(dest, "%u", v8);
|
||||
break;
|
||||
case TYPE_U16:
|
||||
g_MMU->LH_VAddr(address, v16);
|
||||
sprintf(dest, "%u", v16);
|
||||
break;
|
||||
case TYPE_U32:
|
||||
g_MMU->LW_VAddr(address, v32);
|
||||
sprintf(dest, "%u", v32);
|
||||
break;
|
||||
case TYPE_U64:
|
||||
g_MMU->LD_VAddr(address, v64);
|
||||
sprintf(dest, "%ull", v64);
|
||||
break;
|
||||
case TYPE_S8:
|
||||
g_MMU->LB_VAddr(address, v8);
|
||||
sprintf(dest, "%ihh", v8);
|
||||
break;
|
||||
case TYPE_S16:
|
||||
g_MMU->LH_VAddr(address, v16);
|
||||
sprintf(dest, "%i", v16);
|
||||
break;
|
||||
case TYPE_S32:
|
||||
g_MMU->LW_VAddr(address, v32);
|
||||
sprintf(dest, "%i", v32);
|
||||
break;
|
||||
case TYPE_S64:
|
||||
g_MMU->LD_VAddr(address, v64);
|
||||
sprintf(dest, "%ill", v64);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
g_MMU->LW_VAddr(address, *(uint32_t*)&vf);
|
||||
sprintf(dest, "%f", vf);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
g_MMU->LD_VAddr(address, *(uint64_t*)&vd);
|
||||
sprintf(dest, "%f", vd);
|
||||
break;
|
||||
default:
|
||||
MessageBox(NULL, "unkown type", "", MB_OK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSymbols::ParseErrorAlert(char* message, int lineNumber)
|
||||
{
|
||||
stdstr messageFormatted = stdstr_f("%s\nLine %d", message, lineNumber);
|
||||
MessageBox(NULL, messageFormatted.c_str(), "Parse error", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
void CSymbols::Reset()
|
||||
{
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
delete m_Symbols[i];
|
||||
}
|
||||
m_Symbols.clear();
|
||||
}
|
||||
|
||||
const char* CSymbols::GetNameByAddress(uint32_t address)
|
||||
{
|
||||
int len = GetCount();
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
{
|
||||
if (m_Symbols[i]->m_Address == address)
|
||||
{
|
||||
return m_Symbols[i]->m_Name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CSymbols::SortFunction(CSymbolEntry* a, CSymbolEntry* b)
|
||||
{
|
||||
return (a->m_Address < b->m_Address);
|
||||
}
|
||||
|
||||
void CSymbols::Add(int type, uint32_t address, char* name, char* description)
|
||||
{
|
||||
if (name == NULL || strlen(name) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (description == NULL || strlen(description) == 0)
|
||||
{
|
||||
description = NULL;
|
||||
}
|
||||
|
||||
int id = m_NextSymbolId++;
|
||||
|
||||
CSymbolEntry* symbol = new CSymbolEntry(id, type, address, name, description);
|
||||
m_Symbols.push_back(symbol);
|
||||
|
||||
sort(m_Symbols.begin(), m_Symbols.end(), SortFunction);
|
||||
}
|
||||
|
||||
int CSymbols::GetCount()
|
||||
{
|
||||
return m_Symbols.size();
|
||||
}
|
||||
|
||||
CSymbolEntry* CSymbols::GetEntryByIndex(int index)
|
||||
{
|
||||
if (index < 0 || index >= GetCount())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return m_Symbols[index];
|
||||
}
|
||||
|
||||
CSymbolEntry* CSymbols::GetEntryByAddress(uint32_t address)
|
||||
{
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
if (m_Symbols[i]->m_Address == address)
|
||||
{
|
||||
return m_Symbols[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CSymbolEntry* CSymbols::GetEntryById(int id)
|
||||
{
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
if (m_Symbols[i]->m_Id == id)
|
||||
{
|
||||
return m_Symbols[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CSymbols::RemoveEntryById(int id)
|
||||
{
|
||||
for (int i = 0; i < GetCount(); i++)
|
||||
{
|
||||
if (m_Symbols[i]->m_Id == id)
|
||||
{
|
||||
delete m_Symbols[i];
|
||||
m_Symbols.erase(m_Symbols.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSymbols::EnterCriticalSection()
|
||||
{
|
||||
::EnterCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
|
||||
void CSymbols::LeaveCriticalSection()
|
||||
{
|
||||
::LeaveCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
|
||||
void CSymbols::InitializeCriticalSection()
|
||||
{
|
||||
if (!m_bInitialized)
|
||||
{
|
||||
m_bInitialized = true;
|
||||
::InitializeCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
}
|
||||
|
||||
void CSymbols::DeleteCriticalSection()
|
||||
{
|
||||
if (m_bInitialized)
|
||||
{
|
||||
m_bInitialized = false;
|
||||
::DeleteCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
class CSymbolEntry;
|
||||
|
||||
class CSymbols
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
ERR_SUCCESS,
|
||||
ERR_INVALID_TYPE,
|
||||
ERR_INVALID_ADDR,
|
||||
ERR_INVALID_NAME,
|
||||
ERR_MISSING_FIELDS,
|
||||
} ParseError;
|
||||
|
||||
typedef enum {
|
||||
TYPE_CODE,
|
||||
TYPE_DATA,
|
||||
TYPE_U8,
|
||||
TYPE_U16,
|
||||
TYPE_U32,
|
||||
TYPE_U64,
|
||||
TYPE_S8,
|
||||
TYPE_S16,
|
||||
TYPE_S32,
|
||||
TYPE_S64,
|
||||
TYPE_FLOAT,
|
||||
TYPE_DOUBLE
|
||||
} DataType;
|
||||
|
||||
static constexpr char* SymbolTypes[] = {
|
||||
"code", // 0
|
||||
"data", // 1
|
||||
"u8",
|
||||
"u16",
|
||||
"u32",
|
||||
"u64",
|
||||
"s8",
|
||||
"s16",
|
||||
"s32",
|
||||
"s64",
|
||||
"float",
|
||||
"double",
|
||||
NULL
|
||||
};
|
||||
|
||||
static constexpr int TypeSizes[] = {
|
||||
1, 1, // code data
|
||||
1, 2, 4, 8, // u8 u16 u32 u64
|
||||
1, 2, 4, 8, // s8 s16 s32 s64
|
||||
4, 8 // float double
|
||||
};
|
||||
|
||||
private:
|
||||
static bool m_bInitialized;
|
||||
static vector<CSymbolEntry*> m_Symbols;
|
||||
static int m_NextSymbolId;
|
||||
|
||||
static CFile m_SymFileHandle;
|
||||
static char* m_SymFileBuffer;
|
||||
static size_t m_SymFileSize;
|
||||
|
||||
static CRITICAL_SECTION m_CriticalSection;
|
||||
|
||||
static char* m_ParserToken;
|
||||
static size_t m_ParserTokenLength;
|
||||
static char m_ParserDelimeter;
|
||||
static char* m_SymFileParseBuffer;
|
||||
static bool m_bHaveFirstToken;
|
||||
|
||||
static void ParserInit();
|
||||
static void ParserDone();
|
||||
static void ParserFetchToken(const char* delim);
|
||||
|
||||
static bool SortFunction(CSymbolEntry* a, CSymbolEntry* b);
|
||||
|
||||
public:
|
||||
static CPath GetSymFilePath();
|
||||
static void Load();
|
||||
static void Save();
|
||||
static void ParseErrorAlert(char* message, int lineNumber);
|
||||
|
||||
static void Add(int type, uint32_t address, char* name, char* description = NULL);
|
||||
static void RemoveEntryById(int id);
|
||||
|
||||
static void Reset();
|
||||
|
||||
static const char* GetTypeName(int typeNumber);
|
||||
static int GetTypeNumber(char* typeName);
|
||||
static void GetValueString(char* str, CSymbolEntry* lpSymbol);
|
||||
|
||||
static int GetCount();
|
||||
|
||||
static CSymbolEntry* GetEntryById(int id);
|
||||
static CSymbolEntry* GetEntryByIndex(int id);
|
||||
static CSymbolEntry* GetEntryByAddress(uint32_t address);
|
||||
|
||||
static const char* GetNameByAddress(uint32_t address);
|
||||
|
||||
static void InitializeCriticalSection();
|
||||
static void DeleteCriticalSection();
|
||||
static void EnterCriticalSection();
|
||||
static void LeaveCriticalSection();
|
||||
|
||||
};
|
||||
|
||||
class CSymbolEntry {
|
||||
public:
|
||||
int m_Id;
|
||||
int m_Type;
|
||||
uint32_t m_Address;
|
||||
char* m_Name;
|
||||
char* m_Description;
|
||||
|
||||
CSymbolEntry(int id, int type, uint32_t address, char* name, char* description) :
|
||||
m_Name(NULL),
|
||||
m_Description(NULL),
|
||||
m_Id(id),
|
||||
m_Type(type),
|
||||
m_Address(address)
|
||||
{
|
||||
if (name != NULL)
|
||||
{
|
||||
size_t nameLen = strlen(name);
|
||||
m_Name = (char*)malloc(nameLen + 1);
|
||||
strcpy(m_Name, name);
|
||||
}
|
||||
|
||||
if (description != NULL)
|
||||
{
|
||||
size_t descLen = strlen(description);
|
||||
m_Description = (char*)malloc(descLen + 1);
|
||||
strcpy(m_Description, description);
|
||||
}
|
||||
}
|
||||
|
||||
~CSymbolEntry()
|
||||
{
|
||||
if (m_Name != NULL)
|
||||
{
|
||||
free(m_Name);
|
||||
}
|
||||
if (m_Description != NULL)
|
||||
{
|
||||
free(m_Description);
|
||||
}
|
||||
}
|
||||
|
||||
const char* TypeName()
|
||||
{
|
||||
return CSymbols::SymbolTypes[m_Type];
|
||||
}
|
||||
|
||||
int TypeSize()
|
||||
{
|
||||
return CSymbols::TypeSizes[m_Type];
|
||||
}
|
||||
};
|
|
@ -14,34 +14,82 @@ class CDumpMemory;
|
|||
class CDebugMemoryView;
|
||||
class CDebugMemorySearch;
|
||||
class CDebugTlb;
|
||||
class CDebugCommandsView;
|
||||
class CDebugScripts;
|
||||
class CDebugSymbols;
|
||||
class CDebugDMALogView;
|
||||
class CDebugStackView;
|
||||
class CDebugStackTrace;
|
||||
|
||||
class CDMALog;
|
||||
class CBreakpoints;
|
||||
class CScriptSystem;
|
||||
|
||||
__interface CDebugger
|
||||
{
|
||||
virtual void TLBChanged ( void ) = 0;
|
||||
virtual bool CPUStepStarted ( void ) = 0;
|
||||
virtual void CPUStep ( void ) = 0;
|
||||
virtual void FrameDrawn ( void ) = 0;
|
||||
};
|
||||
|
||||
class CDebuggerUI :
|
||||
public CDebugger
|
||||
{
|
||||
CDumpMemory * m_MemoryDump;
|
||||
CDebugMemoryView * m_MemoryView;
|
||||
CDebugMemorySearch * m_MemorySearch;
|
||||
CDebugTlb * m_DebugTLB;
|
||||
CDumpMemory * m_MemoryDump;
|
||||
CDebugMemoryView * m_MemoryView;
|
||||
CDebugMemorySearch * m_MemorySearch;
|
||||
CDebugTlb * m_DebugTLB;
|
||||
CDebugCommandsView * m_CommandsView;
|
||||
CDebugScripts * m_Scripts;
|
||||
CDebugSymbols * m_Symbols;
|
||||
CDebugDMALogView * m_DMALogView;
|
||||
CDebugStackTrace * m_StackTraceView;
|
||||
CDebugStackView * m_StackView;
|
||||
|
||||
CBreakpoints * m_Breakpoints;
|
||||
CScriptSystem * m_ScriptSystem;
|
||||
CDMALog * m_DMALog;
|
||||
vector<uint32_t> * m_StackTrace;
|
||||
|
||||
void BreakpointHit(void);
|
||||
|
||||
protected:
|
||||
CDebuggerUI();
|
||||
virtual ~CDebuggerUI();
|
||||
|
||||
void TLBChanged ( void );
|
||||
|
||||
bool CPUStepStarted ( void );
|
||||
void CPUStep ( void );
|
||||
void FrameDrawn ( void );
|
||||
|
||||
public:
|
||||
void Debug_Reset ( void );
|
||||
void Debug_ShowMemoryDump ( void );
|
||||
void Debug_ShowMemoryWindow ( void );
|
||||
void Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr );
|
||||
void Debug_ShowMemorySearch ( void );
|
||||
void Debug_ShowTLBWindow ( void );
|
||||
void Debug_RefreshTLBWindow ( void );
|
||||
void Debug_Reset ( void );
|
||||
void Debug_ShowMemoryDump ( void );
|
||||
void Debug_ShowMemoryWindow ( void );
|
||||
void Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr );
|
||||
void Debug_ShowMemorySearch ( void );
|
||||
void Debug_ShowTLBWindow ( void );
|
||||
void Debug_RefreshTLBWindow ( void );
|
||||
void Debug_ShowCommandsWindow ( void );
|
||||
void Debug_ShowCommandsLocation ( uint32_t address, bool top );
|
||||
void Debug_ShowScriptsWindow ( void );
|
||||
void Debug_LogScriptsWindow ( const char* text );
|
||||
void Debug_ClearScriptsWindow ( void );
|
||||
void Debug_RefreshScriptsWindow ( void );
|
||||
void Debug_RefreshSymbolsWindow ( void );
|
||||
void Debug_ShowSymbolsWindow ( void );
|
||||
void Debug_ShowStackTrace ( void );
|
||||
void Debug_ShowStackWindow ( void );
|
||||
void Debug_RefreshStackWindow ( void );
|
||||
void Debug_ShowDMALogWindow ( void );
|
||||
|
||||
static void GameReset ( CDebuggerUI * _this );
|
||||
CBreakpoints* Breakpoints();
|
||||
CDebugSymbols* Symbols();
|
||||
CScriptSystem* ScriptSystem();
|
||||
CDebugScripts* ScriptConsole();
|
||||
CDMALog* DMALog();
|
||||
vector<uint32_t> * StackTrace();
|
||||
|
||||
static void GameReset ( CDebuggerUI * _this );
|
||||
};
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
</ImportGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
@ -42,19 +48,53 @@
|
|||
<Manifest Condition="'$(PlatformToolset)'!='v90'">
|
||||
<EnableDPIAwareness>true</EnableDPIAwareness>
|
||||
</Manifest>
|
||||
<ClCompile>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<OmitFramePointers Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</OmitFramePointers>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<FavorSizeOrSpeed Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Size</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<OmitFramePointers Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</OmitFramePointers>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-StackView.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Assembler.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="Multilanguage\LanguageSelector.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-AddSymbol.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-MemoryDump.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-MemorySearch.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-RegisterTabs.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-TLB.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-ViewMemory.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Breakpoints.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\DMALog.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\ScriptSystem.cpp" />
|
||||
<ClCompile Include="Plugins\PluginList.cpp" />
|
||||
<ClCompile Include="Settings\GuiSettings.cpp" />
|
||||
<ClCompile Include="Settings\NotificationSettings.cpp" />
|
||||
<ClCompile Include="Settings\UISettings.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-Commands.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-Scripts.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-Symbols.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Symbols.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-AddBreakpoint.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\ScriptInstance.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\ScriptHook.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-DMALogView.cpp" />
|
||||
<ClCompile Include="N64System\Debugger\Debugger-StackTrace.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
@ -85,6 +125,22 @@
|
|||
<ClCompile Include="UserInterface\WTLControls\PartialGroupBox.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-StackView.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-AddSymbol.h" />
|
||||
<ClInclude Include="N64System\Debugger\Assembler.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-RegisterTabs.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-StackTrace.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-DMALogView.h" />
|
||||
<ClInclude Include="N64System\Debugger\DMALog.h" />
|
||||
<ClInclude Include="N64System\Debugger\OpInfo.h" />
|
||||
<ClInclude Include="N64System\Debugger\ScriptHook.h" />
|
||||
<ClInclude Include="N64System\Debugger\ScriptInstance.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-AddBreakpoint.h" />
|
||||
<ClInclude Include="N64System\Debugger\Breakpoints.h" />
|
||||
<ClInclude Include="N64System\Debugger\Symbols.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-Symbols.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-Scripts.h" />
|
||||
<ClInclude Include="N64System\Debugger\Debugger-Commands.h" />
|
||||
<ClInclude Include="Multilanguage\LanguageSelector.h" />
|
||||
<ClInclude Include="N64System.h" />
|
||||
<ClInclude Include="N64System\Debugger\DebugDialog.h" />
|
||||
|
@ -94,6 +150,7 @@
|
|||
<ClInclude Include="N64System\Debugger\Debugger-ViewMemory.h" />
|
||||
<ClInclude Include="N64System\Debugger\debugger.h" />
|
||||
<ClInclude Include="N64System\Debugger\DebuggerUI.h" />
|
||||
<ClInclude Include="N64System\Debugger\ScriptSystem.h" />
|
||||
<ClInclude Include="Settings\GuiSettings.h" />
|
||||
<ClInclude Include="Settings\NotificationSettings.h" />
|
||||
<ClInclude Include="Settings\UISettings.h" />
|
||||
|
@ -129,6 +186,7 @@
|
|||
<ClInclude Include="UserInterface\WTLControls\ModifiedEditBox.h" />
|
||||
<ClInclude Include="UserInterface\WTLControls\numberctrl.h" />
|
||||
<ClInclude Include="UserInterface\WTLControls\PartialGroupBox.h" />
|
||||
<ClInclude Include="UserInterface\WTLControls\TooltipDialog.h" />
|
||||
<ClInclude Include="WTLApp.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -136,6 +194,9 @@
|
|||
<Project>{3326e128-33af-422c-bb7c-67cc6b915610}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdParty\duktape\duktape.vcxproj">
|
||||
<Project>{e8d9a652-a354-4374-b6c5-a51ee62749fd}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\3rdParty\zlib\zlib.vcxproj">
|
||||
<Project>{731bd205-2826-4631-b7af-117658e88dbc}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
|
@ -151,8 +212,11 @@
|
|||
<ItemGroup>
|
||||
<None Include="res\divider.cur" />
|
||||
<None Include="res\hand.cur" />
|
||||
<None Include="UserInterface\API.js" />
|
||||
<None Include="UserInterface\icons\bin00001.bin" />
|
||||
<None Include="UserInterface\Icons\divider.cur" />
|
||||
<None Include="UserInterface\Icons\hand.cur" />
|
||||
<None Include="UserInterface\icons\javascri.bin" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\ListItems.bmp" />
|
||||
|
@ -169,4 +233,9 @@
|
|||
<ItemGroup>
|
||||
<Manifest Include="Project64.exe.manifest" />
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties RESOURCE_FILE="UserInterface\UIResources.rc" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
|
@ -162,11 +162,59 @@
|
|||
<ClCompile Include="Settings\UISettings.cpp">
|
||||
<Filter>Source Files\Settings Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UserInterface\SupportWindow.cpp">
|
||||
<Filter>Source Files\User Interface Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UserInterface\SupportEnterCode.cpp">
|
||||
<Filter>Source Files\User Interface Source</Filter>
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UserInterface\SupportWindow.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-Commands.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-Scripts.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\ScriptSystem.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-Symbols.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Breakpoints.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-AddBreakpoint.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Symbols.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\ScriptHook.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\ScriptInstance.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-StackTrace.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Assembler.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\DMALog.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-AddSymbol.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-DMALogView.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-RegisterTabs.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Debugger\Debugger-StackView.cpp">
|
||||
<Filter>Source Files\User Interface Source\Debugger Source</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -299,11 +347,65 @@
|
|||
<ClInclude Include="Settings\UISettings.h">
|
||||
<Filter>Header Files\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UserInterface\SupportWindow.h">
|
||||
<Filter>Header Files\User Interface Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UserInterface\SupportEnterCode.h">
|
||||
<Filter>Header Files\User Interface Headers</Filter>
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UserInterface\SupportWindow.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-Commands.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-Scripts.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\ScriptSystem.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-Symbols.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Breakpoints.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Symbols.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-AddBreakpoint.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\ScriptHook.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\ScriptInstance.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-StackTrace.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Assembler.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-AddSymbol.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\DMALog.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-DMALogView.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-RegisterTabs.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\Debugger-StackView.h">
|
||||
<Filter>Header Files\N64 System Headers\Debugger Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Debugger\OpInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UserInterface\WTLControls\TooltipDialog.h">
|
||||
<Filter>Header Files\User Interface Headers\WTL Controls Headers</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -319,6 +421,13 @@
|
|||
<None Include="UserInterface\Icons\hand.cur">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="UserInterface\icons\bin00001.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="UserInterface\icons\javascri.bin">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="UserInterface\API.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="res\ListItems.bmp">
|
||||
|
|
|
@ -0,0 +1,705 @@
|
|||
Number.prototype.hex = function(len)
|
||||
{
|
||||
len = (len || 8);
|
||||
var str = (this >>> 0).toString(16).toUpperCase()
|
||||
while (str.length < len)
|
||||
{
|
||||
str = "0" + str
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
const u8 = 'u8', u16 = 'u16', u32 = 'u32',
|
||||
s8 = 's8', s16 = 's16', s32 = 's32',
|
||||
float = 'float', double = 'double'
|
||||
|
||||
const _typeSizes = {
|
||||
u8: 1, u16: 2, u32: 4,
|
||||
s8: 1, s16: 2, s32: 4,
|
||||
float: 4, double: 8
|
||||
}
|
||||
|
||||
const _regNums = {
|
||||
r0: 0, at: 1, v0: 2, v1: 3,
|
||||
a0: 4, a1: 5, a2: 6, a3: 7,
|
||||
t0: 8, t1: 9, t2: 10, t3: 11,
|
||||
t4: 12, t5: 13, t6: 14, t7: 15,
|
||||
s0: 16, s1: 17, s2: 18, s3: 19,
|
||||
s4: 20, s5: 21, s6: 22, s7: 23,
|
||||
t8: 24, t9: 25, k0: 26, k1: 27,
|
||||
gp: 28, sp: 29, fp: 30, ra: 31,
|
||||
|
||||
f0: 0, f1: 1, f2: 2, f3: 3,
|
||||
f4: 4, f5: 5, f6: 6, f7: 7,
|
||||
f8: 8, f9: 9, f10: 10, f11: 11,
|
||||
f12: 12, f13: 13, f14: 14, f15: 15,
|
||||
f16: 16, f17: 17, f18: 18, f19: 19,
|
||||
f20: 20, f21: 21, f22: 22, f23: 23,
|
||||
f24: 24, f25: 25, f26: 26, f27: 27,
|
||||
f28: 28, f29: 29, f30: 30, f31: 31
|
||||
}
|
||||
|
||||
function AddressRange(start, end)
|
||||
{
|
||||
this.start = start >>> 0
|
||||
this.end = end >>> 0
|
||||
Object.freeze(this)
|
||||
}
|
||||
|
||||
const ADDR_ANY = new AddressRange(0x00000000, 0x100000000)
|
||||
const ADDR_ANY_KUSEG = new AddressRange(0x00000000, 0x80000000)
|
||||
const ADDR_ANY_KSEG0 = new AddressRange(0x80000000, 0xA0000000)
|
||||
const ADDR_ANY_KSEG1 = new AddressRange(0xA0000000, 0xC0000000)
|
||||
const ADDR_ANY_KSEG2 = new AddressRange(0xC0000000, 0x100000000)
|
||||
const ADDR_ANY_RDRAM = new AddressRange(0x80000000, 0x80800000)
|
||||
const ADDR_ANY_RDRAM_UNC = new AddressRange(0xA0000000, 0xA0800000)
|
||||
const ADDR_ANY_CART_ROM = new AddressRange(0x90000000, 0x96000000)
|
||||
const ADDR_ANY_CART_ROM_UNC = new AddressRange(0xB0000000, 0xB6000000)
|
||||
|
||||
const system = {
|
||||
pause: function()
|
||||
{
|
||||
_native.pause()
|
||||
},
|
||||
resume: function()
|
||||
{
|
||||
|
||||
},
|
||||
reset: function()
|
||||
{
|
||||
|
||||
},
|
||||
hardreset: function()
|
||||
{
|
||||
|
||||
},
|
||||
savestate: function()
|
||||
{
|
||||
|
||||
},
|
||||
loadstate: function()
|
||||
{
|
||||
|
||||
},
|
||||
setsaveslot: function(slot)
|
||||
{
|
||||
|
||||
},
|
||||
getsaveslot: function()
|
||||
{
|
||||
|
||||
},
|
||||
generatebitmap: function()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const debug = {
|
||||
showmemory: function(address)
|
||||
{
|
||||
|
||||
},
|
||||
showcommands: function(address)
|
||||
{
|
||||
_native.showCommands(address)
|
||||
},
|
||||
breakhere: function()
|
||||
{
|
||||
debug.showcommands(gpr.pc)
|
||||
system.pause()
|
||||
},
|
||||
disasm: function()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const console = {
|
||||
print: function(data)
|
||||
{
|
||||
_native.consolePrint(data);
|
||||
},
|
||||
log: function()
|
||||
{
|
||||
for(var i in arguments)
|
||||
{
|
||||
console.print(arguments[i].toString())
|
||||
if(i < arguments.length - 1)
|
||||
{
|
||||
console.print(" ")
|
||||
}
|
||||
}
|
||||
console.print("\r\n")
|
||||
},
|
||||
clear: function()
|
||||
{
|
||||
_native.consoleClear();
|
||||
}
|
||||
}
|
||||
|
||||
const screen = {
|
||||
print: function(x, y, text)
|
||||
{
|
||||
_native.screenPrint(x, y, text)
|
||||
}
|
||||
}
|
||||
|
||||
const events = (function()
|
||||
{
|
||||
var callbacks = {};
|
||||
var nextCallbackId = 0;
|
||||
return {
|
||||
on: function(hook, callback, param, param2, bOnce)
|
||||
{
|
||||
this._stashCallback(callback)
|
||||
return _native.addCallback(hook, callback, param, param2, bOnce)
|
||||
},
|
||||
onexec: function(addr, callback)
|
||||
{
|
||||
var param = 0;
|
||||
var param2 = 0;
|
||||
|
||||
if (typeof (addr) == "object")
|
||||
{
|
||||
param = addr.start;
|
||||
param2 = addr.end;
|
||||
}
|
||||
else if (typeof (addr) == "number")
|
||||
{
|
||||
param = addr;
|
||||
}
|
||||
|
||||
return events.on('exec', callback, param, param2)
|
||||
},
|
||||
onread: function(addr, callback)
|
||||
{
|
||||
var param = 0;
|
||||
var param2 = 0;
|
||||
|
||||
if (typeof (addr) == "object")
|
||||
{
|
||||
param = addr.start;
|
||||
param2 = addr.end;
|
||||
}
|
||||
else if (typeof (addr) == "number")
|
||||
{
|
||||
param = addr;
|
||||
}
|
||||
|
||||
return events.on('read', callback, param, param2)
|
||||
},
|
||||
onwrite: function(addr, callback)
|
||||
{
|
||||
var param = 0;
|
||||
var param2 = 0;
|
||||
|
||||
if (typeof (addr) == "object")
|
||||
{
|
||||
param = addr.start;
|
||||
param2 = addr.end;
|
||||
}
|
||||
else if (typeof (addr) == "number")
|
||||
{
|
||||
param = addr;
|
||||
}
|
||||
|
||||
return events.on('write', callback, param, param2)
|
||||
},
|
||||
ondraw: function(callback)
|
||||
{
|
||||
return events.on('draw', callback, 0)
|
||||
},
|
||||
remove: function(callbackId)
|
||||
{
|
||||
_native.removeCallback(callbackId)
|
||||
},
|
||||
clear: function(){},
|
||||
_stashCallback: function(callback)
|
||||
{
|
||||
callbacks[nextCallbackId] = callback
|
||||
return nextCallbackId++;
|
||||
},
|
||||
_unstashCallback: function()
|
||||
{
|
||||
|
||||
},
|
||||
}
|
||||
})();
|
||||
|
||||
const gpr = new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
if (typeof prop == 'number' && prop < 32)
|
||||
{
|
||||
return _native.getGPRVal(prop)
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
return _native.getGPRVal(_regNums[prop])
|
||||
}
|
||||
switch(prop)
|
||||
{
|
||||
case 'pc': return _native.getPCVal(); break;
|
||||
case 'hi': return _native.getHIVal(false); break;
|
||||
case 'lo': return _native.getLOVal(false); break;
|
||||
}
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
if (typeof prop == 'number' && prop < 32)
|
||||
{
|
||||
_native.setGPRVal(prop, false, val)
|
||||
return
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
_native.setGPRVal(_regNums[prop], false, val)
|
||||
return
|
||||
}
|
||||
switch(prop)
|
||||
{
|
||||
case 'pc': _native.setPCVal(val); break;
|
||||
case 'hi': _native.setHIVal(false, val); break;
|
||||
case 'lo': _native.setLOVal(false, val); break;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const ugpr = new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
if (typeof prop == 'number' && prop < 32)
|
||||
{
|
||||
return _native.getGPRVal(prop, true)
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
return _native.getGPRVal(_regNums[prop], true)
|
||||
}
|
||||
switch(prop)
|
||||
{
|
||||
case 'hi': return _native.getHIVal(true); break;
|
||||
case 'lo': return _native.getLOVal(true); break;
|
||||
}
|
||||
},
|
||||
set: function (obj, prop, val)
|
||||
{
|
||||
if (typeof prop == 'number' && prop < 32)
|
||||
{
|
||||
_native.setGPRVal(prop, true, val)
|
||||
return
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
_native.setGPRVal(_regNums[prop], true, val)
|
||||
return
|
||||
}
|
||||
switch(prop)
|
||||
{
|
||||
case 'hi': _native.setHIVal(true, val); break;
|
||||
case 'lo': _native.setLOVal(true, val); break;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fpr = new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
if (typeof prop == 'number')
|
||||
{
|
||||
return _native.getFPRVal(prop)
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
return _native.getFPRVal(_regNums[prop])
|
||||
}
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
if (typeof prop == 'number' && prop < 32)
|
||||
{
|
||||
_native.setFPRVal(prop, false, val)
|
||||
return
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
_native.setFPRVal(_regNums[prop], false, val)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const dfpr = new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
if (typeof prop == 'number')
|
||||
{
|
||||
return _native.getFPRVal(prop, true)
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
return _native.getFPRVal(_regNums[prop], true)
|
||||
}
|
||||
},
|
||||
set: function (obj, prop, val)
|
||||
{
|
||||
if (typeof prop == 'number' && prop < 32)
|
||||
{
|
||||
_native.setFPRVal(prop, true, val)
|
||||
return
|
||||
}
|
||||
if (prop in _regNums)
|
||||
{
|
||||
_native.setFPRVal(_regNums[prop], true, val)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const rom = {
|
||||
u8: new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMInt(prop, 8, false)
|
||||
}
|
||||
}),
|
||||
u16: new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMInt(prop, 16, false)
|
||||
}
|
||||
}),
|
||||
u32: new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMInt(prop, 32, false)
|
||||
}
|
||||
}),
|
||||
s8: new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMInt(prop, 8, true)
|
||||
}
|
||||
}),
|
||||
s16: new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMInt(prop, 16, true)
|
||||
}
|
||||
}),
|
||||
s32: new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMInt(prop, 32, true)
|
||||
}
|
||||
}),
|
||||
'float': new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMFloat(prop)
|
||||
},
|
||||
set: function (obj, prop, val)
|
||||
{
|
||||
_native.setROMFloat(prop, val)
|
||||
}
|
||||
}),
|
||||
'double': new Proxy({},
|
||||
{
|
||||
get: function (obj, prop)
|
||||
{
|
||||
return _native.getROMFloat(prop, true)
|
||||
},
|
||||
set: function (obj, prop, val)
|
||||
{
|
||||
_native.setROMFloat(prop, val, true)
|
||||
}
|
||||
}),
|
||||
getblock: function (address, size)
|
||||
{
|
||||
return _native.getROMBlock(address, size)
|
||||
},
|
||||
getstring: function(address, maxLen)
|
||||
{
|
||||
return _native.getROMString(address, maxLen)
|
||||
},
|
||||
}
|
||||
|
||||
const mem = {
|
||||
u8: new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMInt(prop, 8, false)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMInt(prop, 8, val)
|
||||
}
|
||||
}),
|
||||
u16: new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMInt(prop, 16, false)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMInt(prop, 16, val)
|
||||
}
|
||||
}),
|
||||
u32: new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMInt(prop, 32, false)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMInt(prop, 32, val)
|
||||
}
|
||||
}),
|
||||
s8: new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMInt(prop, 8, true)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMInt(prop, 8, val)
|
||||
}
|
||||
}),
|
||||
s16: new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMInt(prop, 16, true)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMInt(prop, 16, val)
|
||||
}
|
||||
}),
|
||||
s32: new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMInt(prop, 32, true)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMInt(prop, 32, val)
|
||||
}
|
||||
}),
|
||||
'float': new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMFloat(prop)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMFloat(prop, val)
|
||||
}
|
||||
}),
|
||||
'double': new Proxy({},
|
||||
{
|
||||
get: function(obj, prop)
|
||||
{
|
||||
return _native.getRDRAMFloat(prop, true)
|
||||
},
|
||||
set: function(obj, prop, val)
|
||||
{
|
||||
_native.setRDRAMFloat(prop, val, true)
|
||||
}
|
||||
}),
|
||||
getblock: function(address, size)
|
||||
{
|
||||
return _native.getRDRAMBlock(address, size)
|
||||
},
|
||||
getstring: function(address, maxLen)
|
||||
{
|
||||
return _native.getRDRAMString(address, maxLen)
|
||||
},
|
||||
bindvar: function(obj, baseAddr, name, type)
|
||||
{
|
||||
Object.defineProperty(obj, name,
|
||||
{
|
||||
get: function()
|
||||
{
|
||||
return mem[type][baseAddr]
|
||||
},
|
||||
set: function(val)
|
||||
{
|
||||
mem[type][baseAddr] = val
|
||||
}
|
||||
})
|
||||
return obj
|
||||
},
|
||||
bindvars: function(obj, list)
|
||||
{
|
||||
for(var i = 0; i < list.length; i++)
|
||||
{
|
||||
mem.bindvar(obj, list[i][0], list[i][1], list[i][2])
|
||||
}
|
||||
return obj
|
||||
},
|
||||
bindstruct: function(obj, baseAddr, props)
|
||||
{
|
||||
for (var name in props)
|
||||
{
|
||||
var type = props[name]
|
||||
var size = _typeSizes[type]
|
||||
mem.bindvar(obj, baseAddr, name, type)
|
||||
baseAddr += size
|
||||
}
|
||||
return obj
|
||||
},
|
||||
typedef: function(props, proto)
|
||||
{
|
||||
var size = 0
|
||||
for (var name in props)
|
||||
{
|
||||
size += _typeSizes[props[name]]
|
||||
}
|
||||
var StructClass = function(baseAddr)
|
||||
{
|
||||
mem.bindstruct(this, baseAddr, props)
|
||||
}
|
||||
StructClass.sizeof = function()
|
||||
{
|
||||
return size
|
||||
}
|
||||
/*if(proto)
|
||||
{
|
||||
StructClass.prototype = proto
|
||||
}*/
|
||||
return StructClass
|
||||
}
|
||||
}
|
||||
|
||||
function alert(text, caption){
|
||||
caption = caption || ""
|
||||
_native.msgBox(text, caption)
|
||||
}
|
||||
|
||||
|
||||
function Socket(fd)
|
||||
{
|
||||
var connected = false;
|
||||
|
||||
var _fd;
|
||||
|
||||
if(fd)
|
||||
{
|
||||
// assume this was constructed from Server
|
||||
_fd = fd;
|
||||
connected = true;
|
||||
} else {
|
||||
_fd = _native.sockCreate();
|
||||
}
|
||||
|
||||
var _ondata = function(data){}
|
||||
var _onclose = function(){}
|
||||
var _onconnect = function(){}
|
||||
|
||||
var _onconnect_base = function(){
|
||||
connected = 1;
|
||||
_onconnect();
|
||||
}
|
||||
|
||||
var _bufferSize = 2048
|
||||
|
||||
this.write = function(data, callback)
|
||||
{
|
||||
_native.write(_fd, data, callback)
|
||||
}
|
||||
|
||||
this.close = function()
|
||||
{
|
||||
_native.close(_fd)
|
||||
}
|
||||
|
||||
this.connect = function(settings, callback)
|
||||
{
|
||||
if(!connected)
|
||||
{
|
||||
_onconnect = callback;
|
||||
_native.sockConnect(_fd, settings.host || '127.0.0.1', settings.port || 80, _onconnect_base);
|
||||
}
|
||||
}
|
||||
|
||||
var _read = function(data)
|
||||
{
|
||||
if(data == null)
|
||||
{
|
||||
connected = false;
|
||||
_onclose();
|
||||
return;
|
||||
}
|
||||
_native.read(_fd, _bufferSize, _read)
|
||||
_ondata(data)
|
||||
}
|
||||
|
||||
this.on = function(eventType, callback)
|
||||
{
|
||||
switch(eventType)
|
||||
{
|
||||
case 'data':
|
||||
_ondata = callback
|
||||
_native.read(_fd, _bufferSize, _read)
|
||||
break;
|
||||
case 'close':
|
||||
// note: does nothing if ondata not set
|
||||
_onclose = callback
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Server(settings)
|
||||
{
|
||||
var _this = this;
|
||||
var _fd = _native.sockCreate()
|
||||
|
||||
var _onconnection = function(socket){}
|
||||
|
||||
if(settings.port)
|
||||
{
|
||||
_native.sockListen(_fd, settings.port || 80)
|
||||
}
|
||||
|
||||
// Intermediate callback
|
||||
// convert clientFd to Socket and accept next client
|
||||
var _acceptClient = function(clientFd)
|
||||
{
|
||||
_onconnection(new Socket(clientFd))
|
||||
_native.sockAccept(_fd, _acceptClient)
|
||||
}
|
||||
|
||||
this.listen = function(port)
|
||||
{
|
||||
_native.sockListen(_fd, port)
|
||||
}
|
||||
|
||||
this.on = function(eventType, callback)
|
||||
{
|
||||
switch(eventType)
|
||||
{
|
||||
case 'connection':
|
||||
_onconnection = callback
|
||||
_native.sockAccept(_fd, _acceptClient)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,9 @@
|
|||
#include "RomInformationClass.h"
|
||||
#include <Project64-core/N64System/N64DiskClass.h>
|
||||
|
||||
#include <Project64/N64System/Debugger/Breakpoints.h>
|
||||
#include <Project64/N64System/Debugger/ScriptSystem.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
|
@ -51,7 +54,7 @@ CMainMenu::CMainMenu(CMainGui * hMainWindow) :
|
|||
m_ChangeSettingList.push_back(Debugger_AppLogFlush);
|
||||
m_ChangeSettingList.push_back(Game_CurrentSaveState);
|
||||
m_ChangeSettingList.push_back(Setting_CurrentLanguage);
|
||||
|
||||
|
||||
for (UISettingList::const_iterator iter = m_ChangeUISettingList.begin(); iter != m_ChangeUISettingList.end(); iter++)
|
||||
{
|
||||
g_Settings->RegisterChangeCB((SettingID)(FirstUISettings + *iter), this, (CSettings::SettingChangedFunc)SettingsChanged);
|
||||
|
@ -467,6 +470,7 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
|
|||
case ID_DEBUG_DISABLE_GAMEFIX:
|
||||
g_Settings->SaveBool(Debugger_DisableGameFixes, !g_Settings->LoadBool(Debugger_DisableGameFixes));
|
||||
break;
|
||||
|
||||
case ID_DEBUGGER_TRACE_MD5: SetTraceModuleSetttings(Debugger_TraceMD5); break;
|
||||
case ID_DEBUGGER_TRACE_SETTINGS: SetTraceModuleSetttings(Debugger_TraceSettings); break;
|
||||
case ID_DEBUGGER_TRACE_UNKNOWN: SetTraceModuleSetttings(Debugger_TraceUnknown); break;
|
||||
|
@ -503,7 +507,13 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
|
|||
case ID_DEBUGGER_INTERRUPT_VI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_VI); break;
|
||||
case ID_DEBUGGER_INTERRUPT_PI: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_PI); break;
|
||||
case ID_DEBUGGER_INTERRUPT_DP: g_BaseSystem->ExternalEvent(SysEvent_Interrupt_DP); break;
|
||||
case ID_CURRENT_SAVE_DEFAULT:
|
||||
case ID_DEBUGGER_BREAKPOINTS: m_Gui->Debug_ShowCommandsWindow(); break;
|
||||
case ID_DEBUGGER_SCRIPTS: m_Gui->Debug_ShowScriptsWindow(); break;
|
||||
case ID_DEBUGGER_SYMBOLS: m_Gui->Debug_ShowSymbolsWindow(); break;
|
||||
case ID_DEBUGGER_DMALOG: m_Gui->Debug_ShowDMALogWindow(); break;
|
||||
case ID_DEBUGGER_STACKTRACE: m_Gui->Debug_ShowStackTrace(); break;
|
||||
case ID_DEBUGGER_STACKVIEW: m_Gui->Debug_ShowStackWindow(); break;
|
||||
case ID_CURRENT_SAVE_DEFAULT:
|
||||
g_Notify->DisplayMessage(3, stdstr_f(GS(MENU_SLOT_SAVE), GetSaveSlotString(MenuID - ID_CURRENT_SAVE_DEFAULT).c_str()).c_str());
|
||||
g_Settings->SaveDword(Game_CurrentSaveState, (DWORD)(MenuID - ID_CURRENT_SAVE_DEFAULT));
|
||||
break;
|
||||
|
@ -994,12 +1004,15 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
|
|||
|
||||
/* Debug - R4300i
|
||||
*******************/
|
||||
Item.Reset(ID_DEBUGGER_LOGOPTIONS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Commands...");
|
||||
Item.SetItemEnabled(false);
|
||||
DebugR4300Menu.push_back(Item);
|
||||
Item.Reset(ID_DEBUGGER_R4300REGISTERS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Registers...");
|
||||
Item.SetItemEnabled(true);
|
||||
|
||||
//ID_DEBUGGER_LOGOPTIONS
|
||||
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Commands...");
|
||||
Item.SetItemEnabled(CPURunning);
|
||||
|
||||
DebugR4300Menu.push_back(Item);
|
||||
//Item.Reset(ID_DEBUGGER_R4300REGISTERS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Registers...");
|
||||
//Item.SetItemEnabled(true);
|
||||
// DebugR4300Menu.push_back(Item);
|
||||
Item.Reset(ID_DEBUG_DISABLE_GAMEFIX, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Disable Game Fixes");
|
||||
if (g_Settings->LoadBool(Debugger_DisableGameFixes))
|
||||
{
|
||||
|
@ -1112,9 +1125,39 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
|
|||
/* Debugger Main Menu
|
||||
****************/
|
||||
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Breakpoint...");
|
||||
Item.SetItemEnabled(CPURunning);
|
||||
//Item.SetItemEnabled(CPURunning);
|
||||
DebugMenu.push_back(Item);
|
||||
DebugMenu.push_back(MENU_ITEM(SPLITER));
|
||||
|
||||
/* Debugger - Symbols
|
||||
****************/
|
||||
Item.Reset(ID_DEBUGGER_SYMBOLS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Symbols...");
|
||||
//Item.SetItemEnabled(CPURunning);
|
||||
DebugMenu.push_back(Item);
|
||||
|
||||
/* Debug - Scripts
|
||||
*******************/
|
||||
Item.Reset(ID_DEBUGGER_SCRIPTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Scripts...");
|
||||
//Item.SetItemEnabled(CPURunning);
|
||||
DebugMenu.push_back(Item);
|
||||
|
||||
/* Debug - DMA Log
|
||||
*******************/
|
||||
Item.Reset(ID_DEBUGGER_DMALOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DMA Log...");
|
||||
//Item.SetItemEnabled(CPURunning);
|
||||
DebugMenu.push_back(Item);
|
||||
|
||||
/* Debug - Stack
|
||||
*******************/
|
||||
Item.Reset(ID_DEBUGGER_STACKVIEW, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack...");
|
||||
DebugMenu.push_back(Item);
|
||||
|
||||
/* Debug - Stack Trace
|
||||
*******************/
|
||||
Item.Reset(ID_DEBUGGER_STACKTRACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack Trace...");
|
||||
Item.SetItemEnabled(false);
|
||||
DebugMenu.push_back(Item);
|
||||
|
||||
DebugMenu.push_back(MENU_ITEM(SPLITER));
|
||||
|
||||
/* Debug - RSP
|
||||
*******************/
|
||||
|
|
|
@ -39,7 +39,8 @@ enum MainMenuID
|
|||
ID_DEBUGGER_LOGOPTIONS, ID_DEBUGGER_GENERATELOG, ID_DEBUGGER_DUMPMEMORY, ID_DEBUGGER_SEARCHMEMORY,
|
||||
ID_DEBUGGER_TLBENTRIES, ID_DEBUGGER_BREAKPOINTS, ID_DEBUGGER_MEMORY, ID_DEBUGGER_R4300REGISTERS,
|
||||
ID_DEBUGGER_INTERRUPT_SP, ID_DEBUGGER_INTERRUPT_SI, ID_DEBUGGER_INTERRUPT_AI, ID_DEBUGGER_INTERRUPT_VI,
|
||||
ID_DEBUGGER_INTERRUPT_PI, ID_DEBUGGER_INTERRUPT_DP,
|
||||
ID_DEBUGGER_INTERRUPT_PI, ID_DEBUGGER_INTERRUPT_DP, ID_DEBUGGER_SCRIPTS, ID_DEBUGGER_SYMBOLS, ID_DEBUGGER_DMALOG,
|
||||
ID_DEBUGGER_STACKTRACE, ID_DEBUGGER_STACKVIEW,
|
||||
|
||||
// App logging
|
||||
ID_DEBUGGER_APPLOG_FLUSH, ID_DEBUGGER_TRACE_MD5, ID_DEBUGGER_TRACE_SETTINGS, ID_DEBUGGER_TRACE_UNKNOWN, ID_DEBUGGER_TRACE_APPINIT,
|
||||
|
|
|
@ -32,6 +32,7 @@ CAdvancedOptionsPage::CAdvancedOptionsPage(HWND hParent, const RECT & rcDispay)
|
|||
AddModCheckBox(GetDlgItem(IDC_START_ON_ROM_OPEN), Setting_AutoStart);
|
||||
AddModCheckBox(GetDlgItem(IDC_ZIP), Setting_AutoZipInstantSave);
|
||||
AddModCheckBox(GetDlgItem(IDC_DEBUGGER), Debugger_Enabled);
|
||||
AddModCheckBox(GetDlgItem(IDC_INTERPRETER), Setting_ForceInterpreterCPU);
|
||||
AddModCheckBox(GetDlgItem(IDC_REMEMBER_CHEAT), Setting_RememberCheats);
|
||||
AddModCheckBox(GetDlgItem(IDC_UNIQUE_SAVE_DIR), Setting_UniqueSaveDir);
|
||||
AddModCheckBox(GetDlgItem(IDC_CHECK_RUNNING), Setting_CheckEmuRunning);
|
||||
|
|
|
@ -19,6 +19,7 @@ class CAdvancedOptionsPage :
|
|||
COMMAND_ID_HANDLER_EX(IDC_START_ON_ROM_OPEN,CheckBoxChanged)
|
||||
COMMAND_ID_HANDLER_EX(IDC_ZIP,CheckBoxChanged)
|
||||
COMMAND_ID_HANDLER_EX(IDC_DEBUGGER,CheckBoxChanged)
|
||||
COMMAND_ID_HANDLER_EX(IDC_INTERPRETER, CheckBoxChanged)
|
||||
COMMAND_ID_HANDLER_EX(IDC_REMEMBER_CHEAT,CheckBoxChanged)
|
||||
COMMAND_ID_HANDLER_EX(IDC_CHECK_RUNNING, CheckBoxChanged)
|
||||
COMMAND_ID_HANDLER_EX(IDC_UNIQUE_SAVE_DIR, CheckBoxChanged)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
|||
// CListCtrl - A WTL list control with Windows Vista style item selection.
|
||||
//
|
||||
// Revision: 1.5
|
||||
// Last modified: 9th April 2006
|
||||
// Last modified: 2nd November 2016
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -43,6 +43,7 @@ public:
|
|||
CListImpl()
|
||||
{
|
||||
m_bSortEnabled = TRUE; // Added by Rowan 05/12/2006
|
||||
m_bRightClickSelect = FALSE; // shygoo 2016 Nov 2
|
||||
m_bShowHeader = TRUE;
|
||||
m_bSortAscending = TRUE;
|
||||
m_bButtonDown = FALSE;
|
||||
|
@ -97,10 +98,16 @@ public:
|
|||
|
||||
~CListImpl()
|
||||
{
|
||||
if (m_wndItemEdit.IsWindow())
|
||||
{
|
||||
// patch memory window crash
|
||||
m_wndItemEdit.UnsubclassWindow();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
BOOL m_bSortEnabled; // Added by Rowan 05/12/2006 to disable sorting
|
||||
BOOL m_bRightClickSelect; // shygoo 2016 Nov 2
|
||||
BOOL m_bShowHeader;
|
||||
BOOL m_bShowSort;
|
||||
BOOL m_bSortAscending;
|
||||
|
@ -330,6 +337,12 @@ public:
|
|||
m_bSortEnabled = bSortEnabled;
|
||||
}
|
||||
|
||||
// shygoo 2016 Nov 2
|
||||
void SetRightClickSelect( BOOL bRightClickSelect = TRUE)
|
||||
{
|
||||
m_bRightClickSelect = bRightClickSelect;
|
||||
}
|
||||
|
||||
void ShowHeader( BOOL bShowHeader = TRUE )
|
||||
{
|
||||
m_bShowHeader = bShowHeader;
|
||||
|
@ -2245,7 +2258,7 @@ public:
|
|||
|
||||
if (( pT->GetItemFlags( nItem, nIndex ) & ITEM_FLAGS_HIT_NOTIFY ) != 0)
|
||||
{
|
||||
NotifyParent( nItem, nSubItem, LCN_HITTEST );
|
||||
NotifyParent( nItem, nSubItem, LCN_HITTEST );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2336,9 +2349,12 @@ public:
|
|||
int nItem = NULL_ITEM;
|
||||
int nSubItem = NULL_SUBITEM;
|
||||
|
||||
// only select item if not already selected (de-select in OnLButtonUp)
|
||||
if ( HitTest( point, nItem, nSubItem ) && !IsSelected( nItem ) )
|
||||
SelectItem( nItem, nSubItem, nFlags );
|
||||
if (m_bRightClickSelect)
|
||||
{
|
||||
// only select item if not already selected (de-select in OnLButtonUp)
|
||||
if (HitTest(point, nItem, nSubItem) && !IsSelected(nItem))
|
||||
SelectItem(nItem, nSubItem, nFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void OnRButtonUp( UINT /*nFlags*/, CPoint point )
|
||||
|
@ -2352,7 +2368,7 @@ public:
|
|||
// notify parent of right-click item
|
||||
NotifyParent( nItem, nSubItem, LCN_RIGHTCLICK );
|
||||
}
|
||||
|
||||
|
||||
void OnMouseMove( UINT nFlags, CPoint point )
|
||||
{
|
||||
T* pT = static_cast<T*>(this);
|
||||
|
@ -2485,6 +2501,8 @@ public:
|
|||
|
||||
m_nHotItem = nItem;
|
||||
m_nHotSubItem = nSubItem;
|
||||
|
||||
NotifyParent(nItem, nSubItem, LCN_HOTITEMCHANGED);
|
||||
}
|
||||
|
||||
int nIndex = GetColumnIndex( m_nHotSubItem );
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
#define LCN_MODIFIED ( LCN_FIRST - 6 )
|
||||
#define LCN_HYPERLINK ( LCN_FIRST - 7 )
|
||||
#define LCN_HITTEST ( LCN_FIRST - 8 )
|
||||
#define LCN_HOTITEMCHANGED ( LCN_FIRST - 9 )
|
||||
|
||||
struct CListNotify
|
||||
{
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
WORD ctrlId;
|
||||
char* text;
|
||||
} _ToolTipMap;
|
||||
|
||||
template <class T>
|
||||
class CToolTipDialog
|
||||
{
|
||||
private:
|
||||
HWND m_hWndTooltip;
|
||||
|
||||
public:
|
||||
CToolTipDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void AddToolTip(WORD ctrlId, char* lpszText)
|
||||
{
|
||||
T* pT = static_cast<T*>(this);
|
||||
|
||||
TOOLINFO toolInfo = { 0 };
|
||||
toolInfo.cbSize = sizeof(toolInfo);
|
||||
toolInfo.hwnd = pT->m_hWnd;
|
||||
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
|
||||
toolInfo.uId = (UINT_PTR) ::GetDlgItem(pT->m_hWnd, ctrlId);
|
||||
toolInfo.lpszText = lpszText;
|
||||
SendMessage(m_hWndTooltip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
|
||||
}
|
||||
|
||||
void DlgToolTip_Init()
|
||||
{
|
||||
T* pT = static_cast<T*>(this);
|
||||
|
||||
m_hWndTooltip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
|
||||
WS_POPUP | TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
pT->m_hWnd, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
const _ToolTipMap* map = pT->_GetToolTipMap();
|
||||
|
||||
for (int i = 0; map[i].ctrlId != 0; i++)
|
||||
{
|
||||
AddToolTip(map[i].ctrlId, map[i].text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define BEGIN_TOOLTIP_MAP() static const _ToolTipMap* _GetToolTipMap() { static const _ToolTipMap map[] = {
|
||||
#define TOOLTIP(ctrlId, text) { ctrlId, text },
|
||||
#define END_TOOLTIP_MAP() { 0 } }; return map; }
|
|
@ -1,8 +1,12 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by UI Resources.rc
|
||||
// Used by UIResources.rc
|
||||
//
|
||||
#define VERSION_REVISION 0
|
||||
#define VER_VER_DEBUG 0
|
||||
#define VERSION_MAJOR 2
|
||||
#define IDAPPLY 3
|
||||
#define VERSION_MINOR 3
|
||||
#define IDI_PJ64_Icon 101
|
||||
#define IDD_Rom_Information 104
|
||||
#define IDD_Key_Prompt 108
|
||||
|
@ -40,17 +44,44 @@
|
|||
#define IDD_Settings_Config 149
|
||||
#define IDD_Support_Project64 150
|
||||
#define IDD_Support_EnterCode 151
|
||||
#define IDD_Debugger_Commands 152
|
||||
#define IDR_POPUP 155
|
||||
#define IDD_Debugger_RegGPR 158
|
||||
#define IDR_CHEAT_MENU 160
|
||||
#define IDD_Debugger_AddBreakpoint 160
|
||||
#define IDD_Lang_Select 161
|
||||
#define IDD_Settings_GameRecompiler 162
|
||||
#define IDD_Settings_GamePlugin 163
|
||||
#define IDD_Settings_GameStatus 164
|
||||
#define IDD_Debugger_RegFPR 166
|
||||
#define IDD_Debugger_Scripts 169
|
||||
#define IDD_Debugger_RegPI 170
|
||||
#define IDD_Debugger_Symbols 172
|
||||
#define IDD_Debugger_AddSymbol 174
|
||||
#define IDR_MEM_BP_POPUP 177
|
||||
#define IDR_JSAPI_TEXT 181
|
||||
#define IDD_Debugger_DMALog 182
|
||||
#define IDD_Debugger_StackTrace 184
|
||||
#define IDD_Debugger_RegCOP0 185
|
||||
#define IDR_MENU1 186
|
||||
#define IDR_SCRIPT_POPUP 186
|
||||
#define IDR_OP_POPUP 187
|
||||
#define IDD_Debugger_Stack 191
|
||||
#define IDD_Debugger_RegSP 192
|
||||
#define IDD_Debugger_RegMI 193
|
||||
#define IDD_Debugger_RegAI 194
|
||||
#define IDD_Debugger_RegSI 195
|
||||
#define IDD_Debugger_RegRI 196
|
||||
#define IDD_Debugger_RegDPC 197
|
||||
#define IDD_Debugger_RegRDRAM 198
|
||||
#define IDD_Debugger_RegVI 199
|
||||
#define IDD_Debugger_RegDD 200
|
||||
#define IDC_MENU_ITEM_TEXT 1000
|
||||
#define IDC_CLOSE_BUTTON 1001
|
||||
#define IDC_LIST2 1003
|
||||
#define IDC_CURRENT_KEYS 1003
|
||||
#define RSP_LIST 1004
|
||||
#define IDC_CURRENT_KEYS2 1004
|
||||
#define RSP_ABOUT 1006
|
||||
#define IDC_ASSIGN 1006
|
||||
#define IDC_BTN_CHOOSE_FILE 1006
|
||||
|
@ -59,7 +90,6 @@
|
|||
#define IDC_BTN_RDRAM 1007
|
||||
#define IDC_REFRSH_MEM 1007
|
||||
#define IDC_INFO_ROMNAME 1008
|
||||
#define IDC_BUTTON3 1008
|
||||
#define IDC_RESET_PAGE 1008
|
||||
#define IDC_INFO_CARTID 1009
|
||||
#define IDC_VIRTUALKEY 1009
|
||||
|
@ -93,6 +123,7 @@
|
|||
#define IDC_SMM_DMA 1013
|
||||
#define IDC_UNKNOWN_ALIGN 1013
|
||||
#define IDC_DELAY_DP 1013
|
||||
#define IDC_INTERPRETER 1013
|
||||
#define IDC_INFO_CRC1 1014
|
||||
#define IDC_ASSIGNED_MENU_ITEM 1014
|
||||
#define IDC_TLB_RULES 1014
|
||||
|
@ -225,6 +256,7 @@
|
|||
#define IDC_ZIP 1092
|
||||
#define IDC_SETTING_INFO 1092
|
||||
#define IDC_GOOD_NAME_TEXT 1093
|
||||
#define IDC_SETTING_INFO2 1093
|
||||
#define IDC_FUNCFIND_TEXT 1094
|
||||
#define IDC_REMEMBER 1095
|
||||
#define IDC_GFX_NAME 1095
|
||||
|
@ -237,7 +269,6 @@
|
|||
#define IDC_AUDIO_NAME 1099
|
||||
#define IDC_ROM_REGCACHE 1099
|
||||
#define IDC_COUNTPERBYTE_TEXT 1099
|
||||
#define IDC_BORDER 1099
|
||||
#define IDC_CONT_NAME 1100
|
||||
#define IDC_COUNTPERBYTE 1100
|
||||
#define ID_SUPPORT_PJ64 1100
|
||||
|
@ -255,9 +286,15 @@
|
|||
#define IDC_DIR_FRAME5 1105
|
||||
#define IDC_MAXROMS_TXT 1111
|
||||
#define IDC_ROMSEL_TEXT2 1112
|
||||
#define IDC_R0_EDIT 1112
|
||||
#define IDC_MAXROMDIR_TXT 1113
|
||||
#define IDC_CMD_LIST 1113
|
||||
#define IDC_ROMSEL_TEXT4 1114
|
||||
#define IDC_R1_EDIT 1114
|
||||
#define IDC_GO_BTN 1116
|
||||
#define IDC_UNMARK 1119
|
||||
#define IDC_STEP_BTN 1119
|
||||
#define IDC_ADDSYMBOL_BTN 1119
|
||||
#define IDC_NOTES 1120
|
||||
#define IDC_CHEAT_LIST 1121
|
||||
#define IDC_CHEAT_NAME 1122
|
||||
|
@ -269,28 +306,45 @@
|
|||
#define IDC_USE_ROMBROWSER 1133
|
||||
#define IDC_USING 1134
|
||||
#define IDC_AVALIABLE 1135
|
||||
#define IDC_R2_EDIT 1135
|
||||
#define IDC_R3_EDIT 1136
|
||||
#define IDC_REMOVE 1137
|
||||
#define IDC_R4_EDIT 1137
|
||||
#define IDC_RECURSION 1138
|
||||
#define IDC_R5_EDIT 1138
|
||||
#define IDC_R6_EDIT 1139
|
||||
#define IDC_R7_EDIT 1140
|
||||
#define IDC_V64 1141
|
||||
#define IDC_R8_EDIT 1141
|
||||
#define IDC_LOAD_FULLSCREEN 1142
|
||||
#define IDC_Z64 1142
|
||||
#define IDC_R9_EDIT 1142
|
||||
#define IDC_ROMSEL_TEXT5 1143
|
||||
#define IDC_REMEMBER_CHEAT 1143
|
||||
#define IDC_N64 1143
|
||||
#define IDC_R10_EDIT 1143
|
||||
#define IDC_ROMSEL_TEXT6 1144
|
||||
#define IDC_SCREEN_SAVER 1144
|
||||
#define IDC_ROM 1144
|
||||
#define IDC_CHECK_RUNNING 1144
|
||||
#define IDC_R11_EDIT 1144
|
||||
#define IDC_BASIC_MODE 1145
|
||||
#define IDC_JAP 1145
|
||||
#define IDC_UNIQUE_SAVE_DIR 1145
|
||||
#define IDC_R12_EDIT 1145
|
||||
#define IDC_PAL 1146
|
||||
#define IDC_R13_EDIT 1146
|
||||
#define IDC_USA 1147
|
||||
#define IDC_R14_EDIT 1147
|
||||
#define IDC_R15_EDIT 1148
|
||||
#define IDC_SHELL_INT_TEXT 1149
|
||||
#define IDC_RDB_HOME 1150
|
||||
#define IDC_SHELL_INT_TEXT2 1150
|
||||
#define IDC_COUNTFACT 1151
|
||||
#define IDC_CHT_HOME 1151
|
||||
#define IDC_SHELL_INT_TEXT3 1151
|
||||
#define IDC_RDX_HOME 1152
|
||||
#define IDC_SHELL_INT_TEXT4 1152
|
||||
#define IDC_MEMORY_SIZE_TEXT 1153
|
||||
#define IDC_SAVE_TYPE_TEXT 1154
|
||||
#define IDC_LAN 1154
|
||||
|
@ -307,15 +361,39 @@
|
|||
#define IDC_CHT_AUTHOR 1163
|
||||
#define IDC_CHT_VERSION 1164
|
||||
#define IDC_CHT_DATE 1165
|
||||
#define IDC_R16_EDIT 1165
|
||||
#define IDC_RDX 1166
|
||||
#define IDC_R17_EDIT 1166
|
||||
#define IDC_RDX_AUTHOR 1167
|
||||
#define IDC_R18_EDIT 1167
|
||||
#define IDC_RDX_VERSION 1168
|
||||
#define IDC_R19_EDIT 1168
|
||||
#define IDC_RDX_DATE 1169
|
||||
#define IDC_R20_EDIT 1169
|
||||
#define IDC_R21_EDIT 1170
|
||||
#define IDC_R22_EDIT 1171
|
||||
#define IDC_NEWCHEAT 1172
|
||||
#define IDC_R23_EDIT 1172
|
||||
#define IDC_R24_EDIT 1173
|
||||
#define IDC_R25_EDIT 1174
|
||||
#define IDC_R26_EDIT 1175
|
||||
#define IDC_R27_EDIT 1176
|
||||
#define IDC_R28_EDIT 1177
|
||||
#define IDC_INFO_LOCATION 1178
|
||||
#define IDC_CHEAT_CODES 1178
|
||||
#define IDC_R29_EDIT 1178
|
||||
#define IDC_STATE 1179
|
||||
#define IDC_R30_EDIT 1179
|
||||
#define IDC_R31_EDIT 1180
|
||||
#define IDC_HI_EDIT 1183
|
||||
#define IDC_LO_EDIT 1184
|
||||
#define IDC_BP_LIST 1185
|
||||
#define IDC_CTX_INFO_EDIT 1185
|
||||
#define IDC_ADDBP_BTN 1186
|
||||
#define IDC_REMOVESYMBOL_BTN 1186
|
||||
#define IDC_RMBP_BTN 1187
|
||||
#define IDC_CHEATSFRAME 1188
|
||||
#define IDC_CLEARBP_BTN 1188
|
||||
#define IDC_ADDCHEATSFRAME 1189
|
||||
#define IDC_CHEAT_OPTIONS 1190
|
||||
#define IDC_ROM_NAME 1191
|
||||
|
@ -324,6 +402,7 @@
|
|||
#define IDC_LABEL_OPTIONS_FORMAT 1192
|
||||
#define IDC_LOCATION 1193
|
||||
#define IDC_ROM_SIZE 1194
|
||||
#define IDC_REG_TABS 1194
|
||||
#define IDC_CART_ID 1195
|
||||
#define IDC_MANUFACTURER 1196
|
||||
#define IDC_COUNTRY 1197
|
||||
|
@ -332,16 +411,220 @@
|
|||
#define IDC_CIC_CHIP 1200
|
||||
#define IDC_ROM_MD5 1201
|
||||
#define IDC_NOTESFRAME 1201
|
||||
#define IDC_CHK_READ 1201
|
||||
#define IDC_CHK_WRITE 1203
|
||||
#define IDC_CHK_EXEC 1204
|
||||
#define IDC_F0_EDIT 1204
|
||||
#define IDC_NOTE 1205
|
||||
#define IDC_F1_EDIT 1205
|
||||
#define IDC_DIGITAL_TEXT 1206
|
||||
#define IDC_F2_EDIT 1206
|
||||
#define IDC_VALUE_TEXT 1207
|
||||
#define IDC_F3_EDIT 1207
|
||||
#define IDC_NOTES_TEXT 1208
|
||||
#define IDC_F4_EDIT 1208
|
||||
#define IDC_F5_EDIT 1209
|
||||
#define IDC_F6_EDIT 1210
|
||||
#define IDC_F7_EDIT 1211
|
||||
#define IDC_F8_EDIT 1212
|
||||
#define IDC_F9_EDIT 1213
|
||||
#define IDC_F10_EDIT 1214
|
||||
#define IDC_F11_EDIT 1215
|
||||
#define IDC_F12_EDIT 1216
|
||||
#define IDC_F13_EDIT 1217
|
||||
#define IDC_F14_EDIT 1218
|
||||
#define IDC_LANG_SEL 1219
|
||||
#define IDC_F15_EDIT 1219
|
||||
#define IDC_IPL_DIR 1220
|
||||
#define IDC_F16_EDIT 1220
|
||||
#define IDC_SELECT_IPL_DIR 1221
|
||||
#define IDC_F17_EDIT 1221
|
||||
#define IDC_IPLDIR_TXT 1222
|
||||
#define IDC_F18_EDIT 1222
|
||||
#define IDC_F19_EDIT 1223
|
||||
#define IDC_F20_EDIT 1224
|
||||
#define IDC_F21_EDIT 1225
|
||||
#define IDC_F22_EDIT 1226
|
||||
#define IDC_F23_EDIT 1227
|
||||
#define IDC_F24_EDIT 1228
|
||||
#define IDC_F25_EDIT 1229
|
||||
#define IDC_F26_EDIT 1230
|
||||
#define IDC_F27_EDIT 1231
|
||||
#define IDC_F28_EDIT 1232
|
||||
#define IDC_F29_EDIT 1233
|
||||
#define IDC_F30_EDIT 1234
|
||||
#define IDC_F31_EDIT 1235
|
||||
#define IDC_SKIP_BTN 1268
|
||||
#define IDC_CONSOLE_EDIT 1271
|
||||
#define IDC_FILTER_EDIT 1271
|
||||
#define IDC_EVAL_EDIT 1272
|
||||
#define IDC_PI00_EDIT 1274
|
||||
#define IDC_PI04_EDIT 1275
|
||||
#define IDC_PI08_EDIT 1276
|
||||
#define IDC_PI0C_EDIT 1277
|
||||
#define IDC_PI10_EDIT 1278
|
||||
#define IDC_PI14_EDIT 1279
|
||||
#define IDC_PI18_EDIT 1280
|
||||
#define IDC_PI1C_EDIT 1281
|
||||
#define IDC_PI20_EDIT 1282
|
||||
#define IDC_PI24_EDIT 1283
|
||||
#define IDC_PI28_EDIT 1284
|
||||
#define IDC_PI2C_EDIT 1285
|
||||
#define IDC_PI30_EDIT 1286
|
||||
#define IDC_STACK_LIST 1288
|
||||
#define IDC_SYMBOLS_LIST 1290
|
||||
#define IDC_SYMBOLS_BTN 1291
|
||||
#define IDC_DESC_EDIT 1292
|
||||
#define IDC_TYPE_COMBOBOX 1293
|
||||
#define IDC_OPCODE_BOX 1295
|
||||
#define IDC_NAME_EDIT 1296
|
||||
#define IDC_SCRIPT_LIST 1297
|
||||
#define IDC_DMA_LIST 1300
|
||||
#define IDC_CLEAR_BTN 1302
|
||||
#define IDC_DMA_RAM_EDIT 1303
|
||||
#define IDC_COPY_BTN 1303
|
||||
#define IDC_BUTTON1 1305
|
||||
#define IDC_DMA_ROM_EDIT 1306
|
||||
#define IDC_TRACE_STATIC 1307
|
||||
#define IDC_RAM_STATIC 1308
|
||||
#define IDC_ROM_STATIC 1309
|
||||
#define IDC_STACKTRACE_LIST 1313
|
||||
#define IDC_OP_EDIT 1314
|
||||
#define IDC_COP0_0_EDIT 1315
|
||||
#define IDC_COP0_1_EDIT 1316
|
||||
#define IDC_COP0_2_EDIT 1317
|
||||
#define IDC_COP0_3_EDIT 1318
|
||||
#define IDC_COP0_4_EDIT 1319
|
||||
#define IDC_COP0_5_EDIT 1320
|
||||
#define IDC_COP0_6_EDIT 1321
|
||||
#define IDC_COP0_7_EDIT 1322
|
||||
#define IDC_COP0_8_EDIT 1323
|
||||
#define IDC_COP0_9_EDIT 1324
|
||||
#define IDC_COP0_10_EDIT 1325
|
||||
#define IDC_COP0_11_EDIT 1326
|
||||
#define IDC_COP0_12_EDIT 1327
|
||||
#define IDC_COP0_13_EDIT 1328
|
||||
#define IDC_COP0_14_EDIT 1329
|
||||
#define IDC_COP0_15_EDIT 1330
|
||||
#define IDC_COP0_16_EDIT 1331
|
||||
#define IDC_COP0_17_EDIT 1332
|
||||
#define IDC_COP0_18_EDIT 1333
|
||||
#define IDC_FILTER_STATIC 1339
|
||||
#define IDC_SYM_INFO 1348
|
||||
#define IDC_BLOCK_INFO 1350
|
||||
#define IDC_DMA_INFO 1351
|
||||
#define IDC_BACK_BTN 1352
|
||||
#define IDC_FORWARD_BTN 1353
|
||||
#define IDC_PC_EDIT 1354
|
||||
#define IDC_VIEWPC_BTN 1355
|
||||
#define IDC_PC_STATIC 1356
|
||||
#define IDC_SP_STATIC 1358
|
||||
#define IDC_MEM_BTN 1359
|
||||
#define IDC_CAUSE_TIP 1361
|
||||
#define IDC_EDIT1 1362
|
||||
#define IDC_FCSR_EDIT 1362
|
||||
#define IDC_SP00_EDIT 1363
|
||||
#define IDC_SP04_EDIT 1364
|
||||
#define IDC_SP08_EDIT 1365
|
||||
#define IDC_SP0C_EDIT 1366
|
||||
#define IDC_SP10_EDIT 1367
|
||||
#define IDC_SP14_EDIT 1368
|
||||
#define IDC_SP18_EDIT 1369
|
||||
#define IDC_SP1C_EDIT 1370
|
||||
#define IDC_SP_PC_EDIT 1371
|
||||
#define IDC_SI00_EDIT 1372
|
||||
#define IDC_SI04_EDIT 1373
|
||||
#define IDC_SI08_EDIT 1374
|
||||
#define IDC_SI0C_EDIT 1375
|
||||
#define IDC_AI00_EDIT 1376
|
||||
#define IDC_AI04_EDIT 1377
|
||||
#define IDC_AI08_EDIT 1378
|
||||
#define IDC_AI0C_EDIT 1379
|
||||
#define IDC_AI10_EDIT 1380
|
||||
#define IDC_AI14_EDIT 1381
|
||||
#define IDC_MI00_EDIT 1382
|
||||
#define IDC_MI04_EDIT 1383
|
||||
#define IDC_MI08_EDIT 1384
|
||||
#define IDC_MI0C_EDIT 1385
|
||||
#define IDC_RI00_EDIT 1386
|
||||
#define IDC_RI04_EDIT 1387
|
||||
#define IDC_RI08_EDIT 1388
|
||||
#define IDC_RI0C_EDIT 1389
|
||||
#define IDC_RI10_EDIT 1390
|
||||
#define IDC_RI14_EDIT 1391
|
||||
#define IDC_RI18_EDIT 1392
|
||||
#define IDC_RI1C_EDIT 1393
|
||||
#define IDC_DPC00_EDIT 1394
|
||||
#define IDC_DPC04_EDIT 1395
|
||||
#define IDC_DPC08_EDIT 1396
|
||||
#define IDC_DPC0C_EDIT 1397
|
||||
#define IDC_DPC10_EDIT 1398
|
||||
#define IDC_DPC14_EDIT 1399
|
||||
#define IDC_DPC18_EDIT 1400
|
||||
#define IDC_DPC1C_EDIT 1401
|
||||
#define IDC_RDRAM00_EDIT 1402
|
||||
#define IDC_RDRAM04_EDIT 1403
|
||||
#define IDC_RDRAM08_EDIT 1404
|
||||
#define IDC_RDRAM0C_EDIT 1405
|
||||
#define IDC_RDRAM10_EDIT 1406
|
||||
#define IDC_RDRAM14_EDIT 1407
|
||||
#define IDC_RDRAM18_EDIT 1408
|
||||
#define IDC_RDRAM1C_EDIT 1409
|
||||
#define IDC_RDRAM20_EDIT 1410
|
||||
#define IDC_RDRAM24_EDIT 1411
|
||||
#define IDC_VI00_EDIT 1412
|
||||
#define IDC_VI04_EDIT 1413
|
||||
#define IDC_VI08_EDIT 1414
|
||||
#define IDC_VI0C_EDIT 1415
|
||||
#define IDC_VI10_EDIT 1416
|
||||
#define IDC_VI14_EDIT 1417
|
||||
#define IDC_VI18_EDIT 1418
|
||||
#define IDC_VI1C_EDIT 1419
|
||||
#define IDC_VI20_EDIT 1420
|
||||
#define IDC_VI24_EDIT 1421
|
||||
#define IDC_VI28_EDIT 1422
|
||||
#define IDC_VI2C_EDIT 1423
|
||||
#define IDC_VI30_EDIT 1424
|
||||
#define IDC_VI34_EDIT 1425
|
||||
#define IDC_DD00_EDIT 1426
|
||||
#define IDC_DD04_EDIT 1427
|
||||
#define IDC_DD08_EDIT 1428
|
||||
#define IDC_DD0C_EDIT 1429
|
||||
#define IDC_DD10_EDIT 1430
|
||||
#define IDC_DD14_EDIT 1431
|
||||
#define IDC_DD18_EDIT 1432
|
||||
#define IDC_DD1C_EDIT 1433
|
||||
#define IDC_DD20_EDIT 1434
|
||||
#define IDC_DD24_EDIT 1435
|
||||
#define IDC_DD28_EDIT 1436
|
||||
#define IDC_DD2C_EDIT 1437
|
||||
#define IDC_DD30_EDIT 1438
|
||||
#define IDC_DD34_EDIT 1439
|
||||
#define IDC_DD38_EDIT 1440
|
||||
#define IDC_DD3C_EDIT 1441
|
||||
#define IDC_DD40_EDIT 1442
|
||||
#define IDC_DD44_EDIT 1443
|
||||
#define IDC_DD48_EDIT 1444
|
||||
#define VERSION_BUILD 9999
|
||||
#define ID_POPUP_SHOWINMEMORYVIEWER 40005
|
||||
#define ID_POPUPMENU_PLAYGAMEWITHDISK 40008
|
||||
#define ID_POPUPMENU_ADDSYMBOL 40013
|
||||
#define ID_POPUPMENU_VIEWDISASM 40017
|
||||
#define ID_POPUPMENU_CLEARALLBPS 40019
|
||||
#define ID_POPUPMENU_TOGGLERBP 40020
|
||||
#define ID_POPUPMENU_TOGGLEWBP 40021
|
||||
#define ID_POPUP_RUN 40024
|
||||
#define ID_POPUP_STOP 40025
|
||||
#define ID_POPUPMENU_INSERTNOP 40026
|
||||
#define ID_POPUPMENU_RESTORE 40027
|
||||
#define ID_POPUPMENU_RESTOREALL 40029
|
||||
#define ID_POPUPMENU_EDIT 40030
|
||||
#define ID_POPUPMENU_FOLLOWJUMP 40032
|
||||
#define ID_POPUPMENU_RUNTO 40034
|
||||
#define ID_Menu 40035
|
||||
#define ID_POPUPMENU_VIEWMEMORY 40036
|
||||
#define ID_POPUPMENU_TOGGLEBP 40039
|
||||
#define ID_POPUPMENU_CLEARBPS 40040
|
||||
#define ID_POPUPMENU_ROMDIRECTORY 40137
|
||||
#define ID_POPUPMENU_REFRESHROMLIST 40138
|
||||
#define ID_POPUPMENU_PLAYGAME 40152
|
||||
|
@ -356,9 +639,9 @@
|
|||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 153
|
||||
#define _APS_NEXT_COMMAND_VALUE 40009
|
||||
#define _APS_NEXT_CONTROL_VALUE 1104
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#define _APS_NEXT_RESOURCE_VALUE 194
|
||||
#define _APS_NEXT_COMMAND_VALUE 40041
|
||||
#define _APS_NEXT_CONTROL_VALUE 1445
|
||||
#define _APS_NEXT_SYMED_VALUE 102
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -147,8 +147,8 @@ int DisplayRSPCommand (DWORD location, int InsertPos)
|
|||
RSPCommandLine[InsertPos].Location = location;
|
||||
RSPCommandLine[InsertPos].status = status;
|
||||
RSPCommandLine[InsertPos].opcode = OpCode;
|
||||
sprintf(RSPCommandLine[InsertPos].String," 0x%03X\t%s",location,
|
||||
RSPOpcodeName ( OpCode, location ));
|
||||
sprintf(RSPCommandLine[InsertPos].String," 0x%04X\t%s",0x1000 | location,
|
||||
RSPOpcodeName ( OpCode, 0x1000 | location ));
|
||||
if ( SendMessage(hList,LB_GETCOUNT,0,0) <= InsertPos)
|
||||
{
|
||||
SendMessage(hList,LB_INSERTSTRING,(WPARAM)InsertPos, (LPARAM)location);
|
||||
|
@ -471,7 +471,7 @@ void Paint_RSP_Commands (HWND hDlg)
|
|||
TextOut( ps.hdc, 97,16,"Instruction",11);
|
||||
TextOut( ps.hdc, 180,16,"Arguments",9);
|
||||
TextOut( ps.hdc, 354,2," Address ",9);
|
||||
TextOut( ps.hdc, 358,19,"0x",2);
|
||||
TextOut( ps.hdc, 358,19,"0x1",3);
|
||||
|
||||
SelectObject( ps.hdc,hOldFont );
|
||||
SetBkMode( ps.hdc, OldBkMode );
|
||||
|
@ -1004,18 +1004,18 @@ char * RSPRegimmName ( DWORD OpCode, DWORD PC )
|
|||
{ /* MIPS pseudo-instruction: BAL (Branch and Link) */
|
||||
sprintf(
|
||||
CommandName,
|
||||
"BAL\t0x%03X",
|
||||
(PC + ((short)command.offset << 2) + 4) & 0xFFC
|
||||
"BAL\t0x%04X",
|
||||
(PC + ((short)command.offset << 2) + 4) & 0x1FFC
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(
|
||||
CommandName,
|
||||
"%s\t%s, 0x%03X",
|
||||
"%s\t%s, 0x%04X",
|
||||
mnemonics_regimm[command.rt],
|
||||
GPR_Name(command.rs),
|
||||
(PC + ((short)command.offset << 2) + 4) & 0xFFC
|
||||
(PC + ((short)command.offset << 2) + 4) & 0x1FFC
|
||||
);
|
||||
}
|
||||
return CommandName;
|
||||
|
@ -1210,44 +1210,44 @@ char * RSPOpcodeName ( DWORD OpCode, DWORD PC )
|
|||
break;
|
||||
case RSP_J:
|
||||
case RSP_JAL:
|
||||
sprintf(CommandName, "%s\t0x%03X",
|
||||
sprintf(CommandName, "%s\t0x%04X",
|
||||
mnemonics_primary[command.op],
|
||||
(command.target << 2) & 0xFFC
|
||||
(command.target << 2) & 0x1FFC
|
||||
);
|
||||
break;
|
||||
case RSP_BEQ:
|
||||
if (command.rs == 0 && command.rt == 0)
|
||||
{
|
||||
sprintf(CommandName, "%s\t0x%03X",
|
||||
sprintf(CommandName, "%s\t0x%04X",
|
||||
"B",
|
||||
(PC + ((short)command.offset << 2) + 4) & 0xFFC
|
||||
(PC + ((short)command.offset << 2) + 4) & 0x1FFC
|
||||
);
|
||||
break;
|
||||
}
|
||||
else if (command.rs == 0 || command.rt == 0)
|
||||
{
|
||||
sprintf(CommandName, "%s\t%s, 0x%03X",
|
||||
sprintf(CommandName, "%s\t%s, 0x%04X",
|
||||
"BEQZ",
|
||||
GPR_Name(command.rs == 0 ? command.rt : command.rs),
|
||||
(PC + ((short)command.offset << 2) + 4) & 0xFFC
|
||||
(PC + ((short)command.offset << 2) + 4) & 0x1FFC
|
||||
);
|
||||
break;
|
||||
}
|
||||
/* else { fall through to show the full BEQ } */
|
||||
case RSP_BNE:
|
||||
sprintf(CommandName, "%s\t%s, %s, 0x%03X",
|
||||
sprintf(CommandName, "%s\t%s, %s, 0x%04X",
|
||||
mnemonics_primary[command.op],
|
||||
GPR_Name(command.rs),
|
||||
GPR_Name(command.rt),
|
||||
(PC + ((short)command.offset << 2) + 4) & 0xFFC
|
||||
(PC + ((short)command.offset << 2) + 4) & 0x1FFC
|
||||
);
|
||||
break;
|
||||
case RSP_BLEZ:
|
||||
case RSP_BGTZ:
|
||||
sprintf(CommandName, "%s\t%s, 0x%03X",
|
||||
sprintf(CommandName, "%s\t%s, 0x%04X",
|
||||
mnemonics_primary[command.op],
|
||||
GPR_Name(command.rs),
|
||||
(PC + ((short)command.offset << 2) + 4) & 0xFFC
|
||||
(PC + ((short)command.offset << 2) + 4) & 0x1FFC
|
||||
);
|
||||
break;
|
||||
case RSP_ADDI:
|
||||
|
|
|
@ -368,13 +368,11 @@ LRESULT CALLBACK RefreshRSP_RegProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|||
PaintRSP_Vector2_Panel (hWnd);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return( (*RefreshProc)(hWnd, uMsg, wParam, lParam) );
|
||||
}
|
||||
return( FALSE );
|
||||
|
||||
return CallWindowProc(RefreshProc, hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK RSP_Registers_Proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
|
|
|
@ -0,0 +1,691 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Project64d JS API</title>
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic' rel='stylesheet' type='text/css'>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Open Sans", segoe ui, tahoma, sans;
|
||||
font-size: 14px;
|
||||
background-color: #EEE;
|
||||
}
|
||||
a {
|
||||
color: #494;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
div.inline-content {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
div.panel {
|
||||
background-color: #FFF;
|
||||
padding: 10px;
|
||||
border-top: 4px solid #FFAAAA;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: -5px 5px 5px #DDD;
|
||||
}
|
||||
div.classname {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
}
|
||||
div.propertyname {
|
||||
font-weight: bold;
|
||||
}
|
||||
div.property {
|
||||
padding: 10px;
|
||||
}
|
||||
div.propertydesc {
|
||||
padding: 10px;
|
||||
}
|
||||
pre.example {
|
||||
background-color: #EFE;
|
||||
border: 1px solid #BCB;
|
||||
padding: 5px;
|
||||
font-family: consolas, courier new, monospace;
|
||||
white-space: pre;
|
||||
margin: 10px;
|
||||
font-size: 12px;
|
||||
color: #020;
|
||||
}
|
||||
pre.example::before {
|
||||
content: "Example";
|
||||
float: right;
|
||||
opacity: 0.5;
|
||||
font-size: 11px;
|
||||
font-family: "Open Sans", segoe ui, tahoma, sans;
|
||||
}
|
||||
span.snip {
|
||||
background-color: #EFE;
|
||||
border: 1px solid #BCB;
|
||||
padding: 0px 2px;
|
||||
font-size: 13px;
|
||||
color: #020;
|
||||
font-family: consolas, courier new, monospace;
|
||||
border-radius: 3px;
|
||||
}
|
||||
span.tag {
|
||||
float: right;
|
||||
margin-left: 2px;
|
||||
border: 2px solid #885;
|
||||
border-radius: 5px;
|
||||
background-color: #FFE;
|
||||
color: #885;
|
||||
font-weight: bold;
|
||||
padding: 0px 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
span.tag2 {
|
||||
float: right;
|
||||
margin-left: 2px;
|
||||
border: 2px solid #588;
|
||||
border-radius: 5px;
|
||||
background-color: #EFF;
|
||||
color: #588;
|
||||
font-weight: bold;
|
||||
padding: 0px 2px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="margin: 10px; font-size: 24px;">Project64d Javascript API</div>
|
||||
<div class="inline-content" style="width: 150px; min-width: 150px; margin-left: 10px;">
|
||||
<div class="panel" id="sidebar" style="width: 120px; position: absolute;">
|
||||
<a href="#mem">mem</a><br>
|
||||
<a href="#rom">rom</a><br>
|
||||
<a href="#events">events</a><br>
|
||||
<a href="#debug">debug</a><br>
|
||||
<a href="#console">console</a><br>
|
||||
<a href="#alert">alert</a><br>
|
||||
<a href="#screen">screen</a><br>
|
||||
<a href="#gpr">gpr</a><br>
|
||||
<a href="#ugpr">ugpr</a><br>
|
||||
<a href="#fpr">fpr</a><br>
|
||||
<a href="#dfpr">dfpr</a><br>
|
||||
<a href="#Server">Server</a><br>
|
||||
<a href="#Socket">Socket</a><br>
|
||||
<a href="#AddressRange">AddressRange</a><br>
|
||||
<a href="#Number">Number</a><br>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline-content" style="max-width: 700px;">
|
||||
<div class="panel" id="mem">
|
||||
<div class="classname">mem</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.u8|u16|u32|s8|s16|s32|float|double</div>
|
||||
<div class="propertydesc">
|
||||
Arrays for reading and modifying values in virtual memory.
|
||||
Virtual addresses are always used for indeces regardless of type size.
|
||||
<pre class="example">
|
||||
var addr_power = 0x8033B21E
|
||||
|
||||
if(mem.u8[addr_power] < 1)
|
||||
{
|
||||
mem.u8[addr_power] = 8
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.getblock(baseAddr, size)</div>
|
||||
<div class="propertydesc">
|
||||
Returns a Buffer object from a block of data of <span class="snip">size</span> bytes at <span class="snip">baseAddr</span> in virtual memory.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.getstring(baseAddr[, maxLen])</div>
|
||||
<div class="propertydesc">
|
||||
Returns a string from a zero-terminated ASCII string at <span class="snip">baseAddr</span> in virtual memory.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.bindvar(obj, baseAddr, name, type)</div>
|
||||
<div class="propertydesc">
|
||||
Adds property <span class="snip">name</span> to <span class="snip">obj</span> and "binds" it to the virtual address specified by <span class="snip">baseAddr</span>.
|
||||
Valid types are: <span class="snip">u8</span>, <span class="snip">u16</span>, <span class="snip">u32</span>, <span class="snip">s8</span>, <span class="snip">s16</span>, <span class="snip">s32</span>, <span class="snip">float</span>, and <span class="snip">double</span>.
|
||||
<pre class="example">
|
||||
mem.bindvar(this, 0x8033B21E, 'power', u8)
|
||||
|
||||
if(power < 1)
|
||||
{
|
||||
power = 8
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.bindvars(obj, vars)</div>
|
||||
<div class="propertydesc">
|
||||
Adds multiple virtual memory-bound properties to <span class="snip">obj</span>.
|
||||
Returns <span class="snip">obj</span>.
|
||||
<pre class="example">
|
||||
var mario = mem.bindvars({},
|
||||
[
|
||||
[0x8033B1B0, 'y', float],
|
||||
[0x8033B21E, 'power', u8]
|
||||
])
|
||||
|
||||
mario.power = 5
|
||||
mario.y = 500.00
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.bindstruct(obj, baseAddr, props)</div>
|
||||
<div class="propertydesc">
|
||||
Adds multiple virtual memory-bound properties to <span class="snip">obj</span>.
|
||||
Addresses are determined by type sizes.
|
||||
Returns <span class="snip">obj</span>.
|
||||
<pre class="example">
|
||||
var marioPos = mem.bindstruct(this, 0x8033B1AC,
|
||||
{
|
||||
x: float,
|
||||
y: float,
|
||||
z: float
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">mem.typedef(props)</div>
|
||||
<div class="propertydesc">
|
||||
Returns a "struct" class that may be constructed using the address of a real struct in virtual memory.
|
||||
<pre class="example">
|
||||
const Player = mem.typedef(
|
||||
{
|
||||
health: u32,
|
||||
x: float,
|
||||
y: float,
|
||||
z: float
|
||||
})
|
||||
|
||||
Player.prototype.move = function(x, y, z)
|
||||
{
|
||||
this.x = x
|
||||
this.y = y
|
||||
this.z = z
|
||||
}
|
||||
|
||||
Player.prototype.heal = function()
|
||||
{
|
||||
this.health = 100;
|
||||
}
|
||||
|
||||
var player = new Player(0x8033B1AC)
|
||||
|
||||
player.move(100, 200, 300)
|
||||
player.heal()
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel" id="rom">
|
||||
<div class="classname">rom</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">rom.u8|u16|u32|s8|s16|s32|float|double</div>
|
||||
<div class="propertydesc">
|
||||
Arrays for reading values in cartridge ROM. Indexing works in a similar manner to <a href="#mem">mem</a>'s.
|
||||
<pre class="example">
|
||||
var crc1 = rom.u32[0x00000010]
|
||||
var crc2 = rom.u32[0x00000014]
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">rom.getblock(baseAddr, size)</div>
|
||||
<div class="propertydesc">
|
||||
Returns a Buffer object from a block of data of size bytes at <span class="snip">baseAddr</span> in cartridge ROM.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">rom.getstring(baseAddr[, maxLen])</div>
|
||||
<div class="propertydesc">
|
||||
Returns a string from a zero-terminated ASCII string at <span class="snip">baseAddr</span> in cartridge ROM.
|
||||
<pre class="example">
|
||||
var romName = rom.getstring(0x00000020)
|
||||
console.log('Internal ROM name: ' + romName)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel" id="events">
|
||||
<div class="classname">events</div>
|
||||
<!--
|
||||
<div class="property">
|
||||
<div class="propertyname">events.on(hook, callback, tag)</div>
|
||||
<div class="propertydesc">
|
||||
<pre class="example"></pre>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="property">
|
||||
<span class="tag2">emulation thread</span>
|
||||
<span class="tag">interpreter mode</span>
|
||||
<div class="propertyname">events.onexec(address, callback)</div>
|
||||
<div class="propertydesc">
|
||||
Adds a CPU execution callback for a virtual address or <a href="AddressRange">AddressRange</a> and returns a callback ID.
|
||||
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the program counter is at <span class="snip">address</span>.
|
||||
<span class="snip">callback</span> receives the program counter address at which the event is fired.
|
||||
<pre class="example">
|
||||
events.onexec(0x802CB1C0, function()
|
||||
{
|
||||
console.log('CPU is calling 0x802CB1C0')
|
||||
})
|
||||
</pre>
|
||||
<pre class="example">
|
||||
events.onexec(ADDR_ANY, function(addr))
|
||||
{
|
||||
// Log every step!
|
||||
console.log('CPU is executing ' + addr.hex())
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<span class="tag2">emulation thread</span>
|
||||
<span class="tag">interpreter mode</span>
|
||||
<div class="propertyname">events.onread(address, callback)</div>
|
||||
<div class="propertydesc">
|
||||
Adds a CPU read callback for a virtual address or <a href="AddressRange">AddressRange</a> and returns a callback ID.
|
||||
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the current instruction is going to read from <span class="snip">address</span>.
|
||||
<span class="snip">callback</span> receives the virtual address that the CPU is going to read.
|
||||
<pre class="example">
|
||||
events.onread(0x8033B1B0, function()
|
||||
{
|
||||
console.log('CPU is reading 8033B1B0')
|
||||
})
|
||||
</pre>
|
||||
<pre class="example">
|
||||
const addr_range_rom = {start: 0xB0000000, end: 0xB6000000}
|
||||
|
||||
events.onread(addr_range_rom, function(addr)
|
||||
{
|
||||
console.log('CPU is reading ROM ' + addr)
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<span class="tag2">emulation thread</span>
|
||||
<span class="tag">interpreter mode</span>
|
||||
<div class="propertyname">events.onwrite(address, callback)</div>
|
||||
<div class="propertydesc">
|
||||
Adds a CPU write callback for a virtual address or <a href="AddressRange">AddressRange</a> and returns a callback ID.
|
||||
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the current instruction is going to write to <span class="snip">address</span>.
|
||||
<span class="snip">callback</span> receives the virtual address that the CPU is going to write to.
|
||||
<pre class="example">
|
||||
events.onwrite(0x8033B1B0, function()
|
||||
{
|
||||
console.log('CPU is modifying 8033B1B0')
|
||||
})
|
||||
</pre>
|
||||
<pre class="example">
|
||||
events.onwrite({0xB0000000, 0x90000000}, function(addr)
|
||||
{
|
||||
console.log(gpr.pc.hex() + ': wrote to cartridge ' + addr.hex());
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<span class="tag2">emulation thread</span>
|
||||
<div class="propertyname">events.ondraw(callback)</div>
|
||||
<div class="propertydesc">
|
||||
Adds a callback which will be invoked immediately after Project64 requests a screen update from the graphics plugin.
|
||||
Returns a callback ID.
|
||||
<pre class="example">
|
||||
events.ondraw(function()
|
||||
{
|
||||
console.log('Frame drawn')
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">events.remove(callbackId)</div>
|
||||
<div class="propertydesc">
|
||||
Removes a registered callback by its ID.
|
||||
<pre class="example">
|
||||
var callbackId = events.onexec(0x80000180, function()
|
||||
{
|
||||
// Only invoked once
|
||||
console.log('Interrupt fired')
|
||||
events.remove(callbackId)
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<!-- template
|
||||
<div class="property">
|
||||
<div class="propertyname"></div>
|
||||
<div class="propertydesc">
|
||||
<pre class="example"></pre>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="panel" id="debug">
|
||||
<div class="classname">debug</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">debug.breakhere()</div>
|
||||
<div class="propertydesc">
|
||||
Pauses emulation and opens the debugger window. Useful for creating conditional breakpoints.
|
||||
<pre class="example">
|
||||
events.onexec(0x802CB1C0, function()
|
||||
{
|
||||
if(gpr.a0 == 0)
|
||||
{
|
||||
console.log('0 passed to 0x802CB1C0, breaking')
|
||||
debug.breakhere()
|
||||
}
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="console">
|
||||
<div class="classname">console</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">console.print(text)</div>
|
||||
<div class="propertydesc">
|
||||
Prints text to the script console.
|
||||
<pre class="example">console.print('Hello world\n')</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">console.log(text[, text2, ...])</div>
|
||||
<div class="propertydesc">
|
||||
Concatenates all provided text arguments with spaces and prints the result to the script console with a trailing newline.
|
||||
<pre class="example">console.log('Hello', 'world')</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">console.clear()</div>
|
||||
<div class="propertydesc">
|
||||
Clears all previously printed text from the script console.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="alert">
|
||||
<div class="classname">alert</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">alert(message[, caption])</div>
|
||||
<div class="propertydesc">
|
||||
Shows a message box with an optional caption.
|
||||
The calling thread will be blocked until the message box is dismissed.
|
||||
<pre class="example">
|
||||
alert('Hello world') // Blocks the script's thread
|
||||
|
||||
events.onexec(0x80000180, function()
|
||||
{
|
||||
alert('Interrupt fired!') // Blocks the emulation thread
|
||||
})</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="screen">
|
||||
<div class="classname">screen</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">screen.print(x, y, text)</div>
|
||||
<div class="propertydesc">
|
||||
Prints <span class="snip">text</span> to the screen at the provided <span class="snip">x</span> and <span class="snip">y</span> coordinates.
|
||||
Should be called from an <span class="snip">events.ondraw</span> callback.
|
||||
<b>(Unstable!)</b>
|
||||
<pre class="example">
|
||||
events.ondraw(function()
|
||||
{
|
||||
screen.print(20, 20, "power: ' + mem.u8[0x8033B21E])
|
||||
})</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="gpr">
|
||||
<div class="classname">gpr</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">gpr.r0|at|v0|v1|a0 ...</div>
|
||||
<div class="propertyname">gpr[0|1|2 ...]</div>
|
||||
<div class="propertydesc">
|
||||
Variables representing the lower 32 bits of each general purpose register.
|
||||
<pre class="example">
|
||||
events.onexec(0x802CB1C0, function()
|
||||
{
|
||||
if(gpr.a0 == 2)
|
||||
{
|
||||
gpr.a0 = 3
|
||||
}
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">gpr.pc</div>
|
||||
<div class="propertydesc">
|
||||
Variable representing the CPU's program counter.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">gpr.hi</div>
|
||||
<div class="propertydesc">
|
||||
Variable representing the lower 32 bits of the HI register.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">gpr.lo</div>
|
||||
<div class="propertydesc">
|
||||
Variable representing the lower 32 bits of the LO register.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="ugpr">
|
||||
<div class="classname">ugpr</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">ugpr.r0|at|v0|v1|a0 ...</div>
|
||||
<div class="propertyname">ugpr[0|1|2 ...]</div>
|
||||
<div class="propertydesc">
|
||||
Variables representing the upper 32 bits of each general purpose register.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">ugpr.hi</div>
|
||||
<div class="propertydesc">
|
||||
Variable representing the upper 32 bits of the HI register.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">ugpr.lo</div>
|
||||
<div class="propertydesc">
|
||||
Variable representing the upper 32 bits of the LO register.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="fpr">
|
||||
<div class="classname">fpr</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">fpr.f0|f1|f2|f3|f4 ...</div>
|
||||
<div class="propertyname">fpr[0|1|2 ...]</div>
|
||||
<div class="propertydesc">
|
||||
Variables representing the 32-bit floating point registers.
|
||||
<pre class="example">
|
||||
events.onexec(0x802CB1C0, function()
|
||||
{
|
||||
if(gpr.f0 == 2.0)
|
||||
{
|
||||
gpr.f0 = 3.0
|
||||
}
|
||||
})
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="dfpr">
|
||||
<div class="classname">dfpr</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">dfpr.f0|f2|f4|f6 ...</div>
|
||||
<div class="propertyname">dfpr[0|2|4 ...]</div>
|
||||
<div class="propertydesc">
|
||||
Variables representing the 64-bit floating point registers.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel" id="Server">
|
||||
<div class="classname">Server</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">new Server(settings)</div>
|
||||
<div class="propertydesc">
|
||||
Creates a new server socket.
|
||||
If <span class="snip">port</span> is provided in <span class="snip">settings</span>, the server will start listening immediately.
|
||||
<pre class="example">var server = new Server({port: 80})</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">server.listen(port)</div>
|
||||
<div class="propertydesc">
|
||||
Binds the server socket to a port and starts listening.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">server.on('connection', callback)</div>
|
||||
<div class="propertydesc">
|
||||
Starts accepting clients.
|
||||
When a client is accepted, a Socket object for it is created and passed to <span class="snip">callback</span>.
|
||||
<pre class="example">
|
||||
server.on('connection', function(socket)
|
||||
{
|
||||
socket.on('data', function(data)
|
||||
{
|
||||
socket.write('hello')
|
||||
})
|
||||
})</pre>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
server.listen(port)
|
||||
server.on(evt, callback)
|
||||
'connection' -> callback(socket)-->
|
||||
</div>
|
||||
|
||||
<div class="panel" id="Socket">
|
||||
<div class="classname">Socket</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">new Socket([fd])</div>
|
||||
<div class="propertydesc">
|
||||
Creates a new socket object.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">socket.connect(settings[, callback])</div>
|
||||
<div class="propertydesc">
|
||||
Connects the socket to the <span class="snip">host</span> and <span class="snip">port</span> specified by the <span class="snip">settings</span> object.
|
||||
The default values for the host and port are <span class="snip">"127.0.0.1"</span> and <span class="snip">80</span> respectively.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">socket.write(data[, callback])</div>
|
||||
<div class="propertydesc">
|
||||
Writes <span class="snip">data</span> to the socket.
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">socket.on('data', callback)</div>
|
||||
<div class="propertydesc">
|
||||
Starts reading data from the socket asynchronously. When data arrives, it is passed to <span class="snip">callback</span> as a Buffer object.
|
||||
<!--<pre class="example"></pre>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">socket.on('close', callback)</div>
|
||||
<div class="propertydesc">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="AddressRange">
|
||||
<div class="classname">AddressRange</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">new AddressRange(start, end)</div>
|
||||
<div class="propertydesc">
|
||||
Creates an immutable object with <span class="snip">start</span> and <span class="snip">end</span> address properties.<br>
|
||||
The following <b>AddressRange</b> objects are defined globally:
|
||||
<pre>
|
||||
<b>ADDR_ANY</b> 0x00000000 : 0x100000000 Any 32-bit address
|
||||
|
||||
<b>ADDR_ANY_KUSEG</b> 0x00000000 : 0x80000000 MIPS user mode TLB mapped segment
|
||||
<b>ADDR_ANY_KSEG0</b> 0x80000000 : 0xA0000000 MIPS cached unmapped segment
|
||||
<b>ADDR_ANY_KSEG1</b> 0xA0000000 : 0xC0000000 MIPS uncached unmapped segment
|
||||
<b>ADDR_ANY_KSEG2</b> 0xC0000000 : 0x100000000 MIPS kernel mode TLB mapped segment
|
||||
|
||||
<b>ADDR_ANY_RDRAM</b> 0x80000000 : 0x80800000 Cached RDRAM
|
||||
<b>ADDR_ANY_RDRAM_UNC</b> 0xA0000000 : 0xA0800000 Uncached RDRAM
|
||||
|
||||
<b>ADDR_ANY_CART_ROM</b> 0x90000000 : 0x96000000 Cached cartridge ROM
|
||||
<b>ADDR_ANY_CART_ROM_UNC</b> 0xB0000000 : 0xB6000000 Uncached cartridge ROM
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel" id="Number">
|
||||
<div class="classname">Number</div>
|
||||
<div class="property">
|
||||
<div class="propertyname">number.hex([nChars])</div>
|
||||
<div class="propertydesc">
|
||||
Returns a hexadecimal string representation of the number object. The resulting string is prepended with zeroes until its character length meets <span class="snip">nChars</span> or 8 by default.
|
||||
<pre class="example">
|
||||
var sm64EntryPC = rom.u32[0x00000008]
|
||||
console.log("Entry: " + sm64EntryPC.hex()) // "Entry: 80246000"</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="panel">
|
||||
alert(message)<br>
|
||||
_native<br>
|
||||
_native.addCallback(hook, callback, tag)<br>
|
||||
_native.setGPRVal(regnum, val)<br>
|
||||
_native.getGPRVal(regnum)<br>
|
||||
_native.getRDRAMInt(address, bitWidth)<br>
|
||||
_native.setRDRAMInt(address, bitWidth, val)<br>
|
||||
_native.getRDRAMFloat(address[, bDouble])<br>
|
||||
_native.setRDRAMFloat(address, val[, bDouble])<br>
|
||||
_native.sockCreate(port)<br>
|
||||
_native.sockListen(fd)<br>
|
||||
_native.sockAccept(fd)<br>
|
||||
_native.sockRead(fd, callback)<br>
|
||||
_native.sockWrite(fd, data, callback)<br>
|
||||
_native.msgBox(message[, caption])<br>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
var domSidebar = document.getElementById('sidebar');
|
||||
var baseTop = domSidebar.getBoundingClientRect().top + window.scrollY;
|
||||
document.onscroll = function(){
|
||||
if(window.scrollY > baseTop) {
|
||||
domSidebar.style.position = "fixed";
|
||||
domSidebar.style.top = '0px';
|
||||
} else {
|
||||
domSidebar.style.position = "absolute";
|
||||
domSidebar.style.top = baseTop + 'px';
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue