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 +#include "DisAsmListView.h" + +class CRegisterDlg + : public CDialogImpl, public CUpdateUI +{ + public: + + CRegisterDlg(); + + enum { IDD = IDD_REGISTERDLG }; + + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual BOOL OnIdle(); + + + BEGIN_UPDATE_UI_MAP(CRegisterDlg) + END_UPDATE_UI_MAP() + + BEGIN_MSG_MAP(CRegisterDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnCustomDraw) + +// COMMAND_ID_HANDLER(ID_STEP, OnStep) +// COMMAND_ID_HANDLER(ID_GO, OnGo) +// COMMAND_ID_HANDLER(ID_SHOW_REGISTER, OnShowRegisters) + 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 OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, 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*/); + + void CloseDialog(int nVal); + + void UpdateRegisterListView(); + + + private: + + CListViewCtrl m_RegisterListViewCtrl; + + static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); + + + uint64 m_CachedCounter; + uint16 m_CachedRegs[32]; + bool m_CachedRegHasChanged[32]; +}; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript b/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript new file mode 100644 index 0000000000..0a935fa938 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/SConscript @@ -0,0 +1,45 @@ +# -*- python -*- + +Import('env') +import sys + +name = "Plugin_DSP_LLE_Testing" + +if not env['HAVE_AO']: + print name + " must have AO to be build" + Return() + +files = [ + "AOSoundStream.cpp", +# "DisAsmDlg.cpp", + "disassemble.cpp", +# "DSoundStream.cpp", + "gdsp_aram.cpp", + "gdsp_ext_op.cpp", + "gdsp_interface.cpp", + "gdsp_interpreter.cpp", + "gdsp_memory.cpp", + "gdsp_opcodes.cpp", + "gdsp_registers.cpp", + "Globals.cpp", + "HLE_Functions.cpp", + "HLE_Helper.cpp", + "main.cpp", + "Mixer.cpp", + "opcodes.cpp", +# "RegisterDlg.cpp", +# "RegSettings.cpp", +# "stdafx.cpp", + "Tools.cpp", + "Logging/AXTask.cpp", + "Logging/Logging.cpp", + "Logging/ReadPBs.cpp", + ] + +lleenv = env.Clone() +lleenv.Append( + CXXFLAGS = [ '-fPIC' ], + LIBS = [ 'common' ], + ) + +lleenv.SharedLibrary(env['plugin_dir']+name, files) diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Tools.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Tools.cpp new file mode 100644 index 0000000000..e88de886f3 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Tools.cpp @@ -0,0 +1,93 @@ +// 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 +#include + +#include "Common.h" +#include "Globals.h" + +#include "gdsp_interpreter.h" + +bool DumpDSPCode(uint32 _Address, uint32 _Length, uint32 crc) +{ + char szFilename[MAX_PATH]; + sprintf(szFilename, "c:\\_\\DSP_UC_%08X.bin", crc); + FILE* pFile = fopen(szFilename, "wb"); + + if (pFile != NULL) + { + fwrite(g_dspInitialize.pGetMemoryPointer(_Address), _Length, 1, pFile); + fclose(pFile); + return(true); + } + else + { + PanicAlert("Cant open file (%s) to dump UCode!!", szFilename); + } + + return(false); +} + + +uint32 GenerateCRC(const unsigned char* _pBuffer, int _pLength) +{ + unsigned long CRC = 0xFFFFFFFF; + + while (_pLength--) + { + unsigned long Temp = (unsigned long)((CRC & 0xFF) ^ *_pBuffer++); + + for (int j = 0; j < 8; j++) + { + if (Temp & 0x1) + { + Temp = (Temp >> 1) ^ 0xEDB88320; + } + else + { + Temp >>= 1; + } + } + + CRC = (CRC >> 8) ^ Temp; + } + + return(CRC ^ 0xFFFFFFFF); +} + + +bool DumpCWCode(uint32 _Address, uint32 _Length) +{ + FILE* pFile = fopen("d:\\DSP_UCode.bin", "wb"); + + if (pFile != NULL) + { + for (size_t i = _Address; i < _Address + _Length; i++) + { + uint16 val = Common::swap16(g_dsp.iram[i]); + fprintf(pFile, " cw 0x%04x \n", val); + } + + fclose(pFile); + return(true); + } + + return(false); +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Tools.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Tools.h new file mode 100644 index 0000000000..6c66e6f993 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Tools.h @@ -0,0 +1,50 @@ +// 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 + +// UDSPControl +union UDSPControl +{ + uint16 Hex; + struct + { + unsigned DSPReset : 1; // Write 1 to reset and waits for 0 + unsigned DSPAssertInt : 1; + unsigned DSPHalt : 1; + + unsigned AI : 1; + unsigned AI_mask : 1; + unsigned ARAM : 1; + unsigned ARAM_mask : 1; + unsigned DSP : 1; + unsigned DSP_mask : 1; + + unsigned ARAM_DMAState : 1; // DSPGetDMAStatus() uses this flag + unsigned unk3 : 1; + unsigned DSPInit : 1; // DSPInit() writes to this flag + unsigned pad : 4; + }; + + UDSPControl(uint16 _Hex = 0) + : Hex(_Hex) {} +}; + + +bool DumpDSPCode(uint32 _Address, uint32 _Length, uint32 crc); +uint32 GenerateCRC(const unsigned char* _pBuffer, int _pLength); +bool DumpCWCode(uint32 _Address, uint32 _Length); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp new file mode 100644 index 0000000000..0b7ceb8894 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.cpp @@ -0,0 +1,622 @@ +/*==================================================================== + + filename: disassemble.cpp + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include +#include +#include + +#include "Globals.h" + +#include "disassemble.h" +#include "opcodes.h" +// #include "gdsp_tool.h" + +#ifdef _MSC_VER +#pragma warning(disable:4996) +#endif + +uint32 unk_opcodes[0x10000]; + +uint16 swap16(uint16 x); + + +// predefined labels +typedef struct pdlabel_t +{ + uint16 addr; + const char* name; + const char* description; +} pdlabels_t; + +const pdlabel_t pdlabels[] = +{ + {0xffa0, "COEF_A1_0", "COEF_A1_0",}, + {0xffa1, "COEF_A2_0", "COEF_A2_0",}, + {0xffa2, "COEF_A1_1", "COEF_A1_1",}, + {0xffa3, "COEF_A2_1", "COEF_A2_1",}, + {0xffa4, "COEF_A1_2", "COEF_A1_2",}, + {0xffa5, "COEF_A2_2", "COEF_A2_2",}, + {0xffa6, "COEF_A1_3", "COEF_A1_3",}, + {0xffa7, "COEF_A2_3", "COEF_A2_3",}, + {0xffa8, "COEF_A1_4", "COEF_A1_4",}, + {0xffa9, "COEF_A2_4", "COEF_A2_4",}, + {0xffaa, "COEF_A1_5", "COEF_A1_5",}, + {0xffab, "COEF_A2_5", "COEF_A2_5",}, + {0xffac, "COEF_A1_6", "COEF_A1_6",}, + {0xffad, "COEF_A2_6", "COEF_A2_6",}, + {0xffae, "COEF_A1_7", "COEF_A1_7",}, + {0xffaf, "COEF_A2_7", "COEF_A2_7",}, + {0xffc9, "DSCR", "DSP DMA Control Reg",}, + {0xffcb, "DSBL", "DSP DMA Block Length",}, + {0xffcd, "DSPA", "DSP DMA DMEM Address",}, + {0xffce, "DSMAH", "DSP DMA Mem Address H",}, + {0xffcf, "DSMAL", "DSP DMA Mem Address L",}, + {0xffd1, "SampleFormat", "SampleFormat",}, + + {0xffd3, "Unk Zelda", "Unk Zelda writes to it",}, + + {0xffd4, "ACSAH", "Accelerator start address H",}, + {0xffd5, "ACSAL", "Accelerator start address L",}, + {0xffd6, "ACEAH", "Accelerator end address H",}, + {0xffd7, "ACEAL", "Accelerator end address L",}, + {0xffd8, "ACCAH", "Accelerator current address H",}, + {0xffd9, "ACCAL", "Accelerator current address L",}, + {0xffda, "pred_scale", "pred_scale",}, + {0xffdb, "yn1", "yn1",}, + {0xffdc, "yn2", "yn2",}, + {0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",}, + {0xffde, "GAIN", "Gain",}, + {0xffef, "AMDM", "ARAM DMA Request Mask",}, + {0xfffb, "DIRQ", "DSP IRQ Request",}, + {0xfffc, "DMBH", "DSP Mailbox H",}, + {0xfffd, "DMBL", "DSP Mailbox L",}, + {0xfffe, "CMBH", "CPU Mailbox H",}, + {0xffff, "CMBL", "CPU Mailbox L",}, +}; + +pdlabel_t regnames[] = +{ + {0x00, "R00", "Register 00",}, + {0x01, "R01", "Register 01",}, + {0x02, "R02", "Register 02",}, + {0x03, "R03", "Register 03",}, + {0x04, "R04", "Register 04",}, + {0x05, "R05", "Register 05",}, + {0x06, "R06", "Register 06",}, + {0x07, "R07", "Register 07",}, + {0x08, "R08", "Register 08",}, + {0x09, "R09", "Register 09",}, + {0x0a, "R10", "Register 10",}, + {0x0b, "R11", "Register 11",}, + {0x0c, "ST0", "Call stack",}, + {0x0d, "ST1", "Data stack",}, + {0x0e, "ST2", "Loop address stack",}, + {0x0f, "ST3", "Loop counter",}, + {0x00, "ACH0", "Accumulator High 0",}, + {0x11, "ACH1", "Accumulator High 1",}, + {0x12, "CR", "Config Register",}, + {0x13, "SR", "Special Register",}, + {0x14, "PROD.L", "PROD L",}, + {0x15, "PROD.M1", "PROD M1",}, + {0x16, "PROD.H", "PROD H",}, + {0x17, "PROD.M2", "PROD M2",}, + {0x18, "AX0.L", "Additional Accumulators Low 0",}, + {0x19, "AX1.L", "Additional Accumulators Low 1",}, + {0x1a, "AX0.H", "Additional Accumulators High 0",}, + {0x1b, "AX1.H", "Additional Accumulators High 1",}, + {0x1c, "AC0.L", "Register 28",}, + {0x1d, "AC1.L", "Register 29",}, + {0x1e, "AC0.M", "Register 00",}, + {0x1f, "AC1.M", "Register 00",}, + +// additional to resolve special names + {0x20, "ACC0", "Accumulators 0",}, + {0x21, "ACC1", "Accumulators 1",}, + {0x22, "AX0", "Additional Accumulators 0",}, + {0x23, "AX1", "Additional Accumulators 1",}, +}; + +const char* pdname(uint16 val) +{ + static char tmpstr[12]; // nasty + + for (int i = 0; i < (int)(sizeof(pdlabels) / sizeof(pdlabel_t)); i++) + { + if (pdlabels[i].addr == val) + { + return(pdlabels[i].name); + } + } + + sprintf(tmpstr, "0x%04x", val); + return(tmpstr); +} + + +char* gd_dis_params(gd_globals_t* gdg, opc_t* opc, uint16 op1, uint16 op2, char* strbuf) +{ + char* buf = strbuf; + uint32 val; + int j; + + for (j = 0; j < opc->param_count; j++) + { + if (j > 0) + { + sprintf(buf, ", "); + buf += strlen(buf); + } + + if (opc->params[j].loc >= 1) + { + val = op2; + } + else + { + val = op1; + } + + val &= opc->params[j].mask; + + if (opc->params[j].lshift < 0) + { + val = val << (-opc->params[j].lshift); + } + else + { + val = val >> opc->params[j].lshift; + } + + uint32 type; + type = opc->params[j].type; + + if (type & P_REG) + { + if (type == P_ACCM_D) + { + val = (~val & 0x1) | ((type & P_REGS_MASK) >> 8); + } + else + { + val |= (type & P_REGS_MASK) >> 8; + } + + type &= ~P_REGS_MASK; + } + + switch (type) + { + case P_REG: + + if (gdg->decode_registers){sprintf(buf, "$%s", regnames[val].name);} + else {sprintf(buf, "$%d", val);} + + break; + + case P_PRG: + + if (gdg->decode_registers){sprintf(buf, "@$%s", regnames[val].name);} + else {sprintf(buf, "@$%d", val);} + + break; + + case P_VAL: + sprintf(buf, "0x%04x", val); + break; + + case P_IMM: + + if (opc->params[j].size != 2) + { + sprintf(buf, "#0x%02x", val); + } + else + { + sprintf(buf, "#0x%04x", val); + } + + break; + + case P_MEM: + + if (opc->params[j].size != 2) + { + val = (uint16)(sint8)val; + } + + if (gdg->decode_names) + { + sprintf(buf, "@%s", pdname(val)); + } + else + { + sprintf(buf, "@0x%04x", val); + } + + break; + + default: + ERROR_LOG(DSPHLE, "Unknown parameter type: %x\n", opc->params[j].type); + exit(-1); + break; + } + + buf += strlen(buf); + } + + return(strbuf); +} + + +gd_globals_t* gd_init() +{ + gd_globals_t* gdg = (gd_globals_t*)malloc(sizeof(gd_globals_t)); + memset(gdg, 0, sizeof(gd_globals_t)); + return(gdg); +} + + +uint16 gd_dis_get_opcode_size(gd_globals_t* gdg) +{ + opc_t* opc = 0; + opc_t* opc_ext = 0; + bool extended; + + if ((gdg->pc & 0x7fff) >= 0x1000) + { + return(1); + } + + uint32 op1 = swap16(gdg->binbuf[gdg->pc & 0x0fff]); + + for (uint32 j = 0; j < opcodes_size; j++) + { + uint16 mask; + + if (opcodes[j].size & P_EXT) + { + mask = opcodes[j].opcode_mask & 0xff00; + } + else + { + mask = opcodes[j].opcode_mask; + } + + if ((op1 & mask) == opcodes[j].opcode) + { + opc = &opcodes[j]; + break; + } + } + + if (!opc) + { + ERROR_LOG(DSPHLE, "get_opcode_size ARGH"); + exit(0); + } + + if (opc->size & P_EXT && op1 & 0x00ff) + { + extended = true; + } + else + { + extended = false; + } + + if (extended) + { + // opcode has an extension + // find opcode + for (uint32 j = 0; j < opcodes_ext_size; j++) + { + if ((op1 & opcodes_ext[j].opcode_mask) == opcodes_ext[j].opcode) + { + opc_ext = &opcodes_ext[j]; + break; + } + } + + if (!opc_ext) + { + ERROR_LOG(DSPHLE, "get_opcode_size ext ARGH"); + } + + return(opc_ext->size); + } + + return(opc->size & ~P_EXT); +} + + +char* gd_dis_opcode(gd_globals_t* gdg) +{ + uint32 j; + uint32 op1, op2; + opc_t* opc = NULL; + opc_t* opc_ext = NULL; + uint16 pc; + char* buf = gdg->buffer; + bool extended; + + pc = gdg->pc; + *buf = '\0'; + + if ((pc & 0x7fff) >= 0x1000) + { + gdg->pc++; + return(gdg->buffer); + } + + pc &= 0x0fff; + op1 = swap16(gdg->binbuf[pc]); + + // find opcode + for (j = 0; j < opcodes_size; j++) + { + uint16 mask; + + if (opcodes[j].size & P_EXT) + { + mask = opcodes[j].opcode_mask & 0xff00; + } + else + { + mask = opcodes[j].opcode_mask; + } + + if ((op1 & mask) == opcodes[j].opcode) + { + opc = &opcodes[j]; + break; + } + } + + if (opc->size & P_EXT && op1 & 0x00ff) + { + extended = true; + } + else + { + extended = false; + } + + if (extended) + { + // opcode has an extension + // find opcode + for (j = 0; j < opcodes_ext_size; j++) + { + if ((op1 & opcodes_ext[j].opcode_mask) == opcodes_ext[j].opcode) + { + opc_ext = &opcodes_ext[j]; + break; + } + } + } + + // printing + + if (gdg->show_pc){sprintf(buf, "%04x ", gdg->pc);} + + buf += strlen(buf); + + if ((opc->size & ~P_EXT) == 2) + { + op2 = swap16(gdg->binbuf[pc + 1]); + + if (gdg->show_hex){sprintf(buf, "%04x %04x ", op1, op2);} + } + else + { + op2 = 0; + + if (gdg->show_hex){sprintf(buf, "%04x ", op1);} + } + + buf += strlen(buf); + + char tmpbuf[20]; + + if (extended) + { + sprintf(tmpbuf, "%s%c%s", opc->name, gdg->ext_separator, opc_ext->name); + } + else + { + sprintf(tmpbuf, "%s", opc->name); + } + + if (gdg->print_tabs) + { + sprintf(buf, "%s\t", tmpbuf); + } + else + { + sprintf(buf, "%-12s", tmpbuf); + } + + buf += strlen(buf); + + if (opc->param_count > 0) + { + gd_dis_params(gdg, opc, op1, op2, buf); + } + + buf += strlen(buf); + + if (extended) + { + if (opc->param_count > 0) + { + sprintf(buf, " "); + } + + buf += strlen(buf); + + sprintf(buf, ": "); + buf += strlen(buf); + + if (opc_ext->param_count > 0) + { + gd_dis_params(gdg, opc_ext, op1, op2, buf); + } + + buf += strlen(buf); + } + + if (opc->opcode_mask == 0) + { + // unknown opcode + unk_opcodes[op1]++; + sprintf(buf, "\t\t; *** UNKNOWN OPCODE ***"); + } + + if (extended) + { + gdg->pc += opc_ext->size; + } + else + { + gdg->pc += opc->size & ~P_EXT; + } + + return(gdg->buffer); +} + + +bool gd_dis_file(gd_globals_t* gdg, char* name, FILE* output) +{ + FILE* in; + uint32 size; + + in = fopen(name, "rb"); + + if (in == NULL) + { + return(false); + } + + fseek(in, 0, SEEK_END); + size = (int)ftell(in); + fseek(in, 0, SEEK_SET); + gdg->binbuf = (uint16*)malloc(size); + fread(gdg->binbuf, 1, size, in); + + gdg->buffer = (char*)malloc(256); + gdg->buffer_size = 256; + + for (gdg->pc = 0; gdg->pc < (size / 2);) + { + fprintf(output, "%s\n", gd_dis_opcode(gdg)); + } + + fclose(in); + + free(gdg->binbuf); + gdg->binbuf = NULL; + + free(gdg->buffer); + gdg->buffer = NULL; + gdg->buffer_size = 0; + + return(true); +} + + +void gd_dis_close_unkop() +{ + FILE* uo; + int i, j; + uint32 count = 0; + + uo = fopen("uo.bin", "wb"); + + if (uo) + { + fwrite(unk_opcodes, 1, sizeof(unk_opcodes), uo); + fclose(uo); + } + + uo = fopen("unkopc.txt", "w"); + + if (uo) + { + for (i = 0; i < 0x10000; i++) + { + if (unk_opcodes[i]) + { + count++; + fprintf(uo, "OP%04x\t%d", i, unk_opcodes[i]); + + for (j = 15; j >= 0; j--) + { + if ((j & 0x3) == 3) + { + fprintf(uo, "\tb"); + } + + fprintf(uo, "%d", (i >> j) & 0x1); + } + + fprintf(uo, "\n"); + } + } + + fprintf(uo, "Unknown opcodes count: %d\n", count); + fclose(uo); + } +} + + +void gd_dis_open_unkop() +{ + FILE* uo; + + uo = fopen("uo.bin", "rb"); + + if (uo) + { + fread(unk_opcodes, 1, sizeof(unk_opcodes), uo); + fclose(uo); + } + else + { + int i; + + for (i = 0; i < 0x10000; i++) + { + unk_opcodes[i] = 0; + } + } +} + + +const char* gd_dis_get_reg_name(uint16 reg) +{ + return(regnames[reg].name); +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.h new file mode 100644 index 0000000000..13772d12f3 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/disassemble.h @@ -0,0 +1,46 @@ +/*==================================================================== + + filename: opcodes.h + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#pragma once + +typedef struct gd_globals_t +{ + bool print_tabs; + bool show_hex; + bool show_pc; + bool decode_names; + bool decode_registers; + + uint16* binbuf; + uint16 pc; + char* buffer; + uint16 buffer_size; + char ext_separator; +} gd_globals_t; + + +char* gd_dis_opcode(gd_globals_t* gdg); +bool gd_dis_file(gd_globals_t* gdg, char* name, FILE* output); +const char* gd_dis_get_reg_name(uint16 reg); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_aram.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_aram.cpp new file mode 100644 index 0000000000..79a2154af1 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_aram.cpp @@ -0,0 +1,113 @@ +// 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 "gdsp_interface.h" + +extern uint16 dsp_swap16(uint16 x); + +// The hardware adpcm decoder :) +sint16 ADPCM_Step(uint32& _rSamplePos, uint32 _BaseAddress) +{ + sint16* pCoefTable = (sint16*)&gdsp_ifx_regs[DSP_COEF_A1_0]; + + if (((_rSamplePos) & 15) == 0) + { + gdsp_ifx_regs[DSP_PRED_SCALE] = g_dspInitialize.pARAM_Read_U8((_rSamplePos & ~15) >> 1); + _rSamplePos += 2; + } + + int scale = 1 << (gdsp_ifx_regs[DSP_PRED_SCALE] & 0xF); + int coef_idx = gdsp_ifx_regs[DSP_PRED_SCALE] >> 4; + + sint32 coef1 = pCoefTable[coef_idx * 2 + 0]; + sint32 coef2 = pCoefTable[coef_idx * 2 + 1]; + + int temp = (_rSamplePos & 1) ? + (g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) & 0xF) : + (g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) >> 4); + + if (temp >= 8) + temp -= 16; + + // 0x400 = 0.5 in 11-bit fixed point + int val = (scale * temp) + ((0x400 + coef1 * (sint16)gdsp_ifx_regs[DSP_YN1] + coef2 * (sint16)gdsp_ifx_regs[DSP_YN2]) >> 11); + + // Clamp values. + if (val > 0x7FFF) + val = 0x7FFF; + else if (val < -0x7FFF) + val = -0x7FFF; + + gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1]; + gdsp_ifx_regs[DSP_YN1] = val; + + _rSamplePos++; + + // The advanced interpolation (linear, polyphase,...) is done by the UCode, so we don't + // need to bother with it here. + return val; +} + +extern void gdsp_generate_exception(uint8 level); +uint16 dsp_read_aram() +{ + // uint32 BaseAddress = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL]; + uint32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL]; + uint32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL]; + + uint16 val; + + // lets the "hardware" decode + switch (gdsp_ifx_regs[DSP_FORMAT]) + { + case 0x00: + val = ADPCM_Step(Address, EndAddress); + break; + + case 0x0A: + val = (g_dspInitialize.pARAM_Read_U8(Address) << 8) | g_dspInitialize.pARAM_Read_U8(Address + 1); + + gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1]; + gdsp_ifx_regs[DSP_YN1] = val; + + Address += 2; + break; + + default: + val = (g_dspInitialize.pARAM_Read_U8(Address) << 8) | g_dspInitialize.pARAM_Read_U8(Address + 1); + Address += 2; + ERROR_LOG(DSPHLE, "Unknown DSP Format %i", gdsp_ifx_regs[DSP_FORMAT]); + break; + } + + // check for loop + if (Address > EndAddress) + { + Address = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL]; + gdsp_generate_exception(3); + gdsp_generate_exception(5); + + // Somehow, YN1 and YN2 must be initialized with their "loop" values, so yeah, + // it seems likely that we should raise an exception to let the DSP program do that, + // at least if DSP_FORMAT == 0x0A. + } + + gdsp_ifx_regs[DSP_ACCAH] = Address >> 16; + gdsp_ifx_regs[DSP_ACCAL] = Address & 0xffff; + return(val); +} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_aram.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_aram.h new file mode 100644 index 0000000000..4866b38147 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_aram.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/ + +#ifndef _GDSP_ARAM_H +#define _GDSP_ARAM_H + +uint16 dsp_read_aram(); + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ext_op.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ext_op.cpp new file mode 100644 index 0000000000..3eec84083f --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ext_op.cpp @@ -0,0 +1,284 @@ +/*==================================================================== + + filename: opcodes.h + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ +// +// +// At the moment just ls and sl are using the prolog +// perhaps all actions on r03 must be in the prolog +// +#include "Globals.h" + +#include "gdsp_opcodes_helper.h" + + +// +void dsp_op_ext_r_epi(uint16 _Opcode) +{ + uint8 op = (_Opcode >> 2) & 0x3; + uint8 reg = _Opcode & 0x3; + + switch (op) + { + case 0x00: + ERROR_LOG(DSPHLE, "dsp_op_ext_r_epi"); + break; + + case 0x01: + g_dsp.r[reg]--; + break; + + case 0x02: + g_dsp.r[reg]++; + break; + + case 0x03: + g_dsp.r[reg] += g_dsp.r[reg + 4]; + break; + } +} + + +void dsp_op_ext_mv(uint16 _Opcode) +{ + uint8 sreg = _Opcode & 0x3; + uint8 dreg = ((_Opcode >> 2) & 0x3); + + g_dsp.r[dreg + 0x18] = g_dsp.r[sreg + 0x1c]; +} + + +void dsp_op_ext_s(uint16 _Opcode) +{ + uint8 dreg = _Opcode & 0x3; + uint8 sreg = ((_Opcode >> 3) & 0x3) + 0x1c; + + dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]); + + if (_Opcode & 0x04) + { + g_dsp.r[dreg] += g_dsp.r[dreg + 4]; + } + else + { + g_dsp.r[dreg]++; + } +} + + +void dsp_op_ext_l(uint16 _Opcode) +{ + uint8 sreg = _Opcode & 0x3; + uint8 dreg = ((_Opcode >> 3) & 0x7) + 0x18; + + uint16 val = dsp_dmem_read(g_dsp.r[sreg]); + g_dsp.r[dreg] = val; + + if (_Opcode & 0x04) + { + g_dsp.r[sreg] += g_dsp.r[sreg + 4]; + } + else + { + g_dsp.r[sreg]++; + } +} + + +void dsp_op_ext_ls_pro(uint16 _Opcode) +{ + uint8 areg = (_Opcode & 0x1) + 0x1e; + dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]); + + if (_Opcode & 0x8) + { + g_dsp.r[0x03] += g_dsp.r[0x07]; + } + else + { + g_dsp.r[0x03]++; + } +} + + +void dsp_op_ext_ls_epi(uint16 _Opcode) +{ + uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18; + uint16 val = dsp_dmem_read(g_dsp.r[0x00]); + dsp_op_write_reg(dreg, val); + + if (_Opcode & 0x4) + { + g_dsp.r[0x00] += g_dsp.r[0x04]; + } + else + { + g_dsp.r[0x00]++; + } +} + + +void dsp_op_ext_sl_pro(uint16 _Opcode) +{ + uint8 areg = (_Opcode & 0x1) + 0x1e; + dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); + + if (_Opcode & 0x4) + { + g_dsp.r[0x00] += g_dsp.r[0x04]; + } + else + { + g_dsp.r[0x00]++; + } +} + + +void dsp_op_ext_sl_epi(uint16 _Opcode) +{ + uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18; + uint16 val = dsp_dmem_read(g_dsp.r[0x03]); + dsp_op_write_reg(dreg, val); + + if (_Opcode & 0x8) + { + g_dsp.r[0x03] += g_dsp.r[0x07]; + } + else + { + g_dsp.r[0x03]++; + } +} + + +void dsp_op_ext_ld(uint16 _Opcode) +{ + uint8 dreg1 = (((_Opcode >> 5) & 0x1) << 1) + 0x18; + uint8 dreg2 = (((_Opcode >> 4) & 0x1) << 1) + 0x19; + uint8 sreg = _Opcode & 0x3; + g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]); + g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]); + + if (_Opcode & 0x04) + { + g_dsp.r[sreg] += g_dsp.r[sreg + 0x04]; + } + else + { + g_dsp.r[sreg]++; + } + + if (_Opcode & 0x08) + { + g_dsp.r[0x03] += g_dsp.r[0x07]; + } + else + { + g_dsp.r[0x03]++; + } +} + + +// ================================================================================ +// +// +// +// ================================================================================ + +void dsp_op_ext_ops_pro(uint16 _Opcode) +{ + if ((_Opcode & 0xFF) == 0){return;} + + switch ((_Opcode >> 4) & 0xf) + { + case 0x00: + dsp_op_ext_r_epi(_Opcode); + break; + + case 0x01: + dsp_op_ext_mv(_Opcode); + break; + + case 0x02: + case 0x03: + dsp_op_ext_s(_Opcode); + break; + + case 0x04: + case 0x05: + case 0x06: + case 0x07: + dsp_op_ext_l(_Opcode); + break; + + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + + if (_Opcode & 0x2) + { + dsp_op_ext_sl_pro(_Opcode); + } + else + { + dsp_op_ext_ls_pro(_Opcode); + } + + return; + + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dsp_op_ext_ld(_Opcode); + break; + } +} + + +void dsp_op_ext_ops_epi(uint16 _Opcode) +{ + if ((_Opcode & 0xFF) == 0){return;} + + switch ((_Opcode >> 4) & 0xf) + { + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + + if (_Opcode & 0x2) + { + dsp_op_ext_sl_epi(_Opcode); + } + else + { + dsp_op_ext_ls_epi(_Opcode); + } + + return; + } +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ext_op.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ext_op.h new file mode 100644 index 0000000000..b27a5bbcca --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ext_op.h @@ -0,0 +1,33 @@ +/*==================================================================== + + filename: opcodes.h + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#ifndef _GDSP_EXT_OP_H +#define _GDSP_EXT_OP_H + +void dsp_op_ext_ops_pro(uint16 _Opcode); +void dsp_op_ext_ops_epi(uint16 _Opcode); + + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ifx.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ifx.h new file mode 100644 index 0000000000..24fb43555d --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_ifx.h @@ -0,0 +1,35 @@ +/*==================================================================== + + filename: gdsp_ifx.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +// ADPCM hw + +#ifndef _GDSP_IFX_H +#define _GDSP_IFX_H + +void gdsp_ifx_write(uint16 addr, uint16 val); +uint16 gdsp_ifx_read(uint16 addr); + + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp new file mode 100644 index 0000000000..07afe04b83 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp @@ -0,0 +1,357 @@ +/*==================================================================== + + filename: gdsp_interface.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include +#include "Globals.h" +#include "Thread.h" + +#include "gdsp_aram.h" +#include "gdsp_interpreter.h" +#include "gdsp_interface.h" + +#include "Tools.h" + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef _WIN32 +#undef WITH_DSP_ON_THREAD +//TODO FIX +#endif + +const char* reg_names[] = +{ + // a0 + "COEF_A1_0", "COEF_A2_0", "COEF_A1_1", "COEF_A2_1", "COEF_A1_2", "COEF_A2_2", "COEF_A1_3", "COEF_A2_3", + "COEF_A1_4", "COEF_A2_4", "COEF_A1_5", "COEF_A2_5", "COEF_A1_6", "COEF_A2_6", "COEF_A1_7", "COEF_A2_7", + // b0 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // c0 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, "DSCR", NULL, "DSBL", NULL, "DSPA", "DSMAH", "DSMAL", + // d0 + NULL, "SampleFormat", NULL, NULL, "ACSAH", "ACSAL", "ACEAH", "ACEAL", + "ACCAH", "ACCAL", "PRED_SCALE", "YN1", "YN2", "ARAM", "GAIN", NULL, + // e0 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, "AMDM", + // f0 + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, "DMBH", "DMBL", "CMBH", "CMBL", +}; + + +void gdsp_dma(); + +#ifdef WITH_DSP_ON_THREAD +Common::CriticalSection g_CriticalSection; +#endif + +static volatile uint16 gdsp_mbox[2][2]; + +uint16 gdsp_ifx_regs[256]; + +void gdsp_ifx_init() +{ + int i; + + for (i = 0; i < 256; i++) + { + gdsp_ifx_regs[i] = 0; + } + + gdsp_mbox[0][0] = 0; + gdsp_mbox[0][1] = 0; + gdsp_mbox[1][0] = 0; + gdsp_mbox[1][1] = 0; +} + + +uint32 gdsp_mbox_peek(uint8 mbx) +{ +#if WITH_DSP_ON_THREAD + g_CriticalSection.Enter(); +#endif + uint32 value = ((gdsp_mbox[mbx][0] << 16) | gdsp_mbox[mbx][1]); +#if WITH_DSP_ON_THREAD + g_CriticalSection.Leave(); +#endif + return value; +} + + +void gdsp_mbox_write_h(uint8 mbx, uint16 val) +{ +#if WITH_DSP_ON_THREAD + g_CriticalSection.Enter(); +#endif + + gdsp_mbox[mbx][0] = val & 0x7fff; + +#if WITH_DSP_ON_THREAD + g_CriticalSection.Leave(); +#endif +} + + +void gdsp_mbox_write_l(uint8 mbx, uint16 val) +{ +#if WITH_DSP_ON_THREAD + g_CriticalSection.Enter(); +#endif + + gdsp_mbox[mbx][1] = val; + gdsp_mbox[mbx][0] |= 0x8000; + +#if WITH_DSP_ON_THREAD + g_CriticalSection.Leave(); +#endif + + if (mbx == GDSP_MBOX_DSP) + { + DEBUG_LOG(DSPHLE, "- Write DSP Mail: 0x%08x (pc=0x%04x)\n", gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.err_pc); + } +} + + +uint16 gdsp_mbox_read_h(uint8 mbx) +{ + return (gdsp_mbox[mbx][0]); +} + + +uint16 gdsp_mbox_read_l(uint8 mbx) +{ + uint16 val; +#if WITH_DSP_ON_THREAD + g_CriticalSection.Enter(); +#endif + + val = gdsp_mbox[mbx][1]; + gdsp_mbox[mbx][0] &= ~0x8000; + +#if WITH_DSP_ON_THREAD + g_CriticalSection.Leave(); +#endif + return(val); +} + + +void gdsp_ifx_write(uint16 addr, uint16 val) +{ + addr &= 0xff; + + switch (addr & 0xff) + { + case 0xfb: // DIRQ + + if (val & 0x1) + { + g_dsp.irq_request(); + } + + break; + + case 0xfc: // DMBH + gdsp_mbox_write_h(GDSP_MBOX_DSP, val); + break; + + case 0xfd: // DMBL + gdsp_mbox_write_l(GDSP_MBOX_DSP, val); + break; + + case 0xcb: // DSBL + gdsp_ifx_regs[addr] = val; + gdsp_dma(); + gdsp_ifx_regs[DSP_DSCR] &= ~0x0004; + break; + + case 0xcd: + case 0xce: + case 0xcf: + case 0xc9: + gdsp_ifx_regs[addr] = val; + break; + + default: +/* if ((addr & 0xff) >= 0xa0 && reg_names[addr - 0xa0]) + DEBUG_LOG(DSPHLE, "%04x MW %s (%04x)\n", g_dsp.pc, reg_names[addr - 0xa0], val); + else + DEBUG_LOG(DSPHLE, "%04x MW %04x (%04x)\n", g_dsp.pc, addr, val);*/ + gdsp_ifx_regs[addr] = val; + break; + } +} + + +uint16 gdsp_ifx_read(uint16 addr) +{ + uint16 val; + + addr &= 0xff; + + switch (addr & 0xff) + { + case 0xfc: // DMBH + val = gdsp_mbox_read_h(GDSP_MBOX_DSP); + break; + + case 0xfe: // CMBH + val = gdsp_mbox_read_h(GDSP_MBOX_CPU); + break; + + case 0xff: // CMBL + val = gdsp_mbox_read_l(GDSP_MBOX_CPU); + break; + + case 0xc9: + val = gdsp_ifx_regs[addr]; + break; + + case 0xdd: + val = dsp_read_aram(); + break; + + default: + val = gdsp_ifx_regs[addr]; +/* if ((addr & 0xff) >= 0xc0 && reg_names[addr & 0x3f]) + printf("%04x MR %s (%04x)\n", g_dsp.pc, reg_names[addr & 0x3f], val); + else + printf("%04x MR %04x (%04x)\n", g_dsp.pc, addr, val);*/ + break; + } + + return(val); +} + + +void gdsp_idma_in(uint16 dsp_addr, uint32 addr, uint32 size) +{ + uint8* dst = ((uint8*)g_dsp.iram); + + for (uint32 i = 0; i < size; i += 2) + { + *(uint16*)&dst[dsp_addr + i] = *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff]; + } + + g_dsp.iram_crc = GenerateCRC(g_dsp.cpu_ram + (addr & 0x0fffffff), size); + DEBUG_LOG(DSPHLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)\n", addr, dsp_addr, g_dsp.iram_crc); + +#if DUMP_DSP_IMEM + DumpDSPCode(addr, size, g_dsp.iram_crc ); +#endif +} + + +void gdsp_idma_out(uint16 dsp_addr, uint32 addr, uint32 size) +{ + ERROR_LOG(DSPHLE, "*** idma_out IRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size); +} + + +void gdsp_ddma_in(uint16 dsp_addr, uint32 addr, uint32 size) +{ + if ((addr & 0x7FFFFFFF) > 0x01FFFFFF) + { + ERROR_LOG(DSPHLE, "*** ddma_in read from invalid addr (0x%08x)\n", addr); + return; + } + + uint8* dst = ((uint8*)g_dsp.dram); + + for (uint32 i = 0; i < size; i += 2) + { + *(uint16*)&dst[dsp_addr + i] = *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x7FFFFFFF]; + } + + DEBUG_LOG(DSPHLE, "*** ddma_in RAM (0x%08x) -> DRAM_DSP (0x%04x) : size (0x%08x)\n", addr, dsp_addr / 2, size); +} + + +void gdsp_ddma_out(uint16 dsp_addr, uint32 addr, uint32 size) +{ + if ((addr & 0x7FFFFFFF) > 0x01FFFFFF) + { + ERROR_LOG(DSPHLE, "*** gdsp_ddma_out to invalid addr (0x%08x)\n", addr); + return; + } + + uint8* src = ((uint8*)g_dsp.dram); + + for (uint32 i = 0; i < size; i += 2) + { + *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x7FFFFFFF] = *(uint16*)&src[dsp_addr + i]; + } + + DEBUG_LOG(DSPHLE, "*** ddma_out DRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size); +} + + +#define DSP_CR_IMEM (2) +#define DSP_CR_DMEM (0) +#define DSP_CR_TO_CPU (1) +#define DSP_CR_FROM_CPU (0) + +void gdsp_dma() +{ + uint16 ctl; + uint32 addr; + uint16 dsp_addr; + uint16 len; + + addr = (gdsp_ifx_regs[DSP_DSMAH] << 16) | gdsp_ifx_regs[DSP_DSMAL]; + ctl = gdsp_ifx_regs[DSP_DSCR]; + dsp_addr = gdsp_ifx_regs[DSP_DSPA] * 2; + len = gdsp_ifx_regs[DSP_DSBL]; + + if ((ctl > 3) || (len > 0x4000)) + { + ERROR_LOG(DSPHLE, "DMA ERROR pc: %04x ctl: %04x addr: %08x da: %04x size: %04x\n", g_dsp.pc, ctl, addr, dsp_addr, len); + exit(0); + } + + switch (ctl & 0x3) + { + case (DSP_CR_DMEM | DSP_CR_TO_CPU): + gdsp_ddma_out(dsp_addr, addr, len); + break; + + case (DSP_CR_DMEM | DSP_CR_FROM_CPU): + gdsp_ddma_in(dsp_addr, addr, len); + break; + + case (DSP_CR_IMEM | DSP_CR_TO_CPU): + gdsp_idma_out(dsp_addr, addr, len); + break; + + case (DSP_CR_IMEM | DSP_CR_FROM_CPU): + gdsp_idma_in(dsp_addr, addr, len); + break; + } +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.h new file mode 100644 index 0000000000..b051a7c4d8 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.h @@ -0,0 +1,67 @@ +/*==================================================================== + + filename: gdsp_interface.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ +#ifndef _GDSP_INTERFACE_H +#define _GDSP_INTERFACE_H + +#include "Globals.h" + +#define GDSP_MBOX_CPU 0 +#define GDSP_MBOX_DSP 1 + +#define DSP_DSMAH 0xce +#define DSP_DSMAL 0xcf +#define DSP_DSCR 0xc9 +#define DSP_DSPA 0xcd +#define DSP_DSBL 0xcb +#define DSP_ACSAH 0xd4 +#define DSP_ACSAL 0xd5 +#define DSP_ACEAH 0xd6 +#define DSP_ACEAL 0xd7 +#define DSP_ACCAH 0xd8 +#define DSP_ACCAL 0xd9 + +#define DSP_COEF_A1_0 0xa0 +#define DSP_FORMAT 0xd1 +#define DSP_PRED_SCALE 0xda +#define DSP_YN1 0xdb +#define DSP_YN2 0xdc +#define DSP_ARAM 0xdd +#define DSP_GAIN 0xde + +extern uint16 gdsp_ifx_regs[256]; + +uint32 gdsp_mbox_peek(uint8 mbx); +void gdsp_mbox_write_h(uint8 mbx, uint16 val); +void gdsp_mbox_write_l(uint8 mbx, uint16 val); +uint16 gdsp_mbox_read_h(uint8 mbx); +uint16 gdsp_mbox_read_l(uint8 mbx); + +void gdsp_ifx_init(); + +void gdsp_idma_in(uint16 dsp_addr, uint32 addr, uint32 size); + + +#endif + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp new file mode 100644 index 0000000000..3a3c1e001f --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp @@ -0,0 +1,443 @@ +/*==================================================================== + + filename: gdsp_interpreter.cpp + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include +#include + +#include "gdsp_interface.h" +#include "gdsp_opcodes_helper.h" +#include "Tools.h" + +//------------------------------------------------------------------------------- + +SDSP g_dsp; + +uint16 SDSP::r[32]; +uint16 SDSP::pc = 0; +uint16 SDSP::err_pc = 0; +uint16* SDSP::iram = 0; +uint16* SDSP::dram = 0; +uint16* SDSP::irom = 0; +uint16* SDSP::drom = 0; +uint16* SDSP::coef = 0; +uint8* SDSP::cpu_ram = 0; +uint16 SDSP::cr = 0; +uint8 SDSP::reg_stack_ptr[4]; +// lets make stack depth to 32 for now +uint16 SDSP::reg_stack[4][DSP_STACK_DEPTH]; +void (*SDSP::irq_request)() = NULL; +bool SDSP::exception_in_progress_hack = false; + +// for debugger only +uint32 SDSP::iram_crc = 0; +uint64 SDSP::step_counter = 0; + + +//------------------------------------------------------------------------------- + +static bool CR_HALT = true; +static bool CR_EXTERNAL_INT = false; + +void UpdateCachedCR() +{ + CR_HALT = (g_dsp.cr & 0x4) != 0; + CR_EXTERNAL_INT = (g_dsp.cr & 0x02) != 0; +} + + + +//------------------------------------------------------------------------------- +void (*dsp_op[])(uint16 opc) = +{ + dsp_op0, dsp_op1, dsp_op2, dsp_op3, + dsp_op4, dsp_op5, dsp_op6, dsp_op7, + dsp_op8, dsp_op9, dsp_opab, dsp_opab, + dsp_opcd, dsp_opcd, dsp_ope, dsp_opf, +}; + +void dbg_error(char* err_msg) +{ + return; +} + + +void gdsp_init() +{ + g_dsp.irom = (uint16*)malloc(DSP_IROM_SIZE * sizeof(uint16)); + g_dsp.iram = (uint16*)malloc(DSP_IRAM_SIZE * sizeof(uint16)); + g_dsp.drom = (uint16*)malloc(DSP_DROM_SIZE * sizeof(uint16)); + g_dsp.dram = (uint16*)malloc(DSP_DRAM_SIZE * sizeof(uint16)); + g_dsp.coef = (uint16*)malloc(DSP_COEF_SIZE * sizeof(uint16)); + + for (int i = 0; i < DSP_IRAM_SIZE; i++) + { + g_dsp.iram[i] = 0x0021; // HALT opcode + } + + for (int i = 0; i < DSP_DRAM_SIZE; i++) + { + g_dsp.dram[i] = 0x0021; // HALT opcode + } + + for (int i = 0; i < 32; i++) + { + g_dsp.r[i] = 0; + } + + for (int i = 0; i < 4; i++) + { + g_dsp.reg_stack_ptr[i] = 0; + + for (int j = 0; j < DSP_STACK_DEPTH; j++) + { + g_dsp.reg_stack[i][j] = 0; + } + } + + // copied from a real console after the custom UCode has been loaded + g_dsp.r[0x08] = 0xffff; + g_dsp.r[0x09] = 0xffff; + g_dsp.r[0x0a] = 0xffff; + g_dsp.r[0x0b] = 0xffff; + + g_dsp.cr = 0x804; + gdsp_ifx_init(); + + UpdateCachedCR(); +} + + +void gdsp_reset() +{ +// _assert_msg_(0, "gdsp_reset()"); + _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception"); + g_dsp.pc = DSP_RESET_VECTOR; + g_dsp.exception_in_progress_hack = false; +} + + +uint8 gdsp_exceptions = 0; +void gdsp_generate_exception(uint8 level) +{ + gdsp_exceptions |= 1 << level; +} + + +bool gdsp_load_rom(char* fname) +{ + FILE* pFile = fopen(fname, "rb"); + + if (pFile) + { + fread(g_dsp.irom, 1, DSP_IRAM_SIZE, pFile); + fclose(pFile); + return(true); + } + + return(false); +} + + +bool gdsp_load_coef(char* fname) +{ + FILE* pFile = fopen(fname, "rb"); + + if (pFile) + { + fread(g_dsp.coef, 1, DSP_COEF_SIZE, pFile); + fclose(pFile); + return(true); + } + + return(false); +} + + +void gdsp_write_cr(uint16 val) +{ + // reset + if (val & 0x0001) + { + gdsp_reset(); + } + + val &= ~0x0001; + + // update cr + g_dsp.cr = val; + + UpdateCachedCR(); +} + + +uint16 gdsp_read_cr() +{ + if (g_dsp.pc & 0x8000) + { + g_dsp.cr |= 0x800; + } + else + { + g_dsp.cr &= ~0x800; + } + + UpdateCachedCR(); + + return(g_dsp.cr); +} + + +// special loop step.. because exception in loop or loopi fails +// dunno how we have to fix it +// atm we execute this instructions directly inside the loop command +// so it cant be interrupted by an exception +void gdsp_loop_step() +{ + g_dsp.err_pc = g_dsp.pc; + uint16 opc = dsp_fetch_code(); + dsp_op[opc >> 12](opc); +} + +u16 HLE_ROM_80E7_81F8(); +void hacks(); +void gdsp_step() +{ + g_dsp.step_counter++; + + if (g_dsp.pc == 0x80e7) + { + //g_dsp.pc = HLE_ROM_80E7_81F8(); + } + + g_dsp.err_pc = g_dsp.pc; + +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); + if (g_dsp.step_counter == 1) + { + ProfilerInit(); + } + + if ((g_dsp.step_counter & 0xFFFFF) == 0) + { + ProfilerDump(g_dsp.step_counter); + } + +#endif + + uint16 opc = dsp_fetch_code(); + dsp_op[opc >> 12](opc); + + uint16& rLoopCounter = g_dsp.r[DSP_REG_ST0 + 3]; + + if (rLoopCounter > 0) + { + const uint16& rCallAddress = g_dsp.r[DSP_REG_ST0 + 0]; + const uint16& rLoopAddress = g_dsp.r[DSP_REG_ST0 + 2]; + + if (g_dsp.pc == (rLoopAddress + 1)) + { + rLoopCounter--; + + if (rLoopCounter > 0) + { + g_dsp.pc = rCallAddress; + } + else + { + // end of loop + dsp_reg_load_stack(0); + dsp_reg_load_stack(2); + dsp_reg_load_stack(3); + } + } + } + + // check if there is an external interrupt + if (CR_EXTERNAL_INT) + { + if (dsp_SR_is_flag_set(FLAG_ENABLE_INTERUPT) && (g_dsp.exception_in_progress_hack == false)) + { + // level 7 is the interrupt exception + gdsp_generate_exception(7); + g_dsp.cr &= ~0x0002; + UpdateCachedCR(); + } + } + + // check exceptions + if ((gdsp_exceptions > 0) && (!g_dsp.exception_in_progress_hack)) + { + for (uint8 i=0; i<8; i++) + { + if (gdsp_exceptions & (1< 1024*1024*1) + + /* if (g_dsp.pc == 0x165) + { + PanicAlert("Opcode_06"); + + } + if (g_dsp.pc == 0x43b) + { + PanicAlert("Opcode_14"); + + } + if (g_dsp.pc == 0xb37) + { + PanicAlert("Opcode_08"); + + }*/ + /* if (g_dsp.pc == 0x1bc) + { + r30 = g_dsp.r[30]; + r31 = g_dsp.r[31]; + } + else if (g_dsp.pc == 0x384) + { + // if ((r30 == 0x1bc) && (r31 == 0xaff)) + { + //PanicAlert("%x, %x", r30, r31); + + const int numSamples = 0x280; + static short Buffer[numSamples]; + + uint16 bufferAddr = 0x280; //dsp_dmem_read(0xe44); + for (int i=0; i 1024*1024*2) + { + //PanicAlert("%x", bufferAddr); + g_wave_writer.Stop(); + exit(1); + } + } + } */ + + if (g_dsp.pc == 0x468) + { + int numSamples = g_dsp.r[25] / 2; + uint16 bufferAddr = g_dsp.r[27]; + + // PanicAlert("%x %x", bufferAddr, numSamples); + + short samples[1024]; + for (int i=0; i 1024*1024*2) + { + //PanicAlert("%x", bufferAddr); + g_wave_writer.Stop(); + exit(1); + } + } +} diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h new file mode 100644 index 0000000000..65123e6927 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h @@ -0,0 +1,94 @@ +/*==================================================================== + + filename: gdsp_interpreter.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#ifndef _GDSP_INTERPRETER_H +#define _GDSP_INTERPRETER_H + +#include "Globals.h" + +#define DSP_IRAM_SIZE (0x1000) +#define DSP_IRAM_MASK (0x0fff) +#define DSP_IROM_SIZE (0x1000) +#define DSP_IROM_MASK (0x0fff) +#define DSP_DRAM_SIZE (0x1000) +#define DSP_DRAM_MASK (0x0fff) +#define DSP_DROM_SIZE (0x1000) +#define DSP_DROM_MASK (0x0fff) +#define DSP_COEF_SIZE (0x1000) +#define DSP_COEF_MASK (0x0fff) + +#define DSP_RESET_VECTOR (0x8000) + +#define DSP_STACK_DEPTH 0x20 +#define DSP_STACK_MASK 0x1f + +struct SDSP +{ + static uint16 r[32]; + static uint16 pc; + static uint16 err_pc; + static uint16* iram; + static uint16* dram; + static uint16* irom; + static uint16* drom; + static uint16* coef; + static uint8* cpu_ram; + static uint16 cr; + static uint8 reg_stack_ptr[4]; + // lets make stack depth to 32 for now + static uint16 reg_stack[4][DSP_STACK_DEPTH]; + static void (* irq_request)(void); + + // for debugger only + static uint32 iram_crc; + static uint64 step_counter; + static bool exception_in_progress_hack; +}; + +extern SDSP g_dsp; + + +void gdsp_init(void); +void gdsp_reset(void); +bool gdsp_load_rom(char* fname); +bool gdsp_load_coef(char* fname); + + +// steps through DSP code, returns false if error occured +void gdsp_step(void); +void gdsp_loop_step(); +bool gdsp_run(void); +bool gdsp_runx(uint16 cnt); +void gdsp_stop(void); + +void gdsp_write_cr(uint16 val); +uint16 gdsp_read_cr(void); + +uint16* gdsp_get_iram(void); +uint16* gdsp_get_irom(void); +uint16* gdsp_get_dram(void); +uint16* gdsp_get_drom(void); + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp new file mode 100644 index 0000000000..c2a051431f --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp @@ -0,0 +1,156 @@ +/*==================================================================== + + filename: gdsp_memory.cpp + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include +#include "Globals.h" +#include "gdsp_interpreter.h" +#include "gdsp_memory.h" +#include "gdsp_ifx.h" + +uint16 dsp_swap16(uint16 x) +{ + return((x >> 8) | (x << 8)); +} + + +uint16* gdsp_get_iram(void) +{ + return(g_dsp.iram); +} + + +uint16* gdsp_get_irom(void) +{ + return(g_dsp.irom); +} + + +uint16* gdsp_get_dram(void) +{ + return(g_dsp.dram); +} + + +uint16* gdsp_get_drom(void) +{ + return(g_dsp.drom); +} + + +uint16 dsp_imem_read(uint16 addr) +{ + uint16 opc; + + if (g_dsp.pc & 0x8000) + { + opc = g_dsp.irom[addr & DSP_IROM_MASK]; + } + else + { + opc = g_dsp.iram[addr & DSP_IRAM_MASK]; + } + + return(dsp_swap16(opc)); +} + + +uint16 dsp_dmem_read(uint16 addr) +{ + uint16 val; + + switch (addr >> 12) + { + case 0x0: // 0xxx DRAM + val = g_dsp.dram[addr & DSP_DRAM_MASK]; + val = dsp_swap16(val); + break; + + case 0x8: // 8xxx DROM + DEBUG_LOG(DSPHLE, "someone reads from ROM\n"); + val = g_dsp.drom[addr & DSP_DROM_MASK]; + val = dsp_swap16(val); + break; + + case 0x1: // 1xxx COEF + val = g_dsp.coef[addr & DSP_DROM_MASK]; + val = dsp_swap16(val); + break; + + case 0xf: // Fxxx HW regs + val = gdsp_ifx_read(addr); + break; + + default: // error +// ERROR_LOG(DSPHLE, "%04x DSP ERROR: Read from UNKNOWN (%04x) memory\n", g_dsp.pc, addr); + val = 0; + break; + } + + return(val); +} + + +bool dsp_dmem_write(uint16 addr, uint16 val) +{ + switch (addr >> 12) + { + case 0x8: // 8xxx DROM + DEBUG_LOG(DSPHLE, "someone writes to ROM\n"); + /* val = dsp_swap16(val); + g_dsp.drom[addr & DSP_DROM_MASK] = val;*/ + break; + + case 0xf: // Fxxx HW regs + gdsp_ifx_write(addr, val); + break; + + case 0x0: // 0xxx DRAM + val = dsp_swap16(val); + g_dsp.dram[addr & DSP_DRAM_MASK] = val; + break; + + default: // error + DEBUG_LOG(DSPHLE, "%04x DSP ERROR: Write to UNKNOWN (%04x) memory\n", g_dsp.pc, addr); + break; + } + + return(true); +} + + +uint16 dsp_fetch_code(void) +{ + uint16 opc = dsp_imem_read(g_dsp.pc); + g_dsp.pc++; + return(opc); +} + + +uint16 dsp_peek_code(void) +{ + return(dsp_imem_read(g_dsp.pc)); +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.h new file mode 100644 index 0000000000..df42a1a951 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.h @@ -0,0 +1,37 @@ +/*==================================================================== + + filename: gdsp_memory.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ +#ifndef _GDSP_MEMORY_H +#define _GDSP_MEMORY_H + +#include "Globals.h" + +uint16 dsp_fetch_code(void); +uint16 dsp_peek_code(void); +uint16 dsp_imem_read(uint16 addr); +bool dsp_dmem_write(uint16 addr, uint16 val); +uint16 dsp_dmem_read(uint16 addr); + + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp new file mode 100644 index 0000000000..a3e22ec058 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.cpp @@ -0,0 +1,2235 @@ +// Change Log + +// fixed dsp_opc_mulx (regarding DSP 0.0.4.pdf) +// fixed dsp_opc_mulxmv (regarding DSP 0.0.4.pdf) +// fixed dsp_opc_mulxmvz (regarding DSP 0.0.4.pdf) +// dsp_opc_shifti: removed strange " >> 9" +// added masking for SR_COMPARE_FLAGS +// added "UNKNOWN_CW" but without a function (yet? :) +// added missing compare type to MISSING_COMPARES_JX ... but i dunno what it does + +// added "MULXMV" to another function table + +/*==================================================================== + + filename: gdsp_opcodes.cpp + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include +#include "Globals.h" +#include "gdsp_opcodes.h" +#include "gdsp_memory.h" +#include "gdsp_interpreter.h" +#include "gdsp_registers.h" +#include "gdsp_opcodes_helper.h" +#include "gdsp_ext_op.h" + +#define SR_CMP_MASK 0x3f +#define DSP_REG_MASK 0x1f + + +void Update_SR_Register(sint64 _Value) +{ + g_dsp.r[R_SR] &= ~SR_CMP_MASK; + + if (_Value < 0) + { + g_dsp.r[R_SR] |= 0x8; + } + + if (_Value == 0) + { + g_dsp.r[R_SR] |= 0x4; + } + + // logic + if ((_Value >> 62) == 0) + { + g_dsp.r[R_SR] |= 0x20; + } +} + + +void Update_SR_Register(sint16 _Value) +{ + g_dsp.r[R_SR] &= ~SR_CMP_MASK; + + if (_Value < 0) + { + g_dsp.r[R_SR] |= 0x8; + } + + if (_Value == 0) + { + g_dsp.r[R_SR] |= 0x4; + } + + // logic + if ((_Value >> 14) == 0) + { + g_dsp.r[R_SR] |= 0x20; + } +} + + +sint8 GetMultiplyModifier() +{ + if (g_dsp.r[R_SR] & (1 << 13)) + { + return(1); + } + + return(2); +} + + +bool CheckCondition(uint8 _Condition) +{ + bool taken = false; + + switch (_Condition & 0xf) + { + case 0x0: + + if ((!(g_dsp.r[R_SR] & 0x02)) && (!(g_dsp.r[R_SR] & 0x08))) + { + taken = true; + } + + break; + + case 0x3: + + if ((g_dsp.r[R_SR] & 0x02) || (g_dsp.r[R_SR] & 0x04) || (g_dsp.r[R_SR] & 0x08)) + { + taken = true; + } + + break; + + // old from duddie + case 0x1: // seems okay + + if ((!(g_dsp.r[R_SR] & 0x02)) && (g_dsp.r[R_SR] & 0x08)) + { + taken = true; + } + + break; + + case 0x2: + + if (!(g_dsp.r[R_SR] & 0x08)) + { + taken = true; + } + + break; + + case 0x4: + + if (!(g_dsp.r[R_SR] & 0x04)) + { + taken = true; + } + + break; + + case 0x5: + + if (g_dsp.r[R_SR] & 0x04) + { + taken = true; + } + + break; + + case 0xc: + + if (!(g_dsp.r[R_SR] & 0x40)) + { + taken = true; + } + + break; + + case 0xd: + + if (g_dsp.r[R_SR] & 0x40) + { + taken = true; + } + + break; + + case 0xf: + taken = true; + break; + + default: + // DEBUG_LOG(DSPHLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf); + break; + } + + return(taken); +} + + +// ======================================================================= + +void dsp_op_unknown(uint16 opc) +{ + _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception"); + ERROR_LOG(DSPHLE, "dsp_op_unknown somewhere"); + g_dsp.pc = g_dsp.err_pc; +} + + +void dsp_opc_call(uint16 opc) +{ + uint16 dest = dsp_fetch_code(); + + if (CheckCondition(opc & 0xf)) + { + dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); + g_dsp.pc = dest; + } +} + + +void dsp_opc_ifcc(uint16 opc) +{ + if (!CheckCondition(opc & 0xf)) + { + dsp_fetch_code(); // skip the next opcode + } +} + + +void dsp_opc_jcc(uint16 opc) +{ + uint16 dest = dsp_fetch_code(); + + if (CheckCondition(opc & 0xf)) + { + g_dsp.pc = dest; + } +} + + +void dsp_opc_jmpa(uint16 opc) +{ + uint8 reg; + uint16 addr; + + if ((opc & 0xf) != 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_jmpa"); + } + + reg = (opc >> 5) & 0x7; + addr = dsp_op_read_reg(reg); + + if (opc & 0x0010) + { + // CALLA + dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); + } + + g_dsp.pc = addr; +} + + +// NEW (added condition check) +void dsp_opc_ret(uint16 opc) +{ + if (CheckCondition(opc & 0xf)) + { + g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); + } +} + + +void dsp_opc_rti(uint16 opc) +{ + if ((opc & 0xf) != 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_rti"); + } + + g_dsp.r[R_SR] = dsp_reg_load_stack(DSP_STACK_D); + g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); + + g_dsp.exception_in_progress_hack = false; +} + + +void dsp_opc_halt(uint16 opc) +{ + g_dsp.cr |= 0x4; + g_dsp.pc = g_dsp.err_pc; +} + + +void dsp_opc_loop(uint16 opc) +{ + uint16 reg = opc & 0x1f; + uint16 cnt = g_dsp.r[reg]; + uint16 loop_pc = g_dsp.pc; + + while (cnt--) + { + gdsp_loop_step(); + g_dsp.pc = loop_pc; + } + + g_dsp.pc = loop_pc + 1; +} + + +void dsp_opc_loopi(uint16 opc) +{ + uint16 cnt = opc & 0xff; + uint16 loop_pc = g_dsp.pc; + + while (cnt--) + { + gdsp_loop_step(); + g_dsp.pc = loop_pc; + } + + g_dsp.pc = loop_pc + 1; +} + + +void dsp_opc_bloop(uint16 opc) +{ + uint16 reg = opc & 0x1f; + uint16 cnt = g_dsp.r[reg]; + uint16 loop_pc = dsp_fetch_code(); + + if (cnt) + { + dsp_reg_store_stack(0, g_dsp.pc); + dsp_reg_store_stack(2, loop_pc); + dsp_reg_store_stack(3, cnt); + } + else + { + g_dsp.pc = loop_pc + 1; + } +} + + +void dsp_opc_bloopi(uint16 opc) +{ + uint16 cnt = opc & 0xff; + uint16 loop_pc = dsp_fetch_code(); + + if (cnt) + { + dsp_reg_store_stack(0, g_dsp.pc); + dsp_reg_store_stack(2, loop_pc); + dsp_reg_store_stack(3, cnt); + } + else + { + g_dsp.pc = loop_pc + 1; + } +} + + +//------------------------------------------------------------- + + +void dsp_opc_mrr(uint16 opc) +{ + uint8 sreg = opc & 0x1f; + uint8 dreg = (opc >> 5) & 0x1f; + + uint16 val = dsp_op_read_reg(sreg); + dsp_op_write_reg(dreg, val); +} + + +void dsp_opc_lrr(uint16 opc) +{ + uint8 sreg = (opc >> 5) & 0x3; + uint8 dreg = opc & 0x1f; + + uint16 val = dsp_dmem_read(g_dsp.r[sreg]); + dsp_op_write_reg(dreg, val); + + // post processing of source reg + switch ((opc >> 7) & 0x3) + { + case 0x0: // LRR + break; + + case 0x1: // LRRD + g_dsp.r[sreg]--; + break; + + case 0x2: // LRRI + g_dsp.r[sreg]++; + break; + + case 0x3: + g_dsp.r[sreg] += g_dsp.r[sreg + 4]; + break; + } +} + + +void dsp_opc_srr(uint16 opc) +{ + uint8 dreg = (opc >> 5) & 0x3; + uint8 sreg = opc & 0x1f; + + uint16 val = dsp_op_read_reg(sreg); + dsp_dmem_write(g_dsp.r[dreg], val); + + // post processing of dest reg + switch ((opc >> 7) & 0x3) + { + case 0x0: // SRR + break; + + case 0x1: // SRRD + g_dsp.r[dreg]--; + break; + + case 0x2: // SRRI + g_dsp.r[dreg]++; + break; + + case 0x3: // SRRX + g_dsp.r[dreg] += g_dsp.r[dreg + 4]; + break; + } +} + + +void dsp_opc_ilrr(uint16 opc) +{ + uint16 reg = opc & 0x3; + uint16 dreg = 0x1e + ((opc >> 8) & 1); + + // always to acc0 ? + g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); + + switch ((opc >> 2) & 0x3) + { + case 0x0: // no change + break; + + case 0x1: // post decrement + g_dsp.r[reg]--; + break; + + case 0x2: // post increment + g_dsp.r[reg]++; + break; + + default: + ERROR_LOG(DSPHLE, "dsp_opc_ilrr"); + } +} + + +void dsp_opc_lri(uint16 opc) +{ + uint8 reg = opc & DSP_REG_MASK; + uint16 imm = dsp_fetch_code(); + dsp_op_write_reg(reg, imm); +} + + +void dsp_opc_lris(uint16 opc) +{ + uint8 reg = ((opc >> 8) & 0x7) + 0x18; + uint16 imm = (sint8)opc; + dsp_op_write_reg(reg, imm); +} + + +void dsp_opc_lr(uint16 opc) +{ + uint8 reg = opc & DSP_REG_MASK; + uint16 addr = dsp_fetch_code(); + uint16 val = dsp_dmem_read(addr); + dsp_op_write_reg(reg, val); +} + + +void dsp_opc_sr(uint16 opc) +{ + uint8 reg = opc & DSP_REG_MASK; + uint16 addr = dsp_fetch_code(); + uint16 val = dsp_op_read_reg(reg); + dsp_dmem_write(addr, val); +} + + +void dsp_opc_si(uint16 opc) +{ + uint16 addr = (sint8)opc; + uint16 imm = dsp_fetch_code(); + dsp_dmem_write(addr, imm); +} + + +void dsp_opc_tstaxh(uint16 opc) +{ + uint8 reg = (opc >> 8) & 0x1; + sint16 val = dsp_get_ax_h(reg); + + Update_SR_Register(val); +} + + +void dsp_opc_clr(uint16 opc) +{ + uint8 reg = (opc >> 11) & 0x1; + + dsp_set_long_acc(reg, 0); + + Update_SR_Register((sint64)0); +} + + +void dsp_opc_clrp(uint16 opc) +{ + g_dsp.r[0x14] = 0x0000; + g_dsp.r[0x15] = 0xfff0; + g_dsp.r[0x16] = 0x00ff; + g_dsp.r[0x17] = 0x0010; +} + + +// NEW +void dsp_opc_mulc(uint16 opc) +{ + // math new prod + uint8 sreg = (opc >> 11) & 0x1; + uint8 treg = (opc >> 12) & 0x1; + + sint64 prod = dsp_get_acc_m(sreg) * dsp_get_ax_h(treg) * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulcmvz(uint16 opc) +{ + ERROR_LOG(DSPHLE, "dsp_opc_mulcmvz ni"); +} + + +// NEW +void dsp_opc_mulcmv(uint16 opc) +{ + ERROR_LOG(DSPHLE, "dsp_opc_mulcmv ni"); +} + + +void dsp_opc_cmpar(uint16 opc) +{ + uint8 rreg = ((opc >> 12) & 0x1) + 0x1a; + uint8 areg = (opc >> 11) & 0x1; + + // we compare + sint64 rr = (sint16)g_dsp.r[rreg]; + rr <<= 16; + + sint64 ar = dsp_get_long_acc(areg); + + Update_SR_Register(ar - rr); +} + + +void dsp_opc_cmp(uint16 opc) +{ + sint64 acc0 = dsp_get_long_acc(0); + sint64 acc1 = dsp_get_long_acc(1); + + Update_SR_Register(acc0 - acc1); +} + + +void dsp_opc_tsta(uint16 opc) +{ + uint8 reg = (opc >> 11) & 0x1; + sint64 acc = dsp_get_long_acc(reg); + + Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_addaxl(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + sint64 acc = dsp_get_long_acc(dreg); + sint64 acx = dsp_get_ax_l(sreg); + + acc += acx; + + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_addarn(uint16 opc) +{ + uint8 dreg = opc & 0x3; + uint8 sreg = (opc >> 2) & 0x3; + + g_dsp.r[dreg] += (sint16)g_dsp.r[0x04 + sreg]; +} + + +// NEW +void dsp_opc_mulcac(uint16 opc) +{ + sint64 TempProd = dsp_get_long_prod(); + + // update prod + uint8 sreg = (opc >> 12) & 0x1; + sint64 Prod = (sint64)dsp_get_acc_m(sreg) * (sint64)dsp_get_acc_h(sreg) * GetMultiplyModifier(); + dsp_set_long_prod(Prod); + + // update acc + uint8 rreg = (opc >> 8) & 0x1; + dsp_set_long_acc(rreg, TempProd); +} + + +// NEW +void dsp_opc_movr(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = ((opc >> 9) & 0x3) + 0x18; + + sint64 acc = (sint16)g_dsp.r[sreg]; + acc <<= 16; + acc &= ~0xffff; + + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_movax(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + g_dsp.r[0x1c + dreg] = g_dsp.r[0x18 + sreg]; + g_dsp.r[0x1e + dreg] = g_dsp.r[0x1a + sreg]; + + if ((sint16)g_dsp.r[0x1a + sreg] < 0) + { + g_dsp.r[0x10 + dreg] = 0xffff; + } + else + { + g_dsp.r[0x10 + dreg] = 0; + } + + dsp_opc_tsta(dreg << 11); +} + + +// NEW +void dsp_opc_xorr(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + g_dsp.r[0x1e + dreg] ^= g_dsp.r[0x1a + sreg]; + + dsp_opc_tsta(dreg << 11); +} + + +void dsp_opc_andr(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + g_dsp.r[0x1e + dreg] &= g_dsp.r[0x1a + sreg]; + + dsp_opc_tsta(dreg << 11); +} + + +// NEW +void dsp_opc_orr(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 dreg = (opc >> 8) & 0x1; + + g_dsp.r[0x1e + dreg] |= g_dsp.r[0x1a + sreg]; + + dsp_opc_tsta(dreg << 11); +} + + +// NEW +void dsp_opc_andc(uint16 opc) +{ + uint8 D = (opc >> 8) & 0x1; + + uint16 ac1 = dsp_get_acc_m(D); + uint16 ac2 = dsp_get_acc_m(1 - D); + + dsp_set_long_acc(D, ac1 & ac2); + + if ((ac1 & ac2) == 0) + { + g_dsp.r[R_SR] |= 0x20; + } + else + { + g_dsp.r[R_SR] &= ~0x20; + } +} + + +//------------------------------------------------------------- + +void dsp_opc_nx(uint16 opc) +{} + + +// NEW +void dsp_opc_andfc(uint16 opc) +{ + if (opc & 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_andfc"); + } + + uint8 reg = (opc >> 8) & 0x1; + uint16 imm = dsp_fetch_code(); + uint16 val = dsp_get_acc_m(reg); + + if ((val & imm) == imm) + { + g_dsp.r[R_SR] |= 0x40; + } + else + { + g_dsp.r[R_SR] &= ~0x40; + } +} + + +void dsp_opc_andf(uint16 opc) +{ + uint8 reg; + uint16 imm; + uint16 val; + + if (opc & 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_andf"); + } + + reg = 0x1e + ((opc >> 8) & 0x1); + imm = dsp_fetch_code(); + val = g_dsp.r[reg]; + + if ((val & imm) == 0) + { + g_dsp.r[R_SR] |= 0x40; + } + else + { + g_dsp.r[R_SR] &= ~0x40; + } +} + + +void dsp_opc_subf(uint16 opc) +{ + if (opc & 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_subf"); + } + + uint8 reg = 0x1e + ((opc >> 8) & 0x1); + sint64 imm = (sint16)dsp_fetch_code(); + + sint64 val = (sint16)g_dsp.r[reg]; + sint64 res = val - imm; + + Update_SR_Register(res); +} + + +void dsp_opc_xori(uint16 opc) +{ + if (opc & 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_xori"); + } + + uint8 reg = 0x1e + ((opc >> 8) & 0x1); + uint16 imm = dsp_fetch_code(); + g_dsp.r[reg] ^= imm; + + Update_SR_Register((sint16)g_dsp.r[reg]); +} + + +void dsp_opc_andi(uint16 opc) +{ + if (opc & 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_andi"); + } + + uint8 reg = 0x1e + ((opc >> 8) & 0x1); + uint16 imm = dsp_fetch_code(); + g_dsp.r[reg] &= imm; + + Update_SR_Register((sint16)g_dsp.r[reg]); +} + + +// F|RES: i am not sure if this shouldnt be the whole ACC +// +void dsp_opc_ori(uint16 opc) +{ + if (opc & 0xf) + { + ERROR_LOG(DSPHLE, "dsp_opc_ori"); + return; + } + + uint8 reg = 0x1e + ((opc >> 8) & 0x1); + uint16 imm = dsp_fetch_code(); + g_dsp.r[reg] |= imm; + + Update_SR_Register((sint16)g_dsp.r[reg]); +} + + +//------------------------------------------------------------- + +void dsp_opc_add(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + sint64 acc0 = dsp_get_long_acc(0); + sint64 acc1 = dsp_get_long_acc(1); + + sint64 res = acc0 + acc1; + + dsp_set_long_acc(areg, res); + + Update_SR_Register(res); +} + + +//------------------------------------------------------------- + +void dsp_opc_addp(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x1; + sint64 acc = dsp_get_long_acc(dreg); + acc = acc + dsp_get_long_prod(); + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_cmpis(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + sint64 acc = dsp_get_long_acc(areg); + sint64 val = (sint8)opc; + val <<= 16; + + sint64 res = acc - val; + + Update_SR_Register(res); +} + + +// NEW +// verified at the console +void dsp_opc_addpaxz(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x1; + uint8 sreg = (opc >> 9) & 0x1; + + sint64 prod = dsp_get_long_prod() & ~0x0ffff; + sint64 ax_h = dsp_get_long_acx(sreg); + sint64 acc = (prod + ax_h) & ~0x0ffff; + + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_movpz(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x01; + + // overwrite acc and clear low part + sint64 prod = dsp_get_long_prod(); + sint64 acc = prod & ~0xffff; + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_decm(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x01; + + sint64 sub = 0x10000; + sint64 acc = dsp_get_long_acc(dreg); + acc -= sub; + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_dec(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x01; + + sint64 acc = dsp_get_long_acc(dreg) - 1; + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_incm(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x1; + + sint64 sub = 0x10000; + sint64 acc = dsp_get_long_acc(dreg); + acc += sub; + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_inc(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x1; + + sint64 acc = dsp_get_long_acc(dreg); + acc++; + dsp_set_long_acc(dreg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_neg(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + sint64 acc = dsp_get_long_acc(areg); + acc = 0 - acc; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_movnp(uint16 opc) +{ + ERROR_LOG(DSPHLE, "dsp_opc_movnp\n"); +} + + +// NEW +void dsp_opc_addax(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = (opc >> 9) & 0x1; + + sint64 ax = dsp_get_long_acx(sreg); + sint64 acc = dsp_get_long_acc(areg); + acc += ax; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_addr(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = ((opc >> 9) & 0x3) + 0x18; + + sint64 ax = (sint16)g_dsp.r[sreg]; + ax <<= 16; + + sint64 acc = dsp_get_long_acc(areg); + acc += ax; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_subr(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + uint8 sreg = ((opc >> 9) & 0x3) + 0x18; + + sint64 ax = (sint16)g_dsp.r[sreg]; + ax <<= 16; + + sint64 acc = dsp_get_long_acc(areg); + acc -= ax; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + +// NEW +void dsp_opc_subax(uint16 opc) +{ + int regD = (opc >> 8) & 0x1; + int regT = (opc >> 9) & 0x1; + + sint64 Acc = dsp_get_long_acc(regD) - dsp_get_long_acx(regT); + + dsp_set_long_acc(regD, Acc); + Update_SR_Register(Acc); +} + +void dsp_opc_addis(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + sint64 Imm = (sint8)opc; + Imm <<= 16; + sint64 acc = dsp_get_long_acc(areg); + acc += Imm; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_addi(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + sint64 sub = (sint16)dsp_fetch_code(); + sub <<= 16; + sint64 acc = dsp_get_long_acc(areg); + acc += sub; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_lsl16(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + sint64 acc = dsp_get_long_acc(areg); + acc <<= 16; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +// NEW +void dsp_opc_madd(uint16 opc) +{ + uint8 sreg = (opc >> 8) & 0x1; + + sint64 prod = dsp_get_long_prod(); + prod += (sint64)dsp_get_ax_l(sreg) * (sint64)dsp_get_ax_h(sreg) * GetMultiplyModifier(); + dsp_set_long_prod(prod); +} + + +void dsp_opc_lsr16(uint16 opc) +{ + uint8 areg = (opc >> 8) & 0x1; + + sint64 acc = dsp_get_long_acc(areg); + acc >>= 16; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +void dsp_opc_asr16(uint16 opc) +{ + uint8 areg = (opc >> 11) & 0x1; + + sint64 acc = dsp_get_long_acc(areg); + acc >>= 16; + dsp_set_long_acc(areg, acc); + + Update_SR_Register(acc); +} + + +union UOpcodeShifti +{ + uint16 Hex; + struct + { + signed shift : 6; + unsigned negating : 1; + unsigned arithmetic : 1; + unsigned areg : 1; + unsigned op : 7; + }; + struct + { + unsigned ushift : 6; + }; + UOpcodeShifti(uint16 _Hex) + : Hex(_Hex) {} +}; + +void dsp_opc_shifti(uint16 opc) +{ + UOpcodeShifti Opcode(opc); + + // direction: left + bool ShiftLeft = true; + uint16 shift = Opcode.ushift; + + if ((Opcode.negating) && (Opcode.shift < 0)) + { + ShiftLeft = false; + shift = -Opcode.shift; + } + + sint64 acc; + uint64 uacc; + + if (Opcode.arithmetic) + { + // arithmetic shift + uacc = dsp_get_long_acc(Opcode.areg); + + if (!ShiftLeft) + { + uacc >>= shift; + } + else + { + uacc <<= shift; + } + + acc = uacc; + } + else + { + acc = dsp_get_long_acc(Opcode.areg); + + if (!ShiftLeft) + { + acc >>= shift; + } + else + { + acc <<= shift; + } + } + + dsp_set_long_acc(Opcode.areg, acc); + + Update_SR_Register(acc); +} + + +//------------------------------------------------------------- +// hcs give me this code!! +void dsp_opc_dar(uint16 opc) +{ + uint8 reg = opc & 0x3; + + int temp = g_dsp.r[reg] + g_dsp.r[8]; + + if (temp <= 0x7ff){g_dsp.r[reg] = temp;} + else {g_dsp.r[reg]--;} +} + + +// hcs give me this code!! +void dsp_opc_iar(uint16 opc) +{ + uint8 reg = opc & 0x3; + + int temp = g_dsp.r[reg] + g_dsp.r[8]; + + if (temp <= 0x7ff){g_dsp.r[reg] = temp;} + else {g_dsp.r[reg]++;} +} + + +//------------------------------------------------------------- + +void dsp_opc_sbclr(uint16 opc) +{ + uint8 bit = (opc & 0xff) + 6; + g_dsp.r[R_SR] &= ~(1 << bit); +} + + +void dsp_opc_sbset(uint16 opc) +{ + uint8 bit = (opc & 0xff) + 6; + g_dsp.r[R_SR] |= (1 << bit); +} + + +void dsp_opc_srbith(uint16 opc) +{ + switch ((opc >> 8) & 0xf) + { + case 0xe: // SET40 + g_dsp.r[R_SR] &= ~(1 << 14); + break; + + // FIXME: Both of these appear in the beginning of the Wind Waker + //case 0xb: + //case 0xc: + +/* case 0xf: // SET16 // that doesnt happen on a real console + g_dsp.r[R_SR] |= (1 << 14); + break;*/ + + default: + break; + } +} + + +//------------------------------------------------------------- + +void dsp_opc_movp(uint16 opc) +{ + uint8 dreg = (opc >> 8) & 0x1; + + sint64 prod = dsp_get_long_prod(); + sint64 acc = prod; + dsp_set_long_acc(dreg, acc); +} + + +void dsp_opc_mul(uint16 opc) +{ + uint8 sreg = (opc >> 11) & 0x1; + sint64 prod = (sint64)dsp_get_ax_h(sreg) * (sint64)dsp_get_ax_l(sreg) * GetMultiplyModifier(); + + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + +// NEW +void dsp_opc_mulac(uint16 opc) +{ + // add old prod to acc + uint8 rreg = (opc >> 8) & 0x1; + sint64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod(); + dsp_set_long_acc(rreg, acR); + + // math new prod + uint8 sreg = (opc >> 11) & 0x1; + sint64 prod = dsp_get_ax_l(sreg) * dsp_get_ax_h(sreg) * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +void dsp_opc_mulmv(uint16 opc) +{ + uint8 rreg = (opc >> 8) & 0x1; + sint64 prod = dsp_get_long_prod(); + sint64 acc = prod; + dsp_set_long_acc(rreg, acc); + + uint8 areg = ((opc >> 11) & 0x1) + 0x18; + uint8 breg = ((opc >> 11) & 0x1) + 0x1a; + sint64 val1 = (sint16)g_dsp.r[areg]; + sint64 val2 = (sint16)g_dsp.r[breg]; + + prod = val1 * val2 * GetMultiplyModifier(); + + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulmvz(uint16 opc) +{ + uint8 sreg = (opc >> 11) & 0x1; + uint8 rreg = (opc >> 8) & 0x1; + + // overwrite acc and clear low part + sint64 prod = dsp_get_long_prod(); + sint64 acc = prod & ~0xffff; + dsp_set_long_acc(rreg, acc); + + // math prod + prod = (sint64)g_dsp.r[0x18 + sreg] * (sint64)g_dsp.r[0x1a + sreg] * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulx(uint16 opc) +{ + uint8 sreg = ((opc >> 12) & 0x1); + uint8 treg = ((opc >> 11) & 0x1); + + sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + sint64 prod = val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulxac(uint16 opc) +{ + // add old prod to acc + uint8 rreg = (opc >> 8) & 0x1; + sint64 acR = dsp_get_long_acc(rreg) + dsp_get_long_prod(); + dsp_set_long_acc(rreg, acR); + + // math new prod + uint8 sreg = (opc >> 12) & 0x1; + uint8 treg = (opc >> 11) & 0x1; + + sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + sint64 prod = val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulxmv(uint16 opc) +{ + // add old prod to acc + uint8 rreg = ((opc >> 8) & 0x1); + sint64 acR = dsp_get_long_prod(); + dsp_set_long_acc(rreg, acR); + + // math new prod + uint8 sreg = (opc >> 12) & 0x1; + uint8 treg = (opc >> 11) & 0x1; + + sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + sint64 prod = val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_mulxmvz(uint16 opc) +{ + // overwrite acc and clear low part + uint8 rreg = (opc >> 8) & 0x1; + sint64 prod = dsp_get_long_prod(); + sint64 acc = prod & ~0xffff; + dsp_set_long_acc(rreg, acc); + + // math prod + uint8 sreg = (opc >> 12) & 0x1; + uint8 treg = (opc >> 11) & 0x1; + + sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + prod = val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); + + Update_SR_Register(prod); +} + + +// NEW +void dsp_opc_sub(uint16 opc) +{ + uint8 D = (opc >> 8) & 0x1; + sint64 Acc1 = dsp_get_long_acc(D); + sint64 Acc2 = dsp_get_long_acc(1 - D); + + Acc1 -= Acc2; + + dsp_set_long_acc(D, Acc1); +} + + +//------------------------------------------------------------- +// +// --- Table E +// +//------------------------------------------------------------- + +// NEW +void dsp_opc_maddx(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 treg = (opc >> 8) & 0x1; + + sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + sint64 prod = dsp_get_long_prod(); + prod += val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); +} + + +// NEW +void dsp_opc_msubx(uint16 opc) +{ + uint8 sreg = (opc >> 9) & 0x1; + uint8 treg = (opc >> 8) & 0x1; + + sint64 val1 = (sreg == 0) ? dsp_get_ax_l(0) : dsp_get_ax_h(0); + sint64 val2 = (treg == 0) ? dsp_get_ax_l(1) : dsp_get_ax_h(1); + + sint64 prod = dsp_get_long_prod(); + prod -= val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); +} + + +// NEW +void dsp_opc_maddc(uint16 opc) +{ + uint sreg = (opc >> 9) & 0x1; + uint treg = (opc >> 8) & 0x1; + + sint64 val1 = dsp_get_acc_m(sreg); + sint64 val2 = dsp_get_ax_h(treg); + + sint64 prod = dsp_get_long_prod(); + prod += val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); +} + + +// NEW +void dsp_opc_msubc(uint16 opc) +{ + uint sreg = (opc >> 9) & 0x1; + uint treg = (opc >> 8) & 0x1; + + sint64 val1 = dsp_get_acc_m(sreg); + sint64 val2 = dsp_get_ax_h(treg); + + sint64 prod = dsp_get_long_prod(); + prod -= val1 * val2 * GetMultiplyModifier(); + dsp_set_long_prod(prod); +} + + +//------------------------------------------------------------- +void dsp_op0(uint16 opc) +{ + if (opc == 0) + { + return; + } + + switch ((opc >> 8) & 0xf) + { + case 0x0: + + switch ((opc >> 4) & 0xf) + { + case 0x0: + + switch (opc & 0xf) + { + case 0x4: + case 0x5: + case 0x6: + case 0x7: + dsp_opc_dar(opc); + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + dsp_opc_iar(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op0"); + break; + } + + break; + + case 0x1: + dsp_opc_addarn(opc); + break; + + case 0x2: // HALT + dsp_opc_halt(opc); + break; + + case 0x4: // LOOP + case 0x5: // LOOP + dsp_opc_loop(opc); + break; + + case 0x6: // BLOOP + case 0x7: // BLOOP + dsp_opc_bloop(opc); + break; + + case 0x8: // LRI + case 0x9: // LRI + dsp_opc_lri(opc); + break; + + case 0xC: // LR + case 0xD: // LR + dsp_opc_lr(opc); + break; + + case 0xE: // SR + case 0xF: // SR + dsp_opc_sr(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op0"); + break; + } + + break; + + case 0x2: + + switch ((opc >> 4) & 0xf) + { + case 0x0: // ADDI + dsp_opc_addi(opc); + break; + + case 0x1: // IL + dsp_opc_ilrr(opc); + break; + + case 0x2: // XORI + dsp_opc_xori(opc); + break; + + case 0x4: // ANDI + dsp_opc_andi(opc); + break; + + case 0x6: // ORI + dsp_opc_ori(opc); + break; + + case 0x7: // + dsp_opc_ifcc(opc); + break; + + case 0x8: // SUBF + dsp_opc_subf(opc); + break; + + case 0x9: // Jxx + dsp_opc_jcc(opc); + break; + + case 0xa: // ANDF + dsp_opc_andf(opc); + break; + + case 0xb: // CALL + dsp_opc_call(opc); + break; + + case 0xc: + dsp_opc_andfc(opc); + break; + + case 0xd: // RET + dsp_opc_ret(opc); + break; + + case 0xf: // RTI + dsp_opc_rti(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op0"); + break; + } + + break; + + case 0x3: + + switch ((opc >> 4) & 0xf) + { + case 0x0: // ADDAI + dsp_opc_addi(opc); + break; + + case 0x1: // ILR + dsp_opc_ilrr(opc); + break; + + case 0x2: // XORI + dsp_opc_xori(opc); + break; + + case 0x4: // ANDI + dsp_opc_andi(opc); + break; + + case 0x6: // ORI + dsp_opc_ori(opc); + break; + + case 0x8: // SUBF + dsp_opc_subf(opc); + break; + + case 0xa: // ANDF + dsp_opc_andf(opc); + break; + + case 0xc: // ANDFC + dsp_opc_andfc(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op0"); + break; + } + + break; + + case 0x4: + case 0x5: + dsp_opc_addis(opc); + break; + + case 0x6: // SUBISF + case 0x7: + dsp_opc_cmpis(opc); + break; + + case 0x8: // LRIS + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + dsp_opc_lris(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op0"); + break; + } +} + + +void dsp_op1(uint16 opc) +{ + switch ((opc >> 8) & 0xf) + { + case 0x0: + dsp_opc_loopi(opc); + break; + + case 0x1: // BLOOPI + dsp_opc_bloopi(opc); + break; + + case 0x2: // SBCLR + dsp_opc_sbclr(opc); + break; + + case 0x3: // SBSET + dsp_opc_sbset(opc); + break; + + case 0x4: // shifti + case 0x5: + dsp_opc_shifti(opc); + break; + + case 0x6: // SI + dsp_opc_si(opc); + break; + + case 0x7: // JMPA/CALLA + dsp_opc_jmpa(opc); + break; + + case 0x8: // LRRx + case 0x9: // LRRx + dsp_opc_lrr(opc); + break; + + case 0xa: // SRRx + case 0xb: // SRRx + dsp_opc_srr(opc); + break; + + case 0xc: // MRR + case 0xd: // MRR + case 0xe: // MRR + case 0xf: // MRR + dsp_opc_mrr(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op1"); + break; + } +} + + +void dsp_op2(uint16 opc) +{ + // lrs, srs + uint8 reg = ((opc >> 8) & 0x7) + 0x18; + uint16 addr = (sint8) opc; + + if (opc & 0x0800) + { + // srs + dsp_dmem_write(addr, g_dsp.r[reg]); + } + else + { + // lrs + g_dsp.r[reg] = dsp_dmem_read(addr); + } +} + + +void dsp_op3(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + dsp_opc_xorr(opc); + break; + + case 0x4: + case 0x5: + case 0x6: + case 0x7: + dsp_opc_andr(opc); + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + dsp_opc_orr(opc); + break; + + case 0xc: + case 0xd: + dsp_opc_andc(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op3"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op4(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + dsp_opc_addr(opc); + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + dsp_opc_addax(opc); + break; + + case 0xc: + case 0xd: + dsp_opc_add(opc); + break; + + case 0xe: + case 0xf: + dsp_opc_addp(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op4"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op5(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + dsp_opc_subr(opc); + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + dsp_opc_subax(opc); + break; + + case 0xc: + case 0xd: + dsp_opc_sub(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op5: %x", (opc >> 8) & 0xf); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op6(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x00: // MOVR + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + dsp_opc_movr(opc); + break; + + case 0x8: // MVAXA + case 0x9: + case 0xa: + case 0xb: + dsp_opc_movax(opc); + break; + + case 0xe: + case 0xf: + dsp_opc_movp(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op6"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op7(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + dsp_opc_addaxl(opc); + break; + + case 0x4: + case 0x5: + dsp_opc_incm(opc); + break; + + case 0x6: + case 0x7: + dsp_opc_inc(opc); + break; + + case 0x8: + case 0x9: + dsp_opc_decm(opc); + break; + + case 0xa: + case 0xb: + dsp_opc_dec(opc); + break; + + case 0xc: + case 0xd: + dsp_opc_neg(opc); + break; + + case 0xe: + case 0xf: + dsp_opc_movnp(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op7"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op8(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x0: + case 0x8: + dsp_opc_nx(opc); + break; + + case 0x1: // CLR 0 + case 0x9: // CLR 1 + dsp_opc_clr(opc); + break; + + case 0x2: // CMP + dsp_opc_cmp(opc); + break; + + case 0x4: // CLRP + dsp_opc_clrp(opc); + break; + + case 0x6: + case 0x7: + dsp_opc_tstaxh(opc); + break; + + case 0xc: + case 0xb: + case 0xe: // SET40 + case 0xd: + case 0xa: + case 0xf: + dsp_opc_srbith(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op8"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_op9(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x02: + case 0x03: + case 0x0a: + case 0x0b: + dsp_opc_mulmvz(opc); + break; + + case 0x04: + case 0x05: + case 0x0c: + case 0x0d: + dsp_opc_mulac(opc); + break; + + case 0x6: + case 0x7: + case 0xe: + case 0xf: + dsp_opc_mulmv(opc); + break; + + case 0x0: + case 0x8: + dsp_opc_mul(opc); + break; + + case 0x1: + case 0x9: + dsp_opc_asr16(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_op9"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_opab(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0x7) + { + case 0x0: + dsp_opc_mulx(opc); + break; + + case 0x1: + dsp_opc_tsta(opc); + break; + + case 0x2: + case 0x3: + dsp_opc_mulxmvz(opc); + break; + + case 0x4: + case 0x5: + dsp_opc_mulxac(opc); + break; + + case 0x6: + case 0x7: + dsp_opc_mulxmv(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_opab"); + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_opcd(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0x7) + { + case 0x0: // MULC + dsp_opc_mulc(opc); + break; + + case 0x1: // CMPAR + dsp_opc_cmpar(opc); + break; + + case 0x2: // MULCMVZ + case 0x3: + dsp_opc_mulcmvz(opc); + break; + + case 0x4: // MULCAC + case 0x5: + dsp_opc_mulcac(opc); + break; + + case 0x6: // MULCMV + case 0x7: + dsp_opc_mulcmv(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_opcd"); + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_ope(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 10) & 0x3) + { + case 0x00: // MADDX + dsp_opc_maddx(opc); + break; + + case 0x01: // MSUBX + dsp_opc_msubx(opc); + break; + + case 0x02: // MADDC + dsp_opc_maddc(opc); + break; + + case 0x03: // MSUBC + dsp_opc_msubc(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_ope"); + } + + dsp_op_ext_ops_epi(opc); +} + + +void dsp_opf(uint16 opc) +{ + dsp_op_ext_ops_pro(opc); + + switch ((opc >> 8) & 0xf) + { + case 0x0: + case 0x1: + dsp_opc_lsl16(opc); + break; + + case 0x02: + case 0x03: + dsp_opc_madd(opc); + break; + + case 0x4: + case 0x5: + dsp_opc_lsr16(opc); + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + dsp_opc_addpaxz(opc); + break; + + case 0xe: + case 0xf: + dsp_opc_movpz(opc); + break; + + default: + ERROR_LOG(DSPHLE, "dsp_opf"); + break; + } + + dsp_op_ext_ops_epi(opc); +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h new file mode 100644 index 0000000000..e44ffa1c8c --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes.h @@ -0,0 +1,50 @@ +/*==================================================================== + + filename: gdsp_opcodes.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ +#ifndef _GDSP_OPCODES_H +#define _GDSP_OPCODES_H + +#include "Globals.h" + +void dsp_op0(uint16 opc); +void dsp_op1(uint16 opc); +void dsp_op2(uint16 opc); +void dsp_op3(uint16 opc); +void dsp_op4(uint16 opc); +void dsp_op5(uint16 opc); +void dsp_op6(uint16 opc); +void dsp_op7(uint16 opc); +void dsp_op8(uint16 opc); +void dsp_op9(uint16 opc); +void dsp_opab(uint16 opc); +void dsp_opcd(uint16 opc); +void dsp_ope(uint16 opc); +void dsp_opf(uint16 opc); + + +#define R_SR 0x13 + +#define FLAG_ENABLE_INTERUPT 11 + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h new file mode 100644 index 0000000000..38ba759a80 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_opcodes_helper.h @@ -0,0 +1,258 @@ +/*==================================================================== + + filename: opcodes.h + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#ifndef _GDSP_OPCODES_HELPER_H +#define _GDSP_OPCODES_HELPER_H + +#include "Globals.h" + +#include "gdsp_opcodes.h" +#include "gdsp_memory.h" +#include "gdsp_interpreter.h" +#include "gdsp_registers.h" +#include "gdsp_ext_op.h" + +// --------------------------------------------------------------------------------------- +// +// --- SR +// +// --------------------------------------------------------------------------------------- + +inline void dsp_SR_set_flag(uint8 flag) +{ + g_dsp.r[R_SR] |= (1 << flag); +} + + +inline bool dsp_SR_is_flag_set(uint8 flag) +{ + return((g_dsp.r[R_SR] & (1 << flag)) > 0); +} + + +// --------------------------------------------------------------------------------------- +// +// --- reg +// +// --------------------------------------------------------------------------------------- + +inline uint16 dsp_op_read_reg(uint8 reg) +{ + uint16 val; + + switch (reg & 0x1f) + { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + val = dsp_reg_load_stack(reg - 0x0c); + break; + + default: + val = g_dsp.r[reg]; + break; + } + + return(val); +} + + +inline void dsp_op_write_reg(uint8 reg, uint16 val) +{ + switch (reg & 0x1f) + { + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dsp_reg_store_stack(reg - 0x0c, val); + break; + + default: + g_dsp.r[reg] = val; + break; + } +} + + +// --------------------------------------------------------------------------------------- +// +// --- prod +// +// --------------------------------------------------------------------------------------- + + +inline sint64 dsp_get_long_prod() +{ +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); +#endif + + 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); +} + + +inline void dsp_set_long_prod(sint64 val) +{ +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); +#endif + + 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; +} + + +// --------------------------------------------------------------------------------------- +// +// --- acc +// +// --------------------------------------------------------------------------------------- + +inline sint64 dsp_get_long_acc(uint8 reg) +{ +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); +#endif + + _assert_(reg < 2); + sint64 val; + sint64 low_acc; + val = (sint8)g_dsp.r[0x10 + reg]; + val <<= 32; + low_acc = g_dsp.r[0x1e + reg]; + low_acc <<= 16; + low_acc |= g_dsp.r[0x1c + reg]; + val |= low_acc; + return(val); +} + + +inline uint64 dsp_get_ulong_acc(uint8 reg) +{ +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); +#endif + + _assert_(reg < 2); + uint64 val; + uint64 low_acc; + val = (uint8)g_dsp.r[0x10 + reg]; + val <<= 32; + low_acc = g_dsp.r[0x1e + reg]; + low_acc <<= 16; + low_acc |= g_dsp.r[0x1c + reg]; + val |= low_acc; + return(val); +} + + +inline void dsp_set_long_acc(uint8 _reg, sint64 val) +{ +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); +#endif + + _assert_(_reg < 2); + g_dsp.r[0x1c + _reg] = (uint16)val; + val >>= 16; + g_dsp.r[0x1e + _reg] = (uint16)val; + val >>= 16; + g_dsp.r[0x10 + _reg] = (uint16)val; +} + + +inline sint16 dsp_get_acc_l(uint8 _reg) +{ + _assert_(_reg < 2); + return(g_dsp.r[0x1c + _reg]); +} + + +inline sint16 dsp_get_acc_m(uint8 _reg) +{ + _assert_(_reg < 2); + return(g_dsp.r[0x1e + _reg]); +} + + +inline sint16 dsp_get_acc_h(uint8 _reg) +{ + _assert_(_reg < 2); + return(g_dsp.r[0x10 + _reg]); +} + + +// --------------------------------------------------------------------------------------- +// +// --- acx +// +// --------------------------------------------------------------------------------------- + + +inline sint64 dsp_get_long_acx(uint8 _reg) +{ +#if PROFILE + ProfilerAddDelta(g_dsp.err_pc, 1); +#endif + + _assert_(_reg < 2); + sint64 val = (sint16)g_dsp.r[0x1a + _reg]; + val <<= 16; + sint64 low_acc = g_dsp.r[0x18 + _reg]; + val |= low_acc; + return(val); +} + + +inline sint16 dsp_get_ax_l(uint8 _reg) +{ + _assert_(_reg < 2); + return(g_dsp.r[0x18 + _reg]); +} + + +inline sint16 dsp_get_ax_h(uint8 _reg) +{ + _assert_(_reg < 2); + return(g_dsp.r[0x1a + _reg]); +} + + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.cpp new file mode 100644 index 0000000000..3d70274479 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.cpp @@ -0,0 +1,62 @@ +/*==================================================================== + + filename: gdsp_registers.cpp + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include "Globals.h" +#include "gdsp_registers.h" +#include "gdsp_interpreter.h" + + + +void dsp_reg_stack_push(uint8 stack_reg) +{ + g_dsp.reg_stack_ptr[stack_reg]++; + g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; + g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg]; +} + + +void dsp_reg_stack_pop(uint8 stack_reg) +{ + g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]; + g_dsp.reg_stack_ptr[stack_reg]--; + g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; +} + + +void dsp_reg_store_stack(uint8 stack_reg, uint16 val) +{ + dsp_reg_stack_push(stack_reg); + g_dsp.r[DSP_REG_ST0 + stack_reg] = val; +} + + +uint16 dsp_reg_load_stack(uint8 stack_reg) +{ + uint16 val = g_dsp.r[DSP_REG_ST0 + stack_reg]; + dsp_reg_stack_pop(stack_reg); + return(val); +} + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h new file mode 100644 index 0000000000..20a2525ab4 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_registers.h @@ -0,0 +1,42 @@ +/*==================================================================== + + filename: gdsp_registers.h + project: GCemu + created: 2004-6-18 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie & Tratax + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ +#ifndef _GDSP_REGISTERS_H +#define _GDSP_REGISTERS_H + +#include "Globals.h" + +#define DSP_REG_ST0 0x0c +#define DSP_REG_ST1 0x0c +#define DSP_REG_ST2 0x0c +#define DSP_REG_ST3 0x0c + +#define DSP_STACK_C 0 +#define DSP_STACK_D 1 + +void dsp_reg_store_stack(uint8 stack_reg, uint16 val); +uint16 dsp_reg_load_stack(uint8 stack_reg); + + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp new file mode 100644 index 0000000000..74129d76f2 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp @@ -0,0 +1,438 @@ +// 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/ + + +// ======================================================================================= +// Includes +// -------------- +#include "Common.h" // Common +#include "WaveFile.h" +#include "CommonTypes.h" +#include "Mixer.h" + +#include "Globals.h" // Local +#include "gdsp_interpreter.h" +#include "gdsp_interface.h" +#include "disassemble.h" + +#ifdef _WIN32 + #include "DisAsmDlg.h" + #include "DSoundStream.h" + #include "Logging/Logging.h" // For Logging + + HINSTANCE g_hInstance = NULL; + HANDLE g_hDSPThread = NULL; + CRITICAL_SECTION g_CriticalSection; + CDisAsmDlg g_Dialog; +#else + #define WINAPI + #define LPVOID void* + #include + #include + #include + #include + #include "AOSoundStream.h" + pthread_t g_hDSPThread = NULL; +#endif + +#include "ChunkFile.h" +// ============== + + +// ======================================================================================= +// Global declarations and definitions +// -------------- +PLUGIN_GLOBALS* globals = NULL; +DSPInitialize g_dspInitialize; + +#define GDSP_MBOX_CPU 0 +#define GDSP_MBOX_DSP 1 + +uint32 g_LastDMAAddress = 0; +uint32 g_LastDMASize = 0; + +extern u32 m_addressPBs; +bool AXTask(u32& _uMail); + +bool bCanWork = false; + +// Set this if you want to log audio. search for log_ai in this file to see the filename. +static bool log_ai = false; +WaveFileWriter g_wave_writer; +// ============== + + +#ifdef _WIN32 +BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle + DWORD dwReason, // reason called + LPVOID lpvReserved) // reserved +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + break; + + case DLL_PROCESS_DETACH: + break; + + default: + break; + } + + g_hInstance = hinstDLL; + return(TRUE); +} +#endif + +void GetDllInfo(PLUGIN_INFO* _PluginInfo) +{ + _PluginInfo->Version = 0x0100; + _PluginInfo->Type = PLUGIN_TYPE_DSP; + +#ifdef DEBUGFAST + sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin (DebugFast)"); +#else +#ifndef _DEBUG + sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin"); +#else + sprintf(_PluginInfo->Name, "Dolphin DSP-LLE-Testing Plugin (Debug)"); +#endif +#endif +} + +void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) +{ + globals = _pPluginGlobals; + LogManager::SetInstance((LogManager *)globals->logManager); +} + +void DllAbout(HWND _hParent) +{} + + +void DllConfig(HWND _hParent) +{} + + +void DoState(unsigned char **ptr, int mode) { + PointerWrap p(ptr, mode); +} + +void DllDebugger(HWND _hParent, bool Show) +{ +#ifdef _WIN32 + #if defined (_DEBUG) || defined (DEBUGFAST) + g_Dialog.Create(NULL); //_hParent); + g_Dialog.ShowWindow(SW_SHOW); + // MoveWindow(g_Dialog.m_hWnd, 450,0, 780,530, true); + + // Open the console window + // Console::Open(155, 100, "Sound Debugging"); // give room for 100 rows + // Console::Print("DllDebugger > Console opened\n"); + // Todo: Make this adjustable from the Debugging window + // MoveWindow(Console::GetHwnd(), 0,400, 1280,500, true); + #else + MessageBox(0, "Can't open debugging window in the Release build of this plugin.", "DSP LLE", 0); + #endif +#endif +} + + +// ======================================================================================= +// Regular thread +// -------------- +#ifdef _WIN32 +DWORD WINAPI dsp_thread(LPVOID lpParameter) +#else +void* dsp_thread(void* lpParameter) +#endif +{ + while (1) + { + if (!gdsp_run()) + { + PanicAlert("ERROR: DSP Halt"); + return 0; + } + } +} +// ============== + + +// ======================================================================================= +// Debug thread +// -------------- +#ifdef _WIN32 +DWORD WINAPI dsp_thread_debug(LPVOID lpParameter) +#else +void* dsp_thread_debug(void* lpParameter) +#endif +{ + + //if (g_hDSPThread) + //{ + // return NULL; // enable this to disable the plugin + //} +#ifdef _WIN32 + + while (1) + { + Logging(); // logging + + if (g_Dialog.CanDoStep()) + { + gdsp_runx(1); + } + else + { + Sleep(100); + } + } +#endif + return NULL; +} +// ============== + + +void DSP_DebugBreak() +{ +#ifdef _WIN32 +#if defined(_DEBUG) || defined(DEBUGFAST) + g_Dialog.DebugBreak(); +#endif +#endif +} + + +void dspi_req_dsp_irq() +{ + g_dspInitialize.pGenerateDSPInterrupt(); +} + +void Initialize(void *init) +{ + bCanWork = true; + g_dspInitialize = *(DSPInitialize*)init; + + gdsp_init(); + g_dsp.step_counter = 0; + g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); + g_dsp.irq_request = dspi_req_dsp_irq; + gdsp_reset(); + + if (!gdsp_load_rom((char *)DSP_ROM_FILE)) + { + bCanWork = false; + PanicAlert("No DSP ROM"); + ERROR_LOG(DSPHLE, "Cannot load DSP ROM\n"); + } + + if (!gdsp_load_coef((char *)DSP_COEF_FILE)) + { + bCanWork = false; + PanicAlert("No DSP COEF"); + ERROR_LOG(DSPHLE, "Cannot load DSP COEF\n"); + } + + if(!bCanWork) + return; // TODO: Don't let it work + +// --------------------------------------------------------------------------------------- +// First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in Globals.h. Then +// make the disassembled file here. +// -------------- +// Dump UCode to file... + + FILE* t = fopen("C:\\_\\DSP_UC_09CD143F.txt", "wb"); + if (t != NULL) + { + gd_globals_t gdg; + gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t); + fclose(t); + } +// -------------- + +#ifdef _WIN32 +#if defined(_DEBUG) || defined(DEBUGFAST) + g_hDSPThread = CreateThread(NULL, 0, dsp_thread_debug, 0, 0, NULL); +#else + g_hDSPThread = CreateThread(NULL, 0, dsp_thread, 0, 0, NULL); +#endif // DEBUG +#else +#if _DEBUG + pthread_create(&g_hDSPThread, NULL, dsp_thread_debug, (void *)NULL); +#else + pthread_create(&g_hDSPThread, NULL, dsp_thread, (void *)NULL); +#endif // DEBUG +#endif // WIN32 + + if (log_ai) { + g_wave_writer.Start("C:\\_\\ai_log.wav"); + g_wave_writer.SetSkipSilence(false); + } + +#ifdef _WIN32 + InitializeCriticalSection(&g_CriticalSection); + DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer); +#else + AOSound::AOSound_StartSound(48000, Mixer); +#endif +} + +void DSP_StopSoundStream() +{ +#ifdef _WIN32 + if (g_hDSPThread != NULL) + { + TerminateThread(g_hDSPThread, 0); + } +#else + // Isn't pthread_cancel kind of evil? + pthread_cancel(g_hDSPThread); +#endif +} + +void Shutdown(void) +{ + if (log_ai) + g_wave_writer.Stop(); +} + +u16 DSP_WriteControlRegister(u16 _uFlag) +{ + gdsp_write_cr(_uFlag); + return(gdsp_read_cr()); +} + +u16 DSP_ReadControlRegister() +{ + return(gdsp_read_cr()); +} + +u16 DSP_ReadMailboxHigh(bool _CPUMailbox) +{ + if (_CPUMailbox) + { + return(gdsp_mbox_read_h(GDSP_MBOX_CPU)); + } + else + { + return(gdsp_mbox_read_h(GDSP_MBOX_DSP)); + } +} + +u16 DSP_ReadMailboxLow(bool _CPUMailbox) +{ + if (_CPUMailbox) + { + return(gdsp_mbox_read_l(GDSP_MBOX_CPU)); + } + else + { + return(gdsp_mbox_read_l(GDSP_MBOX_DSP)); + } +} + +void DSP_WriteMailboxHigh(bool _CPUMailbox, u16 _uHighMail) +{ + if (_CPUMailbox) + { + if (gdsp_mbox_peek(GDSP_MBOX_CPU) & 0x80000000) + { + ERROR_LOG(DSPHLE, "Mailbox isnt empty ... strange"); + } + +#if PROFILE + if ((_uHighMail) == 0xBABE) + { + ProfilerStart(); + } +#endif + + gdsp_mbox_write_h(GDSP_MBOX_CPU, _uHighMail); + } + else + { + ERROR_LOG(DSPHLE, "CPU cant write to DSP mailbox"); + } +} + +void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail) +{ + if (_CPUMailbox) + { + gdsp_mbox_write_l(GDSP_MBOX_CPU, _uLowMail); + + u32 uAddress = gdsp_mbox_peek(GDSP_MBOX_CPU); + u16 errpc = g_dsp.err_pc; + + DEBUG_LOG(DSPHLE, "Write CPU Mail: 0x%08x (pc=0x%04x)\n", uAddress, errpc); + + // --------------------------------------------------------------------------------------- + // I couldn't find any better way to detect the AX mails so this had to do. Please feel free + // to change it. + // -------------- + if ((errpc == 0x0054 || errpc == 0x0055) && m_addressPBs == 0) + { + DEBUG_LOG(DSPHLE, "AXTask ======== 0x%08x (pc=0x%04x)", uAddress, errpc); + AXTask(uAddress); + } + } + else + { + ERROR_LOG(DSPHLE, "CPU cant write to DSP mailbox"); + } +} + + +void DSP_Update(int cycles) +{ + if (g_hDSPThread) + { + return; + } + #ifdef _WIN32 + if (g_Dialog.CanDoStep()) + { + gdsp_runx(100); // cycles + } + #endif +} + + +void DSP_SendAIBuffer(unsigned int address, int sample_rate) +{ + short samples[16] = {0}; // interleaved stereo + if (address) { + for (int i = 0; i < 16; i++) { + samples[i] = Memory_Read_U16(address + i * 2); + } + if (log_ai) + g_wave_writer.AddStereoSamples(samples, 8); + } + Mixer_PushSamples(samples, 32 / 4, sample_rate); + + static int counter = 0; + counter++; +#ifdef _WIN32 + if ((counter & 255) == 0) + DSound::DSound_UpdateSound(); +#endif +} + + + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.cpp new file mode 100644 index 0000000000..16fc50030d --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.cpp @@ -0,0 +1,237 @@ +/*==================================================================== + + filename: opcodes.cpp + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ + +#include "Globals.h" +#include "opcodes.h" + +opc_t opcodes[] = +{ + {"NOP", 0x0000, 0xffff, 1, 0, {},}, + {"HALT", 0x0021, 0xffff, 1, 0, {},}, + {"RET", 0x02df, 0xffff, 1, 0, {},}, + {"RETEQ", 0x02d5, 0xffff, 1, 0, {},}, + {"RETNZ", 0x02dd, 0xffff, 1, 0, {},}, + {"RTI", 0x02ff, 0xffff, 1, 0, {},}, + {"CALL", 0x02bf, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + + {"CALLNE", 0x02b4, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + + {"IF_0", 0x0270, 0xffff, 1, 0, {},}, + {"IF_1", 0x0271, 0xffff, 1, 0, {},}, + {"IF_2", 0x0272, 0xffff, 1, 0, {},}, + {"IF_3", 0x0273, 0xffff, 1, 0, {},}, + {"IF_E", 0x0274, 0xffff, 1, 0, {},}, + {"IF_Q", 0x0275, 0xffff, 1, 0, {},}, + {"IF_R", 0x027c, 0xffff, 1, 0, {},}, + {"IF_Z", 0x027d, 0xffff, 1, 0, {},}, + {"IF_P", 0x027f, 0xffff, 1, 0, {},}, + + {"JX0", 0x0290, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JX1", 0x0291, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JX2", 0x0292, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JX3", 0x0293, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JNE", 0x0294, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JEQ", 0x0295, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JZR", 0x029c, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JNZ", 0x029d, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + {"JMP", 0x029f, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, + + {"DAR", 0x0004, 0xfffc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, + {"IAR", 0x0008, 0xfffc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, + + {"CALLR", 0x171f, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},}, + {"JMPR", 0x170f, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},}, + + {"SBCLR", 0x1200, 0xfff8, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},}, + {"SBSET", 0x1300, 0xfff8, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},}, + + {"LSL", 0x1400, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},}, + {"LSR", 0x1440, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},}, + {"ASL", 0x1480, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},}, + {"ASR", 0x14c0, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},}, + + + {"LRI", 0x0080, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}},}, + {"LR", 0x00c0, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}},}, + {"SR", 0x00e0, 0xffe0, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}},}, + + {"MRR", 0x1c00, 0xfc00, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}},}, + + {"SI", 0x1600, 0xff00, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}},}, + + {"LRS", 0x2000, 0xf800, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}},}, + {"SRS", 0x2800, 0xf800, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}},}, + + {"LRIS", 0x0800, 0xf800, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}},}, + + {"ADDIS", 0x0400, 0xfe00, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},}, + {"CMPIS", 0x0600, 0xfe00, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},}, + + {"ANDI", 0x0240, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, + {"ANDF", 0x02c0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, + + {"XORI", 0x0220, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, + {"ANDCF", 0x02a0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, + + {"ORI", 0x0260, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, + {"ORF", 0x02e0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, + + {"ADDI", 0x0200, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64 + {"CMPI", 0x0280, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64 + + {"ILRR", 0x0210, 0xfedc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"ILRRI", 0x0218, 0xfedc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},}, + + // load and store value pointed by indexing reg and increment; LRR/SRR variants + {"LRRI", 0x1900, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, + {"LRRD", 0x1880, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, + {"LRRN", 0x1980, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, + {"LRR", 0x1800, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, + {"SRRI", 0x1b00, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, + {"SRRD", 0x1a80, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, + {"SRRN", 0x1b80, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, + {"SRR", 0x1a00, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, + + {"LOOPI", 0x1000, 0xff00, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}},}, + {"BLOOPI", 0x1100, 0xff00, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_VAL, 2, 1, 0, 0xffff}},}, + {"LOOP", 0x0040, 0xffe0, 1, 1, {{P_REG, 1, 0, 0, 0x001f}},}, + {"BLOOP", 0x0060, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_VAL, 2, 1, 0, 0xffff}},}, + + + + // opcodes that can be extended + // extended opcodes, note size of opcode will be set to 0 + + {"NX", 0x8000, 0xffff, 1 | P_EXT, 0, {},}, + + {"S40", 0x8e00, 0xffff, 1 | P_EXT, 0, {},}, + {"S16", 0x8f00, 0xffff, 1 | P_EXT, 0, {},}, + {"M2", 0x8a00, 0xffff, 1 | P_EXT, 0, {},}, + {"M0", 0x8b00, 0xffff, 1 | P_EXT, 0, {},}, + {"CLR15", 0x8c00, 0xffff, 1 | P_EXT, 0, {},}, + {"SET15", 0x8d00, 0xffff, 1 | P_EXT, 0, {},}, + + {"DECM", 0x7800, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"INCM", 0x7400, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"DEC", 0x7a00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"INC", 0x7600, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + + {"NEG", 0x7c00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + + {"TST", 0xb100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},}, + {"TSTAXH", 0x8600, 0xfeff, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}},}, + {"CMP", 0x8200, 0xffff, 1 | P_EXT, 0, {},}, + {"CMPAXH", 0xc100, 0xe7ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}},}, + + {"CLR", 0x8100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},}, + {"CLRP", 0x8400, 0xffff, 1 | P_EXT, 0, {},}, + + {"MOV", 0x6c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},}, + {"MOVAX", 0x6800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, + {"MOVR", 0x6000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},}, + {"MOVP", 0x6e00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"MOVPZ", 0xfe00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + + {"ADDPAXZ", 0xf800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}},}, + {"ADDP", 0x4e00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + + {"LSL16", 0xf000, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"LSR16", 0xf400, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"ASR16", 0x9100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},}, + + {"XORR", 0x3000, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},}, + {"ANDR", 0x3400, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},}, + {"ORR", 0x3800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},}, + {"ANDC", 0x3C00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + {"ORC", 0x3E00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, + + {"MULX", 0xa000, 0xe7ff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}},}, + {"MULXAC", 0xa400, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, + {"MULXMV", 0xa600, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, + {"MULXMVZ", 0xa200, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, + + {"MUL", 0x9000, 0xf7ff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}},}, + {"MULAC", 0x9400, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, + {"MULMV", 0x9600, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, + {"MULMVZ", 0x9200, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, + + {"MULC", 0xc000, 0xe7ff, 1 | P_EXT, 2, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}},}, + {"MULCAC", 0xc400, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},}, + {"MULCMV", 0xc600, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},}, + {"MULCMVZ", 0xc200, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},}, + + {"ADDR", 0x4000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},}, + {"ADDAX", 0x4800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, + {"ADD", 0x4c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},}, + {"ADDAXL", 0x7000, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, + + {"SUBR", 0x5000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},}, + {"SUBAX", 0x5800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, + {"SUB", 0x5c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},}, + + {"MADD", 0xf200, 0xfeff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},}, + {"MSUB", 0xf600, 0xfeff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},}, + {"MADDX", 0xe000, 0xfcff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, + {"MSUBX", 0xe400, 0xfcff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, + {"MADDC", 0xe800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, + {"MSUBC", 0xec00, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, + + // assemble CW + {"CW", 0x0000, 0xffff, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},}, + // unknown opcode for disassemble + {"CW", 0x0000, 0x0000, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},}, +}; +opc_t opcodes_ext[] = +{ + {"L", 0x0040, 0x00c4, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"LN", 0x0044, 0x00c4, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"LS", 0x0080, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, + {"LSN", 0x0084, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, + {"LSM", 0x0088, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, + {"LSNM", 0x008c, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, + {"SL", 0x0082, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, + {"SLN", 0x0086, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, + {"SLM", 0x008a, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, + {"SLNM", 0x008e, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, + {"S", 0x0020, 0x00e4, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},}, + {"SN", 0x0024, 0x00e4, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},}, + {"LDX", 0x00c0, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, + {"LDXN", 0x00c4, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, + {"LDXM", 0x00c8, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, + {"LDXNM", 0x00cc, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, + {"LD", 0x00c0, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"LDN", 0x00c4, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"LDM", 0x00c8, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"LDNM", 0x00cc, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, + {"MV", 0x0010, 0x00f0, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}},}, + {"DR", 0x0004, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, + {"IR", 0x0008, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, + {"NR", 0x000c, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, + {"XXX", 0x0000, 0x0000, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}},}, +}; + +const uint32 opcodes_size = sizeof(opcodes) / sizeof(opc_t); +const uint32 opcodes_ext_size = sizeof(opcodes_ext) / sizeof(opc_t); + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h new file mode 100644 index 0000000000..c26e291c22 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/opcodes.h @@ -0,0 +1,86 @@ +/*==================================================================== + + filename: opcodes.h + project: GameCube DSP Tool (gcdsp) + created: 2005.03.04 + mail: duddie@walla.com + + Copyright (c) 2005 Duddie + + 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; either version 2 + of the License, or (at your option) any later version. + + 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 for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + ====================================================================*/ +#ifndef _OPCODES_H +#define _OPCODES_H + +enum partype_t +{ + P_NONE = 0x0000, + P_VAL = 0x0001, + P_IMM = 0x0002, + P_MEM = 0x0003, + P_STR = 0x0004, + P_REG = 0x8000, + P_REG08 = P_REG | 0x0800, + P_REG10 = P_REG | 0x1000, + P_REG18 = P_REG | 0x1800, + P_REG19 = P_REG | 0x1900, + P_REG1A = P_REG | 0x1a00, + P_REG1C = P_REG | 0x1c00, + P_ACCM = P_REG | 0x1e00, + P_ACCM_D = P_REG | 0x1e80, + P_ACC = P_REG | 0x2000, + P_ACC_D = P_REG | 0x2080, + P_AX = P_REG | 0x2200, + P_AX_D = P_REG | 0x2280, + P_REGS_MASK = 0x03f80, + P_REF = P_REG | 0x4000, + P_PRG = P_REF | P_REG, +}; + +#define P_EXT 0x80 + +typedef struct opcpar_t +{ + partype_t type; + uint8 size; + uint8 loc; + sint8 lshift; + uint16 mask; +} opcpar_t; + +typedef struct opc_t +{ + const char* name; + uint16 opcode; + uint16 opcode_mask; + uint8 size; + uint8 param_count; + opcpar_t params[8]; +} opc_t; + +extern opc_t opcodes[]; +extern const uint32 opcodes_size; +extern opc_t opcodes_ext[]; +extern const uint32 opcodes_ext_size; + +inline uint16 swap16(uint16 x) +{ + return((x >> 8) | (x << 8)); +} + + +#endif + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/stdafx.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/stdafx.cpp new file mode 100644 index 0000000000..9a2f6b5212 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/stdafx.cpp @@ -0,0 +1,19 @@ +// 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" + diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/stdafx.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/stdafx.h new file mode 100644 index 0000000000..d9c6c36428 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/stdafx.h @@ -0,0 +1,36 @@ +// 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 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define _CRT_SECURE_NO_DEPRECATE 1 + +#include +#include + +// WTL +#include +#include + +#include +#include +#include +#include + +#include "PluginSpecs_DSP.h" +