diff --git a/SConstruct b/SConstruct
index 4ff9b1b3e2..3698a2541d 100644
--- a/SConstruct
+++ b/SConstruct
@@ -67,6 +67,7 @@ dirs = [
'Source/Plugins/Plugin_VideoOGL/Src',
'Source/Plugins/Plugin_DSP_HLE/Src',
'Source/Plugins/Plugin_DSP_LLE/Src',
+ 'Source/Plugins/Plugin_DSP_LLE-testing/Src',
'Source/Plugins/Plugin_PadSimple/Src',
'Source/Plugins/Plugin_PadSimpleEvnt/Src',
'Source/Plugins/Plugin_nJoy_SDL/Src',
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.sln b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.sln
new file mode 100644
index 0000000000..f046e7bf54
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_DSP_LLE", "Plugin_DSP_LLE.vcproj", "{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|Win32.Build.0 = Debug|Win32
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|x64.ActiveCfg = Debug|x64
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|x64.Build.0 = Debug|x64
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.ActiveCfg = Release|Win32
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.Build.0 = Release|Win32
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|x64.ActiveCfg = Release|x64
+ {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj
new file mode 100644
index 0000000000..ff1aeb5d63
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Plugin_DSP_LLE.vcproj
@@ -0,0 +1,869 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Res/atlres.h b/Source/Plugins/Plugin_DSP_LLE-testing/Res/atlres.h
new file mode 100644
index 0000000000..4fec890c15
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Res/atlres.h
@@ -0,0 +1,262 @@
+// Windows Template Library - WTL version 8.0
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//
+// This file is a part of the Windows Template Library.
+// The use and distribution terms for this software are covered by the
+// Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
+// which can be found in the file CPL.TXT at the root of this distribution.
+// By using this software in any fashion, you are agreeing to be bound by
+// the terms of this license. You must not remove this notice, or
+// any other, from this software.
+
+#ifndef __ATLRES_H__
+#define __ATLRES_H__
+
+#pragma once
+
+#if defined (_WIN32_WCE) && !defined (__ATLRESCE_H__)
+ #error Use atlresCE.h instead of atlres.h for Windows CE
+#endif
+
+
+#ifdef RC_INVOKED
+#ifndef _INC_WINDOWS
+
+#define _INC_WINDOWS
+
+ #ifndef _WIN32_WCE
+#define VS_VERSION_INFO 1
+
+ #ifdef APSTUDIO_INVOKED
+#define APSTUDIO_HIDDEN_SYMBOLS // Ignore following symbols
+ #endif // APSTUDIO_INVOKED
+
+ #ifndef WINVER
+#define WINVER 0x0400 // default to Windows Version 4.0
+ #endif // !WINVER
+
+ #include
+
+// operation messages sent to DLGINIT
+#define LB_ADDSTRING (WM_USER + 1)
+#define CB_ADDSTRING (WM_USER + 3)
+ #endif // !_WIN32_WCE
+
+ #ifdef APSTUDIO_INVOKED
+ #undef APSTUDIO_HIDDEN_SYMBOLS
+ #endif // APSTUDIO_INVOKED
+
+ #ifdef IDC_STATIC
+ #undef IDC_STATIC
+ #endif // IDC_STATIC
+#define IDC_STATIC (-1)
+
+#endif // !_INC_WINDOWS
+#endif // RC_INVOKED
+
+#ifdef APSTUDIO_INVOKED
+#define APSTUDIO_HIDDEN_SYMBOLS
+#endif // APSTUDIO_INVOKED
+
+///////////////////////////////////////////////////////////////////////////////
+// ATL resource types
+
+#ifndef RC_INVOKED
+#define RT_DLGINIT MAKEINTRESOURCE(240)
+#define RT_TOOLBAR MAKEINTRESOURCE(241)
+#endif // RC_INVOKED
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef APSTUDIO_INVOKED
+ #undef APSTUDIO_HIDDEN_SYMBOLS
+#endif // APSTUDIO_INVOKED
+
+///////////////////////////////////////////////////////////////////////////////
+// Standard window components
+
+#define ID_SEPARATOR 0 // special separator value
+#define ID_DEFAULT_PANE 0 // default status bar pane
+
+#ifndef RC_INVOKED // code only
+// standard control bars (IDW = window ID)
+#define ATL_IDW_TOOLBAR 0xE800 // main Toolbar for window
+#define ATL_IDW_STATUS_BAR 0xE801 // Status bar window
+#define ATL_IDW_COMMAND_BAR 0xE802 // Command bar window
+
+// parts of a frame window
+#define ATL_IDW_CLIENT 0xE900
+#define ATL_IDW_PANE_FIRST 0xE900 // first pane (256 max)
+#define ATL_IDW_PANE_LAST 0xE9FF
+#define ATL_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
+#define ATL_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
+
+#define ATL_IDW_SIZE_BOX 0xEA20 // size box for splitters
+#define ATL_IDW_PANE_SAVE 0xEA21 // to shift ATL_IDW_PANE_FIRST
+
+// bands for a rebar
+#define ATL_IDW_BAND_FIRST 0xEB00
+#define ATL_IDW_BAND_LAST 0xEBFF
+#endif // !RC_INVOKED
+
+///////////////////////////////////////////////////////////////////////////////
+// Standard Commands
+
+// File commands
+#define ID_FILE_NEW 0xE100
+#define ID_FILE_OPEN 0xE101
+#define ID_FILE_CLOSE 0xE102
+#define ID_FILE_SAVE 0xE103
+#define ID_FILE_SAVE_AS 0xE104
+#define ID_FILE_PAGE_SETUP 0xE105
+#define ID_FILE_PRINT_SETUP 0xE106
+#define ID_FILE_PRINT 0xE107
+#define ID_FILE_PRINT_DIRECT 0xE108
+#define ID_FILE_PRINT_PREVIEW 0xE109
+#define ID_FILE_UPDATE 0xE10A
+#define ID_FILE_SAVE_COPY_AS 0xE10B
+#define ID_FILE_SEND_MAIL 0xE10C
+
+#define ID_FILE_MRU_FIRST 0xE110
+#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
+#define ID_FILE_MRU_FILE2 0xE111
+#define ID_FILE_MRU_FILE3 0xE112
+#define ID_FILE_MRU_FILE4 0xE113
+#define ID_FILE_MRU_FILE5 0xE114
+#define ID_FILE_MRU_FILE6 0xE115
+#define ID_FILE_MRU_FILE7 0xE116
+#define ID_FILE_MRU_FILE8 0xE117
+#define ID_FILE_MRU_FILE9 0xE118
+#define ID_FILE_MRU_FILE10 0xE119
+#define ID_FILE_MRU_FILE11 0xE11A
+#define ID_FILE_MRU_FILE12 0xE11B
+#define ID_FILE_MRU_FILE13 0xE11C
+#define ID_FILE_MRU_FILE14 0xE11D
+#define ID_FILE_MRU_FILE15 0xE11E
+#define ID_FILE_MRU_FILE16 0xE11F
+#define ID_FILE_MRU_LAST 0xE11F
+
+// Edit commands
+#define ID_EDIT_CLEAR 0xE120
+#define ID_EDIT_CLEAR_ALL 0xE121
+#define ID_EDIT_COPY 0xE122
+#define ID_EDIT_CUT 0xE123
+#define ID_EDIT_FIND 0xE124
+#define ID_EDIT_PASTE 0xE125
+#define ID_EDIT_PASTE_LINK 0xE126
+#define ID_EDIT_PASTE_SPECIAL 0xE127
+#define ID_EDIT_REPEAT 0xE128
+#define ID_EDIT_REPLACE 0xE129
+#define ID_EDIT_SELECT_ALL 0xE12A
+#define ID_EDIT_UNDO 0xE12B
+#define ID_EDIT_REDO 0xE12C
+
+// Window commands
+#define ID_WINDOW_NEW 0xE130
+#define ID_WINDOW_ARRANGE 0xE131
+#define ID_WINDOW_CASCADE 0xE132
+#define ID_WINDOW_TILE_HORZ 0xE133
+#define ID_WINDOW_TILE_VERT 0xE134
+#define ID_WINDOW_SPLIT 0xE135
+#ifndef RC_INVOKED // code only
+#define ATL_IDM_WINDOW_FIRST 0xE130
+#define ATL_IDM_WINDOW_LAST 0xE13F
+#define ATL_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
+#define ATL_IDM_LAST_MDICHILD 0xFFFD
+#endif // !RC_INVOKED
+// TabView
+#define ID_WINDOW_TABFIRST 0xFF00 // = ATL_IDM_FIRST_MDICHILD
+#define ID_WINDOW_TABLAST 0xFFFD
+#define ID_WINDOW_SHOWTABLIST 0xFFFE
+
+// Help and App commands
+#define ID_APP_ABOUT 0xE140
+#define ID_APP_EXIT 0xE141
+#define ID_HELP_INDEX 0xE142
+#define ID_HELP_FINDER 0xE143
+#define ID_HELP_USING 0xE144
+#define ID_CONTEXT_HELP 0xE145 // shift-F1
+// special commands for processing help
+#define ID_HELP 0xE146 // first attempt for F1
+#define ID_DEFAULT_HELP 0xE147 // last attempt
+
+// Misc
+#define ID_NEXT_PANE 0xE150
+#define ID_PREV_PANE 0xE151
+#define ID_PANE_CLOSE 0xE152
+
+// Format
+#define ID_FORMAT_FONT 0xE160
+
+// Scroll
+#define ID_SCROLL_UP 0xE170
+#define ID_SCROLL_DOWN 0xE171
+#define ID_SCROLL_PAGE_UP 0xE172
+#define ID_SCROLL_PAGE_DOWN 0xE173
+#define ID_SCROLL_TOP 0xE174
+#define ID_SCROLL_BOTTOM 0xE175
+#define ID_SCROLL_LEFT 0xE176
+#define ID_SCROLL_RIGHT 0xE177
+#define ID_SCROLL_PAGE_LEFT 0xE178
+#define ID_SCROLL_PAGE_RIGHT 0xE179
+#define ID_SCROLL_ALL_LEFT 0xE17A
+#define ID_SCROLL_ALL_RIGHT 0xE17B
+
+// OLE commands
+#define ID_OLE_INSERT_NEW 0xE200
+#define ID_OLE_EDIT_LINKS 0xE201
+#define ID_OLE_EDIT_CONVERT 0xE202
+#define ID_OLE_EDIT_CHANGE_ICON 0xE203
+#define ID_OLE_EDIT_PROPERTIES 0xE204
+#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
+#ifndef RC_INVOKED // code only
+#define ID_OLE_VERB_LAST 0xE21F
+#endif // !RC_INVOKED
+
+// View commands (same number used as IDW used for toolbar and status bar)
+#define ID_VIEW_TOOLBAR 0xE800
+#define ID_VIEW_STATUS_BAR 0xE801
+#define ID_VIEW_REFRESH 0xE803
+
+///////////////////////////////////////////////////////////////////////////////
+// Standard control IDs
+
+#ifdef IDC_STATIC
+ #undef IDC_STATIC
+#endif // IDC_STATIC
+#define IDC_STATIC (-1) // all static controls
+
+///////////////////////////////////////////////////////////////////////////////
+// Standard string error/warnings
+
+// idle status bar message
+#define ATL_IDS_IDLEMESSAGE 0xE001
+
+#ifndef RC_INVOKED // code only
+#define ATL_IDS_SCFIRST 0xEF00
+#endif // !RC_INVOKED
+
+#define ATL_IDS_SCSIZE 0xEF00
+#define ATL_IDS_SCMOVE 0xEF01
+#define ATL_IDS_SCMINIMIZE 0xEF02
+#define ATL_IDS_SCMAXIMIZE 0xEF03
+#define ATL_IDS_SCNEXTWINDOW 0xEF04
+#define ATL_IDS_SCPREVWINDOW 0xEF05
+#define ATL_IDS_SCCLOSE 0xEF06
+#define ATL_IDS_SCRESTORE 0xEF12
+#define ATL_IDS_SCTASKLIST 0xEF13
+
+#define ATL_IDS_MDICHILD 0xEF1F
+#define ATL_IDS_MRU_FILE 0xEFDA
+
+///////////////////////////////////////////////////////////////////////////////
+// Misc. control IDs
+
+// Property Sheet control id's (determined with Spy++)
+#define ID_APPLY_NOW 0x3021
+#define ID_WIZBACK 0x3023
+#define ID_WIZNEXT 0x3024
+#define ID_WIZFINISH 0x3025
+#define ATL_IDC_TAB_CONTROL 0x3020
+
+#endif // __ATLRES_H__
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Res/resource.h b/Source/Plugins/Plugin_DSP_LLE-testing/Res/resource.h
new file mode 100644
index 0000000000..7d5ff49484
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Res/resource.h
@@ -0,0 +1,30 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by resources.rc
+//
+#define IDR_MAINFRAME 128
+#define IDD_MAINDLG 129
+#define IDD_DISASMDLG 129
+#define IDD_DISASMDLG1 130
+#define IDD_REGISTERDLG 130
+#define IDC_LIST1 1000
+#define IDC_DISASM_LIST 1000
+#define ID_STEP 1001
+#define ID_SHOW_REGISTER 1002
+#define IDC_ASSERT_INT 1003
+#define ID_GO 1004
+#define IDC_HALT 1005
+#define IDC_HALT2 1006
+#define IDC_INIT 1006
+#define IDC_GROUP 1007
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 202
+#define _APS_NEXT_COMMAND_VALUE 32772
+#define _APS_NEXT_CONTROL_VALUE 1008
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Res/resources.rc b/Source/Plugins/Plugin_DSP_LLE-testing/Res/resources.rc
new file mode 100644
index 0000000000..030efd07b1
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Res/resources.rc
@@ -0,0 +1,323 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "atlres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDR_MAINFRAME DIALOGEX 0, 0, 186, 94
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,129,7,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDR_MAINFRAME, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 87
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""atlres.h""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DISASMDLG DIALOGEX 0, 0, 513, 298
+STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
+CAPTION "Debugger"
+FONT 8, "Tahoma", 400, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "Step",ID_STEP,456,7,50,14
+ CONTROL "",IDC_DISASM_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SORTDESCENDING | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,445,284
+ PUSHBUTTON "&Show Regs",ID_SHOW_REGISTER,456,277,50,14
+ DEFPUSHBUTTON "Go",ID_GO,456,23,50,14
+ CONTROL "AssertInt",IDC_ASSERT_INT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,455,50,51,9
+ CONTROL "Halt",IDC_HALT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,455,63,51,9
+ CONTROL "Init",IDC_INIT,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,455,75,51,9
+END
+
+IDD_REGISTERDLG DIALOGEX 0, 0, 312, 170
+STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
+CAPTION "Registers Dialog"
+FONT 8, "Tahoma", 400, 0, 0x0
+BEGIN
+ CONTROL "",IDC_DISASM_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTDESCENDING | LVS_ALIGNLEFT | LVS_NOSCROLL | WS_BORDER | WS_TABSTOP,7,7,298,156
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DISASMDLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 506
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 291
+ END
+
+ IDD_REGISTERDLG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 305
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 163
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS
+BEGIN
+ "N", ID_FILE_NEW, VIRTKEY, CONTROL
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL
+ "S", ID_FILE_SAVE, VIRTKEY, CONTROL
+ "P", ID_FILE_PRINT, VIRTKEY, CONTROL
+ "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL
+ "X", ID_EDIT_CUT, VIRTKEY, CONTROL
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL
+ "V", ID_EDIT_PASTE, VIRTKEY, CONTROL
+ VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT
+ VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL
+ VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT
+ VK_F6, ID_NEXT_PANE, VIRTKEY
+ VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0"
+ BEGIN
+ VALUE "FileDescription", "test1 Module"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "TEST1"
+ VALUE "LegalCopyright", "Copyright 2004"
+ VALUE "OriginalFilename", "demoproject1.exe"
+ VALUE "ProductName", "demoproject1 Module"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDR_MAINFRAME "demoproject1"
+END
+
+STRINGTABLE
+BEGIN
+ ID_FILE_NEW "Create a new document\nNew"
+ ID_FILE_OPEN "Open an existing document\nOpen"
+ ID_FILE_CLOSE "Close the active document\nClose"
+ ID_FILE_SAVE "Save the active document\nSave"
+ ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
+ ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup"
+ ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup"
+ ID_FILE_PRINT "Print the active document\nPrint"
+ ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
+END
+
+STRINGTABLE
+BEGIN
+ ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
+ ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
+END
+
+STRINGTABLE
+BEGIN
+ ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
+ ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
+END
+
+STRINGTABLE
+BEGIN
+ ID_WINDOW_NEW "Open another window for the active document\nNew Window"
+ ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
+ ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows"
+ ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows"
+ ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
+END
+
+STRINGTABLE
+BEGIN
+ ID_EDIT_CLEAR "Erase the selection\nErase"
+ ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
+ ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
+ ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
+ ID_EDIT_FIND "Find the specified text\nFind"
+ ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
+ ID_EDIT_REPEAT "Repeat the last action\nRepeat"
+ ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
+ ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
+ ID_EDIT_UNDO "Undo the last action\nUndo"
+ ID_EDIT_REDO "Redo the previously undone action\nRedo"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_SCSIZE "Change the window size"
+ ATL_IDS_SCMOVE "Change the window position"
+ ATL_IDS_SCMINIMIZE "Reduce the window to an icon"
+ ATL_IDS_SCMAXIMIZE "Enlarge the window to full size"
+ ATL_IDS_SCNEXTWINDOW "Switch to the next document window"
+ ATL_IDS_SCPREVWINDOW "Switch to the previous document window"
+ ATL_IDS_SCCLOSE "Close the active window and prompts to save the documents"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_SCRESTORE "Restore the window to normal size"
+ ATL_IDS_SCTASKLIST "Activate Task List"
+ ATL_IDS_MDICHILD "Activate this window"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_IDLEMESSAGE "Ready"
+END
+
+STRINGTABLE
+BEGIN
+ ATL_IDS_MRU_FILE "Open this document"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.cpp
new file mode 100644
index 0000000000..7e416ebfbe
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.cpp
@@ -0,0 +1,126 @@
+#include
+#include
+#include "AOSoundStream.h"
+
+namespace AOSound
+{
+ pthread_t thread;
+ StreamCallback callback;
+
+ char *buffer;
+ int buf_size;
+
+ ao_device *device;
+ ao_sample_format format;
+ int default_driver;
+
+ int bufferSize;
+ int totalRenderedBytes;
+ int sampleRate;
+ volatile int threadData;
+ int currentPos;
+ int lastPos;
+ short realtimeBuffer[1024 * 1024];
+ int AOSound_GetSampleRate()
+ {
+ return sampleRate;
+ }
+ bool WriteDataToBuffer(int dwOffset,char* soundData, int dwSoundBytes)
+ {
+ //void* ptr1, * ptr2;
+ //DWORD numBytes1, numBytes2;
+ // Obtain memory address of write block. This will be in two parts if the block wraps around.
+ //HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
+
+ // If the buffer was lost, restore and retry lock.
+ /*if (DSERR_BUFFERLOST == hr)
+ {
+ dsBuffer->Restore();
+ hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ memcpy(ptr1, soundData, numBytes1);
+
+ if (ptr2 != 0)
+ {
+ memcpy(ptr2, soundData + numBytes1, numBytes2);
+ }
+
+ // Release the data back to DirectSound.
+ dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2);
+ return(true);
+ }
+
+ return(false);*/
+ ao_play(device, soundData, dwSoundBytes);
+ return true;
+
+ }
+
+ void* soundThread(void*)
+ {
+ currentPos = 0;
+ lastPos = 0;
+
+ // Prefill buffer?
+ //writeDataToBuffer(0,realtimeBuffer,bufferSize);
+ // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0);
+ //dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
+
+ while (!threadData)
+ {
+ // No blocking inside the csection
+ //dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0);
+ int numBytesToRender = 256;
+
+ if (numBytesToRender >= 256)
+ {
+ (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2);
+
+ WriteDataToBuffer(0, (char*)realtimeBuffer, numBytesToRender);
+ //currentPos = ModBufferSize(lastPos + numBytesToRender);
+ //totalRenderedBytes += numBytesToRender;
+
+ //lastPos = currentPos;
+ }
+
+ //WaitForSingleObject(soundSyncEvent, MAXWAIT);
+ }
+
+ //dsBuffer->Stop();
+ return(0); //hurra!
+ }
+ bool AOSound_StartSound(int _sampleRate, StreamCallback _callback)
+ {
+ callback = _callback;
+ threadData = 0;
+ sampleRate = _sampleRate;
+
+ //no security attributes, automatic resetting, init state nonset, untitled
+ //soundSyncEvent = CreateEvent(0, false, false, 0);
+ ao_initialize();
+ default_driver = ao_default_driver_id();
+ format.bits = 16;
+ format.channels = 2;
+ format.rate = sampleRate;
+ format.byte_format = AO_FMT_LITTLE;
+
+ //vi vill ha access till DSOUND så...
+ device = ao_open_live(default_driver, &format, NULL /* no options */);
+ if (device == NULL) {
+ fprintf(stderr, "DSP_LLE: Error opening AO device.\n");
+ return 1;
+ }
+ buf_size = format.bits/8 * format.channels * format.rate;
+ buffer = (char*)calloc(buf_size, sizeof(char));
+ pthread_create(&thread, NULL, soundThread, (void *)NULL);
+ return(true);
+ }
+ void AOSound_StopSound()
+ {
+ ao_close(device);
+ ao_shutdown();
+ }
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.h
new file mode 100644
index 0000000000..dfef628e0c
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/AOSoundStream.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef __AOSOUNDSTREAM_H__
+#define __AOSOUNDSTREAM_H__
+
+namespace AOSound
+{
+typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels);
+
+bool AOSound_StartSound(int sampleRate, StreamCallback _callback);
+void AOSound_UpdateSound();
+void AOSound_StopSound();
+
+float AOSound_GetTimer();
+int AOSound_GetCurSample();
+int AOSound_GetSampleRate();
+}
+
+
+#endif //__AOSOUNDSTREAM_H__
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.cpp
new file mode 100644
index 0000000000..823003e17b
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.cpp
@@ -0,0 +1,280 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+
+#include
+#include
+
+#include "DSoundStream.h"
+
+namespace DSound
+{
+#define BUFSIZE 32768
+#define MAXWAIT 70 //ms
+
+//THE ROCK SOLID SYNCED DSOUND ENGINE :)
+
+
+//våran kritiska sektion och vår syncevent-handle
+CRITICAL_SECTION soundCriticalSection;
+HANDLE soundSyncEvent;
+HANDLE hThread;
+
+StreamCallback callback;
+
+//lite mojs
+IDirectSound8* ds;
+IDirectSoundBuffer* dsBuffer;
+
+//tja.. behövs
+int bufferSize; //i bytes
+int totalRenderedBytes;
+int sampleRate;
+
+//med den här synkar vi stängning..
+//0=vi spelar oväsen, 1=stäng tråden NU! 2=japp,tråden är stängd så fortsätt
+volatile int threadData;
+
+
+//ser till så X kan delas med 32
+inline int FIX32(int x)
+{
+ return(x & (~127));
+}
+
+
+int DSound_GetSampleRate()
+{
+ return(sampleRate);
+}
+
+
+//Dags att skapa vår directsound buffert
+bool createBuffer()
+{
+ PCMWAVEFORMAT pcmwf;
+ DSBUFFERDESC dsbdesc;
+
+ //ljudformatet
+ memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
+ memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
+
+ pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
+ pcmwf.wf.nChannels = 2;
+ pcmwf.wf.nSamplesPerSec = sampleRate;
+ pcmwf.wf.nBlockAlign = 4;
+ pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
+ pcmwf.wBitsPerSample = 16;
+
+ //buffer description
+ dsbdesc.dwSize = sizeof(DSBUFFERDESC);
+ dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
+ dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //ändra för att ställa in bufferstorlek
+ dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf;
+ // nu skapar vi bufferjäveln
+
+ if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL)))
+ {
+ dsBuffer->SetCurrentPosition(0);
+ return(true);
+ }
+ else
+ {
+ // Failed.
+ dsBuffer = NULL;
+ return(false);
+ }
+}
+
+
+bool writeDataToBuffer(DWORD dwOffset, // Our own write cursor.
+ char* soundData, // Start of our data.
+ DWORD dwSoundBytes) // Size of block to copy.
+{
+ void* ptr1, * ptr2;
+ DWORD numBytes1, numBytes2;
+ // Obtain memory address of write block. This will be in two parts if the block wraps around.
+ HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
+
+ // If the buffer was lost, restore and retry lock.
+
+ if (DSERR_BUFFERLOST == hr)
+ {
+ dsBuffer->Restore();
+ hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ memcpy(ptr1, soundData, numBytes1);
+
+ if (ptr2 != 0)
+ {
+ memcpy(ptr2, soundData + numBytes1, numBytes2);
+ }
+
+ // Release the data back to DirectSound.
+ dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2);
+ return(true);
+ } /*
+ else
+ {
+ char temp[8];
+ sprintf(temp,"%i\n",hr);
+ OutputDebugString(temp);
+ }*/
+
+ return(false);
+}
+
+
+inline int ModBufferSize(int x)
+{
+ return((x + bufferSize) % bufferSize);
+}
+
+
+int currentPos;
+int lastPos;
+short realtimeBuffer[1024 * 1024];
+
+
+DWORD WINAPI soundThread(void*)
+{
+ currentPos = 0;
+ lastPos = 0;
+ //writeDataToBuffer(0,realtimeBuffer,bufferSize);
+ // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0);
+
+ dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
+
+ while (!threadData)
+ {
+ EnterCriticalSection(&soundCriticalSection);
+
+ dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0);
+ int numBytesToRender = FIX32(ModBufferSize(currentPos - lastPos));
+
+ //renderStuff(numBytesToRender/2);
+ //if (numBytesToRender>bufferSize/2) numBytesToRender=0;
+
+ if (numBytesToRender >= 256)
+ {
+ (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2);
+
+ writeDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
+
+ currentPos = ModBufferSize(lastPos + numBytesToRender);
+ totalRenderedBytes += numBytesToRender;
+
+ lastPos = currentPos;
+ }
+
+ LeaveCriticalSection(&soundCriticalSection);
+ WaitForSingleObject(soundSyncEvent, MAXWAIT);
+ }
+
+ dsBuffer->Stop();
+
+ threadData = 2;
+ return(0); //hurra!
+}
+
+
+bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback)
+{
+ callback = _callback;
+ threadData = 0;
+ sampleRate = _sampleRate;
+
+ //no security attributes, automatic resetting, init state nonset, untitled
+ soundSyncEvent = CreateEvent(0, false, false, 0);
+
+ //vi initierar den...........
+ InitializeCriticalSection(&soundCriticalSection);
+
+ //vi vill ha access till DSOUND så...
+ if (FAILED(DirectSoundCreate8(0, &ds, 0)))
+ {
+ return(false);
+ }
+
+ //samarbetsvillig? nää :)
+ ds->SetCooperativeLevel(window, DSSCL_NORMAL); //DSSCL_PRIORITY?
+
+ //så.. skapa buffern
+ if (!createBuffer())
+ {
+ return(false);
+ }
+
+ //rensa den.. ?
+ DWORD num1;
+ short* p1;
+
+ dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
+
+ memset(p1, 0, num1);
+ dsBuffer->Unlock(p1, num1, 0, 0);
+ totalRenderedBytes = -bufferSize;
+ DWORD h;
+ hThread = CreateThread(0, 0, soundThread, 0, 0, &h);
+ SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
+ return(true);
+}
+
+
+void DSound_UpdateSound()
+{
+ SetEvent(soundSyncEvent);
+}
+
+
+void DSound_StopSound()
+{
+ EnterCriticalSection(&soundCriticalSection);
+ threadData = 1;
+ //kick the thread if it's waiting
+ SetEvent(soundSyncEvent);
+ LeaveCriticalSection(&soundCriticalSection);
+ WaitForSingleObject(hThread, INFINITE);
+ CloseHandle(hThread);
+
+ dsBuffer->Release();
+ ds->Release();
+
+ CloseHandle(soundSyncEvent);
+}
+
+
+int DSound_GetCurSample()
+{
+ EnterCriticalSection(&soundCriticalSection);
+ int playCursor;
+ dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0);
+ playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes;
+ LeaveCriticalSection(&soundCriticalSection);
+ return(playCursor);
+}
+
+
+float DSound_GetTimer()
+{
+ return((float)DSound_GetCurSample() * (1.0f / (4.0f * 44100.0f)));
+}
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.h
new file mode 100644
index 0000000000..99e3a9d7c6
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSoundStream.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef __SOUNDSTREAM_H__
+#define __SOUNDSTREAM_H__
+
+namespace DSound
+{
+typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels);
+
+bool DSound_StartSound(HWND window, int sampleRate, StreamCallback _callback);
+void DSound_UpdateSound();
+void DSound_StopSound();
+
+float DSound_GetTimer();
+int DSound_GetCurSample();
+int DSound_GetSampleRate();
+}
+
+
+#endif //__SOUNDSTREAM_H__
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmDlg.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmDlg.cpp
new file mode 100644
index 0000000000..a72c7a08fa
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmDlg.cpp
@@ -0,0 +1,667 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "stdafx.h"
+#include "../res/resource.h"
+#include "DisAsmDlg.h"
+
+#include "gdsp_memory.h"
+#include "gdsp_interpreter.h"
+#include "disassemble.h"
+#include "RegSettings.h"
+
+CDisAsmDlg::CDisAsmDlg()
+ : m_CachedStepCounter(-1)
+ , m_CachedCR(-1)
+ , m_State(RUN)
+ , m_CachedUCodeCRC(-1)
+{}
+
+
+BOOL CDisAsmDlg::PreTranslateMessage(MSG* pMsg)
+{
+ return(IsDialogMessage(pMsg));
+}
+
+
+BOOL CDisAsmDlg::OnIdle()
+{
+ return(FALSE);
+}
+
+
+LRESULT CDisAsmDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+{
+ CWindowSettings ws;
+
+ if (ws.Load("Software\\Dolphin\\DSP", "DisAsm"))
+ {
+ ws.ApplyTo(CWindow(m_hWnd), SW_SHOW);
+ }
+
+ m_DisAsmListViewCtrl.m_hWnd = GetDlgItem(IDC_DISASM_LIST);
+
+ UIAddChildWindowContainer(m_hWnd);
+
+ m_DisAsmListViewCtrl.AddColumn(_T("BP"), ColumnBP);
+ m_DisAsmListViewCtrl.AddColumn(_T("Function"), ColumnFunction);
+ m_DisAsmListViewCtrl.AddColumn(_T("Address"), ColumnAddress);
+ m_DisAsmListViewCtrl.AddColumn(_T("Mnenmomic"), ColumnMenmomic);
+ m_DisAsmListViewCtrl.AddColumn(_T("Opcode"), ColumnOpcode);
+ m_DisAsmListViewCtrl.AddColumn(_T("Ext"), ColumnExt);
+ m_DisAsmListViewCtrl.AddColumn(_T("Parameter"), ColumnParameter);
+
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnBP, 25);
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnFunction, 160);
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnAddress, 55);
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnMenmomic, 55);
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnOpcode, 60);
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnExt, 40);
+ m_DisAsmListViewCtrl.SetColumnWidth(ColumnParameter, 500);
+
+ m_DisAsmListViewCtrl.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
+
+ m_RegisterDlg.Create(m_hWnd);
+
+ UpdateDialog();
+
+ DlgResize_Init(true, false, WS_THICKFRAME);
+
+ return(TRUE);
+}
+
+
+LRESULT CDisAsmDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+{
+ CWindowSettings ws;
+ ws.GetFrom(CWindow(m_hWnd));
+ ws.Save("Software\\Dolphin\\DSP", "DisAsm");
+
+ return(0);
+}
+
+
+LRESULT CDisAsmDlg::OnStep(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+{
+ m_State = STEP;
+
+ UpdateButtonTexts();
+ return(0);
+}
+
+
+LRESULT CDisAsmDlg::OnGo(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+{
+ if ((m_State == RUN) || (m_State == RUN_START))
+ {
+ m_State = PAUSE;
+ }
+ else
+ {
+ m_State = RUN_START;
+ }
+
+ UpdateButtonTexts();
+ return(0);
+}
+
+
+LRESULT CDisAsmDlg::OnShowRegisters(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+{
+ if (m_RegisterDlg.IsWindowVisible())
+ {
+ m_RegisterDlg.ShowWindow(SW_HIDE);
+ }
+ else
+ {
+ m_RegisterDlg.ShowWindow(SW_SHOW);
+ }
+
+ UpdateButtonTexts();
+ return(0);
+}
+
+
+LRESULT CDisAsmDlg::OnDblClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
+{
+ int Index = m_DisAsmListViewCtrl.GetSelectedIndex();
+
+ if (Index != -1)
+ {
+ uint16 SelectedPC = static_cast(m_DisAsmListViewCtrl.GetItemData(Index));
+ ToggleBreakPoint(SelectedPC);
+ }
+
+ RedrawDisAsmListView();
+ return(0);
+}
+
+
+LRESULT CDisAsmDlg::OnRClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
+{
+ int Index = m_DisAsmListViewCtrl.GetSelectedIndex();
+
+ if (Index != -1)
+ {
+ uint16 SelectedPC = static_cast(m_DisAsmListViewCtrl.GetItemData(Index));
+ g_dsp.pc = SelectedPC;
+ }
+
+ RedrawDisAsmListView();
+ return(0);
+}
+
+
+void CDisAsmDlg::CloseDialog(int nVal)
+{
+ DestroyWindow();
+ ::PostQuitMessage(nVal);
+}
+
+
+int CALLBACK CDisAsmDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+ return(lParam1 > lParam2);
+}
+
+
+void CDisAsmDlg::RebuildDisAsmListView()
+{
+ if (!m_DisAsmListViewCtrl.IsWindow())
+ return;
+
+ m_DisAsmListViewCtrl.ShowWindow(SW_HIDE);
+ m_DisAsmListViewCtrl.DeleteAllItems();
+
+ char Buffer[256];
+ gd_globals_t gdg;
+
+ if (g_dsp.pc & 0x8000)
+ {
+ gdg.binbuf = g_dsp.irom;
+ }
+ else
+ {
+ gdg.binbuf = g_dsp.iram;
+ }
+
+ gdg.buffer = Buffer;
+ gdg.buffer_size = 256;
+ gdg.ext_separator = (char)0xff;
+
+ gdg.show_pc = false;
+ gdg.show_hex = false;
+ gdg.print_tabs = true;
+ gdg.decode_names = true;
+ gdg.decode_registers = true;
+
+ for (gdg.pc = 0; gdg.pc < DSP_IROM_SIZE;)
+ {
+ uint16 CurrentPC = gdg.pc;
+
+ if (g_dsp.pc & 0x8000)
+ {
+ CurrentPC |= 0x8000;
+ }
+
+ char Temp[256];
+ sprintf_s(Temp, 256, "0x%04x", CurrentPC);
+
+ char Temp2[256];
+ sprintf_s(Temp2, 256, "0x%04x", dsp_imem_read(CurrentPC));
+
+ char* pOpcode = gd_dis_opcode(&gdg);
+ const char* pParameter = NULL;
+ const char* pExtension = NULL;
+
+ size_t WholeString = strlen(pOpcode);
+
+ for (size_t i = 0; i < WholeString; i++)
+ {
+ if (pOpcode[i] == (char)0xff)
+ {
+ pOpcode[i] = 0x00;
+ pExtension = &pOpcode[i + 1];
+ }
+
+ if (pOpcode[i] == 0x09)
+ {
+ pOpcode[i] = 0x00;
+ pParameter = &pOpcode[i + 1];
+ }
+ }
+
+
+ const char* pFunctionName = NULL;
+
+ if (m_SymbolMap.find(CurrentPC) != m_SymbolMap.end())
+ {
+ pFunctionName = m_SymbolMap[CurrentPC].Name.c_str();
+ }
+
+ int Item = m_DisAsmListViewCtrl.AddItem(0, ColumnBP, _T(" "));
+ m_DisAsmListViewCtrl.AddItem(Item, ColumnFunction, pFunctionName);
+ m_DisAsmListViewCtrl.AddItem(Item, ColumnAddress, Temp);
+ m_DisAsmListViewCtrl.AddItem(Item, ColumnMenmomic, Temp2);
+ m_DisAsmListViewCtrl.AddItem(Item, ColumnOpcode, pOpcode);
+ m_DisAsmListViewCtrl.AddItem(Item, ColumnExt, pExtension);
+
+ if (!_stricmp(pOpcode, "CALL"))
+ {
+ uint32 FunctionAddress = -1;
+ sscanf(pParameter, "0x%04x", &FunctionAddress);
+
+ if (m_SymbolMap.find(FunctionAddress) != m_SymbolMap.end())
+ {
+ pParameter = m_SymbolMap[FunctionAddress].Name.c_str();
+ }
+ }
+
+ m_DisAsmListViewCtrl.AddItem(Item, ColumnParameter, pParameter);
+
+ m_DisAsmListViewCtrl.SetItemData(Item, CurrentPC);
+ }
+
+ m_DisAsmListViewCtrl.SortItems(CompareFunc, (LPARAM) this);
+
+ m_DisAsmListViewCtrl.ShowWindow(SW_SHOW);
+}
+
+
+void CDisAsmDlg::UpdateDisAsmListView()
+{
+ if (g_dsp.dram == NULL)
+ {
+ return;
+ }
+
+ // check if we have to rebuild the list view
+ if (m_DisAsmListViewCtrl.GetItemCount() == 0)
+ {
+ RebuildDisAsmListView();
+ }
+ else
+ {
+ uint16 FirstPC = static_cast(m_DisAsmListViewCtrl.GetItemData(0));
+
+ if ((FirstPC & 0x8000) != (g_dsp.pc & 0x8000))
+ {
+ RebuildDisAsmListView();
+ }
+ }
+
+ if (m_CachedStepCounter == g_dsp.step_counter)
+ {
+ return;
+ }
+
+ // show PC
+ for (int i = 0; i < m_DisAsmListViewCtrl.GetItemCount(); i++)
+ {
+ if (m_DisAsmListViewCtrl.GetItemData(i) == g_dsp.pc)
+ {
+ m_DisAsmListViewCtrl.EnsureVisible(i - 5, FALSE);
+ m_DisAsmListViewCtrl.EnsureVisible(i + 14, FALSE);
+ break;
+ }
+ }
+
+ m_CachedStepCounter = g_dsp.step_counter;
+
+ RedrawDisAsmListView();
+
+ m_RegisterDlg.UpdateRegisterListView();
+}
+
+
+void CDisAsmDlg::UpdateSymbolMap()
+{
+ if (g_dsp.dram == NULL)
+ {
+ return;
+ }
+
+ if (m_CachedUCodeCRC != g_dsp.iram_crc)
+ {
+ // load symbol map (if there is one)
+ m_CachedUCodeCRC = g_dsp.iram_crc;
+ char FileName[MAX_PATH];
+ sprintf(FileName, "maps\\DSP_%08x.map", m_CachedUCodeCRC);
+ LoadSymbolMap(FileName);
+
+ // rebuild the disasm
+ RebuildDisAsmListView();
+ }
+}
+
+
+void CDisAsmDlg::UpdateRegisterFlags()
+{
+ if (m_CachedCR == g_dsp.cr)
+ {
+ return;
+ }
+
+ CButton ButtonAssertInt(GetDlgItem(IDC_ASSERT_INT));
+ ButtonAssertInt.SetCheck(g_dsp.cr & 0x02 ? BST_CHECKED : BST_UNCHECKED);
+
+ CButton ButtonReset(GetDlgItem(IDC_HALT));
+ ButtonReset.SetCheck(g_dsp.cr & 0x04 ? BST_CHECKED : BST_UNCHECKED);
+
+ CButton ButtonInit(GetDlgItem(IDC_INIT));
+ ButtonInit.SetCheck(g_dsp.cr & 0x800 ? BST_CHECKED : BST_UNCHECKED);
+
+ m_CachedCR = g_dsp.cr;
+}
+
+
+bool CDisAsmDlg::CanDoStep()
+{
+ UpdateSymbolMap(); // update the symbols all the time because there a script cmds like bps
+
+ switch (m_State)
+ {
+ case RUN_START:
+ m_State = RUN;
+ return(true);
+
+ case RUN:
+
+ if (IsBreakPoint(g_dsp.pc))
+ {
+ UpdateDialog();
+ m_State = PAUSE;
+ return(false);
+ }
+
+ return(true);
+
+ case PAUSE:
+ UpdateDialog();
+ return(false);
+
+ case STEP:
+ UpdateDialog();
+ m_State = PAUSE;
+ return(true);
+ }
+
+ return(false);
+}
+
+
+void CDisAsmDlg::DebugBreak()
+{
+ m_State = PAUSE;
+}
+
+
+void CDisAsmDlg::UpdateButtonTexts()
+{
+ // go button
+ {
+ CButton Button(GetDlgItem(ID_GO));
+
+ switch (m_State)
+ {
+ case RUN_START:
+ case RUN:
+ Button.SetWindowText("Pause");
+ break;
+
+ case PAUSE:
+ case STEP:
+ Button.SetWindowText("Go");
+ break;
+ }
+ }
+
+ // show register
+ {
+ CButton Button(GetDlgItem(ID_SHOW_REGISTER));
+
+ if (m_RegisterDlg.IsWindowVisible())
+ {
+ Button.SetWindowText("Hide Regs");
+ }
+ else
+ {
+ Button.SetWindowText("Show Regs");
+ }
+ }
+}
+
+
+bool CDisAsmDlg::IsBreakPoint(uint16 _Address)
+{
+ return(std::find(m_BreakPoints.begin(), m_BreakPoints.end(), _Address) != m_BreakPoints.end());
+}
+
+
+void CDisAsmDlg::ToggleBreakPoint(uint16 _Address)
+{
+ if (IsBreakPoint(_Address))
+ {
+ RemoveBreakPoint(_Address);
+ }
+ else
+ {
+ AddBreakPoint(_Address);
+ }
+}
+
+
+void CDisAsmDlg::RemoveBreakPoint(uint16 _Address)
+{
+ CBreakPointList::iterator itr = std::find(m_BreakPoints.begin(), m_BreakPoints.end(), _Address);
+
+ if (itr != m_BreakPoints.end())
+ {
+ m_BreakPoints.erase(itr);
+ }
+}
+
+
+void CDisAsmDlg::AddBreakPoint(uint16 _Address)
+{
+ CBreakPointList::iterator itr = std::find(m_BreakPoints.begin(), m_BreakPoints.end(), _Address);
+
+ if (itr == m_BreakPoints.end())
+ {
+ m_BreakPoints.push_back(_Address);
+ }
+}
+
+
+void CDisAsmDlg::ClearBreakPoints()
+{
+ m_BreakPoints.clear();
+}
+
+
+LRESULT CDisAsmDlg::OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& _bHandled)
+{
+ int result = CDRF_DODEFAULT;
+
+ NMLVCUSTOMDRAW* pLVCD = reinterpret_cast(pnmh);
+
+ switch (pLVCD->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ result = CDRF_NOTIFYITEMDRAW;
+ break;
+
+ case CDDS_ITEMPREPAINT:
+ result = CDRF_NOTIFYSUBITEMDRAW;
+ break;
+
+ case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
+ {
+ pLVCD->nmcd.uItemState &= ~(CDIS_SELECTED | CDIS_FOCUS);
+
+ uint16 CurrentAddress = static_cast(m_DisAsmListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec));
+ pLVCD->clrTextBk = FindColor(CurrentAddress);
+
+ if (CurrentAddress == g_dsp.pc)
+ {
+ pLVCD->clrTextBk = RGB(96, 192, 128);
+ }
+
+ switch (pLVCD->iSubItem)
+ {
+ case 0x00:
+ {
+ if (IsBreakPoint(CurrentAddress))
+ {
+ pLVCD->clrTextBk = RGB(255, 64, 64);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return(result);
+}
+
+
+void CDisAsmDlg::RedrawDisAsmListView()
+{
+ ::InvalidateRect(m_DisAsmListViewCtrl.m_hWnd, NULL, FALSE);
+}
+
+
+bool CDisAsmDlg::LoadSymbolMap(const char* _pFileName)
+{
+ m_SymbolMap.clear();
+
+ FILE* pFile = fopen(_pFileName, "r");
+
+ if (!pFile)
+ {
+ return(false);
+ }
+
+ char Name[1024];
+ uint32 AddressStart, AddressEnd;
+
+ while (!feof(pFile))
+ {
+ char line[512];
+ fgets(line, 511, pFile);
+
+ if (strlen(line) < 2)
+ {
+ continue;
+ }
+
+ // check for comment
+ if (line[0] == '.')
+ {
+ continue;
+ }
+
+ // clear all breakpoints
+ if (line[0] == 'C')
+ {
+ ClearBreakPoints();
+ continue;
+ }
+
+ // add breakpoint
+ if (line[0] == 'B')
+ {
+ sscanf(line, "B %04x", &AddressStart);
+ AddBreakPoint(static_cast(AddressStart));
+ continue;
+ }
+
+ // default add new symbol
+ sscanf(line, "%04x %04x %s", &AddressStart, &AddressEnd, Name);
+
+ if (m_SymbolMap.find(AddressStart) == m_SymbolMap.end())
+ {
+ m_SymbolMap.insert(std::pair(AddressStart, SSymbol(AddressStart, AddressEnd, Name)));
+ }
+ else
+ {
+ m_SymbolMap[AddressStart] = SSymbol(AddressStart, AddressEnd, Name);
+ }
+ }
+
+ fclose(pFile);
+
+ return(true);
+}
+
+
+DWORD CDisAsmDlg::FindColor(uint16 _Address)
+{
+ size_t Color = 0;
+ static int Colors[6] = {0xC0FFFF, 0xFFE0C0, 0xC0C0FF, 0xFFC0FF, 0xC0FFC0, 0xFFFFC0};
+
+ for (CSymbolMap::const_iterator itr = m_SymbolMap.begin(); itr != m_SymbolMap.end(); itr++)
+ {
+ const SSymbol& rSymbol = itr->second;
+
+ if ((rSymbol.AddressStart <= _Address) && (_Address <= rSymbol.AddressEnd))
+ {
+ return(Colors[Color % 6]);
+ }
+
+ Color++;
+ }
+
+ return(GetSysColor(COLOR_3DLIGHT));
+}
+
+
+void CDisAsmDlg::UpdateDialog()
+{
+ UpdateSymbolMap();
+ UpdateDisAsmListView();
+// UpdateButtonTexts();
+ UpdateRegisterFlags();
+}
+
+LRESULT CDisAsmDlg::OnLvnItemchangedDisasmList(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/)
+{
+ LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
+ // TODO: Add your control notification handler code here
+
+ return 0;
+}
+
+
+// TODO: make the members adjust with the dialog
+LRESULT CDisAsmDlg::OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
+{
+ // we habe to make a group of the items I think
+ /*
+ CRect lpRect;
+
+
+ int wid = lpRect.right - lpRect.left - 100;
+ int hei = lpRect.bottom - lpRect.top - 20;
+ m_DisAsmListViewCtrl.ResizeClient(wid, hei, true);
+ */
+
+ return 0;
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmDlg.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmDlg.h
new file mode 100644
index 0000000000..ef128c24fc
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmDlg.h
@@ -0,0 +1,163 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Globals.h"
+
+#include
+#include
+
+#include "../res/resource.h"
+#include "DisAsmListView.h"
+#include "RegisterDlg.h"
+
+class CDisAsmDlg
+ : public CDialogImpl, public CUpdateUI, public CDialogResize
+{
+ public:
+
+ CDisAsmDlg();
+
+ enum { IDD = IDD_DISASMDLG };
+
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ virtual BOOL OnIdle();
+
+
+ BEGIN_UPDATE_UI_MAP(CDisAsmDlg)
+ END_UPDATE_UI_MAP()
+
+ BEGIN_DLGRESIZE_MAP(CDisAsmDlg)
+ DLGRESIZE_CONTROL(IDR_MAINFRAME, DLSZ_SIZE_X | DLSZ_SIZE_Y)
+ END_DLGRESIZE_MAP()
+
+ BEGIN_MSG_MAP(CDisAsmDlg)
+ MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
+ MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
+ COMMAND_ID_HANDLER(ID_STEP, OnStep)
+ COMMAND_ID_HANDLER(ID_GO, OnGo)
+ COMMAND_ID_HANDLER(ID_SHOW_REGISTER, OnShowRegisters)
+ NOTIFY_CODE_HANDLER(NM_CLICK, OnDblClick)
+ NOTIFY_CODE_HANDLER(NM_RETURN, OnDblClick)
+ NOTIFY_CODE_HANDLER(NM_RCLICK, OnRClick)
+ NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw)
+ NOTIFY_HANDLER(IDC_DISASM_LIST, LVN_ITEMCHANGED, OnLvnItemchangedDisasmList)
+ MESSAGE_HANDLER(WM_SIZE, OnSize)
+ CHAIN_MSG_MAP(CDialogResize)
+
+ END_MSG_MAP()
+
+// Handler prototypes (uncomment arguments if needed):
+// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
+// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
+
+ LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/);
+ LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/);
+
+ LRESULT OnStep(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/);
+ LRESULT OnGo(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/);
+ LRESULT OnShowRegisters(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/);
+ LRESULT OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& _bHandled);
+
+ LRESULT OnDblClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/);
+ LRESULT OnRClick(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/);
+
+ void CloseDialog(int nVal);
+
+ bool CanDoStep();
+
+ void DebugBreak();
+
+
+ private:
+
+ enum EColumns
+ {
+ ColumnBP = 0,
+ ColumnFunction = 1,
+ ColumnAddress = 2,
+ ColumnMenmomic = 3,
+ ColumnOpcode = 4,
+ ColumnExt = 5,
+ ColumnParameter = 6
+ };
+
+ enum EState
+ {
+ PAUSE,
+ STEP,
+ RUN,
+ RUN_START // ignores breakpoints and switches after one step to RUN
+ };
+ EState m_State;
+
+
+ CListViewCtrl m_DisAsmListViewCtrl;
+ CRegisterDlg m_RegisterDlg;
+ //CWindow GroupLeft
+ CStatic GroupLeft;
+
+ uint64 m_CachedStepCounter;
+ uint16 m_CachedCR;
+ uint32 m_CachedUCodeCRC;
+
+ typedef std::listCBreakPointList;
+ CBreakPointList m_BreakPoints;
+
+ // break point handling
+ bool IsBreakPoint(uint16 _Address);
+ void ToggleBreakPoint(uint16 _Address);
+ void RemoveBreakPoint(uint16 _Address);
+ void AddBreakPoint(uint16 _Address);
+ void ClearBreakPoints();
+
+
+ // update dialog
+ void UpdateDisAsmListView();
+ void UpdateRegisterFlags();
+ void UpdateSymbolMap();
+ void UpdateButtonTexts();
+
+ void RedrawDisAsmListView();
+ void RebuildDisAsmListView();
+
+
+ struct SSymbol
+ {
+ uint32 AddressStart;
+ uint32 AddressEnd;
+ std::string Name;
+
+ SSymbol(uint32 _AddressStart = 0, uint32 _AddressEnd = 0, char* _Name = NULL)
+ : AddressStart(_AddressStart)
+ , AddressEnd(_AddressEnd)
+ , Name(_Name)
+ {}
+ };
+ typedef std::mapCSymbolMap;
+ CSymbolMap m_SymbolMap;
+
+ void AddSymbol(uint16 _AddressStart, uint16 _AddressEnd, char* _Name);
+ bool LoadSymbolMap(const char* _pFileName);
+ DWORD FindColor(uint16 _Address);
+ void UpdateDialog();
+
+ static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+public:
+ LRESULT OnLvnItemchangedDisasmList(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/);
+ LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
+};
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmListView.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmListView.h
new file mode 100644
index 0000000000..65f9dd7f1f
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DisAsmListView.h
@@ -0,0 +1,64 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _MYLISTVIEW_H
+#define _MYLISTVIEW_H
+
+class CDisAsmListView
+ : public CWindowImpl,
+ public CCustomDraw
+{
+ public:
+
+ BEGIN_MSG_MAP(CDisAsmListView)
+ CHAIN_MSG_MAP(CCustomDraw)
+ END_MSG_MAP()
+
+ DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
+ {
+ return(CDRF_NOTIFYITEMDRAW);
+ }
+
+
+ DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
+ {
+ NMLVCUSTOMDRAW* pLVCD = reinterpret_cast(lpNMCustomDraw);
+
+ // This is the prepaint stage for an item. Here's where we set the
+ // item's text color. Our return value will tell Windows to draw the
+ // item itself, but it will use the new color we set here for the background
+
+ COLORREF crText;
+
+ if ((pLVCD->nmcd.dwItemSpec % 2) == 0)
+ {
+ crText = RGB(200, 200, 255);
+ }
+ else
+ {
+ crText = RGB(255, 255, 255);
+ }
+
+ // Store the color back in the NMLVCUSTOMDRAW struct.
+ pLVCD->clrTextBk = crText;
+
+ // Tell Windows to paint the control itself.
+ return(CDRF_DODEFAULT);
+ }
+};
+
+#endif _MYLISTVIEW_H
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.cpp
new file mode 100644
index 0000000000..cb59ab5c2e
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.cpp
@@ -0,0 +1,87 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include // I hope this doesn't break anything
+#include
+#include
+
+#include "Common.h" // for Common::swap
+#include "Globals.h"
+#include "gdsp_interpreter.h"
+
+// =======================================================================================
+// For PB address detection
+// --------------
+u32 RAM_MASK = 0x1FFFFFF;
+
+
+u16 Memory_Read_U16(u32 _uAddress)
+{
+ _uAddress &= RAM_MASK;
+ return Common::swap16(*(u16*)&g_dsp.cpu_ram[_uAddress]);
+}
+
+u32 Memory_Read_U32(u32 _uAddress)
+{
+ _uAddress &= RAM_MASK;
+ return Common::swap32(*(u32*)&g_dsp.cpu_ram[_uAddress]);
+}
+
+#if PROFILE
+
+#define PROFILE_MAP_SIZE 0x10000
+
+u64 g_profileMap[PROFILE_MAP_SIZE];
+bool g_profile = false;
+
+void ProfilerStart()
+{
+ g_profile = true;
+}
+
+void ProfilerAddDelta(int _addr, int _delta)
+{
+ if (g_profile)
+ {
+ g_profileMap[_addr] += _delta;
+ }
+}
+
+void ProfilerInit()
+{
+ memset(g_profileMap, 0, sizeof(g_profileMap));
+}
+
+void ProfilerDump(uint64 count)
+{
+ FILE* pFile = fopen("c:\\_\\DSP_Prof.txt", "wt");
+ if (pFile != NULL)
+ {
+ fprintf(pFile, "Number of DSP steps: %llu\n\n", count);
+ for (int i=0; i 0)
+ {
+ fprintf(pFile, "0x%04X: %llu\n", i, g_profileMap[i]);
+ }
+ }
+
+ fclose(pFile);
+ }
+}
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h
new file mode 100644
index 0000000000..0b40229f84
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Globals.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _GLOBALS_H
+#define _GLOBALS_H
+
+#include "pluginspecs_dsp.h"
+#include "Common.h"
+#include
+
+#define WITH_DSP_ON_THREAD 1
+#define DUMP_DSP_IMEM 0
+#define PROFILE 1
+
+extern DSPInitialize g_dspInitialize;
+void DSP_DebugBreak();
+
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+typedef unsigned int uint;
+
+typedef signed char sint8;
+typedef signed short sint16;
+typedef signed int sint32;
+typedef signed long long sint64;
+
+typedef const uint32 cuint32;
+
+u16 Memory_Read_U16(u32 _uAddress); // For PB address detection
+u32 Memory_Read_U32(u32 _uAddress);
+
+#if PROFILE
+ void ProfilerDump(uint64 _count);
+ void ProfilerInit();
+ void ProfilerAddDelta(int _addr, int _delta);
+ void ProfilerStart();
+#endif
+
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp
new file mode 100644
index 0000000000..08f4a00d9a
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Functions.cpp
@@ -0,0 +1,1490 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifdef _WIN32
+#include "stdafx.h"
+#endif
+#include "Globals.h"
+#include "HLE_Helper.h"
+
+
+uint16& R00 = g_dsp.r[0x00];
+uint16& R01 = g_dsp.r[0x01];
+uint16& R02 = g_dsp.r[0x02];
+uint16& R03 = g_dsp.r[0x03];
+uint16& R04 = g_dsp.r[0x04];
+uint16& R05 = g_dsp.r[0x05];
+uint16& R06 = g_dsp.r[0x06];
+uint16& R07 = g_dsp.r[0x07];
+uint16& R08 = g_dsp.r[0x08];
+uint16& R09 = g_dsp.r[0x09];
+uint16& R0A = g_dsp.r[0x0a];
+uint16& R0B = g_dsp.r[0x0b];
+uint16& R0C = g_dsp.r[0x0c];
+uint16& R0D = g_dsp.r[0x0d];
+uint16& R0E = g_dsp.r[0x0e];
+uint16& R0F = g_dsp.r[0x0f];
+uint16& R10 = g_dsp.r[0x10];
+uint16& R11 = g_dsp.r[0x11];
+uint16& R12 = g_dsp.r[0x12];
+uint16& R13 = g_dsp.r[0x13];
+uint16& R14 = g_dsp.r[0x14];
+uint16& R15 = g_dsp.r[0x15];
+uint16& R16 = g_dsp.r[0x16];
+uint16& R17 = g_dsp.r[0x17];
+uint16& R18 = g_dsp.r[0x18];
+uint16& R19 = g_dsp.r[0x19];
+uint16& R1A = g_dsp.r[0x1a];
+uint16& R1B = g_dsp.r[0x1b];
+uint16& R1C = g_dsp.r[0x1c];
+uint16& R1D = g_dsp.r[0x1d];
+uint16& R1E = g_dsp.r[0x1e];
+uint16& R1F = g_dsp.r[0x1f];
+
+
+uint16& ST0 = g_dsp.r[0x0c];
+uint16& ST1 = g_dsp.r[0x0d];
+uint16& ST2 = g_dsp.r[0x0e];
+uint16& ST3 = g_dsp.r[0x0f];
+uint16& ACH0 = g_dsp.r[0x10];
+uint16& ACH1 = g_dsp.r[0x11];
+uint16& CR = g_dsp.r[0x12];
+uint16& SR = g_dsp.r[0x13];
+uint16& PROD_l = g_dsp.r[0x14];
+uint16& PROD_m1 = g_dsp.r[0x15];
+uint16& PROD_h = g_dsp.r[0x16];
+uint16& PROD_m2 = g_dsp.r[0x17];
+uint16& AX0_l = g_dsp.r[0x18];
+uint16& AX1_l = g_dsp.r[0x19];
+uint16& AX0_h = g_dsp.r[0x1a];
+uint16& AX1_h = g_dsp.r[0x1b];
+uint16& AC0_l = g_dsp.r[0x1c];
+uint16& AC1_l = g_dsp.r[0x1d];
+uint16& AC0_m = g_dsp.r[0x1e];
+uint16& AC1_m = g_dsp.r[0x1f];
+
+TAccumulator<0> ACC0;
+TAccumulator<1> ACC1;
+CProd PROD;
+
+
+u16 HLE_ROM_80E7_81F8()
+{
+ sint8 MultiplyModifier = GetMultiplyModifier();
+// l_80E7:
+ AX0_h = ReadDMEM(R00);
+ R00++;
+ ACC0 = 0;
+ Update_SR_Register(ACC0);
+// l_80E8:
+ AX1_l = ReadDMEM(R01);
+ R01++;
+ ACC1 = 0;
+ Update_SR_Register(ACC1);
+// l_80E9:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_80EA:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+ ACC1 = 0;
+ Update_SR_Register(ACC1);
+// l_80EB:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+// l_80EC:
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_80ED:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_80EE:
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_80EF:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_80F0:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_80F1:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_80F2:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_80F3:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_80F4:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_80F5:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_80F6:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_80F7:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_80F8:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_80F9:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_80FA:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_80FB:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_80FC:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_80FD:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_80FE:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_80FF:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8100:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8101:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8102:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8103:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8104:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8105:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8106:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8107:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8108:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8109:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_810A:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_810B:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_810C:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_810D:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_810E:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_810F:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8110:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8111:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8112:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8113:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8114:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8115:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8116:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8117:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8118:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8119:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_811A:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_811B:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_811C:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_811D:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_811E:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_811F:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8120:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8121:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8122:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8123:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8124:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8125:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8126:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8127:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8128:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8129:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_812A:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_812B:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_812C:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_812D:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_812E:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_812F:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8130:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8131:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8132:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8133:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8134:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8135:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8136:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8137:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8138:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8139:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_813A:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_813B:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_813C:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_813D:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_813E:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_813F:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8140:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8141:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8142:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8143:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8144:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8145:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8146:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8147:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8148:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8149:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_814A:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_814B:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_814C:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_814D:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_814E:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_814F:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8150:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8151:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8152:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8153:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8154:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8155:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8156:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8157:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8158:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8159:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_815A:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_815B:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_815C:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_815D:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_815E:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_815F:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8160:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8161:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8162:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8163:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8164:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8165:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8166:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8167:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8168:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+// l_8169:
+ ACC0 = PROD;
+// l_816A:
+ AX0_l = AC0_m;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_816B:
+ R01++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_816C:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+// l_816D:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 = 0;
+ Update_SR_Register(ACC0);
+// l_816E:
+ R00 = R04;
+// l_816F:
+ R02 = R05;
+// l_8170:
+ R03 = R02;
+// l_8171:
+ AX0_h = ReadDMEM(R00);
+ R00++;
+ ACC0 = 0;
+ Update_SR_Register(ACC0);
+// l_8172:
+ AX1_l = ReadDMEM(R01);
+ R01++;
+ ACC1 = 0;
+ Update_SR_Register(ACC1);
+// l_8173:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8174:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+ ACC1 = 0;
+ Update_SR_Register(ACC1);
+// l_8175:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+// l_8176:
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8177:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8178:
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8179:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_817A:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_817B:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_817C:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_817D:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_817E:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_817F:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8180:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8181:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8182:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8183:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8184:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8185:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8186:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8187:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8188:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8189:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_818A:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_818B:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_818C:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_818D:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_818E:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_818F:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8190:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8191:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8192:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8193:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_8194:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_8195:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_8196:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_8197:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_8198:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_8199:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_819A:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_819B:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_819C:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_819D:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_819E:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_819F:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81A0:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81A1:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81A2:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81A3:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81A4:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81A5:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81A6:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81A7:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81A8:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81A9:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81AA:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81AB:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81AC:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81AD:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81AE:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81AF:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81B0:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81B1:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81B2:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81B3:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81B4:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81B5:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81B6:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81B7:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81B8:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81B9:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81BA:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81BB:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81BC:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81BD:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81BE:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81BF:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81C0:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81C1:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81C2:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81C3:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81C4:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81C5:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81C6:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81C7:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81C8:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81C9:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81CA:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81CB:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81CC:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81CD:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81CE:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81CF:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81D0:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81D1:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81D2:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81D3:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81D4:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81D5:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81D6:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81D7:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81D8:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81D9:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81DA:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81DB:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81DC:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81DD:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81DE:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81DF:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81E0:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81E1:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81E2:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81E3:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81E4:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81E5:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81E6:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81E7:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81E8:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81E9:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81EA:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81EB:
+ AC0_m = ReadDMEM(R02);
+ R02++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81EC:
+ AC0_l = ReadDMEM(R02);
+ R02++;
+// l_81ED:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+ ACC0 <<= 16;
+ Update_SR_Register(ACC0);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81EE:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81EF:
+ AC1_m = ReadDMEM(R02);
+ R02++;
+ ACC0 >>= 16;
+ Update_SR_Register(ACC0);
+// l_81F0:
+ AC1_l = ReadDMEM(R02);
+ R02++;
+// l_81F1:
+ WriteDMEM(R03, AC0_m);
+ R03++;
+ ACC1 <<= 16;
+ Update_SR_Register(ACC1);
+ AX0_h = ReadDMEM(R00);
+ R00++;
+// l_81F2:
+ WriteDMEM(R03, AC0_l);
+ R03++;
+// l_81F3:
+ ACC0 = PROD;
+// l_81F4:
+ AX1_h = AC0_m;
+ ACC1 += PROD;
+ PROD = AX0_h * AX1_l * MultiplyModifier;
+ Update_SR_Register(PROD);
+// l_81F5:
+ R01++;
+ ACC1 >>= 16;
+ Update_SR_Register(ACC1);
+// l_81F6:
+ WriteDMEM(R03, AC1_m);
+ R03++;
+// l_81F7:
+ WriteDMEM(R03, AC1_l);
+ R03++;
+ ACC0 = 0;
+ Update_SR_Register(ACC0);
+// l_81F8:
+//missing: dsp_opc_ret;
+
+ return 0x81f8;
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.cpp
new file mode 100644
index 0000000000..8d0c523554
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifdef _WIN32
+#include "stdafx.h"
+#endif
+
+#include "Globals.h"
+#include "gdsp_interpreter.h"
+#include "gdsp_memory.h"
+#include "gdsp_opcodes_helper.h"
+
+
+bool WriteDMEM(uint16 addr, uint16 val)
+{
+ return dsp_dmem_write(addr, val);
+}
+
+uint16 ReadDMEM(uint16 addr)
+{
+ return dsp_dmem_read(addr);
+}
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h
new file mode 100644
index 0000000000..f1aa055cf0
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/HLE_Helper.h
@@ -0,0 +1,129 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef HLE_HELPER_H
+#define HLE_HELPER_H
+
+#include "gdsp_interpreter.h"
+
+bool WriteDMEM(uint16 addr, uint16 val);
+uint16 ReadDMEM(uint16 addr);
+void Update_SR_Register(sint64 _Value);
+sint8 GetMultiplyModifier();
+
+template
+class TAccumulator
+{
+public:
+
+ TAccumulator()
+ {
+ _assert_(N < 2);
+ }
+
+ void operator=(sint64 val)
+ {
+ setValue(val);
+ }
+
+ void operator<<=(sint64 value)
+ {
+ sint64 acc = getValue();
+ acc <<= value;
+ setValue(acc);
+ }
+
+ void operator>>=(sint64 value)
+ {
+ sint64 acc = getValue();
+ acc >>= value;
+ setValue(acc);
+ }
+
+ void operator+=(sint64 value)
+ {
+ sint64 acc = getValue();
+ acc += value;
+ setValue(acc);
+ }
+
+ operator sint64()
+ {
+ return getValue();
+ }
+
+ operator uint64()
+ {
+ return getValue();
+ }
+
+ inline void setValue(sint64 val)
+ {
+ g_dsp.r[0x1c + N] = (uint16)val;
+ val >>= 16;
+ g_dsp.r[0x1e + N] = (uint16)val;
+ val >>= 16;
+ g_dsp.r[0x10 + N] = (uint16)val;
+ }
+
+ inline sint64 getValue()
+ {
+ sint64 val;
+ sint64 low_acc;
+ val = (sint8)g_dsp.r[0x10 + N];
+ val <<= 32;
+ low_acc = g_dsp.r[0x1e + N];
+ low_acc <<= 16;
+ low_acc |= g_dsp.r[0x1c + N];
+ val |= low_acc;
+ return(val);
+ }
+};
+
+class CProd
+{
+public:
+ CProd()
+ {
+ }
+
+ void operator=(sint64 val)
+ {
+ g_dsp.r[0x14] = (uint16)val;
+ val >>= 16;
+ g_dsp.r[0x15] = (uint16)val;
+ val >>= 16;
+ g_dsp.r[0x16] = (uint16)val;
+ g_dsp.r[0x17] = 0;
+ }
+
+ operator sint64()
+ {
+ sint64 val;
+ sint64 low_prod;
+ val = (sint8)g_dsp.r[0x16];
+ val <<= 32;
+ low_prod = g_dsp.r[0x15];
+ low_prod += g_dsp.r[0x17];
+ low_prod <<= 16;
+ low_prod |= g_dsp.r[0x14];
+ val += low_prod;
+ return(val);
+ }
+};
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp
new file mode 100644
index 0000000000..b94a06ca24
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/AXTask.cpp
@@ -0,0 +1,100 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+#include "../Globals.h"
+#include "Common.h"
+
+
+extern u32 m_addressPBs;
+
+
+// =======================================================================================
+// Get the parameter block location - Example SSBM: We get the addr 8049cf00, first we
+// always get 0 and go to AXLIST_STUDIOADDR, then we end up at AXLIST_PBADDR.
+// --------------
+bool AXTask(u32& _uMail)
+{
+ u32 uAddress = _uMail;
+ DEBUG_LOG(DSPHLE, "AXTask - ================================================================");
+ DEBUG_LOG(DSPHLE, "AXTask - AXCommandList-Addr: 0x%08x", uAddress);
+
+ bool bExecuteList = true;
+
+ while (bExecuteList)
+ {
+ // ---------------------------------------------------------------------------------------
+ // SSBM: We get the addr 8049cf00, first we always get 0
+ u16 iCommand = Memory_Read_U16(uAddress);
+ uAddress += 2;
+ // ---------------------------------------------------------------------------------------
+
+ switch (iCommand)
+ {
+ // ---------------------------------------------------------------------------------------
+ // ?
+ case 0: // AXLIST_STUDIOADDR: //00
+ {
+ uAddress += 4;
+ DEBUG_LOG(DSPHLE, "AXLIST AXLIST_SBUFFER: %08x", uAddress);
+ }
+ break;
+ // ---------------------------------------------------------------------------------------
+
+
+ // ---------------------------------------------------------------------------------------
+ case 2: // AXLIST_PBADDR: // 02
+ {
+ m_addressPBs = Memory_Read_U32(uAddress);
+ uAddress += 4;
+ DEBUG_LOG(DSPHLE, "AXLIST PB address: %08x", m_addressPBs);
+ bExecuteList = false;
+ }
+ break;
+
+ // ---------------------------------------------------------------------------------------
+ case 7: // AXLIST_SBUFFER: // 7
+ {
+ // Hopefully this is where in main ram to write.
+ uAddress += 4;
+ DEBUG_LOG(DSPHLE, "AXLIST AXLIST_SBUFFER: %08x", uAddress);
+ }
+ break;
+
+
+
+ default:
+ {
+ // ---------------------------------------------------------------------------------------
+ // Stop the execution of this TaskList
+ DEBUG_LOG(DSPHLE, "AXLIST default: %08x", uAddress);
+ bExecuteList = false;
+ // ---------------------------------------------------------------------------------------
+ }
+ break;
+ } // end of switch
+ }
+
+ DEBUG_LOG(DSPHLE, "AXTask - done, send resume");
+ DEBUG_LOG(DSPHLE, "AXTask - ================================================================");
+
+ // now resume
+ return true;
+}
+// =======================================================================================
+
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp
new file mode 100644
index 0000000000..9cebc6df5e
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.cpp
@@ -0,0 +1,382 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+#ifdef _WIN32
+
+
+// =======================================================================================
+// Includes
+// --------------
+#include
+#include
+#include // So that we can test if std::string == abc
+#include
+
+#include "Common.h"
+
+#include "UCode_AXStructs.h" // they are only in a virtual dir called UCodes AX
+// =====================
+
+
+// =======================================================================================
+// Declarations and definitions
+// --------------
+
+// ----------------------------------
+// Settings
+// --------------
+#define NUMBER_OF_PBS 64 // Todo: move this to a logging class
+
+// -----------------------------------
+// Externals
+// --------------
+extern u32 m_addressPBs;
+float ratioFactor;
+int globaliSize;
+short globalpBuffer;
+u32 gLastBlock;
+// --------------
+
+// -----------------------------------
+// Vectors and other things
+// --------------
+std::vector gloopPos(64);
+std::vector gsampleEnd(64);
+std::vector gsamplePos(64);
+ std::vector gratio(64);
+ std::vector gratiohi(64);
+ std::vector gratiolo(64);
+ std::vector gfrac(64);
+ std::vector gcoef(64);
+
+// PBSampleRateConverter mixer
+ std::vector gvolume_left(64);
+ std::vector gvolume_right(64);
+ std::vector gmixer_control(64);
+ std::vector gcur_volume(64);
+ std::vector gcur_volume_delta(64);
+
+
+ std::vector gaudioFormat(64);
+ std::vector glooping(64);
+ std::vector gsrc_type(64);
+ std::vector gis_stream(64);
+
+// loop
+ std::vector gloop1(64);
+ std::vector gloop2(64);
+ std::vector gloop3(64);
+ std::vector gadloop1(64);
+ std::vector gadloop2(64);
+ std::vector gadloop3(64);
+
+// updates
+ std::vector gupdates1(64);
+ std::vector gupdates2(64);
+ std::vector gupdates3(64);
+ std::vector gupdates4(64);
+ std::vector gupdates5(64);
+ std::vector gupdates_addr(64);
+
+// Other things
+std::vector Jump(64); // this is 1 or 0
+std::vector musicLength(64);
+std::vector< std::vector > vector1(64, std::vector(100,0));
+std::vector numberRunning(64);
+
+int j = 0;
+int k = 0;
+__int64 l = 0;
+int iupd = 0;
+bool iupdonce = false;
+std::vector viupd(15); // the length of the update frequency bar
+int vectorLength = 15; // the length of the playback history bar and how long
+// old blocks are shown
+
+std::vector vector62(vectorLength);
+std::vector vector63(vectorLength);
+
+int ReadOutPBs(AXParamBlock * _pPBs, int _num);
+// =====================
+
+
+// =======================================================================================
+// Main logging function
+// --------------
+void Logging()
+{
+ // ---------------------------------------------------------------------------------------
+
+
+ // ---------------------------------------------------------------------------------------
+ // Control how often the screen is updated
+ j++;
+ l++;
+ if (j>1000000) // TODO: make the update frequency adjustable from the logging window
+ {
+
+ AXParamBlock PBs[NUMBER_OF_PBS];
+ int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS);
+
+ // =======================================================================================
+ // Vector1 is a vector1[64][100] vector
+ /*
+ Move all items back like this
+ 1 to 2
+ 2 3
+ 3 ...
+ */
+ // ----------------
+ for (int i = 0; i < 64; i++)
+ {
+ for (int j = 1; j < vectorLength; j++)
+ {
+ vector1.at(i).at(j-1) = vector1.at(i).at(j);
+ }
+ }
+ // =================
+
+ // ---------------------------------------------------------------------------------------
+ // Enter the latest value
+ for (int i = 0; i < numberOfPBs; i++)
+ {
+ vector1.at(i).at(vectorLength-1) = PBs[i].running;
+ }
+ // -----------------
+
+
+ // ---------------------------------------------------------------------------------------
+ // Count how many blocks we have running now
+ int jj = 0;
+ for (int i = 0; i < 64; i++)
+ {
+ for (int j = 0; j < vectorLength-1; j++)
+ {
+ if (vector1.at(i).at(j) == 1)
+ {
+ jj++;
+ }
+ numberRunning.at(i) = jj;
+ }
+ }
+ // --------------
+
+
+ // ---------------------------------------------------------------------------------------
+ // Write the first row
+ char buffer [1000] = "";
+ std::string sbuff;
+ //sbuff = sbuff + " Nr | | frac ratio | old new \n"; // 5
+ sbuff = sbuff + " Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n";
+ // --------------
+
+
+ // ---------------------------------------------------------------------------------------
+ // Read out values for all blocks
+ for (int i = 0; i < numberOfPBs; i++)
+ {
+ if (numberRunning.at(i) > 0)
+ {
+ // =======================================================================================
+ // Write the playback bar
+ // -------------
+ for (int j = 0; j < vectorLength; j++)
+ {
+ if(vector1.at(i).at(j) == 0)
+ {
+ sbuff = sbuff + " ";
+ }
+ else
+ {
+ sprintf(buffer, "%c", 177);
+ sbuff = sbuff + buffer; strcpy(buffer, "");
+ }
+ }
+ // ==============
+
+
+ // ================================================================================================
+ int sampleJump;
+ int loopJump;
+ //if (PBs[i].running && PBs[i].adpcm_loop_info.yn1 && PBs[i].mixer.volume_left)
+ if (true)
+ {
+ // ---------------------------------------------------------------------------------------
+ // AXPB base
+ //int running = pb.running;
+ gcoef[i] = PBs[i].unknown1;
+
+ sampleJump = ((PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo) - gsamplePos[i];
+ loopJump = ((PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo) - gloopPos[i];
+
+ gloopPos[i] = (PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo;
+ gsampleEnd[i] = (PBs[i].audio_addr.end_addr_hi << 16) | PBs[i].audio_addr.end_addr_lo;
+ gsamplePos[i] = (PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo;
+
+ // PBSampleRateConverter src
+
+ gratio[i] = (u32)(((PBs[i].src.ratio_hi << 16) + PBs[i].src.ratio_lo) * ratioFactor);
+ gratiohi[i] = PBs[i].src.ratio_hi;
+ gratiolo[i] = PBs[i].src.ratio_lo;
+ gfrac[i] = PBs[i].src.cur_addr_frac;
+
+ // adpcm_loop_info
+ gadloop1[i] = PBs[i].adpcm.pred_scale;
+ gadloop2[i] = PBs[i].adpcm.yn1;
+ gadloop3[i] = PBs[i].adpcm.yn2;
+
+ gloop1[i] = PBs[i].adpcm_loop_info.pred_scale;
+ gloop2[i] = PBs[i].adpcm_loop_info.yn1;
+ gloop3[i] = PBs[i].adpcm_loop_info.yn2;
+
+ // updates
+ gupdates1[i] = PBs[i].updates.num_updates[0];
+ gupdates2[i] = PBs[i].updates.num_updates[1];
+ gupdates3[i] = PBs[i].updates.num_updates[2];
+ gupdates4[i] = PBs[i].updates.num_updates[3];
+ gupdates5[i] = PBs[i].updates.num_updates[4];
+
+ gupdates_addr[i] = (PBs[i].updates.data_hi << 16) | PBs[i].updates.data_lo;
+
+ gaudioFormat[i] = PBs[i].audio_addr.sample_format;
+ glooping[i] = PBs[i].audio_addr.looping;
+ gsrc_type[i] = PBs[i].src_type;
+ gis_stream[i] = PBs[i].is_stream;
+
+ // mixer
+ gvolume_left[i] = PBs[i].mixer.volume_left;
+ gvolume_right[i] = PBs[i].mixer.volume_right;
+
+ gmixer_control[i] = PBs[i].mixer_control;
+ gcur_volume[i] = PBs[i].vol_env.cur_volume;
+ gcur_volume_delta[i] = PBs[i].vol_env.cur_volume_delta;
+
+ // other stuff
+ Jump[i] = (gfrac[i] >> 16); // This is 1 or 0
+ musicLength[i] = gsampleEnd[i] - gloopPos[i];
+ }
+
+ // ================================================================================================
+
+
+
+ // =======================================================================================
+ // PRESETS
+ // ---------------------------------------------------------------------------------------
+ /*
+ /" Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n";
+ "---------------|00 12341234/12341234 12341234 | 00000 00000 00000 0000 00000 | 0[000 00000 00000] 0 | 00000 00000[0 00000] |
+ */
+ sprintf(buffer,"%c%i %08i/%08i %08i | %05i %05i %05i %04i %05i | %i[%03i %05i %05i] %i | %05i %05i[%i %05i] | %i %i %i %i %i",
+ 223, i, gsamplePos[i], gsampleEnd[i], gloopPos[i],
+ gvolume_left[i], gvolume_right[i], gcur_volume[i], gcur_volume_delta[i], gmixer_control[i],
+ glooping[i], gloop1[i], gloop2[i], gloop3[i], gis_stream[i],
+ gfrac[i], gratio[i], gratiohi[i], gratiolo[i],
+ gupdates1[i], gupdates2[i], gupdates3[i], gupdates4[i], gupdates5[i]
+ );
+ // =======================================================================================
+
+ // write a new line
+ sbuff = sbuff + buffer; strcpy(buffer, "");
+ sbuff = sbuff + "\n";
+
+ } // end of if (true)
+
+
+ } // end of big loop - for (int i = 0; i < numberOfPBs; i++)
+
+
+ // =======================================================================================
+ // Write global values
+ sprintf(buffer, "\nParameter blocks span from %08x | to %08x | distance %i %i\n", m_addressPBs, gLastBlock, (gLastBlock-m_addressPBs), (gLastBlock-m_addressPBs) / 192);
+ sbuff = sbuff + buffer; strcpy(buffer, "");
+ // ==============
+
+
+ // =======================================================================================
+ // Show update frequency
+ // ---------------
+ sbuff = sbuff + "\n";
+ if(!iupdonce)
+ {
+ /*
+ for (int i = 0; i < 10; i++)
+ {
+ viupd.at(i) == 0;
+ }
+ */
+ viupd.at(0) = 1;
+ viupd.at(1) = 1;
+ viupd.at(2) = 1;
+ iupdonce = true;
+ }
+
+ for (int i = 0; i < (int)viupd.size(); i++) // 0, 1,..., 9
+ {
+ if (i < (int)viupd.size()-1)
+ {
+ viupd.at(viupd.size()-i-1) = viupd.at(viupd.size()-i-2); // move all forward
+ }
+ else
+ {
+ viupd.at(0) = viupd.at(viupd.size()-1);
+ }
+
+ // Correction
+ if (viupd.at(viupd.size()-3) == 1 && viupd.at(viupd.size()-2) == 1 && viupd.at(viupd.size()-1) == 1)
+ {
+ viupd.at(0) = 0;
+ }
+ if(viupd.at(0) == 0 && viupd.at(1) == 1 && viupd.at(2) == 1 && viupd.at(3) == 0)
+ {
+ viupd.at(0) = 1;
+ }
+ }
+
+ for (int i = 0; i < (int)viupd.size(); i++)
+ {
+ if(viupd.at(i) == 0)
+ sbuff = sbuff + " ";
+ else
+ sbuff = sbuff + ".";
+ }
+ // ================
+
+
+ // =======================================================================================
+ // Print
+ // ---------------
+ // Console::ClearScreen();
+ INFO_LOG(DSPHLE, "%s", sbuff.c_str());
+ sbuff.clear(); strcpy(buffer, "");
+ // ---------------
+ k=0;
+ j=0;
+ // ---------------
+ }
+
+ // ---------------------------------------------------------------------------------------
+
+}
+// =======================================================================================
+
+
+
+
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h
new file mode 100644
index 0000000000..4b483d7152
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/Logging.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+#ifdef _WIN32
+
+void Logging();
+
+#endif
\ No newline at end of file
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp
new file mode 100644
index 0000000000..d5669e6d5a
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/ReadPBs.cpp
@@ -0,0 +1,114 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+
+
+
+// Turn on and off logging modes
+// --------------
+//#define LOG1 // writes selected parameters only and with more readable formatting
+//#define LOG2 // writes all parameters
+
+#include "Common.h"
+#include "../Globals.h"
+#include "CommonTypes.h" // Pluginspecs
+
+#include "UCode_AXStructs.h" // For the AXParamBlock structure
+
+
+u32 m_addressPBs = 0;
+extern u32 gLastBlock;
+
+
+
+#ifdef _WIN32
+
+int m = 0;
+int n = 0;
+#ifdef LOG2
+bool logall = true;
+#else
+bool logall = false;
+#endif
+int ReadOutPBs(AXParamBlock * _pPBs, int _num)
+{
+ int count = 0;
+ u32 blockAddr = m_addressPBs;
+ u32 OldblockAddr = blockAddr;
+ u32 paraAddr = blockAddr;
+
+ // reading and 'halfword' swap
+ n++;
+ //FIXME if (n > 20 && logall) {Console::ClearScreen();}
+ for (int i = 0; i < _num; i++)
+ {
+ // ---------------------------------------------------------------------------------------
+ // Check if there is something here.
+ const short * pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr);
+ // -------------
+
+ if (pSrc != NULL) // only read non-blank blocks
+ {
+ // ---------------------------------------------------------------------------------------
+ // Create a shortcut that let us update struct members
+ short * pDest = (short *) & _pPBs[i];
+
+ if (n > 20 && logall) {DEBUG_LOG(DSPHLE, "%c%i:", 223, i);} // logging
+
+ // --------------
+ // Here we update the PB. We do it by going through all 192 / 2 = 96 u16 values
+ for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
+ {
+ paraAddr += 2;
+
+ if(pSrc != NULL)
+ {
+ if (pSrc[p] != 0 && n > 20 && logall)
+ {
+ DEBUG_LOG(DSPHLE, "%i %04x | ", p, Common::swap16(pSrc[p]));
+ }
+ }
+
+ pDest[p] = Common::swap16(pSrc[p]);
+
+ }
+
+ if(n > 20 && logall) {DEBUG_LOG(DSPHLE, "\n");} // logging
+ // --------------
+ // Here we update the block address to the starting point of the next PB
+ blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo;
+ // --------------
+ // save some values
+ count++;
+ gLastBlock = paraAddr; // blockAddr
+ // ============
+ }
+ else
+ {
+ break;
+ }
+
+ } // end of the big loop
+ if (n > 20) {n = 0;} // for logging
+
+
+ // return the number of readed PBs
+ return count;
+}
+// =======================================================================================
+
+#endif
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h
new file mode 100644
index 0000000000..f4cc2d0ec6
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Logging/UCode_AXStructs.h
@@ -0,0 +1,146 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+#ifdef _WIN32
+
+
+#ifndef UCODE_AX_STRUCTS
+#define UCODE_AX_STRUCTS
+
+struct PBMixer
+{
+ u16 volume_left;
+ u16 unknown;
+ u16 volume_right;
+ u16 unknown2;
+
+ u16 unknown3[8];
+ u16 unknown4[6];
+};
+
+struct PBInitialTimeDelay
+{
+ u16 unknown[7];
+};
+
+// Update data - read these each 1ms subframe and use them!
+// It seems that to provide higher time precisions for MIDI events, some games
+// use this thing to update the parameter blocks per 1ms sub-block (a block is 5ms).
+// Using this data should fix games that are missing MIDI notes.
+struct PBUpdates
+{
+ u16 num_updates[5];
+ u16 data_hi; // These point to main RAM. Not sure about the structure of the data.
+ u16 data_lo;
+};
+
+struct PBUnknown
+{
+ s16 unknown[9];
+};
+
+struct PBVolumeEnvelope
+{
+ u16 cur_volume;
+ s16 cur_volume_delta;
+};
+
+struct PBUnknown2
+{
+ u16 unknown_reserved[3];
+};
+
+struct PBAudioAddr
+{
+ u16 looping;
+ u16 sample_format;
+ u16 loop_addr_hi; // Start of loop (this will point to a shared "zero" buffer if one-shot mode is active)
+ u16 loop_addr_lo;
+ u16 end_addr_hi; // End of sample (and loop), inclusive
+ u16 end_addr_lo;
+ u16 cur_addr_hi;
+ u16 cur_addr_lo;
+};
+
+struct PBADPCMInfo
+{
+ s16 coefs[16];
+ u16 unknown;
+ u16 pred_scale;
+ s16 yn1;
+ s16 yn2;
+};
+
+struct PBSampleRateConverter
+{
+ u16 ratio_hi;
+ u16 ratio_lo;
+ u16 cur_addr_frac;
+ u16 last_samples[4];
+};
+
+struct PBADPCMLoopInfo
+{
+ u16 pred_scale;
+ u16 yn1;
+ u16 yn2;
+};
+
+struct AXParamBlock
+{
+ u16 next_pb_hi;
+ u16 next_pb_lo;
+
+ u16 this_pb_hi;
+ u16 this_pb_lo;
+
+ u16 src_type; // Type of sample rate converter (2 = none, ?, linear)
+ u16 unknown1;
+
+ u16 mixer_control;
+ u16 running; // 1=RUN 0=STOP
+ u16 is_stream; // 1 = stream, 0 = one shot
+
+ PBMixer mixer;
+ PBInitialTimeDelay initial_time_delay;
+ PBUpdates updates;
+ PBUnknown unknown2;
+ PBVolumeEnvelope vol_env;
+ PBUnknown2 unknown3;
+ PBAudioAddr audio_addr;
+ PBADPCMInfo adpcm;
+ PBSampleRateConverter src;
+ PBADPCMLoopInfo adpcm_loop_info;
+ u16 unknown_maybe_padding[3];
+};
+
+enum {
+ AUDIOFORMAT_ADPCM = 0,
+ AUDIOFORMAT_PCM8 = 0x19,
+ AUDIOFORMAT_PCM16 = 0xA,
+};
+
+enum {
+ SRCTYPE_LINEAR = 1,
+ SRCTYPE_NEAREST = 2,
+ MIXCONTROL_RAMPING = 8,
+};
+
+
+#endif
+
+#endif // win32
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.cpp
new file mode 100644
index 0000000000..363571e752
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.cpp
@@ -0,0 +1,164 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+// This queue solution is temporary. I'll implement something more efficient later.
+
+#include
+
+#include "Thread.h"
+#include "Mixer.h"
+#include "FixedSizeQueue.h"
+
+#ifdef _WIN32
+#include "DSoundStream.h"
+#else
+#include
+#endif
+
+namespace {
+Common::CriticalSection push_sync;
+
+// On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so...
+const int queue_minlength = 1024 * 4;
+const int queue_maxlength = 1024 * 28;
+
+FixedSizeQueue sample_queue;
+
+} // namespace
+
+volatile bool mixer_HLEready = false;
+volatile int queue_size = 0;
+
+void Mixer(short *buffer, int numSamples, int bits, int rate, int channels)
+{
+ // silence
+ memset(buffer, 0, numSamples * 2 * sizeof(short));
+
+ push_sync.Enter();
+ int count = 0;
+ while (queue_size > queue_minlength && count < numSamples * 2) {
+ int x = buffer[count];
+ x += sample_queue.front();
+ if (x > 32767) x = 32767;
+ if (x < -32767) x = -32767;
+ buffer[count++] = x;
+ sample_queue.pop();
+ x = buffer[count];
+ x += sample_queue.front();
+ if (x > 32767) x = 32767;
+ if (x < -32767) x = -32767;
+ buffer[count++] = x;
+ sample_queue.pop();
+ queue_size-=2;
+ }
+ push_sync.Leave();
+}
+
+void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) {
+// static FILE *f;
+// if (!f)
+// f = fopen("d:\\hello.raw", "wb");
+// fwrite(buffer, num_stereo_samples * 4, 1, f);
+ if (queue_size == 0)
+ {
+ queue_size = queue_minlength;
+ for (int i = 0; i < queue_minlength; i++)
+ sample_queue.push((s16)0);
+ }
+
+ static int PV1l=0,PV2l=0,PV3l=0,PV4l=0;
+ static int PV1r=0,PV2r=0,PV3r=0,PV4r=0;
+ static int acc=0;
+
+#ifdef _WIN32
+ if (!GetAsyncKeyState(VK_TAB)) {
+ while (queue_size > queue_maxlength / 2) {
+ DSound::DSound_UpdateSound();
+ Sleep(0);
+ }
+ } else {
+ return;
+ }
+#else
+ while (queue_size > queue_maxlength) {
+ sleep(0);
+ }
+#endif
+ //convert into config option?
+ const int mode = 2;
+
+ push_sync.Enter();
+ while (num_stereo_samples)
+ {
+ acc += sample_rate;
+ while (num_stereo_samples && (acc >= 48000))
+ {
+ PV4l=PV3l;
+ PV3l=PV2l;
+ PV2l=PV1l;
+ PV1l=*(buffer++); //32bit processing
+ PV4r=PV3r;
+ PV3r=PV2r;
+ PV2r=PV1r;
+ PV1r=*(buffer++); //32bit processing
+ num_stereo_samples--;
+ acc-=48000;
+ }
+
+ // defaults to nearest
+ s32 DataL = PV1l;
+ s32 DataR = PV1r;
+
+ if (mode == 1) //linear
+ {
+ DataL = PV1l + ((PV2l - PV1l)*acc)/48000;
+ DataR = PV1r + ((PV2r - PV1r)*acc)/48000;
+ }
+ else if (mode == 2) //cubic
+ {
+ s32 a0l = PV1l - PV2l - PV4l + PV3l;
+ s32 a0r = PV1r - PV2r - PV4r + PV3r;
+ s32 a1l = PV4l - PV3l - a0l;
+ s32 a1r = PV4r - PV3r - a0r;
+ s32 a2l = PV1l - PV4l;
+ s32 a2r = PV1r - PV4r;
+ s32 a3l = PV2l;
+ s32 a3r = PV2r;
+
+ s32 t0l = ((a0l )*acc)/48000;
+ s32 t0r = ((a0r )*acc)/48000;
+ s32 t1l = ((t0l+a1l)*acc)/48000;
+ s32 t1r = ((t0r+a1r)*acc)/48000;
+ s32 t2l = ((t1l+a2l)*acc)/48000;
+ s32 t2r = ((t1r+a2r)*acc)/48000;
+ s32 t3l = ((t2l+a3l));
+ s32 t3r = ((t2r+a3r));
+
+ DataL = t3l;
+ DataR = t3r;
+ }
+
+ int l = DataL, r = DataR;
+ if (l < -32767) l = -32767;
+ if (r < -32767) r = -32767;
+ if (l > 32767) l = 32767;
+ if (r > 32767) r = 32767;
+ sample_queue.push(l);
+ sample_queue.push(r);
+ }
+ push_sync.Leave();
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.h
new file mode 100644
index 0000000000..3c5095ab70
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Mixer.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _MIXER_H
+#define _MIXER_H
+
+extern volatile bool mixer_HLEready;
+
+// Called from audio threads
+void Mixer(short* buffer, int numSamples, int bits, int rate, int channels);
+
+// Called from main thread
+void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate);
+
+#endif
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegSettings.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegSettings.cpp
new file mode 100644
index 0000000000..eebd599054
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegSettings.cpp
@@ -0,0 +1,274 @@
+// RegSettings.cpp
+//
+// Copyright (c) 2001 Magomed Abdurakhmanov
+// maq@hotbox.ru, http://mickels.iwt.ru/en
+//
+//
+//
+// No warranties are given. Use at your own risk.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "RegSettings.h"
+
+//////////////////////////////////////////////////////////////////////
+// CWindowSettings
+
+#define S_WINDOW_PLACEMENT_VAL _T("WindowPlacement")
+
+CWindowSettings::CWindowSettings()
+{
+ m_WindowPlacement.length = sizeof(m_WindowPlacement);
+ m_WindowPlacement.flags = 0;
+ m_WindowPlacement.ptMinPosition.x = 0;
+ m_WindowPlacement.ptMinPosition.y = 0;
+ m_WindowPlacement.ptMaxPosition.x = 0;
+ m_WindowPlacement.ptMaxPosition.y = 0;
+
+ CRect rc;
+ SystemParametersInfo(SPI_GETWORKAREA, 0, rc, 0);
+ rc.DeflateRect(100, 100);
+ m_WindowPlacement.rcNormalPosition = rc;
+ m_WindowPlacement.showCmd = SW_SHOWNORMAL;
+}
+
+
+bool CWindowSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/)
+{
+ CRegKey reg;
+ DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ);
+
+ if (err == ERROR_SUCCESS)
+ {
+ DWORD dwType = NULL;
+ DWORD dwSize = sizeof(m_WindowPlacement);
+ err = RegQueryValueEx(reg.m_hKey, CString(szPrefix) + S_WINDOW_PLACEMENT_VAL, NULL, &dwType,
+ (LPBYTE)&m_WindowPlacement, &dwSize);
+ }
+
+ return(err == ERROR_SUCCESS);
+}
+
+
+bool CWindowSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const
+{
+ CRegKey reg;
+ DWORD err = reg.Create(hkRootKey, szRegKey);
+
+ if (err == ERROR_SUCCESS)
+ {
+ err = RegSetValueEx(reg.m_hKey, CString(szPrefix) + S_WINDOW_PLACEMENT_VAL, NULL, REG_BINARY,
+ (LPBYTE)&m_WindowPlacement, sizeof(m_WindowPlacement));
+ }
+
+ return(err == ERROR_SUCCESS);
+}
+
+
+void CWindowSettings::GetFrom(CWindow& Wnd)
+{
+ ATLASSERT(Wnd.IsWindow());
+ Wnd.GetWindowPlacement(&m_WindowPlacement);
+}
+
+
+void CWindowSettings::ApplyTo(CWindow& Wnd, int nCmdShow /* = SW_SHOWNORMAL*/) const
+{
+ ATLASSERT(Wnd.IsWindow());
+
+ Wnd.SetWindowPlacement(&m_WindowPlacement);
+
+ if (SW_SHOWNORMAL != nCmdShow)
+ {
+ Wnd.ShowWindow(nCmdShow);
+ }
+ else
+ if (m_WindowPlacement.showCmd == SW_MINIMIZE || m_WindowPlacement.showCmd == SW_SHOWMINIMIZED)
+ {
+ Wnd.ShowWindow(SW_SHOWNORMAL);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// CReBarSettings
+
+#define S_BAR_BANDCOUNT _T("BandCount")
+#define S_BAR_ID_VAL _T("ID")
+#define S_BAR_CX_VAL _T("CX")
+#define S_BAR_BREAKLINE_VAL _T("BreakLine")
+
+CReBarSettings::CReBarSettings()
+{
+ m_pBands = NULL;
+ m_cbBandCount = 0;
+}
+
+
+CReBarSettings::~CReBarSettings()
+{
+ if (m_pBands != NULL)
+ {
+ delete[] m_pBands;
+ m_pBands = NULL;
+ }
+}
+
+
+bool CReBarSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/)
+{
+ if (m_pBands != NULL)
+ {
+ delete[] m_pBands;
+ m_pBands = NULL;
+ }
+
+ m_pBands = NULL;
+ m_cbBandCount = 0;
+
+ CRegKey reg;
+ DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ);
+
+ if (err == ERROR_SUCCESS)
+ {
+ reg.QueryDWORDValue(CString(szPrefix) + S_BAR_BANDCOUNT, m_cbBandCount);
+
+ if (m_cbBandCount > 0)
+ {
+ m_pBands = new BandInfo[m_cbBandCount];
+ }
+
+ for (DWORD i = 0; i < m_cbBandCount; i++)
+ {
+ CString s;
+ s.Format(_T("%s%i_"), szPrefix, i);
+ reg.QueryDWORDValue(s + S_BAR_ID_VAL, m_pBands[i].ID);
+ reg.QueryDWORDValue(s + S_BAR_CX_VAL, m_pBands[i].cx);
+
+ DWORD dw;
+ reg.QueryDWORDValue(s + S_BAR_BREAKLINE_VAL, dw);
+ m_pBands[i].BreakLine = dw != 0;
+ }
+ }
+
+ return(err == ERROR_SUCCESS);
+}
+
+
+bool CReBarSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const
+{
+ CRegKey reg;
+ DWORD err = reg.Create(hkRootKey, szRegKey);
+
+ if (err == ERROR_SUCCESS)
+ {
+ reg.SetDWORDValue(CString(szPrefix) + S_BAR_BANDCOUNT, m_cbBandCount);
+
+ for (DWORD i = 0; i < m_cbBandCount; i++)
+ {
+ CString s;
+ s.Format(_T("%s%i_"), szPrefix, i);
+ reg.SetDWORDValue(s + S_BAR_ID_VAL, m_pBands[i].ID);
+ reg.SetDWORDValue(s + S_BAR_CX_VAL, m_pBands[i].cx);
+
+ DWORD dw = m_pBands[i].BreakLine;
+ reg.SetDWORDValue(s + S_BAR_BREAKLINE_VAL, dw);
+ }
+ }
+
+ return(err == ERROR_SUCCESS);
+}
+
+
+void CReBarSettings::GetFrom(CReBarCtrl& ReBar)
+{
+ ATLASSERT(ReBar.IsWindow());
+
+ if (m_pBands != NULL)
+ {
+ delete[] m_pBands;
+ }
+
+ m_pBands = NULL;
+ m_cbBandCount = ReBar.GetBandCount();
+
+ if (m_cbBandCount > 0)
+ {
+ m_pBands = new BandInfo[m_cbBandCount];
+ }
+
+ for (UINT i = 0; i < m_cbBandCount; i++)
+ {
+ REBARBANDINFO rbi;
+ rbi.cbSize = sizeof(rbi);
+ rbi.fMask = RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE;
+ ReBar.GetBandInfo(i, &rbi);
+ m_pBands[i].ID = rbi.wID;
+ m_pBands[i].cx = rbi.cx;
+ m_pBands[i].BreakLine = (rbi.fStyle & RBBS_BREAK) != 0;
+ }
+}
+
+
+void CReBarSettings::ApplyTo(CReBarCtrl& ReBar) const
+{
+ ATLASSERT(ReBar.IsWindow());
+
+ for (UINT i = 0; i < m_cbBandCount; i++)
+ {
+ ReBar.MoveBand(ReBar.IdToIndex(m_pBands[i].ID), i);
+ REBARBANDINFO rbi;
+ rbi.cbSize = sizeof(rbi);
+ rbi.fMask = RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE;
+ ReBar.GetBandInfo(i, &rbi);
+
+ rbi.cx = m_pBands[i].cx;
+
+ if (m_pBands[i].BreakLine)
+ {
+ rbi.fStyle |= RBBS_BREAK;
+ }
+ else
+ {
+ rbi.fStyle &= (~RBBS_BREAK);
+ }
+
+ ReBar.SetBandInfo(i, &rbi);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// CSplitterSettings
+
+#define S_SPLITTER_POS _T("SplitterPos")
+
+bool CSplitterSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/)
+{
+ CRegKey reg;
+ DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ);
+
+ if (err == ERROR_SUCCESS)
+ {
+ reg.QueryDWORDValue(CString(szPrefix) + S_SPLITTER_POS, m_dwPos);
+ }
+
+ return(err == ERROR_SUCCESS);
+}
+
+
+bool CSplitterSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const
+{
+ CRegKey reg;
+ DWORD err = reg.Create(hkRootKey, szRegKey);
+
+ if (err == ERROR_SUCCESS)
+ {
+ reg.SetDWORDValue(CString(szPrefix) + S_SPLITTER_POS, m_dwPos);
+ }
+
+ return(err == ERROR_SUCCESS);
+}
+
+
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegSettings.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegSettings.h
new file mode 100644
index 0000000000..83a71e2415
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegSettings.h
@@ -0,0 +1,81 @@
+// RegSettings.h
+//
+// Copyright (c) 2001 Magomed Abdurakhmanov
+// maq@hotbox.ru, http://mickels.iwt.ru/en
+//
+//
+//
+// No warranties are given. Use at your own risk.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined (AFX_REGSETTINGS_H__91E69C67_8104_4819_969A_B5E71A9993D5__INCLUDED_)
+#define AFX_REGSETTINGS_H__91E69C67_8104_4819_969A_B5E71A9993D5__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include
+#include
+
+class CWindowSettings
+{
+ public:
+
+ WINDOWPLACEMENT m_WindowPlacement;
+
+ CWindowSettings();
+ void GetFrom(CWindow& Wnd);
+ void ApplyTo(CWindow& Wnd, int nCmdShow = SW_SHOWNORMAL) const;
+
+ bool Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey = HKEY_CURRENT_USER);
+ bool Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey = HKEY_CURRENT_USER) const;
+};
+
+class CReBarSettings
+{
+ public:
+
+ struct BandInfo
+ {
+ DWORD ID;
+ DWORD cx;
+ bool BreakLine;
+ }* m_pBands;
+
+ DWORD m_cbBandCount;
+
+ CReBarSettings();
+ ~CReBarSettings();
+
+ void GetFrom(CReBarCtrl& ReBar);
+ void ApplyTo(CReBarCtrl& ReBar) const;
+
+ bool Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey = HKEY_CURRENT_USER);
+ bool Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey = HKEY_CURRENT_USER) const;
+};
+
+class CSplitterSettings
+{
+ public:
+
+ DWORD m_dwPos;
+
+ templatevoid GetFrom(const T& Splitter)
+ {
+ m_dwPos = Splitter.GetSplitterPos();
+ }
+
+
+ templatevoid ApplyTo(T& Splitter) const
+ {
+ Splitter.SetSplitterPos(m_dwPos);
+ }
+
+
+ bool Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey = HKEY_CURRENT_USER);
+ bool Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey = HKEY_CURRENT_USER) const;
+};
+
+#endif // !defined(AFX_REGSETTINGS_H__91E69C67_8104_4819_969A_B5E71A9993D5__INCLUDED_)
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegisterDlg.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegisterDlg.cpp
new file mode 100644
index 0000000000..9e0889d3bb
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegisterDlg.cpp
@@ -0,0 +1,207 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "../res/resource.h"
+#include "RegisterDlg.h"
+
+#include "disassemble.h"
+#include "gdsp_interpreter.h"
+#include "RegSettings.h"
+
+CRegisterDlg::CRegisterDlg()
+ : m_CachedCounter(-1)
+{}
+
+
+BOOL CRegisterDlg::PreTranslateMessage(MSG* pMsg)
+{
+ return(IsDialogMessage(pMsg));
+}
+
+
+BOOL CRegisterDlg::OnIdle()
+{
+ return(FALSE);
+}
+
+
+LRESULT CRegisterDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+{
+ CWindowSettings ws;
+
+ if (ws.Load("Software\\Dolphin\\DSP", "Register"))
+ {
+ ws.ApplyTo(CWindow(m_hWnd), SW_SHOW);
+ }
+
+ m_RegisterListViewCtrl.m_hWnd = GetDlgItem(IDC_DISASM_LIST);
+
+ UIAddChildWindowContainer(m_hWnd);
+
+ m_RegisterListViewCtrl.AddColumn(_T("General"), 0);
+ m_RegisterListViewCtrl.AddColumn(_T(" "), 1);
+ m_RegisterListViewCtrl.AddColumn(_T("Special"), 2);
+ m_RegisterListViewCtrl.AddColumn(_T("0"), 3);
+
+ m_RegisterListViewCtrl.SetColumnWidth(0, 50);
+ m_RegisterListViewCtrl.SetColumnWidth(1, 100);
+ m_RegisterListViewCtrl.SetColumnWidth(2, 60);
+ m_RegisterListViewCtrl.SetColumnWidth(3, 100);
+
+ m_RegisterListViewCtrl.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
+ m_RegisterListViewCtrl.SetTextBkColor(GetSysColor(COLOR_3DLIGHT));
+
+
+ for (uint16 i = 0; i < 16; i++)
+ {
+ // 0-15
+ int Item = m_RegisterListViewCtrl.AddItem(0, 0, gd_dis_get_reg_name(i));
+
+ // 16-31
+ m_RegisterListViewCtrl.AddItem(Item, 2, gd_dis_get_reg_name(16 + i));
+
+ // just for easy sort
+ m_RegisterListViewCtrl.SetItemData(Item, i);
+ }
+
+ m_RegisterListViewCtrl.SortItems(CompareFunc, (LPARAM) this);
+
+ UpdateRegisterListView();
+
+ return(TRUE);
+}
+
+
+LRESULT CRegisterDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
+{
+ CWindowSettings ws;
+ ws.GetFrom(CWindow(m_hWnd));
+ ws.Save("Software\\Dolphin\\DSP", "Register");
+
+ return(0);
+}
+
+
+void CRegisterDlg::UpdateRegisterListView()
+{
+ if (m_CachedCounter == g_dsp.step_counter)
+ {
+ return;
+ }
+
+ m_CachedCounter = g_dsp.step_counter;
+
+ char Temp[256];
+
+ for (uint16 i = 0; i < 16; i++)
+ {
+ // 0-15
+ if (m_CachedRegs[i] != g_dsp.r[i])
+ {
+ m_CachedRegHasChanged[i] = true;
+ }
+ else
+ {
+ m_CachedRegHasChanged[i] = false;
+ }
+
+ m_CachedRegs[i] = g_dsp.r[i];
+
+ sprintf_s(Temp, 256, "0x%04x", g_dsp.r[i]);
+ m_RegisterListViewCtrl.SetItemText(i, 1, Temp);
+
+ // 16-31
+ if (m_CachedRegs[16 + i] != g_dsp.r[16 + i])
+ {
+ m_CachedRegHasChanged[16 + i] = true;
+ }
+ else
+ {
+ m_CachedRegHasChanged[16 + i] = false;
+ }
+
+ m_CachedRegs[16 + i] = g_dsp.r[16 + i];
+
+ sprintf_s(Temp, 256, "0x%04x", g_dsp.r[16 + i]);
+ m_RegisterListViewCtrl.SetItemText(i, 3, Temp);
+ }
+}
+
+
+int CALLBACK CRegisterDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+ return(lParam1 > lParam2);
+}
+
+
+LRESULT CRegisterDlg::OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& _bHandled)
+{
+ int result = CDRF_DODEFAULT;
+
+ NMLVCUSTOMDRAW* pLVCD = reinterpret_cast(pnmh);
+
+ switch (pLVCD->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ result = CDRF_NOTIFYITEMDRAW;
+ break;
+
+ case CDDS_ITEMPREPAINT:
+ result = CDRF_NOTIFYSUBITEMDRAW;
+ break;
+
+ case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
+ {
+ pLVCD->nmcd.uItemState &= ~(CDIS_SELECTED | CDIS_FOCUS);
+
+ int Offset = static_cast(m_RegisterListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec));
+
+ size_t Register = -1;
+
+ if (pLVCD->iSubItem == 1)
+ {
+ Register = Offset;
+ }
+ else if (pLVCD->iSubItem == 3)
+ {
+ Register = Offset + 16;
+ }
+
+ if (Register != -1)
+ {
+ if (m_CachedRegHasChanged[Register])
+ {
+ pLVCD->clrTextBk = RGB(0xFF, 192, 192);
+ }
+ else
+ {
+ pLVCD->clrTextBk = RGB(0xF0, 0xF0, 0xF0);
+ }
+ }
+ else
+ {
+ pLVCD->clrTextBk = RGB(192, 224, 192);
+ }
+
+
+ // uint16 CurrentAddress = static_cast(m_DisAsmListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec));
+ }
+ break;
+ }
+
+ return(result);
+}
diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegisterDlg.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegisterDlg.h
new file mode 100644
index 0000000000..7f7a1e4e21
--- /dev/null
+++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/RegisterDlg.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#pragma once
+
+#include "Globals.h"
+
+#include