--- /dev/null
+Mupen64Plus-RSP-HLE INSTALL
+---------------------------
+
+This text file was written to explain the installation process of the
+Mupen64Plus-RSP-HLE plugin.
+
+If this module is part of a Mupen64Plus source code bundle, the user should run
+the "m64p_install.sh" script in the root of the unzipped bundle to install all
+of the included modules in the bundle.
+
+If this module is a standalone source code release, you should build the library
+from source code and install it via the makefile, like this:
+
+$ cd projects/unix
+$ make all
+$ sudo make install
+
+If you want to build the Mupen64Plus-RSP-HLE module for installation in a home
+folder for a single user, you may build it like this (replacing <my-folder>
+with your desired local installation path):
+
+$ cd projects/unix
+$ make all
+$ make install LIBDIR=<my-folder>
+
+
--- /dev/null
+Mupen64Plus-rsp-hle LICENSE
+---------------------------
+
+Mupen64Plus-rsp-hle is licensed under the GNU General Public License version 2.
+
+The authors of Mupen64Plus-rsp-hle are:
+ * Richard Goedeken (Richard42)
+ * Bobby Smiles
+ * John Chadwick (NMN)
+ * James Hood (Ebenblues)
+ * Scott Gorman (okaygo)
+ * Scott Knauert (Tillin9)
+ * Jesse Dean (DarkJezter)
+ * Louai Al-Khanji (slougi)
+ * Bob Forder (orbitaldecay)
+ * Jason Espinosa (hasone)
+ * HyperHacker
+ * and others.
+
+Mupen64Plus is based on GPL-licensed source code from Mupen64 v0.5, originally written by:
+ * Hacktarux
+ * Dave2001
+ * Zilmar
+ * Gregor Anich (Blight)
+ * Juha Luotio (JttL)
+ * and others.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
--- /dev/null
+RSP High-Level Emulation plugin for Mupen64Plus
+-----------------------------------------------
+
+Mupen64Plus-rsp-hle v2.0 - July 4, 2013
+-------------------------------------------------
+ - Add support for MusyX ucode detection
+ - support JPEG decoding used in Pokemon Stadium Japan
+ - lots of refactoring to clean up code
+ - Project files for Visual Studio 2012
+ - Makefile changes
+ - add support for PowerPC and MinGW32 builds
+ - add cross-compiling support to build Win32 executables (MXE) under Linux
+
+Mupen64Plus-rsp-hle v1.99.5 - March 10, 2012
+-------------------------------------------------
+ - Handle JPEG decompression, used in Ogre Battle 64 and Pokemon Stadium
+ - updated RSP plugin for new Mupen64plus 2.0 API versioning scheme
+ - bugfix: #102 - Missing backgrounds in Ogre Battle 64
+ - many makefile fixes and improvements
+
+Mupen64Plus-rsp-hle v1.99.4 - November 22, 2010
+-------------------------------------------------
+ - merged all big-endian fixes from mupen64gc project
+ - makefile fixes and improvements
+
+Mupen64Plus-rsp-hle v1.99.3 - February 13, 2010
+-------------------------------------------------
+ - Makefile improvement: added OS type GNU/kFreeBSD
+
+Mupen64Plus-rsp-hle v1.99.2 - January 6, 2010
+-------------------------------------------------
+ - new feature: added MSVC8 project file for RSP-HLE plugin, fixed a few minor incompatibilities
+ - Makefile improvements:
+ - throw error if OS/CPU not supported
+ - use DESTDIR in install/uninstall paths
+ - Allow user-specified CC/CXX/LD paths
+ - use C++ compiler to link instead of LD, because the compiler knows where the standard C++ libs are
+
+Mupen64Plus-rsp-hle v1.99.1 - December 14, 2009
+-------------------------------------------------
+ - Converted to new Mupen64Plus 2.0 API
+ - Refactored build system to separate source and object files
+ - Refactored all code to remove win32-specific things, unnecessary functions, and clean up
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}</ProjectGuid>
+ <RootNamespace>mupen64plusrsphle</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\alist.c" />
+ <ClCompile Include="..\..\src\cicx105.c" />
+ <ClCompile Include="..\..\src\jpeg.c" />
+ <ClCompile Include="..\..\src\main.c" />
+ <ClCompile Include="..\..\src\ucode1.cpp" />
+ <ClCompile Include="..\..\src\ucode2.cpp" />
+ <ClCompile Include="..\..\src\ucode3.cpp" />
+ <ClCompile Include="..\..\src\ucode3mp3.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\alist.h" />
+ <ClInclude Include="..\..\src\alist_internal.h" />
+ <ClInclude Include="..\..\src\cicx105.h" />
+ <ClInclude Include="..\..\src\hle.h" />
+ <ClInclude Include="..\..\src\jpeg.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="mupen64plus-rsp-hle"
+ ProjectGUID="{2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}"
+ RootNamespace="mupen64plusrsphle"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\..\mupen64plus-core\src\api"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\src\alist.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\cicx105.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\jpeg.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\main.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\ucode1.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\ucode2.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\ucode3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\ucode3mp3.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\src\alist.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\alist_internal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\cicx105.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\hle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\jpeg.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+# * mupen64plus-rsp-hle - Makefile *
+# * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+# * Copyright (C) 2008-2009 Richard Goedeken *
+# * Copyright (C) 2007-2008 DarkJeztr Tillin9 *
+# * *
+# * 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., *
+# * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+# Makefile for Mupen64 HLE RSP plugin in Mupen64plus.
+
+# detect operating system
+UNAME ?= $(shell uname -s)
+OS := NONE
+ifeq ("$(UNAME)","Linux")
+ OS = LINUX
+ SO_EXTENSION = so
+ SHARED = -shared
+endif
+ifeq ("$(UNAME)","linux")
+ OS = LINUX
+ SO_EXTENSION = so
+ SHARED = -shared
+endif
+ifneq ("$(filter GNU hurd,$(UNAME))","")
+ OS = LINUX
+ SO_EXTENSION = so
+ SHARED = -shared
+endif
+ifeq ("$(UNAME)","Darwin")
+ OS = OSX
+ SO_EXTENSION = dylib
+ SHARED = -bundle
+endif
+ifeq ("$(UNAME)","FreeBSD")
+ OS = FREEBSD
+ SO_EXTENSION = so
+ SHARED = -shared
+endif
+ifeq ("$(UNAME)","OpenBSD")
+ OS = FREEBSD
+ SO_EXTENSION = so
+ SHARED = -shared
+ $(warning OS type "$(UNAME)" not officially supported.')
+endif
+ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","")
+ OS = LINUX
+ SO_EXTENSION = so
+ SHARED = -shared
+endif
+ifeq ("$(patsubst MINGW%,MINGW,$(UNAME))","MINGW")
+ OS = MINGW
+ SO_EXTENSION = dll
+ SHARED = -shared
+ PIC = 0
+endif
+ifeq ("$(OS)","NONE")
+ $(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
+endif
+
+# detect system architecture
+HOST_CPU ?= $(shell uname -m)
+NO_ASM ?= 1
+CPU := NONE
+ifneq ("$(filter x86_64 amd64,$(HOST_CPU))","")
+ CPU := X86
+ ifeq ("$(BITS)", "32")
+ ARCH_DETECTED := 64BITS_32
+ PIC ?= 0
+ else
+ ARCH_DETECTED := 64BITS
+ PIC ?= 1
+ endif
+endif
+ifneq ("$(filter pentium i%86,$(HOST_CPU))","")
+ CPU := X86
+ ARCH_DETECTED := 32BITS
+ PIC ?= 0
+endif
+ifneq ("$(filter ppc macppc socppc powerpc,$(HOST_CPU))","")
+ CPU := PPC
+ ARCH_DETECTED := 32BITS
+ BIG_ENDIAN := 1
+ PIC ?= 1
+ $(warning Architecture "$(HOST_CPU)" not officially supported.')
+endif
+ifneq ("$(filter ppc64 powerpc64,$(HOST_CPU))","")
+ CPU := PPC
+ ARCH_DETECTED := 64BITS
+ BIG_ENDIAN := 1
+ PIC ?= 1
+ $(warning Architecture "$(HOST_CPU)" not officially supported.')
+endif
+ifneq ("$(filter arm%,$(HOST_CPU))","")
+ ifeq ("$(filter arm%b,$(HOST_CPU))","")
+ CPU := ARM
+ ARCH_DETECTED := 32BITS
+ PIC ?= 1
+ CFLAGS += -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mtune=cortex-a8 -fsigned-char
+ $(warning Architecture "$(HOST_CPU)" not officially supported.')
+ endif
+endif
+ifeq ("$(CPU)","NONE")
+ $(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues')
+endif
+
+# base CFLAGS, LDLIBS, and LDFLAGS
+OPTFLAGS ?= -O3
+WARNFLAGS ?= -Wall
+CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src
+CXXFLAGS += -fvisibility-inlines-hidden
+LDFLAGS += $(SHARED)
+
+# Since we are building a shared library, we must compile with -fPIC on some architectures
+# On 32-bit x86 systems we do not want to use -fPIC because we don't have to and it has a big performance penalty on this arch
+ifeq ($(PIC), 1)
+ CFLAGS += -fPIC
+else
+ CFLAGS += -fno-PIC
+endif
+
+ifeq ($(BIG_ENDIAN), 1)
+ CFLAGS += -DM64P_BIG_ENDIAN
+endif
+
+# tweak flags for 32-bit build on 64-bit system
+ifeq ($(ARCH_DETECTED), 64BITS_32)
+ ifeq ($(OS), FREEBSD)
+ $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
+ endif
+ CFLAGS += -m32
+ LDFLAGS += -Wl,-m,elf_i386
+endif
+
+# set special flags per-system
+ifeq ($(OS), LINUX)
+ # only export api symbols
+ LDFLAGS += -Wl,-version-script,$(SRCDIR)/rsp_api_export.ver
+endif
+ifeq ($(OS), OSX)
+ # Select the proper SDK
+ # Also, SDKs are stored in a different location since XCode 4.3
+ OSX_SDK ?= $(shell sw_vers -productVersion | cut -f1 -f2 -d .)
+ OSX_XCODEMAJ = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f1 -d .)
+ OSX_XCODEMIN = $(shell xcodebuild -version | grep '[0-9]*\.[0-9]*' | cut -f2 -d ' ' | cut -f2 -d .)
+ OSX_XCODEGE43 = $(shell echo "`expr $(OSX_XCODEMAJ) \>= 4``expr $(OSX_XCODEMIN) \>= 3`")
+ ifeq ($(OSX_XCODEGE43), 11)
+ OSX_SYSROOT := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
+ else
+ OSX_SYSROOT := /Developer/SDKs
+ endif
+
+ ifeq ($(CPU), X86)
+ ifeq ($(ARCH_DETECTED), 64BITS)
+ CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
+ else
+ CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=$(OSX_SDK) -isysroot $(OSX_SYSROOT)/MacOSX$(OSX_SDK).sdk
+ LDFLAGS += -read_only_relocs suppress
+ endif
+ endif
+endif
+
+# set mupen64plus core API header path
+ifneq ("$(APIDIR)","")
+ CFLAGS += "-I$(APIDIR)"
+else
+ TRYDIR = ../../../mupen64plus-core/src/api
+ ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+ CFLAGS += -I$(TRYDIR)
+ else
+ TRYDIR = /usr/local/include/mupen64plus
+ ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+ CFLAGS += -I$(TRYDIR)
+ else
+ TRYDIR = /usr/include/mupen64plus
+ ifneq ("$(wildcard $(TRYDIR)/m64p_types.h)","")
+ CFLAGS += -I$(TRYDIR)
+ else
+ $(error Mupen64Plus API header files not found! Use makefile parameter APIDIR to force a location.)
+ endif
+ endif
+ endif
+endif
+
+# reduced compile output when running make without V=1
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+ifndef V
+ Q_CC = @echo ' CC '$@;
+ Q_CXX = @echo ' CXX '$@;
+ Q_LD = @echo ' LD '$@;
+endif
+endif
+
+# set base program pointers and flags
+CC = $(CROSS_COMPILE)gcc
+CXX = $(CROSS_COMPILE)g++
+RM ?= rm -f
+INSTALL ?= install
+MKDIR ?= mkdir -p
+COMPILE.c = $(Q_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+COMPILE.cc = $(Q_CXX)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
+LINK.o = $(Q_LD)$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TARGET_ARCH)
+
+# set special flags for given Makefile parameters
+ifeq ($(DEBUG),1)
+ CFLAGS += -g
+ INSTALL_STRIP_FLAG ?=
+else
+ ifneq ($(OS),OSX)
+ INSTALL_STRIP_FLAG ?= -s
+ endif
+endif
+
+# set installation options
+ifeq ($(PREFIX),)
+ PREFIX := /usr/local
+endif
+ifeq ($(LIBDIR),)
+ LIBDIR := $(PREFIX)/lib
+endif
+ifeq ($(PLUGINDIR),)
+ PLUGINDIR := $(LIBDIR)/mupen64plus
+endif
+
+SRCDIR = ../../src
+OBJDIR = _obj$(POSTFIX)
+
+# list of source files to compile
+SOURCE = \
+ $(SRCDIR)/main.c \
+ $(SRCDIR)/alist.c \
+ $(SRCDIR)/cicx105.c \
+ $(SRCDIR)/jpeg.c \
+ $(SRCDIR)/ucode3.cpp \
+ $(SRCDIR)/ucode2.cpp \
+ $(SRCDIR)/ucode1.cpp \
+ $(SRCDIR)/ucode3mp3.cpp
+
+# generate a list of object files build, make a temporary directory for them
+OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(filter %.c, $(SOURCE)))
+OBJECTS += $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(filter %.cpp, $(SOURCE)))
+OBJDIRS = $(dir $(OBJECTS))
+$(shell $(MKDIR) $(OBJDIRS))
+
+# build targets
+TARGET = mupen64plus-rsp-hle$(POSTFIX).$(SO_EXTENSION)
+
+targets:
+ @echo "Mupen64Plus-rsp-hle makefile. "
+ @echo " Targets:"
+ @echo " all == Build Mupen64Plus rsp-hle plugin"
+ @echo " clean == remove object files"
+ @echo " rebuild == clean and re-build all"
+ @echo " install == Install Mupen64Plus rsp-hle plugin"
+ @echo " uninstall == Uninstall Mupen64Plus rsp-hle plugin"
+ @echo " Options:"
+ @echo " BITS=32 == build 32-bit binaries on 64-bit machine"
+ @echo " APIDIR=path == path to find Mupen64Plus Core headers"
+ @echo " OPTFLAGS=flag == compiler optimization (default: -O3 -flto)"
+ @echo " WARNFLAGS=flag == compiler warning levels (default: -Wall)"
+ @echo " PIC=(1|0) == Force enable/disable of position independent code"
+ @echo " POSTFIX=name == String added to the name of the the build (default: '')"
+ @echo " Install Options:"
+ @echo " PREFIX=path == install/uninstall prefix (default: /usr/local)"
+ @echo " LIBDIR=path == library prefix (default: PREFIX/lib)"
+ @echo " PLUGINDIR=path == path to install plugin libraries (default: LIBDIR/mupen64plus)"
+ @echo " DESTDIR=path == path to prepend to all installation paths (only for packagers)"
+ @echo " Debugging Options:"
+ @echo " DEBUG=1 == add debugging symbols"
+ @echo " V=1 == show verbose compiler output"
+
+all: $(TARGET)
+
+install: $(TARGET)
+ $(INSTALL) -d "$(DESTDIR)$(PLUGINDIR)"
+ $(INSTALL) -m 0644 $(INSTALL_STRIP_FLAG) $(TARGET) "$(DESTDIR)$(PLUGINDIR)"
+
+uninstall:
+ $(RM) "$(DESTDIR)$(PLUGINDIR)/$(TARGET)"
+
+clean:
+ $(RM) -r $(OBJDIR) $(TARGET)
+
+rebuild: clean all
+
+# build dependency files
+CFLAGS += -MD
+-include $(OBJECTS:.o=.d)
+
+CXXFLAGS += $(CFLAGS)
+
+# standard build rules
+$(OBJDIR)/%.o: $(SRCDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+
+$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
+ $(COMPILE.cc) -o $@ $<
+
+$(TARGET): $(OBJECTS)
+ $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
+
+.PHONY: all clean install uninstall targets
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - alist.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2012 Bobby Smiles *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "hle.h"
+#include "alist_internal.h"
+
+// FIXME: this decomposition into 3 ABI is not accurate,
+// there are a least 9 or 10 different ABI, each with one or a few revisions
+// for a total of almost 16 differents audio ucode.
+//
+// ABI2 in fact is a mix of at least 7 differents ABI which are mostly compatible
+// but not totally, that's why there is a isZeldaABI/isMKABI workaround.
+//
+extern const acmd_callback_t ABI1[0x10];
+extern const acmd_callback_t ABI2[0x20];
+extern const acmd_callback_t ABI3[0x10];
+
+/* local functions */
+static void alist_process(const acmd_callback_t abi[], unsigned int abi_size)
+{
+ u32 inst1, inst2;
+ unsigned int acmd;
+ const OSTask_t * const task = get_task();
+
+ const unsigned int *alist = (unsigned int*)(rsp.RDRAM + task->data_ptr);
+ const unsigned int * const alist_end = alist + (task->data_size >> 2);
+
+ while (alist != alist_end)
+ {
+ inst1 = *(alist++);
+ inst2 = *(alist++);
+
+ acmd = inst1 >> 24;
+
+ if (acmd < abi_size)
+ {
+ (*abi[acmd])(inst1, inst2);
+ }
+ else
+ {
+ DebugMessage(M64MSG_WARNING, "Invalid ABI command %u", acmd);
+ }
+ }
+}
+
+/* global functions */
+void alist_process_ABI1()
+{
+ alist_process(ABI1, 0x10);
+}
+
+void alist_process_ABI2()
+{
+ alist_process(ABI2, 0x20);
+}
+
+void alist_process_ABI3()
+{
+ alist_process(ABI3, 0x10);
+}
+
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - alist.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef ALIST_H
+#define ALIST_H
+
+void alist_process_ABI1();
+void alist_process_ABI2();
+void alist_process_ABI3();
+
+// FIXME: to remove when isZeldaABI/isMKABI workaround is gone
+void init_ucode2();
+
+#endif
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - alist_internal.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef ALIST_INTERNAL_H
+#define ALIST_INTERNAL_H
+
+#include "hle.h"
+
+typedef void (*acmd_callback_t)(u32 inst1, u32 inst2);
+
+/*
+ * Audio flags
+ */
+
+#define A_INIT 0x01
+#define A_CONTINUE 0x00
+#define A_LOOP 0x02
+#define A_OUT 0x02
+#define A_LEFT 0x02
+#define A_RIGHT 0x00
+#define A_VOL 0x04
+#define A_RATE 0x00
+#define A_AUX 0x08
+#define A_NOAUX 0x00
+#define A_MAIN 0x00
+#define A_MIX 0x10
+
+extern u16 AudioInBuffer, AudioOutBuffer, AudioCount;
+extern u16 AudioAuxA, AudioAuxC, AudioAuxE;
+extern u32 loopval; // Value set by A_SETLOOP : Possible conflict with SETVOLUME???
+
+#endif
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - cicx105.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2012 Bobby Smiles *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <string.h>
+
+#include "hle.h"
+
+/**
+ * During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions
+ * necessary for booting the game.
+ *
+ * We only implement the needed DMA transactions for booting.
+ *
+ * Found in Banjo-Tooie, Zelda, Perfect Dark, ...)
+ **/
+void cicx105_ucode()
+{
+ // memcpy is okay to use because access constrains are met (alignment, size)
+ unsigned int i;
+ unsigned char * dst = rsp.RDRAM + 0x2fb1f0;
+ unsigned char * src = rsp.IMEM + 0x120;
+
+ /* dma_read(0x1120, 0x1e8, 0x1e8) */
+ memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1f0);
+
+ /* dma_write(0x1120, 0x2fb1f0, 0xfe817000) */
+ for (i = 0; i < 24; ++i)
+ {
+ memcpy(dst, src, 8);
+ dst += 0xff0;
+ src += 0x8;
+
+ }
+}
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - cicx105.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef CICX105_H
+#define CICX105_H
+
+void cicx105_ucode();
+
+#endif
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - hle.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef HLE_H
+#define HLE_H
+
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_plugin.h"
+
+#define RSP_HLE_VERSION 0x020000
+#define RSP_PLUGIN_API_VERSION 0x020000
+
+#ifdef M64P_BIG_ENDIAN
+#define S 0
+#define S16 0
+#define S8 0
+#else
+#define S 1
+#define S16 2
+#define S8 3
+#endif
+
+// types
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+typedef signed char s8;
+typedef signed short s16;
+typedef signed int s32;
+typedef signed long long s64;
+
+extern RSP_INFO rsp;
+
+typedef struct
+{
+ unsigned int type;
+ unsigned int flags;
+
+ unsigned int ucode_boot;
+ unsigned int ucode_boot_size;
+
+ unsigned int ucode;
+ unsigned int ucode_size;
+
+ unsigned int ucode_data;
+ unsigned int ucode_data_size;
+
+ unsigned int dram_stack;
+ unsigned int dram_stack_size;
+
+ unsigned int output_buff;
+ unsigned int output_buff_size;
+
+ unsigned int data_ptr;
+ unsigned int data_size;
+
+ unsigned int yield_data_ptr;
+ unsigned int yield_data_size;
+} OSTask_t;
+
+static inline const OSTask_t * const get_task()
+{
+ return (OSTask_t*)(rsp.DMEM + 0xfc0);
+}
+
+void DebugMessage(int level, const char *message, ...);
+
+#endif
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - jpeg.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2012 Bobby Smiles *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_types.h"
+#include "m64p_plugin.h"
+#include "hle.h"
+
+#define SUBBLOCK_SIZE 64
+
+typedef void (*tile_line_emitter_t)(const int16_t *y, const int16_t *u, uint32_t address);
+typedef void (*std_macroblock_decoder_t)(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
+
+/* rdram operations */
+// FIXME: these functions deserve their own module
+static void rdram_read_many_u16(uint16_t *dst, uint32_t address, unsigned int count);
+static void rdram_write_many_u16(const uint16_t *src, uint32_t address, unsigned int count);
+static uint32_t rdram_read_u32(uint32_t address);
+static void rdram_write_many_u32(const uint32_t *src, uint32_t address, unsigned int count);
+
+/* standard jpeg ucode decoder */
+static void jpeg_decode_std(const char * const version, const std_macroblock_decoder_t decode_mb, const tile_line_emitter_t emit_line);
+
+/* helper functions */
+static uint8_t clamp_u8(int16_t x);
+static int16_t clamp_s12(int16_t x);
+static int16_t clamp_s16(int32_t x);
+static uint16_t clamp_RGBA_component(int16_t x);
+
+/* pixel conversion & foratting */
+static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v);
+static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v);
+
+/* tile line emitters */
+static void EmitYUVTileLine(const int16_t *y, const int16_t *u, uint32_t address);
+static void EmitRGBATileLine(const int16_t *y, const int16_t *u, uint32_t address);
+
+/* macroblocks operations */
+static void DecodeMacroblock1(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable);
+static void DecodeMacroblock2(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
+static void DecodeMacroblock3(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE]);
+static void EmitTilesMode0(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
+static void EmitTilesMode2(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
+
+/* subblocks operations */
+static void TransposeSubBlock(int16_t *dst, const int16_t *src);
+static void ZigZagSubBlock(int16_t *dst, const int16_t *src);
+static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table);
+static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift);
+static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale);
+static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift);
+static void InverseDCT1D(const float * const x, float *dst, unsigned int stride);
+static void InverseDCTSubBlock(int16_t *dst, const int16_t *src);
+static void RescaleYSubBlock(int16_t *dst, const int16_t *src);
+static void RescaleUVSubBlock(int16_t *dst, const int16_t *src);
+
+/* transposed dequantization table */
+static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] =
+{
+ 16, 12, 14, 14, 18, 24, 49, 72,
+ 11, 12, 13, 17, 22, 35, 64, 92,
+ 10, 14, 16, 22, 37, 55, 78, 95,
+ 16, 19, 24, 29, 56, 64, 87, 98,
+ 24, 26, 40, 51, 68, 81, 103, 112,
+ 40, 58, 57, 87, 109, 104, 121, 100,
+ 51, 60, 69, 80, 103, 113, 120, 103,
+ 61, 55, 56, 62, 77, 92, 101, 99
+};
+
+/* zig-zag indices */
+static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] =
+{
+ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63
+};
+
+/* transposition indices */
+static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] =
+{
+ 0, 8, 16, 24, 32, 40, 48, 56,
+ 1, 9, 17, 25, 33, 41, 49, 57,
+ 2, 10, 18, 26, 34, 42, 50, 58,
+ 3, 11, 19, 27, 35, 43, 51, 59,
+ 4, 12, 20, 28, 36, 44, 52, 60,
+ 5, 13, 21, 29, 37, 45, 53, 61,
+ 6, 14, 22, 30, 38, 46, 54, 62,
+ 7, 15, 23, 31, 39, 47, 55, 63
+};
+
+
+
+/* IDCT related constants
+ * Cn = alpha * cos(n * PI / 16) (alpha is chosen such as C4 = 1) */
+static const float IDCT_C3 = 1.175875602f;
+static const float IDCT_C6 = 0.541196100f;
+static const float IDCT_K[10] =
+{
+ 0.765366865f, /* C2-C6 */
+ -1.847759065f, /* -C2-C6 */
+ -0.390180644f, /* C5-C3 */
+ -1.961570561f, /* -C5-C3 */
+ 1.501321110f, /* C1+C3-C5-C7 */
+ 2.053119869f, /* C1+C3-C5+C7 */
+ 3.072711027f, /* C1+C3+C5-C7 */
+ 0.298631336f, /* -C1+C3+C5-C7 */
+ -0.899976223f, /* C7-C3 */
+ -2.562915448f /* -C1-C3 */
+};
+
+
+/* global functions */
+
+/***************************************************************************
+ * JPEG decoding ucode found in Japanese exclusive version of Pokemon Stadium.
+ **************************************************************************/
+void jpeg_decode_PS0()
+{
+ jpeg_decode_std("PS0", DecodeMacroblock3, EmitYUVTileLine);
+}
+
+/***************************************************************************
+ * JPEG decoding ucode found in Ocarina of Time, Pokemon Stadium 1 and
+ * Pokemon Stadium 2.
+ **************************************************************************/
+void jpeg_decode_PS()
+{
+ jpeg_decode_std("PS", DecodeMacroblock2, EmitRGBATileLine);
+}
+
+/***************************************************************************
+ * JPEG decoding ucode found in Ogre Battle and Bottom of the 9th.
+ **************************************************************************/
+void jpeg_decode_OB()
+{
+ int16_t qtable[SUBBLOCK_SIZE];
+ unsigned int mb;
+
+ int32_t y_dc = 0;
+ int32_t u_dc = 0;
+ int32_t v_dc = 0;
+
+ const OSTask_t * const task = get_task();
+
+ uint32_t address = task->data_ptr;
+ const unsigned int macroblock_count = task->data_size;
+ const int qscale = task->yield_data_size;
+
+ DebugMessage(M64MSG_VERBOSE, "jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d",
+ address,
+ macroblock_count,
+ qscale);
+
+ if (qscale != 0)
+ {
+ if (qscale > 0)
+ {
+ ScaleSubBlock(qtable, DEFAULT_QTABLE, qscale);
+ }
+ else
+ {
+ RShiftSubBlock(qtable, DEFAULT_QTABLE, -qscale);
+ }
+ }
+
+ for (mb = 0; mb < macroblock_count; ++mb)
+ {
+ int16_t macroblock[6*SUBBLOCK_SIZE];
+
+ rdram_read_many_u16((uint16_t*)macroblock, address, 6*SUBBLOCK_SIZE);
+ DecodeMacroblock1(macroblock, &y_dc, &u_dc, &v_dc, (qscale != 0) ? qtable : NULL);
+ EmitTilesMode2(EmitYUVTileLine, macroblock, address);
+
+ address += (2*6*SUBBLOCK_SIZE);
+ }
+}
+
+
+/* local functions */
+static void jpeg_decode_std(const char * const version, const std_macroblock_decoder_t decode_mb, const tile_line_emitter_t emit_line)
+{
+ int16_t qtables[3][SUBBLOCK_SIZE];
+ unsigned int mb;
+ uint32_t address;
+ uint32_t macroblock_count;
+ uint32_t mode;
+ uint32_t qtableY_ptr;
+ uint32_t qtableU_ptr;
+ uint32_t qtableV_ptr;
+ unsigned int subblock_count;
+ unsigned int macroblock_size;
+ int16_t *macroblock;
+ const OSTask_t * const task = get_task();
+
+ if (task->flags & 0x1)
+ {
+ DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: task yielding not implemented", version);
+ return;
+ }
+
+ address = rdram_read_u32(task->data_ptr);
+ macroblock_count = rdram_read_u32(task->data_ptr + 4);
+ mode = rdram_read_u32(task->data_ptr + 8);
+ qtableY_ptr = rdram_read_u32(task->data_ptr + 12);
+ qtableU_ptr = rdram_read_u32(task->data_ptr + 16);
+ qtableV_ptr = rdram_read_u32(task->data_ptr + 20);
+
+ DebugMessage(M64MSG_VERBOSE, "jpeg_decode_%s: *buffer=%x, #MB=%d, mode=%d, *Qy=%x, *Qu=%x, *Qv=%x",
+ version,
+ address,
+ macroblock_count,
+ mode,
+ qtableY_ptr,
+ qtableU_ptr,
+ qtableV_ptr);
+
+ if (mode != 0 && mode != 2)
+ {
+ DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: invalid mode %d", version, mode);
+ return;
+ }
+
+ subblock_count = mode + 4;
+ macroblock_size = 2*subblock_count*SUBBLOCK_SIZE;
+
+ rdram_read_many_u16((uint16_t*)qtables[0], qtableY_ptr, SUBBLOCK_SIZE);
+ rdram_read_many_u16((uint16_t*)qtables[1], qtableU_ptr, SUBBLOCK_SIZE);
+ rdram_read_many_u16((uint16_t*)qtables[2], qtableV_ptr, SUBBLOCK_SIZE);
+
+ macroblock = malloc(sizeof(*macroblock) * macroblock_size);
+ if (!macroblock)
+ {
+ DebugMessage(M64MSG_WARNING, "jpeg_decode_%s: could not allocate macroblock", version);
+ return;
+ }
+
+ for (mb = 0; mb < macroblock_count; ++mb)
+ {
+ rdram_read_many_u16((uint16_t*)macroblock, address, macroblock_size >> 1);
+ decode_mb(macroblock, subblock_count, (const int16_t (*)[SUBBLOCK_SIZE])qtables);
+
+ if (mode == 0)
+ {
+ EmitTilesMode0(emit_line, macroblock, address);
+ }
+ else
+ {
+ EmitTilesMode2(emit_line, macroblock, address);
+ }
+
+ address += macroblock_size;
+ }
+ free(macroblock);
+}
+
+static uint8_t clamp_u8(int16_t x)
+{
+ return (x & (0xff00)) ? ((-x) >> 15) & 0xff : x;
+}
+
+static int16_t clamp_s12(int16_t x)
+{
+ if (x < -0x800) { x = -0x800; } else if (x > 0x7f0) { x = 0x7f0; }
+ return x;
+}
+
+static int16_t clamp_s16(int32_t x)
+{
+ if (x > 32767) { x = 32767; } else if (x < -32768) { x = -32768; }
+ return x;
+}
+
+static uint16_t clamp_RGBA_component(int16_t x)
+{
+ if (x > 0xff0) { x = 0xff0; } else if (x < 0) { x = 0; }
+ return (x & 0xf80);
+}
+
+static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v)
+{
+ return (uint32_t)clamp_u8(u) << 24
+ | (uint32_t)clamp_u8(y1) << 16
+ | (uint32_t)clamp_u8(v) << 8
+ | (uint32_t)clamp_u8(y2);
+}
+
+static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v)
+{
+ const float fY = (float)y + 2048.0f;
+ const float fU = (float)u;
+ const float fV = (float)v;
+
+ const uint16_t r = clamp_RGBA_component((int16_t)(fY + 1.4025*fV));
+ const uint16_t g = clamp_RGBA_component((int16_t)(fY - 0.3443*fU - 0.7144*fV));
+ const uint16_t b = clamp_RGBA_component((int16_t)(fY + 1.7729*fU ));
+
+ return (r << 4) | (g >> 1) | (b >> 6) | 1;
+}
+
+static void EmitYUVTileLine(const int16_t *y, const int16_t *u, uint32_t address)
+{
+ uint32_t uyvy[8];
+
+ const int16_t * const v = u + SUBBLOCK_SIZE;
+ const int16_t * const y2 = y + SUBBLOCK_SIZE;
+
+ uyvy[0] = GetUYVY(y[0], y[1], u[0], v[0]);
+ uyvy[1] = GetUYVY(y[2], y[3], u[1], v[1]);
+ uyvy[2] = GetUYVY(y[4], y[5], u[2], v[2]);
+ uyvy[3] = GetUYVY(y[6], y[7], u[3], v[3]);
+ uyvy[4] = GetUYVY(y2[0], y2[1], u[4], v[4]);
+ uyvy[5] = GetUYVY(y2[2], y2[3], u[5], v[5]);
+ uyvy[6] = GetUYVY(y2[4], y2[5], u[6], v[6]);
+ uyvy[7] = GetUYVY(y2[6], y2[7], u[7], v[7]);
+
+ rdram_write_many_u32(uyvy, address, 8);
+}
+
+static void EmitRGBATileLine(const int16_t *y, const int16_t *u, uint32_t address)
+{
+ uint16_t rgba[16];
+
+ const int16_t * const v = u + SUBBLOCK_SIZE;
+ const int16_t * const y2 = y + SUBBLOCK_SIZE;
+
+ rgba[0] = GetRGBA(y[0], u[0], v[0]);
+ rgba[1] = GetRGBA(y[1], u[0], v[0]);
+ rgba[2] = GetRGBA(y[2], u[1], v[1]);
+ rgba[3] = GetRGBA(y[3], u[1], v[1]);
+ rgba[4] = GetRGBA(y[4], u[2], v[2]);
+ rgba[5] = GetRGBA(y[5], u[2], v[2]);
+ rgba[6] = GetRGBA(y[6], u[3], v[3]);
+ rgba[7] = GetRGBA(y[7], u[3], v[3]);
+ rgba[8] = GetRGBA(y2[0], u[4], v[4]);
+ rgba[9] = GetRGBA(y2[1], u[4], v[4]);
+ rgba[10] = GetRGBA(y2[2], u[5], v[5]);
+ rgba[11] = GetRGBA(y2[3], u[5], v[5]);
+ rgba[12] = GetRGBA(y2[4], u[6], v[6]);
+ rgba[13] = GetRGBA(y2[5], u[6], v[6]);
+ rgba[14] = GetRGBA(y2[6], u[7], v[7]);
+ rgba[15] = GetRGBA(y2[7], u[7], v[7]);
+
+ rdram_write_many_u16(rgba, address, 16);
+}
+
+static void EmitTilesMode0(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address)
+{
+ unsigned int i;
+
+ unsigned int y_offset = 0;
+ unsigned int u_offset = 2*SUBBLOCK_SIZE;
+
+ for (i = 0; i < 8; ++i)
+ {
+ emit_line(¯oblock[y_offset], ¯oblock[u_offset], address);
+
+ y_offset += 8;
+ u_offset += 8;
+ address += 32;
+ }
+}
+
+static void EmitTilesMode2(const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address)
+{
+ unsigned int i;
+
+ unsigned int y_offset = 0;
+ unsigned int u_offset = 4*SUBBLOCK_SIZE;
+
+ for (i = 0; i < 8; ++i)
+ {
+ emit_line(¯oblock[y_offset], ¯oblock[u_offset], address);
+ emit_line(¯oblock[y_offset + 8], ¯oblock[u_offset], address + 32);
+
+ y_offset += (i == 3) ? SUBBLOCK_SIZE+16 : 16;
+ u_offset += 8;
+ address += 64;
+ }
+}
+
+static void DecodeMacroblock1(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable)
+{
+ int sb;
+
+ for (sb = 0; sb < 6; ++sb)
+ {
+ int16_t tmp_sb[SUBBLOCK_SIZE];
+
+ /* update DC */
+ int32_t dc = (int32_t)macroblock[0];
+ switch(sb)
+ {
+ case 0: case 1: case 2: case 3:
+ *y_dc += dc; macroblock[0] = *y_dc & 0xffff; break;
+ case 4: *u_dc += dc; macroblock[0] = *u_dc & 0xffff; break;
+ case 5: *v_dc += dc; macroblock[0] = *v_dc & 0xffff; break;
+ }
+
+ ZigZagSubBlock(tmp_sb, macroblock);
+ if (qtable != NULL) { MultSubBlocks(tmp_sb, tmp_sb, qtable, 0); }
+ TransposeSubBlock(macroblock, tmp_sb);
+ InverseDCTSubBlock(macroblock, macroblock);
+
+ macroblock += SUBBLOCK_SIZE;
+ }
+}
+
+static void DecodeMacroblock2(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE])
+{
+ unsigned int sb;
+ unsigned int q = 0;
+
+ for (sb = 0; sb < subblock_count; ++sb)
+ {
+ int16_t tmp_sb[SUBBLOCK_SIZE];
+ const int isChromaSubBlock = (subblock_count - sb <= 2);
+
+ if (isChromaSubBlock) { ++q; }
+
+ MultSubBlocks(macroblock, macroblock, qtables[q], 4);
+ ZigZagSubBlock(tmp_sb, macroblock);
+ InverseDCTSubBlock(macroblock, tmp_sb);
+
+ macroblock += SUBBLOCK_SIZE;
+ }
+
+}
+
+static void DecodeMacroblock3(int16_t *macroblock, unsigned int subblock_count, const int16_t qtables[3][SUBBLOCK_SIZE])
+{
+ unsigned int sb;
+ unsigned int q = 0;
+
+ for (sb = 0; sb < subblock_count; ++sb)
+ {
+ int16_t tmp_sb[SUBBLOCK_SIZE];
+ const int isChromaSubBlock = (subblock_count - sb <= 2);
+
+ if (isChromaSubBlock) { ++q; }
+
+ MultSubBlocks(macroblock, macroblock, qtables[q], 4);
+ ZigZagSubBlock(tmp_sb, macroblock);
+ InverseDCTSubBlock(macroblock, tmp_sb);
+
+ if (isChromaSubBlock)
+ {
+ RescaleUVSubBlock(macroblock, macroblock);
+ }
+ else
+ {
+ RescaleYSubBlock(macroblock, macroblock);
+ }
+
+ macroblock += SUBBLOCK_SIZE;
+ }
+}
+
+static void TransposeSubBlock(int16_t *dst, const int16_t *src)
+{
+ ReorderSubBlock(dst, src, TRANSPOSE_TABLE);
+}
+
+static void ZigZagSubBlock(int16_t *dst, const int16_t *src)
+{
+ ReorderSubBlock(dst, src, ZIGZAG_TABLE);
+}
+
+static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table)
+{
+ unsigned int i;
+
+ /* source and destination sublocks cannot overlap */
+ assert(abs(dst - src) > SUBBLOCK_SIZE);
+
+ for (i = 0; i < SUBBLOCK_SIZE; ++i)
+ {
+ dst[i] = src[table[i]];
+ }
+}
+
+static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift)
+{
+ unsigned int i;
+
+ for (i = 0; i < SUBBLOCK_SIZE; ++i)
+ {
+ int32_t v = src1[i] * src2[i];
+ dst[i] = clamp_s16(v) << shift;
+ }
+}
+
+static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale)
+{
+ unsigned int i;
+
+ for (i = 0; i < SUBBLOCK_SIZE; ++i)
+ {
+ int32_t v = src[i] * scale;
+ dst[i] = clamp_s16(v);
+ }
+}
+
+static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift)
+{
+ unsigned int i;
+
+ for (i = 0; i < SUBBLOCK_SIZE; ++i)
+ {
+ dst[i] = src[i] >> shift;
+ }
+}
+
+/***************************************************************************
+ * Fast 2D IDCT using separable formulation and normalization
+ * Computations use single precision floats
+ * Implementation based on Wikipedia :
+ * http://fr.wikipedia.org/wiki/Transform%C3%A9e_en_cosinus_discr%C3%A8te
+ **************************************************************************/
+static void InverseDCT1D(const float * const x, float *dst, unsigned int stride)
+{
+ float e[4];
+ float f[4];
+ float x26, x1357, x15, x37, x17, x35;
+
+ x15 = IDCT_K[2] * (x[1] + x[5]);
+ x37 = IDCT_K[3] * (x[3] + x[7]);
+ x17 = IDCT_K[8] * (x[1] + x[7]);
+ x35 = IDCT_K[9] * (x[3] + x[5]);
+ x1357 = IDCT_C3 * (x[1] + x[3] + x[5] + x[7]);
+ x26 = IDCT_C6 * (x[2] + x[6]);
+
+ f[0] = x[0] + x[4];
+ f[1] = x[0] - x[4];
+ f[2] = x26 + IDCT_K[0]*x[2];
+ f[3] = x26 + IDCT_K[1]*x[6];
+
+ e[0] = x1357 + x15 + IDCT_K[4]*x[1] + x17;
+ e[1] = x1357 + x37 + IDCT_K[6]*x[3] + x35;
+ e[2] = x1357 + x15 + IDCT_K[5]*x[5] + x35;
+ e[3] = x1357 + x37 + IDCT_K[7]*x[7] + x17;
+
+ *dst = f[0] + f[2] + e[0]; dst += stride;
+ *dst = f[1] + f[3] + e[1]; dst += stride;
+ *dst = f[1] - f[3] + e[2]; dst += stride;
+ *dst = f[0] - f[2] + e[3]; dst += stride;
+ *dst = f[0] - f[2] - e[3]; dst += stride;
+ *dst = f[1] - f[3] - e[2]; dst += stride;
+ *dst = f[1] + f[3] - e[1]; dst += stride;
+ *dst = f[0] + f[2] - e[0]; dst += stride;
+}
+
+static void InverseDCTSubBlock(int16_t *dst, const int16_t *src)
+{
+ float x[8];
+ float block[SUBBLOCK_SIZE];
+ unsigned int i, j;
+
+ /* idct 1d on rows (+transposition) */
+ for (i = 0; i < 8; ++i)
+ {
+ for (j = 0; j < 8; ++j)
+ {
+ x[j] = (float)src[i*8+j];
+ }
+
+ InverseDCT1D(x, &block[i], 8);
+ }
+
+ /* idct 1d on columns (thanks to previous transposition) */
+ for (i = 0; i < 8; ++i)
+ {
+ InverseDCT1D(&block[i*8], x, 1);
+
+ /* C4 = 1 normalization implies a division by 8 */
+ for (j = 0; j < 8; ++j)
+ {
+ dst[i+j*8] = (int16_t)x[j] >> 3;
+ }
+ }
+}
+
+static void RescaleYSubBlock(int16_t *dst, const int16_t *src)
+{
+ unsigned int i;
+
+ for (i = 0; i < SUBBLOCK_SIZE; ++i)
+ {
+ dst[i] = (((uint32_t)(clamp_s12(src[i]) + 0x800) * 0xdb0) >> 16) + 0x10;
+ }
+}
+
+static void RescaleUVSubBlock(int16_t *dst, const int16_t *src)
+{
+ unsigned int i;
+
+ for (i = 0; i < SUBBLOCK_SIZE; ++i)
+ {
+ dst[i] = (((int)clamp_s12(src[i]) * 0xe00) >> 16) + 0x80;
+ }
+}
+
+
+
+/* FIXME: assume presence of expansion pack */
+#define MEMMASK 0x7fffff
+
+static void rdram_read_many_u16(uint16_t *dst, uint32_t address, unsigned int count)
+{
+ while (count != 0)
+ {
+ uint16_t s = rsp.RDRAM[((address++)^S8) & MEMMASK];
+ s <<= 8;
+ s |= rsp.RDRAM[((address++)^S8) & MEMMASK];
+
+ *(dst++) = s;
+
+ --count;
+ }
+}
+
+static void rdram_write_many_u16(const uint16_t *src, uint32_t address, unsigned int count)
+{
+ while (count != 0)
+ {
+ rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 8);
+ rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*(src++) & 0xff);
+
+ --count;
+ }
+}
+
+static uint32_t rdram_read_u32(uint32_t address)
+{
+ uint32_t r = rsp.RDRAM[((address++) ^ S8) & MEMMASK]; r <<= 8;
+ r |= rsp.RDRAM[((address++) ^ S8) & MEMMASK]; r <<= 8;
+ r |= rsp.RDRAM[((address++) ^ S8) & MEMMASK]; r <<= 8;
+ r |= rsp.RDRAM[((address++) ^ S8) & MEMMASK];
+
+ return r;
+}
+
+static void rdram_write_many_u32(const uint32_t *src, uint32_t address, unsigned int count)
+{
+ while (count != 0)
+ {
+ rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 24);
+ rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 16);
+ rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*src >> 8);
+ rsp.RDRAM[((address++)^S8) & MEMMASK] = (uint8_t)(*(src++) & 0xff);
+
+ --count;
+ }
+}
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - jpeg.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#ifndef JPEG_H
+#define JPEG_H
+
+void jpeg_decode_PS0();
+void jpeg_decode_PS();
+void jpeg_decode_OB();
+
+#endif
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - main.c *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2012 Bobby Smiles *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+
+#define M64P_PLUGIN_PROTOTYPES 1
+#include "m64p_types.h"
+#include "m64p_common.h"
+#include "m64p_plugin.h"
+#include "hle.h"
+#include "alist.h"
+#include "cicx105.h"
+#include "jpeg.h"
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+/* some rsp status flags */
+#define RSP_STATUS_HALT 0x1
+#define RSP_STATUS_BROKE 0x2
+#define RSP_STATUS_INTR_ON_BREAK 0x40
+#define RSP_STATUS_TASKDONE 0x200
+
+/* some rdp status flags */
+#define DP_STATUS_FREEZE 0x2
+
+/* some mips interface interrupt flags */
+#define MI_INTR_SP 0x1
+
+
+/* helper functions prototypes */
+static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size);
+static void dump_binary(const char * const filename, const unsigned char * const bytes,
+ unsigned int size);
+static void dump_task(const char * const filename, const OSTask_t * const task);
+
+static void handle_unknown_task(unsigned int sum);
+static void handle_unknown_non_task(unsigned int sum);
+
+/* global variables */
+RSP_INFO rsp;
+
+/* local variables */
+static const int FORWARD_AUDIO = 0, FORWARD_GFX = 1;
+static void (*l_DebugCallback)(void *, int, const char *) = NULL;
+static void *l_DebugCallContext = NULL;
+static int l_PluginInit = 0;
+
+/* local functions */
+
+
+/**
+ * Try to figure if the RSP was launched using osSpTask* functions
+ * and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless).
+ *
+ * Previously, the ucode_size field was used to determine this,
+ * but it is not robust enough (hi Pokemon Stadium !) because games could write anything
+ * in this field : most ucode_boot discard the value and just use 0xf7f anyway.
+ *
+ * Using ucode_boot_size should be more robust in this regard.
+ **/
+static int is_task()
+{
+ return (get_task()->ucode_boot_size <= 0x1000);
+}
+
+static void rsp_break(unsigned int setbits)
+{
+ *rsp.SP_STATUS_REG |= setbits | RSP_STATUS_BROKE | RSP_STATUS_HALT;
+
+ if ((*rsp.SP_STATUS_REG & RSP_STATUS_INTR_ON_BREAK))
+ {
+ *rsp.MI_INTR_REG |= MI_INTR_SP;
+ rsp.CheckInterrupts();
+ }
+}
+
+static void forward_gfx_task()
+{
+ if (rsp.ProcessDlistList != NULL)
+ {
+ rsp.ProcessDlistList();
+ *rsp.DPC_STATUS_REG &= ~DP_STATUS_FREEZE;
+ }
+}
+
+static void forward_audio_task()
+{
+ if (rsp.ProcessAlistList != NULL)
+ {
+ rsp.ProcessAlistList();
+ }
+}
+
+static void show_cfb()
+{
+ if (rsp.ShowCFB != NULL)
+ {
+ rsp.ShowCFB();
+ }
+}
+
+static int try_fast_audio_dispatching()
+{
+ /* identify audio ucode by using the content of ucode_data */
+ const OSTask_t * const task = get_task();
+ const unsigned char * const udata_ptr = rsp.RDRAM + task->ucode_data;
+
+ if (*(unsigned int*)(udata_ptr + 0) == 0x00000001)
+ {
+ if (*(unsigned int*)(udata_ptr + 0x30) == 0xf0000f00)
+ {
+ /**
+ * Many games including:
+ * Super Mario 64, Diddy Kong Racing, BlastCorp, GoldenEye, ... (most common)
+ **/
+ alist_process_ABI1(); return 1;
+ }
+ else
+ {
+ /**
+ * Mario Kart / Wave Race,
+ * LylatWars,
+ * FZeroX,
+ * Yoshi Story,
+ * 1080 Snowboarding,
+ * Zelda Ocarina of Time,
+ * Zelda Majoras Mask / Pokemon Stadium 2,
+ * Animal Crossing
+ *
+ * FIXME: in fact, all these games do not share the same ABI.
+ * That's the reason of the workaround in ucode2.cpp with isZeldaABI and isMKABI
+ **/
+ alist_process_ABI2(); return 1;
+ }
+ }
+ else
+ {
+ if (*(unsigned int*)(udata_ptr + 0x10) == 0x00000001)
+ {
+ /**
+ * Musyx ucode found in following games:
+ * RogueSquadron, ResidentEvil2, SnowCrossPolaris, TheWorldIsNotEnough,
+ * RugratsInParis, NBAShowTime, HydroThunder, Tarzan,
+ * GauntletLegend, Rush2049, IndianaJones, BattleForNaboo
+ * TODO: implement ucode
+ **/
+ DebugMessage(M64MSG_WARNING, "MusyX ucode not implemented.");
+ /* return 1; */
+ }
+ else
+ {
+ /**
+ * Many games including:
+ * Pokemon Stadium, Banjo Kazooie, Donkey Kong, Banjo Tooie, Jet Force Gemini,
+ * Mickey SpeedWay USA, Perfect Dark, Conker Bad Fur Day ...
+ **/
+ alist_process_ABI3(); return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int try_fast_task_dispatching()
+{
+ /* identify task ucode by its type */
+ const OSTask_t * const task = get_task();
+
+ switch (task->type)
+ {
+ case 1: if (FORWARD_GFX) { forward_gfx_task(); return 1; } break;
+
+ case 2:
+ if (FORWARD_AUDIO) { forward_audio_task(); return 1; }
+ else if (try_fast_audio_dispatching()) { return 1; }
+ break;
+
+ case 7: show_cfb(); return 1;
+ }
+
+ return 0;
+}
+
+static void normal_task_dispatching()
+{
+ const OSTask_t * const task = get_task();
+ const unsigned int sum =
+ sum_bytes(rsp.RDRAM + task->ucode, min(task->ucode_size, 0xf80) >> 1);
+
+ switch (sum)
+ {
+ /* StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4] */
+ case 0x278: /* Nothing to emulate */ return;
+
+ /* GFX: Twintris [misleading task->type == 0] */
+ case 0x212ee:
+ if (FORWARD_GFX) { forward_gfx_task(); return; }
+ break;
+
+ /* JPEG: found in Pokemon Stadium J */
+ case 0x2c85a: jpeg_decode_PS0(); return;
+
+ /* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */
+ case 0x2caa6: jpeg_decode_PS(); return;
+
+ /* JPEG: found in Ogre Battle, Bottom of the 9th */
+ case 0x130de: jpeg_decode_OB(); return;
+ }
+
+ handle_unknown_task(sum);
+}
+
+static void non_task_dispatching()
+{
+ const unsigned int sum = sum_bytes(rsp.IMEM, 0x1000 >> 1);
+
+ switch(sum)
+ {
+ /* CIC x105 ucode (used during boot of CIC x105 games) */
+ case 0x9e2: /* CIC 6105 */
+ case 0x9f2: /* CIC 7105 */
+ cicx105_ucode(); return;
+ }
+
+ handle_unknown_non_task(sum);
+}
+
+static void handle_unknown_task(unsigned int sum)
+{
+ char filename[256];
+ const OSTask_t * const task = get_task();
+
+ DebugMessage(M64MSG_WARNING, "unknown OSTask: sum %x PC:%x", sum, *rsp.SP_PC_REG);
+
+ sprintf(&filename[0], "task_%x.log", sum);
+ dump_task(filename, task);
+
+ // dump ucode_boot
+ sprintf(&filename[0], "ucode_boot_%x.bin", sum);
+ dump_binary(filename, rsp.RDRAM + (task->ucode_boot & 0x7fffff), task->ucode_boot_size);
+
+ // dump ucode
+ if (task->ucode != 0)
+ {
+ sprintf(&filename[0], "ucode_%x.bin", sum);
+ dump_binary(filename, rsp.RDRAM + (task->ucode & 0x7fffff), 0xf80);
+ }
+
+ // dump ucode_data
+ if (task->ucode_data != 0)
+ {
+ sprintf(&filename[0], "ucode_data_%x.bin", sum);
+ dump_binary(filename, rsp.RDRAM + (task->ucode_data & 0x7fffff), task->ucode_data_size);
+ }
+
+ // dump data
+ if (task->data_ptr != 0)
+ {
+ sprintf(&filename[0], "data_%x.bin", sum);
+ dump_binary(filename, rsp.RDRAM + (task->data_ptr & 0x7fffff), task->data_size);
+ }
+}
+
+static void handle_unknown_non_task(unsigned int sum)
+{
+ char filename[256];
+
+ DebugMessage(M64MSG_WARNING, "unknown RSP code: sum: %x PC:%x", sum, *rsp.SP_PC_REG);
+
+ // dump IMEM & DMEM for further analysis
+ sprintf(&filename[0], "imem_%x.bin", sum);
+ dump_binary(filename, rsp.IMEM, 0x1000);
+
+ sprintf(&filename[0], "dmem_%x.bin", sum);
+ dump_binary(filename, rsp.DMEM, 0x1000);
+}
+
+
+/* Global functions */
+void DebugMessage(int level, const char *message, ...)
+{
+ char msgbuf[1024];
+ va_list args;
+
+ if (l_DebugCallback == NULL)
+ return;
+
+ va_start(args, message);
+ vsprintf(msgbuf, message, args);
+
+ (*l_DebugCallback)(l_DebugCallContext, level, msgbuf);
+
+ va_end(args);
+}
+
+/* DLL-exported functions */
+EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context,
+ void (*DebugCallback)(void *, int, const char *))
+{
+ if (l_PluginInit)
+ return M64ERR_ALREADY_INIT;
+
+ /* first thing is to set the callback function for debug info */
+ l_DebugCallback = DebugCallback;
+ l_DebugCallContext = Context;
+
+ /* this plugin doesn't use any Core library functions (ex for Configuration), so no need to keep the CoreLibHandle */
+
+ l_PluginInit = 1;
+ return M64ERR_SUCCESS;
+}
+
+EXPORT m64p_error CALL PluginShutdown(void)
+{
+ if (!l_PluginInit)
+ return M64ERR_NOT_INIT;
+
+ /* reset some local variable */
+ l_DebugCallback = NULL;
+ l_DebugCallContext = NULL;
+
+ l_PluginInit = 0;
+ return M64ERR_SUCCESS;
+}
+
+EXPORT m64p_error CALL PluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, int *APIVersion, const char **PluginNamePtr, int *Capabilities)
+{
+ /* set version info */
+ if (PluginType != NULL)
+ *PluginType = M64PLUGIN_RSP;
+
+ if (PluginVersion != NULL)
+ *PluginVersion = RSP_HLE_VERSION;
+
+ if (APIVersion != NULL)
+ *APIVersion = RSP_PLUGIN_API_VERSION;
+
+ if (PluginNamePtr != NULL)
+ *PluginNamePtr = "Hacktarux/Azimer High-Level Emulation RSP Plugin";
+
+ if (Capabilities != NULL)
+ {
+ *Capabilities = 0;
+ }
+
+ return M64ERR_SUCCESS;
+}
+
+EXPORT unsigned int CALL DoRspCycles(unsigned int Cycles)
+{
+ if (is_task())
+ {
+ if (!try_fast_task_dispatching()) { normal_task_dispatching(); }
+ rsp_break(RSP_STATUS_TASKDONE);
+ }
+ else
+ {
+ non_task_dispatching();
+ rsp_break(0);
+ }
+
+ return Cycles;
+}
+
+EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount)
+{
+ rsp = Rsp_Info;
+}
+
+EXPORT void CALL RomClosed(void)
+{
+ memset(rsp.DMEM, 0, 0x1000);
+ memset(rsp.IMEM, 0, 0x1000);
+
+ init_ucode2();
+}
+
+
+/* local helper functions */
+static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size)
+{
+ unsigned int sum = 0;
+ const unsigned char * const bytes_end = bytes + size;
+
+ while (bytes != bytes_end)
+ sum += *bytes++;
+
+ return sum;
+}
+
+
+static void dump_binary(const char * const filename, const unsigned char * const bytes,
+ unsigned int size)
+{
+ FILE *f;
+
+ // if file already exists, do nothing
+ f = fopen(filename, "r");
+ if (f == NULL)
+ {
+ // else we write bytes to the file
+ f= fopen(filename, "wb");
+ if (f != NULL) {
+ if (fwrite(bytes, 1, size, f) != size)
+ {
+ DebugMessage(M64MSG_ERROR, "Writing error on %s", filename);
+ }
+ fclose(f);
+ }
+ else
+ {
+ DebugMessage(M64MSG_ERROR, "Couldn't open %s for writing !", filename);
+ }
+ }
+ else
+ {
+ fclose(f);
+ }
+}
+
+static void dump_task(const char * const filename, const OSTask_t * const task)
+{
+ FILE *f;
+
+ f = fopen(filename, "r");
+ if (f == NULL)
+ {
+ f = fopen(filename, "w");
+ fprintf(f,
+ "type = %d\n"
+ "flags = %d\n"
+ "ucode_boot = %#08x size = %#x\n"
+ "ucode = %#08x size = %#x\n"
+ "ucode_data = %#08x size = %#x\n"
+ "dram_stack = %#08x size = %#x\n"
+ "output_buff = %#08x *size = %#x\n"
+ "data = %#08x size = %#x\n"
+ "yield_data = %#08x size = %#x\n",
+ task->type, task->flags,
+ task->ucode_boot, task->ucode_boot_size,
+ task->ucode, task->ucode_size,
+ task->ucode_data, task->ucode_data_size,
+ task->dram_stack, task->dram_stack_size,
+ task->output_buff, task->output_buff_size,
+ task->data_ptr, task->data_size,
+ task->yield_data_ptr, task->yield_data_size);
+ fclose(f);
+ }
+ else
+ {
+ fclose(f);
+ }
+}
+
--- /dev/null
+{ global:
+PluginStartup;
+PluginShutdown;
+PluginGetVersion;
+DoRspCycles;
+InitiateRSP;
+RomClosed;
+local: *; };
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - ucode1.cpp *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+# include <string.h>
+
+extern "C" {
+ #include "hle.h"
+ #include "alist_internal.h"
+}
+
+//#include "rsp.h"
+//#define SAFE_MEMORY
+/*
+#ifndef SAFE_MEMORY
+# define wr8 (src , address);
+# define rd8 (dest, address);
+# define wr16 (src, address);
+# define rd16 (dest, address);
+# define wr32 (src, address);
+# define rd32 (dest, address);
+# define wr64 (src, address);
+# define rd64 (dest, address);
+# define dmamem (dest, src, size) memcpy (dest, src, size);
+# define clrmem (dest, size) memset (dest, 0, size);
+#else
+ void wr8 (u8 src, void *address);
+ void rd8 (u8 dest, void *address);
+ void wr16 (u16 src, void *address);
+ void rd16 (u16 dest, void *address);
+ void wr32 (u16 src, void *address);
+ void rd32 (u16 dest, void *address);
+ void wr64 (u16 src, void *address);
+ void rd64 (u16 dest, void *address);
+ void dmamem (void *dest, void *src, int size);
+ void clrmem (void *dest, int size);
+#endif
+*/
+/******** DMEM Memory Map for ABI 1 ***************
+Address/Range Description
+------------- -------------------------------
+0x000..0x2BF UCodeData
+ 0x000-0x00F Constants - 0000 0001 0002 FFFF 0020 0800 7FFF 4000
+ 0x010-0x02F Function Jump Table (16 Functions * 2 bytes each = 32) 0x20
+ 0x030-0x03F Constants - F000 0F00 00F0 000F 0001 0010 0100 1000
+ 0x040-0x03F Used by the Envelope Mixer (But what for?)
+ 0x070-0x07F Used by the Envelope Mixer (But what for?)
+0x2C0..0x31F <Unknown>
+0x320..0x35F Segments
+0x360 Audio In Buffer (Location)
+0x362 Audio Out Buffer (Location)
+0x364 Audio Buffer Size (Location)
+0x366 Initial Volume for Left Channel
+0x368 Initial Volume for Right Channel
+0x36A Auxillary Buffer #1 (Location)
+0x36C Auxillary Buffer #2 (Location)
+0x36E Auxillary Buffer #3 (Location)
+0x370 Loop Value (shared location)
+0x370 Target Volume (Left)
+0x372 Ramp?? (Left)
+0x374 Rate?? (Left)
+0x376 Target Volume (Right)
+0x378 Ramp?? (Right)
+0x37A Rate?? (Right)
+0x37C Dry??
+0x37E Wet??
+0x380..0x4BF Alist data
+0x4C0..0x4FF ADPCM CodeBook
+0x500..0x5BF <Unknown>
+0x5C0..0xF7F Buffers...
+0xF80..0xFFF <Unknown>
+***************************************************/
+#ifdef USE_EXPANSION
+ #define MEMMASK 0x7FFFFF
+#else
+ #define MEMMASK 0x3FFFFF
+#endif
+
+static void SPNOOP (u32 inst1, u32 inst2) {
+ //MessageBox (NULL, "Unknown Audio Command in ABI 1", "Audio HLE Error", MB_OK);
+}
+
+u32 SEGMENTS[0x10]; // 0x0320
+// T8 = 0x360
+u16 AudioInBuffer; // 0x0000(T8)
+u16 AudioOutBuffer; // 0x0002(T8)
+u16 AudioCount; // 0x0004(T8)
+s16 Vol_Left; // 0x0006(T8)
+s16 Vol_Right; // 0x0008(T8)
+u16 AudioAuxA; // 0x000A(T8)
+u16 AudioAuxC; // 0x000C(T8)
+u16 AudioAuxE; // 0x000E(T8)
+u32 loopval; // 0x0010(T8) // Value set by A_SETLOOP : Possible conflict with SETVOLUME???
+s16 VolTrg_Left; // 0x0010(T8)
+s32 VolRamp_Left; // m_LeftVolTarget
+//u16 VolRate_Left; // m_LeftVolRate
+s16 VolTrg_Right; // m_RightVol
+s32 VolRamp_Right; // m_RightVolTarget
+//u16 VolRate_Right; // m_RightVolRate
+s16 Env_Dry; // 0x001C(T8)
+s16 Env_Wet; // 0x001E(T8)
+
+u8 BufferSpace[0x10000];
+
+short hleMixerWorkArea[256];
+u16 adpcmtable[0x88];
+
+extern const u16 ResampleLUT [0x200] = {
+ 0x0C39, 0x66AD, 0x0D46, 0xFFDF, 0x0B39, 0x6696, 0x0E5F, 0xFFD8,
+ 0x0A44, 0x6669, 0x0F83, 0xFFD0, 0x095A, 0x6626, 0x10B4, 0xFFC8,
+ 0x087D, 0x65CD, 0x11F0, 0xFFBF, 0x07AB, 0x655E, 0x1338, 0xFFB6,
+ 0x06E4, 0x64D9, 0x148C, 0xFFAC, 0x0628, 0x643F, 0x15EB, 0xFFA1,
+ 0x0577, 0x638F, 0x1756, 0xFF96, 0x04D1, 0x62CB, 0x18CB, 0xFF8A,
+ 0x0435, 0x61F3, 0x1A4C, 0xFF7E, 0x03A4, 0x6106, 0x1BD7, 0xFF71,
+ 0x031C, 0x6007, 0x1D6C, 0xFF64, 0x029F, 0x5EF5, 0x1F0B, 0xFF56,
+ 0x022A, 0x5DD0, 0x20B3, 0xFF48, 0x01BE, 0x5C9A, 0x2264, 0xFF3A,
+ 0x015B, 0x5B53, 0x241E, 0xFF2C, 0x0101, 0x59FC, 0x25E0, 0xFF1E,
+ 0x00AE, 0x5896, 0x27A9, 0xFF10, 0x0063, 0x5720, 0x297A, 0xFF02,
+ 0x001F, 0x559D, 0x2B50, 0xFEF4, 0xFFE2, 0x540D, 0x2D2C, 0xFEE8,
+ 0xFFAC, 0x5270, 0x2F0D, 0xFEDB, 0xFF7C, 0x50C7, 0x30F3, 0xFED0,
+ 0xFF53, 0x4F14, 0x32DC, 0xFEC6, 0xFF2E, 0x4D57, 0x34C8, 0xFEBD,
+ 0xFF0F, 0x4B91, 0x36B6, 0xFEB6, 0xFEF5, 0x49C2, 0x38A5, 0xFEB0,
+ 0xFEDF, 0x47ED, 0x3A95, 0xFEAC, 0xFECE, 0x4611, 0x3C85, 0xFEAB,
+ 0xFEC0, 0x4430, 0x3E74, 0xFEAC, 0xFEB6, 0x424A, 0x4060, 0xFEAF,
+ 0xFEAF, 0x4060, 0x424A, 0xFEB6, 0xFEAC, 0x3E74, 0x4430, 0xFEC0,
+ 0xFEAB, 0x3C85, 0x4611, 0xFECE, 0xFEAC, 0x3A95, 0x47ED, 0xFEDF,
+ 0xFEB0, 0x38A5, 0x49C2, 0xFEF5, 0xFEB6, 0x36B6, 0x4B91, 0xFF0F,
+ 0xFEBD, 0x34C8, 0x4D57, 0xFF2E, 0xFEC6, 0x32DC, 0x4F14, 0xFF53,
+ 0xFED0, 0x30F3, 0x50C7, 0xFF7C, 0xFEDB, 0x2F0D, 0x5270, 0xFFAC,
+ 0xFEE8, 0x2D2C, 0x540D, 0xFFE2, 0xFEF4, 0x2B50, 0x559D, 0x001F,
+ 0xFF02, 0x297A, 0x5720, 0x0063, 0xFF10, 0x27A9, 0x5896, 0x00AE,
+ 0xFF1E, 0x25E0, 0x59FC, 0x0101, 0xFF2C, 0x241E, 0x5B53, 0x015B,
+ 0xFF3A, 0x2264, 0x5C9A, 0x01BE, 0xFF48, 0x20B3, 0x5DD0, 0x022A,
+ 0xFF56, 0x1F0B, 0x5EF5, 0x029F, 0xFF64, 0x1D6C, 0x6007, 0x031C,
+ 0xFF71, 0x1BD7, 0x6106, 0x03A4, 0xFF7E, 0x1A4C, 0x61F3, 0x0435,
+ 0xFF8A, 0x18CB, 0x62CB, 0x04D1, 0xFF96, 0x1756, 0x638F, 0x0577,
+ 0xFFA1, 0x15EB, 0x643F, 0x0628, 0xFFAC, 0x148C, 0x64D9, 0x06E4,
+ 0xFFB6, 0x1338, 0x655E, 0x07AB, 0xFFBF, 0x11F0, 0x65CD, 0x087D,
+ 0xFFC8, 0x10B4, 0x6626, 0x095A, 0xFFD0, 0x0F83, 0x6669, 0x0A44,
+ 0xFFD8, 0x0E5F, 0x6696, 0x0B39, 0xFFDF, 0x0D46, 0x66AD, 0x0C39
+};
+
+static void CLEARBUFF (u32 inst1, u32 inst2) {
+ u32 addr = (u32)(inst1 & 0xffff);
+ u32 count = (u32)(inst2 & 0xffff);
+ addr &= 0xFFFC;
+ memset(BufferSpace+addr, 0, (count+3)&0xFFFC);
+}
+
+//FILE *dfile = fopen ("d:\\envmix.txt", "wt");
+
+static void ENVMIXER (u32 inst1, u32 inst2) {
+ //static int envmixcnt = 0;
+ u8 flags = (u8)((inst1 >> 16) & 0xff);
+ u32 addy = (inst2 & 0xFFFFFF);// + SEGMENTS[(inst2>>24)&0xf];
+ //static
+// ********* Make sure these conditions are met... ***********
+ /*if ((AudioInBuffer | AudioOutBuffer | AudioAuxA | AudioAuxC | AudioAuxE | AudioCount) & 0x3) {
+ MessageBox (NULL, "Unaligned EnvMixer... please report this to Azimer with the following information: RomTitle, Place in the rom it occurred, and any save state just before the error", "AudioHLE Error", MB_OK);
+ }*/
+// ------------------------------------------------------------
+ short *inp=(short *)(BufferSpace+AudioInBuffer);
+ short *out=(short *)(BufferSpace+AudioOutBuffer);
+ short *aux1=(short *)(BufferSpace+AudioAuxA);
+ short *aux2=(short *)(BufferSpace+AudioAuxC);
+ short *aux3=(short *)(BufferSpace+AudioAuxE);
+ s32 MainR;
+ s32 MainL;
+ s32 AuxR;
+ s32 AuxL;
+ int i1,o1,a1,a2=0,a3=0;
+ unsigned short AuxIncRate=1;
+ short zero[8];
+ memset(zero,0,16);
+ s32 LVol, RVol;
+ s32 LAcc, RAcc;
+ s32 LTrg, RTrg;
+ s16 Wet, Dry;
+ u32 ptr = 0;
+ s32 RRamp, LRamp;
+ s32 LAdderStart, RAdderStart, LAdderEnd, RAdderEnd;
+ s32 oMainR, oMainL, oAuxR, oAuxL;
+
+ //envmixcnt++;
+
+ //fprintf (dfile, "\n----------------------------------------------------\n");
+ if (flags & A_INIT) {
+ LVol = ((Vol_Left * (s32)VolRamp_Left));
+ RVol = ((Vol_Right * (s32)VolRamp_Right));
+ Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
+ LTrg = (VolTrg_Left << 16); RTrg = (VolTrg_Right << 16); // Save Current Left/Right Targets
+ LAdderStart = Vol_Left << 16;
+ RAdderStart = Vol_Right << 16;
+ LAdderEnd = LVol;
+ RAdderEnd = RVol;
+ RRamp = VolRamp_Right;
+ LRamp = VolRamp_Left;
+ } else {
+ // Load LVol, RVol, LAcc, and RAcc (all 32bit)
+ // Load Wet, Dry, LTrg, RTrg
+ memcpy((u8 *)hleMixerWorkArea, (rsp.RDRAM+addy), 80);
+ Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
+ Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
+ LTrg = *(s32 *)(hleMixerWorkArea + 4); // 4-5
+ RTrg = *(s32 *)(hleMixerWorkArea + 6); // 6-7
+ LRamp= *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
+ RRamp= *(s32 *)(hleMixerWorkArea + 10); // 10-11
+ LAdderEnd = *(s32 *)(hleMixerWorkArea + 12); // 12-13
+ RAdderEnd = *(s32 *)(hleMixerWorkArea + 14); // 14-15
+ LAdderStart = *(s32 *)(hleMixerWorkArea + 16); // 12-13
+ RAdderStart = *(s32 *)(hleMixerWorkArea + 18); // 14-15
+ }
+
+ if(!(flags&A_AUX)) {
+ AuxIncRate=0;
+ aux2=aux3=zero;
+ }
+
+ oMainL = (Dry * (LTrg>>16) + 0x4000) >> 15;
+ oAuxL = (Wet * (LTrg>>16) + 0x4000) >> 15;
+ oMainR = (Dry * (RTrg>>16) + 0x4000) >> 15;
+ oAuxR = (Wet * (RTrg>>16) + 0x4000) >> 15;
+
+ for (int y = 0; y < AudioCount; y += 0x10) {
+
+ if (LAdderStart != LTrg) {
+ LAcc = LAdderStart;
+ LVol = (LAdderEnd - LAdderStart) >> 3;
+ LAdderEnd = (s32) (((s64)LAdderEnd * (s64)LRamp) >> 16);
+ LAdderStart = (s32) (((s64)LAcc * (s64)LRamp) >> 16);
+ } else {
+ LAcc = LTrg;
+ LVol = 0;
+ }
+
+ if (RAdderStart != RTrg) {
+ RAcc = RAdderStart;
+ RVol = (RAdderEnd - RAdderStart) >> 3;
+ RAdderEnd = (s32) (((s64)RAdderEnd * (s64)RRamp) >> 16);
+ RAdderStart = (s32) (((s64)RAcc * (s64)RRamp) >> 16);
+ } else {
+ RAcc = RTrg;
+ RVol = 0;
+ }
+
+ for (int x = 0; x < 8; x++) {
+ i1=(int)inp[ptr^S];
+ o1=(int)out[ptr^S];
+ a1=(int)aux1[ptr^S];
+ if (AuxIncRate) {
+ a2=(int)aux2[ptr^S];
+ a3=(int)aux3[ptr^S];
+ }
+ // TODO: here...
+ //LAcc = LTrg;
+ //RAcc = RTrg;
+
+ LAcc += LVol;
+ RAcc += RVol;
+
+ if (LVol <= 0) { // Decrementing
+ if (LAcc < LTrg) {
+ LAcc = LTrg;
+ LAdderStart = LTrg;
+ MainL = oMainL;
+ AuxL = oAuxL;
+ } else {
+ MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;
+ AuxL = (Wet * ((s32)LAcc>>16) + 0x4000) >> 15;
+ }
+ } else {
+ if (LAcc > LTrg) {
+ LAcc = LTrg;
+ LAdderStart = LTrg;
+ MainL = oMainL;
+ AuxL = oAuxL;
+ } else {
+ MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;
+ AuxL = (Wet * ((s32)LAcc>>16) + 0x4000) >> 15;
+ }
+ }
+
+ if (RVol <= 0) { // Decrementing
+ if (RAcc < RTrg) {
+ RAcc = RTrg;
+ RAdderStart = RTrg;
+ MainR = oMainR;
+ AuxR = oAuxR;
+ } else {
+ MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;
+ AuxR = (Wet * ((s32)RAcc>>16) + 0x4000) >> 15;
+ }
+ } else {
+ if (RAcc > RTrg) {
+ RAcc = RTrg;
+ RAdderStart = RTrg;
+ MainR = oMainR;
+ AuxR = oAuxR;
+ } else {
+ MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;
+ AuxR = (Wet * ((s32)RAcc>>16) + 0x4000) >> 15;
+ }
+ }
+
+ //fprintf (dfile, "%04X ", (LAcc>>16));
+
+ /*MainL = (((s64)Dry*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;
+ MainR = (((s64)Dry*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;
+ AuxL = (((s64)Wet*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;
+ AuxR = (((s64)Wet*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;*/
+/*
+ if (MainL>32767) MainL = 32767;
+ else if (MainL<-32768) MainL = -32768;
+ if (MainR>32767) MainR = 32767;
+ else if (MainR<-32768) MainR = -32768;
+ if (AuxL>32767) AuxL = 32767;
+ else if (AuxL<-32768) AuxR = -32768;
+ if (AuxR>32767) AuxR = 32767;
+ else if (AuxR<-32768) AuxR = -32768;*/
+ /*
+ MainR = (Dry * RTrg + 0x10000) >> 15;
+ MainL = (Dry * LTrg + 0x10000) >> 15;
+ AuxR = (Wet * RTrg + 0x8000) >> 16;
+ AuxL = (Wet * LTrg + 0x8000) >> 16;*/
+
+ o1+=(/*(o1*0x7fff)+*/(i1*MainR)+0x4000)>>15;
+ a1+=(/*(a1*0x7fff)+*/(i1*MainL)+0x4000)>>15;
+
+/* o1=((s64)(((s64)o1*0xfffe)+((s64)i1*MainR*2)+0x8000)>>16);
+
+ a1=((s64)(((s64)a1*0xfffe)+((s64)i1*MainL*2)+0x8000)>>16);*/
+
+ if(o1>32767) o1=32767;
+ else if(o1<-32768) o1=-32768;
+
+ if(a1>32767) a1=32767;
+ else if(a1<-32768) a1=-32768;
+
+ out[ptr^S]=o1;
+ aux1[ptr^S]=a1;
+ if (AuxIncRate) {
+ //a2=((s64)(((s64)a2*0xfffe)+((s64)i1*AuxR*2)+0x8000)>>16);
+
+ //a3=((s64)(((s64)a3*0xfffe)+((s64)i1*AuxL*2)+0x8000)>>16);
+ a2+=(/*(a2*0x7fff)+*/(i1*AuxR)+0x4000)>>15;
+ a3+=(/*(a3*0x7fff)+*/(i1*AuxL)+0x4000)>>15;
+
+ if(a2>32767) a2=32767;
+ else if(a2<-32768) a2=-32768;
+
+ if(a3>32767) a3=32767;
+ else if(a3<-32768) a3=-32768;
+
+ aux2[ptr^S]=a2;
+ aux3[ptr^S]=a3;
+ }
+ ptr++;
+ }
+ }
+
+ /*LAcc = LAdderEnd;
+ RAcc = RAdderEnd;*/
+
+ *(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
+ *(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
+ *(s32 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
+ *(s32 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
+ *(s32 *)(hleMixerWorkArea + 8) = LRamp; // 8-9 (hleMixerWorkArea is a 16bit pointer)
+ *(s32 *)(hleMixerWorkArea + 10) = RRamp; // 10-11
+ *(s32 *)(hleMixerWorkArea + 12) = LAdderEnd; // 12-13
+ *(s32 *)(hleMixerWorkArea + 14) = RAdderEnd; // 14-15
+ *(s32 *)(hleMixerWorkArea + 16) = LAdderStart; // 12-13
+ *(s32 *)(hleMixerWorkArea + 18) = RAdderStart; // 14-15
+ memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
+}
+
+static void RESAMPLE (u32 inst1, u32 inst2) {
+ unsigned char Flags=(u8)((inst1>>16)&0xff);
+ unsigned int Pitch=((inst1&0xffff))<<1;
+ u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ unsigned int Accum=0;
+ unsigned int location;
+ s16 *lut/*, *lut2*/;
+ short *dst;
+ s16 *src;
+ dst=(short *)(BufferSpace);
+ src=(s16 *)(BufferSpace);
+ u32 srcPtr=(AudioInBuffer/2);
+ u32 dstPtr=(AudioOutBuffer/2);
+ s32 temp;
+ s32 accum;
+/*
+ if (addy > (1024*1024*8))
+ addy = (inst2 & 0xffffff);
+*/
+ srcPtr -= 4;
+
+ if ((Flags & 0x1) == 0) {
+ //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
+ for (int x=0; x < 4; x++)
+ src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
+ Accum = *(u16 *)(rsp.RDRAM+addy+10);
+ } else {
+ for (int x=0; x < 4; x++)
+ src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
+ }
+
+ for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++) {
+ //location = (((Accum * 0x40) >> 0x10) * 8);
+ // location is the fractional position between two samples
+ location = (Accum >> 0xa) * 4;
+ lut = (s16*)ResampleLUT + location;
+
+ // mov eax, dword ptr [src+srcPtr];
+ // movsx edx, word ptr [lut];
+ // shl edx, 1
+ // imul edx
+ // test eax, 08000h
+ // setz ecx
+ // shl ecx, 16
+ // xor eax, 08000h
+ // add eax, ecx
+ // and edx, 0f000h
+
+ // imul
+ temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
+ accum = (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
+ accum += (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
+ accum += (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
+ accum += (s32)(temp >> 15);
+
+ if (accum > 32767) accum = 32767;
+ if (accum < -32768) accum = -32768;
+
+ dst[dstPtr^S] = (accum);
+ dstPtr++;
+ Accum += Pitch;
+ srcPtr += (Accum>>16);
+ Accum&=0xffff;
+ }
+ for (int x=0; x < 4; x++)
+ ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
+ //memcpy (RSWORK, src+srcPtr, 0x8);
+ *(u16 *)(rsp.RDRAM+addy+10) = Accum;
+}
+
+static void SETVOL (u32 inst1, u32 inst2) {
+// Might be better to unpack these depending on the flags...
+ u8 flags = (u8)((inst1 >> 16) & 0xff);
+ u16 vol = (s16)(inst1 & 0xffff);
+ //u16 voltarg =(u16)((inst2 >> 16)&0xffff);
+ u16 volrate = (u16)((inst2 & 0xffff));
+
+ if (flags & A_AUX) {
+ Env_Dry = (s16)vol; // m_MainVol
+ Env_Wet = (s16)volrate; // m_AuxVol
+ return;
+ }
+
+ if(flags & A_VOL) { // Set the Source(start) Volumes
+ if(flags & A_LEFT) {
+ Vol_Left = (s16)vol; // m_LeftVolume
+ } else { // A_RIGHT
+ Vol_Right = (s16)vol; // m_RightVolume
+ }
+ return;
+ }
+
+//0x370 Loop Value (shared location)
+//0x370 Target Volume (Left)
+//u16 VolRamp_Left; // 0x0012(T8)
+ if(flags & A_LEFT) { // Set the Ramping values Target, Ramp
+ //loopval = (((u32)vol << 0x10) | (u32)voltarg);
+ VolTrg_Left = (s16)inst1; // m_LeftVol
+ //VolRamp_Left = (s32)inst2;
+ VolRamp_Left = (s32)inst2;//(u16)(inst2) | (s32)(s16)(inst2 << 0x10);
+ //fprintf (dfile, "Ramp Left: %f\n", (float)VolRamp_Left/65536.0);
+ //fprintf (dfile, "Ramp Left: %08X\n", inst2);
+ //VolRamp_Left = (s16)voltarg; // m_LeftVolTarget
+ //VolRate_Left = (s16)volrate; // m_LeftVolRate
+ } else { // A_RIGHT
+ VolTrg_Right = (s16)inst1; // m_RightVol
+ //VolRamp_Right = (s32)inst2;
+ VolRamp_Right = (s32)inst2;//(u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
+ //fprintf (dfile, "Ramp Right: %f\n", (float)VolRamp_Right/65536.0);
+ //fprintf (dfile, "Ramp Right: %08X\n", inst2);
+ //VolRamp_Right = (s16)voltarg; // m_RightVolTarget
+ //VolRate_Right = (s16)volrate; // m_RightVolRate
+ }
+}
+
+static void UNKNOWN (u32 inst1, u32 inst2) {}
+
+static void SETLOOP (u32 inst1, u32 inst2) {
+ loopval = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ //VolTrg_Left = (s16)(loopval>>16); // m_LeftVol
+ //VolRamp_Left = (s16)(loopval); // m_LeftVolTarget
+}
+
+static void ADPCM (u32 inst1, u32 inst2) { // Work in progress! :)
+ unsigned char Flags=(u8)(inst1>>16)&0xff;
+ //unsigned short Gain=(u16)(inst1&0xffff);
+ unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ unsigned short inPtr=0;
+ //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
+ short *out=(short *)(BufferSpace+AudioOutBuffer);
+ //unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);
+ short count=(short)AudioCount;
+ unsigned char icode;
+ unsigned char code;
+ int vscale;
+ unsigned short index;
+ unsigned short j;
+ int a[8];
+ short *book1,*book2;
+/*
+ if (Address > (1024*1024*8))
+ Address = (inst2 & 0xffffff);
+*/
+ memset(out,0,32);
+
+ if(!(Flags&0x1))
+ {
+ if(Flags&0x2) {
+ memcpy(out,&rsp.RDRAM[loopval&MEMMASK],32);
+ } else {
+ memcpy(out,&rsp.RDRAM[Address],32);
+ }
+ }
+
+ int l1=out[14^S];
+ int l2=out[15^S];
+ int inp1[8];
+ int inp2[8];
+ out+=16;
+ while(count>0)
+ {
+ // the first interation through, these values are
+ // either 0 in the case of A_INIT, from a special
+ // area of memory in the case of A_LOOP or just
+ // the values we calculated the last time
+
+ code=BufferSpace[(AudioInBuffer+inPtr)^S8];
+ index=code&0xf;
+ index<<=4; // index into the adpcm code table
+ book1=(short *)&adpcmtable[index];
+ book2=book1+8;
+ code>>=4; // upper nibble is scale
+ vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format
+ // so this appears to be a fractional scale based
+ // on the 12 based inverse of the scale value. note
+ // that this could be negative, in which case we do
+ // not use the calculated vscale value... see the
+ // if(code>12) check below
+
+ inPtr++; // coded adpcm data lies next
+ j=0;
+ while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes
+ // which yields 8 short pcm values
+ {
+ icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
+ inPtr++;
+
+ inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed
+ if(code<12)
+ inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+
+ inp1[j]=(s16)((icode&0xf)<<12);
+ if(code<12)
+ inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+ }
+ j=0;
+ while(j<8)
+ {
+ icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
+ inPtr++;
+
+ inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed
+ if(code<12)
+ inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+
+ inp2[j]=(short)((icode&0xf)<<12);
+ if(code<12)
+ inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+ }
+
+ a[0]= (int)book1[0]*(int)l1;
+ a[0]+=(int)book2[0]*(int)l2;
+ a[0]+=(int)inp1[0]*(int)2048;
+
+ a[1] =(int)book1[1]*(int)l1;
+ a[1]+=(int)book2[1]*(int)l2;
+ a[1]+=(int)book2[0]*inp1[0];
+ a[1]+=(int)inp1[1]*(int)2048;
+
+ a[2] =(int)book1[2]*(int)l1;
+ a[2]+=(int)book2[2]*(int)l2;
+ a[2]+=(int)book2[1]*inp1[0];
+ a[2]+=(int)book2[0]*inp1[1];
+ a[2]+=(int)inp1[2]*(int)2048;
+
+ a[3] =(int)book1[3]*(int)l1;
+ a[3]+=(int)book2[3]*(int)l2;
+ a[3]+=(int)book2[2]*inp1[0];
+ a[3]+=(int)book2[1]*inp1[1];
+ a[3]+=(int)book2[0]*inp1[2];
+ a[3]+=(int)inp1[3]*(int)2048;
+
+ a[4] =(int)book1[4]*(int)l1;
+ a[4]+=(int)book2[4]*(int)l2;
+ a[4]+=(int)book2[3]*inp1[0];
+ a[4]+=(int)book2[2]*inp1[1];
+ a[4]+=(int)book2[1]*inp1[2];
+ a[4]+=(int)book2[0]*inp1[3];
+ a[4]+=(int)inp1[4]*(int)2048;
+
+ a[5] =(int)book1[5]*(int)l1;
+ a[5]+=(int)book2[5]*(int)l2;
+ a[5]+=(int)book2[4]*inp1[0];
+ a[5]+=(int)book2[3]*inp1[1];
+ a[5]+=(int)book2[2]*inp1[2];
+ a[5]+=(int)book2[1]*inp1[3];
+ a[5]+=(int)book2[0]*inp1[4];
+ a[5]+=(int)inp1[5]*(int)2048;
+
+ a[6] =(int)book1[6]*(int)l1;
+ a[6]+=(int)book2[6]*(int)l2;
+ a[6]+=(int)book2[5]*inp1[0];
+ a[6]+=(int)book2[4]*inp1[1];
+ a[6]+=(int)book2[3]*inp1[2];
+ a[6]+=(int)book2[2]*inp1[3];
+ a[6]+=(int)book2[1]*inp1[4];
+ a[6]+=(int)book2[0]*inp1[5];
+ a[6]+=(int)inp1[6]*(int)2048;
+
+ a[7] =(int)book1[7]*(int)l1;
+ a[7]+=(int)book2[7]*(int)l2;
+ a[7]+=(int)book2[6]*inp1[0];
+ a[7]+=(int)book2[5]*inp1[1];
+ a[7]+=(int)book2[4]*inp1[2];
+ a[7]+=(int)book2[3]*inp1[3];
+ a[7]+=(int)book2[2]*inp1[4];
+ a[7]+=(int)book2[1]*inp1[5];
+ a[7]+=(int)book2[0]*inp1[6];
+ a[7]+=(int)inp1[7]*(int)2048;
+
+ for(j=0;j<8;j++)
+ {
+ a[j^S]>>=11;
+ if(a[j^S]>32767) a[j^S]=32767;
+ else if(a[j^S]<-32768) a[j^S]=-32768;
+ *(out++)=a[j^S];
+ }
+ l1=a[6];
+ l2=a[7];
+
+ a[0]= (int)book1[0]*(int)l1;
+ a[0]+=(int)book2[0]*(int)l2;
+ a[0]+=(int)inp2[0]*(int)2048;
+
+ a[1] =(int)book1[1]*(int)l1;
+ a[1]+=(int)book2[1]*(int)l2;
+ a[1]+=(int)book2[0]*inp2[0];
+ a[1]+=(int)inp2[1]*(int)2048;
+
+ a[2] =(int)book1[2]*(int)l1;
+ a[2]+=(int)book2[2]*(int)l2;
+ a[2]+=(int)book2[1]*inp2[0];
+ a[2]+=(int)book2[0]*inp2[1];
+ a[2]+=(int)inp2[2]*(int)2048;
+
+ a[3] =(int)book1[3]*(int)l1;
+ a[3]+=(int)book2[3]*(int)l2;
+ a[3]+=(int)book2[2]*inp2[0];
+ a[3]+=(int)book2[1]*inp2[1];
+ a[3]+=(int)book2[0]*inp2[2];
+ a[3]+=(int)inp2[3]*(int)2048;
+
+ a[4] =(int)book1[4]*(int)l1;
+ a[4]+=(int)book2[4]*(int)l2;
+ a[4]+=(int)book2[3]*inp2[0];
+ a[4]+=(int)book2[2]*inp2[1];
+ a[4]+=(int)book2[1]*inp2[2];
+ a[4]+=(int)book2[0]*inp2[3];
+ a[4]+=(int)inp2[4]*(int)2048;
+
+ a[5] =(int)book1[5]*(int)l1;
+ a[5]+=(int)book2[5]*(int)l2;
+ a[5]+=(int)book2[4]*inp2[0];
+ a[5]+=(int)book2[3]*inp2[1];
+ a[5]+=(int)book2[2]*inp2[2];
+ a[5]+=(int)book2[1]*inp2[3];
+ a[5]+=(int)book2[0]*inp2[4];
+ a[5]+=(int)inp2[5]*(int)2048;
+
+ a[6] =(int)book1[6]*(int)l1;
+ a[6]+=(int)book2[6]*(int)l2;
+ a[6]+=(int)book2[5]*inp2[0];
+ a[6]+=(int)book2[4]*inp2[1];
+ a[6]+=(int)book2[3]*inp2[2];
+ a[6]+=(int)book2[2]*inp2[3];
+ a[6]+=(int)book2[1]*inp2[4];
+ a[6]+=(int)book2[0]*inp2[5];
+ a[6]+=(int)inp2[6]*(int)2048;
+
+ a[7] =(int)book1[7]*(int)l1;
+ a[7]+=(int)book2[7]*(int)l2;
+ a[7]+=(int)book2[6]*inp2[0];
+ a[7]+=(int)book2[5]*inp2[1];
+ a[7]+=(int)book2[4]*inp2[2];
+ a[7]+=(int)book2[3]*inp2[3];
+ a[7]+=(int)book2[2]*inp2[4];
+ a[7]+=(int)book2[1]*inp2[5];
+ a[7]+=(int)book2[0]*inp2[6];
+ a[7]+=(int)inp2[7]*(int)2048;
+
+ for(j=0;j<8;j++)
+ {
+ a[j^S]>>=11;
+ if(a[j^S]>32767) a[j^S]=32767;
+ else if(a[j^S]<-32768) a[j^S]=-32768;
+ *(out++)=a[j^S];
+ }
+ l1=a[6];
+ l2=a[7];
+
+ count-=32;
+ }
+ out-=16;
+ memcpy(&rsp.RDRAM[Address],out,32);
+}
+
+static void LOADBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(
+ u32 v0;
+ //u32 cnt;
+ if (AudioCount == 0)
+ return;
+ v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
+ memcpy (BufferSpace+(AudioInBuffer&0xFFFC), rsp.RDRAM+v0, (AudioCount+3)&0xFFFC);
+}
+
+static void SAVEBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(
+ u32 v0;
+ //u32 cnt;
+ if (AudioCount == 0)
+ return;
+ v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
+ memcpy (rsp.RDRAM+v0, BufferSpace+(AudioOutBuffer&0xFFFC), (AudioCount+3)&0xFFFC);
+}
+
+static void SETBUFF (u32 inst1, u32 inst2) { // Should work ;-)
+ if ((inst1 >> 0x10) & 0x8) { // A_AUX - Auxillary Sound Buffer Settings
+ AudioAuxA = u16(inst1);
+ AudioAuxC = u16((inst2 >> 0x10));
+ AudioAuxE = u16(inst2);
+ } else { // A_MAIN - Main Sound Buffer Settings
+ AudioInBuffer = u16(inst1); // 0x00
+ AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02
+ AudioCount = u16(inst2); // 0x04
+ }
+}
+
+static void DMEMMOVE (u32 inst1, u32 inst2) { // Doesn't sound just right?... will fix when HLE is ready - 03-11-01
+ u32 v0, v1;
+ u32 cnt;
+ if ((inst2 & 0xffff)==0)
+ return;
+ v0 = (inst1 & 0xFFFF);
+ v1 = (inst2 >> 0x10);
+ //assert ((v1 & 0x3) == 0);
+ //assert ((v0 & 0x3) == 0);
+ u32 count = ((inst2+3) & 0xfffc);
+ //v0 = (v0) & 0xfffc;
+ //v1 = (v1) & 0xfffc;
+
+ //memcpy (BufferSpace+v1, BufferSpace+v0, count-1);
+ for (cnt = 0; cnt < count; cnt++) {
+ *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
+ }
+}
+
+static void LOADADPCM (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
+ u32 v0;
+ v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+/* if (v0 > (1024*1024*8))
+ v0 = (inst2 & 0xffffff);*/
+ //memcpy (dmem+0x4c0, rsp.RDRAM+v0, inst1&0xffff); // Could prolly get away with not putting this in dmem
+ //assert ((inst1&0xffff) <= 0x80);
+ u16 *table = (u16 *)(rsp.RDRAM+v0);
+ for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
+ adpcmtable[(0x0+(x<<3))^S] = table[0];
+ adpcmtable[(0x1+(x<<3))^S] = table[1];
+
+ adpcmtable[(0x2+(x<<3))^S] = table[2];
+ adpcmtable[(0x3+(x<<3))^S] = table[3];
+
+ adpcmtable[(0x4+(x<<3))^S] = table[4];
+ adpcmtable[(0x5+(x<<3))^S] = table[5];
+
+ adpcmtable[(0x6+(x<<3))^S] = table[6];
+ adpcmtable[(0x7+(x<<3))^S] = table[7];
+ table += 8;
+ }
+}
+
+
+static void INTERLEAVE (u32 inst1, u32 inst2) { // Works... - 3-11-01
+ u32 inL, inR;
+ u16 *outbuff = (u16 *)(AudioOutBuffer+BufferSpace);
+ u16 *inSrcR;
+ u16 *inSrcL;
+ u16 Left, Right, Left2, Right2;
+
+ inL = inst2 & 0xFFFF;
+ inR = (inst2 >> 16) & 0xFFFF;
+
+ inSrcR = (u16 *)(BufferSpace+inR);
+ inSrcL = (u16 *)(BufferSpace+inL);
+
+ for (int x = 0; x < (AudioCount/4); x++) {
+ Left=*(inSrcL++);
+ Right=*(inSrcR++);
+ Left2=*(inSrcL++);
+ Right2=*(inSrcR++);
+
+#ifdef M64P_BIG_ENDIAN
+ *(outbuff++)=Right;
+ *(outbuff++)=Left;
+ *(outbuff++)=Right2;
+ *(outbuff++)=Left2;
+#else
+ *(outbuff++)=Right2;
+ *(outbuff++)=Left2;
+ *(outbuff++)=Right;
+ *(outbuff++)=Left;
+#endif
+ }
+}
+
+
+static void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01
+ u32 dmemin = (u16)(inst2 >> 0x10);
+ u32 dmemout = (u16)(inst2 & 0xFFFF);
+ //u8 flags = (u8)((inst1 >> 16) & 0xff);
+ s32 gain = (s16)(inst1 & 0xFFFF);
+ s32 temp;
+
+ if (AudioCount == 0)
+ return;
+
+ for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier
+ temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
+ temp += *(s16 *)(BufferSpace+dmemout+x);
+
+ if ((s32)temp > 32767)
+ temp = 32767;
+ if ((s32)temp < -32768)
+ temp = -32768;
+
+ *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
+ }
+}
+
+// TOP Performance Hogs:
+//Command: ADPCM - Calls: 48 - Total Time: 331226 - Avg Time: 6900.54 - Percent: 31.53%
+//Command: ENVMIXER - Calls: 48 - Total Time: 408563 - Avg Time: 8511.73 - Percent: 38.90%
+//Command: LOADBUFF - Calls: 56 - Total Time: 21551 - Avg Time: 384.84 - Percent: 2.05%
+//Command: RESAMPLE - Calls: 48 - Total Time: 225922 - Avg Time: 4706.71 - Percent: 21.51%
+
+//Command: ADPCM - Calls: 48 - Total Time: 391600 - Avg Time: 8158.33 - Percent: 32.52%
+//Command: ENVMIXER - Calls: 48 - Total Time: 444091 - Avg Time: 9251.90 - Percent: 36.88%
+//Command: LOADBUFF - Calls: 58 - Total Time: 29945 - Avg Time: 516.29 - Percent: 2.49%
+//Command: RESAMPLE - Calls: 48 - Total Time: 276354 - Avg Time: 5757.38 - Percent: 22.95%
+
+
+extern "C" const acmd_callback_t ABI1[0x10] = { // TOP Performace Hogs: MIXER, RESAMPLE, ENVMIXER
+ SPNOOP , ADPCM , CLEARBUFF, ENVMIXER , LOADBUFF, RESAMPLE , SAVEBUFF, UNKNOWN,
+ SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER , INTERLEAVE, UNKNOWN , SETLOOP
+};
+
+/* BACKUPS
+void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01
+ u16 dmemin = (u16)(inst2 >> 0x10);
+ u16 dmemout = (u16)(inst2 & 0xFFFF);
+ u16 gain = (u16)(inst1 & 0xFFFF);
+ u8 flags = (u8)((inst1 >> 16) & 0xff);
+ u64 temp;
+
+ if (AudioCount == 0)
+ return;
+
+ for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier
+ temp = (s64)(*(s16 *)(BufferSpace+dmemout+x)) * (s64)((s16)(0x7FFF)*2);
+
+ if (temp & 0x8000)
+ temp = (temp^0x8000) + 0x10000;
+ else
+ temp = (temp^0x8000);
+
+ temp = (temp & 0xFFFFFFFFFFFF);
+
+ temp += ((*(s16 *)(BufferSpace+dmemin+x) * (s64)((s16)gain*2))) & 0xFFFFFFFFFFFF;
+
+ temp = (s32)(temp >> 16);
+ if ((s32)temp > 32767)
+ temp = 32767;
+ if ((s32)temp < -32768)
+ temp = -32768;
+
+ *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
+ }
+}
+*/
+
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - ucode2.cpp *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+# include <string.h>
+# include <stdio.h>
+
+extern "C" {
+ #include "m64p_types.h"
+ #include "hle.h"
+ #include "alist_internal.h"
+}
+
+extern u8 BufferSpace[0x10000];
+
+static void SPNOOP (u32 inst1, u32 inst2) {
+ DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 2", (int)(inst1 >> 24));
+}
+extern u16 AudioInBuffer; // 0x0000(T8)
+extern u16 AudioOutBuffer; // 0x0002(T8)
+extern u16 AudioCount; // 0x0004(T8)
+extern u32 loopval; // 0x0010(T8)
+extern u32 SEGMENTS[0x10];
+
+extern u16 adpcmtable[0x88];
+
+extern const u16 ResampleLUT [0x200];
+
+bool isMKABI = false;
+bool isZeldaABI = false;
+
+extern "C" void init_ucode2() { isMKABI = isZeldaABI = false; }
+
+static void LOADADPCM2 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
+ u32 v0;
+ v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ u16 *table = (u16 *)(rsp.RDRAM+v0); // Zelda2 Specific...
+
+ for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
+ adpcmtable[(0x0+(x<<3))^S] = table[0];
+ adpcmtable[(0x1+(x<<3))^S] = table[1];
+
+ adpcmtable[(0x2+(x<<3))^S] = table[2];
+ adpcmtable[(0x3+(x<<3))^S] = table[3];
+
+ adpcmtable[(0x4+(x<<3))^S] = table[4];
+ adpcmtable[(0x5+(x<<3))^S] = table[5];
+
+ adpcmtable[(0x6+(x<<3))^S] = table[6];
+ adpcmtable[(0x7+(x<<3))^S] = table[7];
+ table += 8;
+ }
+}
+
+static void SETLOOP2 (u32 inst1, u32 inst2) {
+ loopval = inst2 & 0xffffff; // No segment?
+}
+
+static void SETBUFF2 (u32 inst1, u32 inst2) {
+ AudioInBuffer = u16(inst1); // 0x00
+ AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02
+ AudioCount = u16(inst2); // 0x04
+}
+
+static void ADPCM2 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...
+ unsigned char Flags=(u8)(inst1>>16)&0xff;
+ //unsigned short Gain=(u16)(inst1&0xffff);
+ unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ unsigned short inPtr=0;
+ //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
+ short *out=(short *)(BufferSpace+AudioOutBuffer);
+ //unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);
+ short count=(short)AudioCount;
+ unsigned char icode;
+ unsigned char code;
+ int vscale;
+ unsigned short index;
+ unsigned short j;
+ int a[8];
+ short *book1,*book2;
+
+ u8 srange;
+ u8 mask1;
+ u8 mask2;
+ u8 shifter;
+
+ memset(out,0,32);
+
+ if (Flags & 0x4) { // Tricky lil Zelda MM and ABI2!!! hahaha I know your secrets! :DDD
+ srange = 0xE;
+ mask1 = 0xC0;
+ mask2 = 0x30;
+ shifter = 10;
+ } else {
+ srange = 0xC;
+ mask1 = 0xf0;
+ mask2 = 0x0f;
+ shifter = 12;
+ }
+
+ if(!(Flags&0x1))
+ {
+ if(Flags&0x2)
+ {/*
+ for(int i=0;i<16;i++)
+ {
+ out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
+ }*/
+ memcpy(out,&rsp.RDRAM[loopval],32);
+ }
+ else
+ {/*
+ for(int i=0;i<16;i++)
+ {
+ out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
+ }*/
+ memcpy(out,&rsp.RDRAM[Address],32);
+ }
+ }
+
+ int l1=out[14^S];
+ int l2=out[15^S];
+ int inp1[8];
+ int inp2[8];
+ out+=16;
+ while(count>0) {
+ code=BufferSpace[(AudioInBuffer+inPtr)^S8];
+ index=code&0xf;
+ index<<=4;
+ book1=(short *)&adpcmtable[index];
+ book2=book1+8;
+ code>>=4;
+ vscale=(0x8000>>((srange-code)-1));
+
+ inPtr++;
+ j=0;
+
+ while(j<8) {
+ icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
+ inPtr++;
+
+ inp1[j]=(s16)((icode&mask1) << 8); // this will in effect be signed
+ if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+
+ inp1[j]=(s16)((icode&mask2)<<shifter);
+ if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+
+ if (Flags & 4) {
+ inp1[j]=(s16)((icode&0xC) << 12); // this will in effect be signed
+ if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+
+ inp1[j]=(s16)((icode&0x3) << 14);
+ if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+ } // end flags
+ } // end while
+
+
+
+ j=0;
+ while(j<8) {
+ icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
+ inPtr++;
+
+ inp2[j]=(s16)((icode&mask1) << 8);
+ if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+
+ inp2[j]=(s16)((icode&mask2)<<shifter);
+ if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+
+ if (Flags & 4) {
+ inp2[j]=(s16)((icode&0xC) << 12);
+ if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+
+ inp2[j]=(s16)((icode&0x3) << 14);
+ if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ //else int catchme=1;
+ j++;
+ } // end flags
+ }
+
+ a[0]= (int)book1[0]*(int)l1;
+ a[0]+=(int)book2[0]*(int)l2;
+ a[0]+=(int)inp1[0]*(int)2048;
+
+ a[1] =(int)book1[1]*(int)l1;
+ a[1]+=(int)book2[1]*(int)l2;
+ a[1]+=(int)book2[0]*inp1[0];
+ a[1]+=(int)inp1[1]*(int)2048;
+
+ a[2] =(int)book1[2]*(int)l1;
+ a[2]+=(int)book2[2]*(int)l2;
+ a[2]+=(int)book2[1]*inp1[0];
+ a[2]+=(int)book2[0]*inp1[1];
+ a[2]+=(int)inp1[2]*(int)2048;
+
+ a[3] =(int)book1[3]*(int)l1;
+ a[3]+=(int)book2[3]*(int)l2;
+ a[3]+=(int)book2[2]*inp1[0];
+ a[3]+=(int)book2[1]*inp1[1];
+ a[3]+=(int)book2[0]*inp1[2];
+ a[3]+=(int)inp1[3]*(int)2048;
+
+ a[4] =(int)book1[4]*(int)l1;
+ a[4]+=(int)book2[4]*(int)l2;
+ a[4]+=(int)book2[3]*inp1[0];
+ a[4]+=(int)book2[2]*inp1[1];
+ a[4]+=(int)book2[1]*inp1[2];
+ a[4]+=(int)book2[0]*inp1[3];
+ a[4]+=(int)inp1[4]*(int)2048;
+
+ a[5] =(int)book1[5]*(int)l1;
+ a[5]+=(int)book2[5]*(int)l2;
+ a[5]+=(int)book2[4]*inp1[0];
+ a[5]+=(int)book2[3]*inp1[1];
+ a[5]+=(int)book2[2]*inp1[2];
+ a[5]+=(int)book2[1]*inp1[3];
+ a[5]+=(int)book2[0]*inp1[4];
+ a[5]+=(int)inp1[5]*(int)2048;
+
+ a[6] =(int)book1[6]*(int)l1;
+ a[6]+=(int)book2[6]*(int)l2;
+ a[6]+=(int)book2[5]*inp1[0];
+ a[6]+=(int)book2[4]*inp1[1];
+ a[6]+=(int)book2[3]*inp1[2];
+ a[6]+=(int)book2[2]*inp1[3];
+ a[6]+=(int)book2[1]*inp1[4];
+ a[6]+=(int)book2[0]*inp1[5];
+ a[6]+=(int)inp1[6]*(int)2048;
+
+ a[7] =(int)book1[7]*(int)l1;
+ a[7]+=(int)book2[7]*(int)l2;
+ a[7]+=(int)book2[6]*inp1[0];
+ a[7]+=(int)book2[5]*inp1[1];
+ a[7]+=(int)book2[4]*inp1[2];
+ a[7]+=(int)book2[3]*inp1[3];
+ a[7]+=(int)book2[2]*inp1[4];
+ a[7]+=(int)book2[1]*inp1[5];
+ a[7]+=(int)book2[0]*inp1[6];
+ a[7]+=(int)inp1[7]*(int)2048;
+
+ for(j=0;j<8;j++)
+ {
+ a[j^S]>>=11;
+ if(a[j^S]>32767) a[j^S]=32767;
+ else if(a[j^S]<-32768) a[j^S]=-32768;
+ *(out++)=a[j^S];
+ }
+ l1=a[6];
+ l2=a[7];
+
+ a[0]= (int)book1[0]*(int)l1;
+ a[0]+=(int)book2[0]*(int)l2;
+ a[0]+=(int)inp2[0]*(int)2048;
+
+ a[1] =(int)book1[1]*(int)l1;
+ a[1]+=(int)book2[1]*(int)l2;
+ a[1]+=(int)book2[0]*inp2[0];
+ a[1]+=(int)inp2[1]*(int)2048;
+
+ a[2] =(int)book1[2]*(int)l1;
+ a[2]+=(int)book2[2]*(int)l2;
+ a[2]+=(int)book2[1]*inp2[0];
+ a[2]+=(int)book2[0]*inp2[1];
+ a[2]+=(int)inp2[2]*(int)2048;
+
+ a[3] =(int)book1[3]*(int)l1;
+ a[3]+=(int)book2[3]*(int)l2;
+ a[3]+=(int)book2[2]*inp2[0];
+ a[3]+=(int)book2[1]*inp2[1];
+ a[3]+=(int)book2[0]*inp2[2];
+ a[3]+=(int)inp2[3]*(int)2048;
+
+ a[4] =(int)book1[4]*(int)l1;
+ a[4]+=(int)book2[4]*(int)l2;
+ a[4]+=(int)book2[3]*inp2[0];
+ a[4]+=(int)book2[2]*inp2[1];
+ a[4]+=(int)book2[1]*inp2[2];
+ a[4]+=(int)book2[0]*inp2[3];
+ a[4]+=(int)inp2[4]*(int)2048;
+
+ a[5] =(int)book1[5]*(int)l1;
+ a[5]+=(int)book2[5]*(int)l2;
+ a[5]+=(int)book2[4]*inp2[0];
+ a[5]+=(int)book2[3]*inp2[1];
+ a[5]+=(int)book2[2]*inp2[2];
+ a[5]+=(int)book2[1]*inp2[3];
+ a[5]+=(int)book2[0]*inp2[4];
+ a[5]+=(int)inp2[5]*(int)2048;
+
+ a[6] =(int)book1[6]*(int)l1;
+ a[6]+=(int)book2[6]*(int)l2;
+ a[6]+=(int)book2[5]*inp2[0];
+ a[6]+=(int)book2[4]*inp2[1];
+ a[6]+=(int)book2[3]*inp2[2];
+ a[6]+=(int)book2[2]*inp2[3];
+ a[6]+=(int)book2[1]*inp2[4];
+ a[6]+=(int)book2[0]*inp2[5];
+ a[6]+=(int)inp2[6]*(int)2048;
+
+ a[7] =(int)book1[7]*(int)l1;
+ a[7]+=(int)book2[7]*(int)l2;
+ a[7]+=(int)book2[6]*inp2[0];
+ a[7]+=(int)book2[5]*inp2[1];
+ a[7]+=(int)book2[4]*inp2[2];
+ a[7]+=(int)book2[3]*inp2[3];
+ a[7]+=(int)book2[2]*inp2[4];
+ a[7]+=(int)book2[1]*inp2[5];
+ a[7]+=(int)book2[0]*inp2[6];
+ a[7]+=(int)inp2[7]*(int)2048;
+
+ for(j=0;j<8;j++)
+ {
+ a[j^S]>>=11;
+ if(a[j^S]>32767) a[j^S]=32767;
+ else if(a[j^S]<-32768) a[j^S]=-32768;
+ *(out++)=a[j^S];
+ }
+ l1=a[6];
+ l2=a[7];
+
+ count-=32;
+ }
+ out-=16;
+ memcpy(&rsp.RDRAM[Address],out,32);
+}
+
+static void CLEARBUFF2 (u32 inst1, u32 inst2) {
+ u16 addr = (u16)(inst1 & 0xffff);
+ u16 count = (u16)(inst2 & 0xffff);
+ if (count > 0)
+ memset(BufferSpace+addr, 0, count);
+}
+
+static void LOADBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u32 v0;
+ u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
+ v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
+ memcpy (BufferSpace+(inst1&0xfffc), rsp.RDRAM+v0, (cnt+3)&0xFFFC);
+}
+
+static void SAVEBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u32 v0;
+ u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
+ v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
+ memcpy (rsp.RDRAM+v0, BufferSpace+(inst1&0xfffc), (cnt+3)&0xFFFC);
+}
+
+
+static void MIXER2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u16 dmemin = (u16)(inst2 >> 0x10);
+ u16 dmemout = (u16)(inst2 & 0xFFFF);
+ u32 count = ((inst1 >> 12) & 0xFF0);
+ s32 gain = (s16)(inst1 & 0xFFFF);
+ s32 temp;
+
+ for (unsigned int x=0; x < count; x+=2) { // I think I can do this a lot easier
+
+ temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
+ temp += *(s16 *)(BufferSpace+dmemout+x);
+
+ if ((s32)temp > 32767)
+ temp = 32767;
+ if ((s32)temp < -32768)
+ temp = -32768;
+
+ *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
+ }
+}
+
+
+static void RESAMPLE2 (u32 inst1, u32 inst2) {
+ unsigned char Flags=(u8)((inst1>>16)&0xff);
+ unsigned int Pitch=((inst1&0xffff))<<1;
+ u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ unsigned int Accum=0;
+ unsigned int location;
+ s16 *lut;
+ short *dst;
+ s16 *src;
+ dst=(short *)(BufferSpace);
+ src=(s16 *)(BufferSpace);
+ u32 srcPtr=(AudioInBuffer/2);
+ u32 dstPtr=(AudioOutBuffer/2);
+ s32 temp;
+ s32 accum;
+
+ if (addy > (1024*1024*8))
+ addy = (inst2 & 0xffffff);
+
+ srcPtr -= 4;
+
+ if ((Flags & 0x1) == 0) {
+ for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
+ src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
+ Accum = *(u16 *)(rsp.RDRAM+addy+10);
+ } else {
+ for (int x=0; x < 4; x++)
+ src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
+ }
+
+ for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++) {
+ location = (((Accum * 0x40) >> 0x10) * 8);
+ //location = (Accum >> 0xa) << 0x3;
+ lut = (s16 *)(((u8 *)ResampleLUT) + location);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
+ accum = (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
+ accum += (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
+ accum += (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
+ accum += (s32)(temp >> 15);
+
+ if (accum > 32767) accum = 32767;
+ if (accum < -32768) accum = -32768;
+
+ dst[dstPtr^S] = (s16)(accum);
+ dstPtr++;
+ Accum += Pitch;
+ srcPtr += (Accum>>16);
+ Accum&=0xffff;
+ }
+ for (int x=0; x < 4; x++)
+ ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
+ *(u16 *)(rsp.RDRAM+addy+10) = (u16)Accum;
+ //memcpy (RSWORK, src+srcPtr, 0x8);
+}
+
+static void DMEMMOVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u32 v0, v1;
+ u32 cnt;
+ if ((inst2 & 0xffff)==0)
+ return;
+ v0 = (inst1 & 0xFFFF);
+ v1 = (inst2 >> 0x10);
+ //assert ((v1 & 0x3) == 0);
+ //assert ((v0 & 0x3) == 0);
+ u32 count = ((inst2+3) & 0xfffc);
+ //v0 = (v0) & 0xfffc;
+ //v1 = (v1) & 0xfffc;
+
+ //memcpy (dmem+v1, dmem+v0, count-1);
+ for (cnt = 0; cnt < count; cnt++) {
+ *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
+ }
+}
+
+static u32 t3, s5, s6;
+static u16 env[8];
+
+static void ENVSETUP1 (u32 inst1, u32 inst2) {
+ u32 tmp;
+
+ //fprintf (dfile, "ENVSETUP1: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
+ t3 = inst1 & 0xFFFF;
+ tmp = (inst1 >> 0x8) & 0xFF00;
+ env[4] = (u16)tmp;
+ tmp += t3;
+ env[5] = (u16)tmp;
+ s5 = inst2 >> 0x10;
+ s6 = inst2 & 0xFFFF;
+ //fprintf (dfile, " t3 = %X / s5 = %X / s6 = %X / env[4] = %X / env[5] = %X\n", t3, s5, s6, env[4], env[5]);
+}
+
+static void ENVSETUP2 (u32 inst1, u32 inst2) {
+ u32 tmp;
+
+ //fprintf (dfile, "ENVSETUP2: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
+ tmp = (inst2 >> 0x10);
+ env[0] = (u16)tmp;
+ tmp += s5;
+ env[1] = (u16)tmp;
+ tmp = inst2 & 0xffff;
+ env[2] = (u16)tmp;
+ tmp += s6;
+ env[3] = (u16)tmp;
+ //fprintf (dfile, " env[0] = %X / env[1] = %X / env[2] = %X / env[3] = %X\n", env[0], env[1], env[2], env[3]);
+}
+
+static void ENVMIXER2 (u32 inst1, u32 inst2) {
+ //fprintf (dfile, "ENVMIXER: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
+
+ s16 *bufft6, *bufft7, *buffs0, *buffs1;
+ s16 *buffs3;
+ s32 count;
+ u32 adder;
+
+ s16 vec9, vec10;
+
+ s16 v2[8];
+
+ buffs3 = (s16 *)(BufferSpace + ((inst1 >> 0x0c)&0x0ff0));
+ bufft6 = (s16 *)(BufferSpace + ((inst2 >> 0x14)&0x0ff0));
+ bufft7 = (s16 *)(BufferSpace + ((inst2 >> 0x0c)&0x0ff0));
+ buffs0 = (s16 *)(BufferSpace + ((inst2 >> 0x04)&0x0ff0));
+ buffs1 = (s16 *)(BufferSpace + ((inst2 << 0x04)&0x0ff0));
+
+
+ v2[0] = 0 - (s16)((inst1 & 0x2) >> 1);
+ v2[1] = 0 - (s16)((inst1 & 0x1));
+ v2[2] = 0 - (s16)((inst1 & 0x8) >> 1);
+ v2[3] = 0 - (s16)((inst1 & 0x4) >> 1);
+
+ count = (inst1 >> 8) & 0xff;
+
+ if (!isMKABI) {
+ s5 *= 2; s6 *= 2; t3 *= 2;
+ adder = 0x10;
+ } else {
+ inst1 = 0;
+ adder = 0x8;
+ t3 = 0;
+ }
+
+
+ while (count > 0) {
+ int temp, x;
+ for (x=0; x < 0x8; x++) {
+ vec9 = (s16)(((s32)buffs3[x^S] * (u32)env[0]) >> 0x10) ^ v2[0];
+ vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[2]) >> 0x10) ^ v2[1];
+ temp = bufft6[x^S] + vec9;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ bufft6[x^S] = temp;
+ temp = bufft7[x^S] + vec10;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ bufft7[x^S] = temp;
+ vec9 = (s16)(((s32)vec9 * (u32)env[4]) >> 0x10) ^ v2[2];
+ vec10 = (s16)(((s32)vec10 * (u32)env[4]) >> 0x10) ^ v2[3];
+ if (inst1 & 0x10) {
+ temp = buffs0[x^S] + vec10;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs0[x^S] = temp;
+ temp = buffs1[x^S] + vec9;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs1[x^S] = temp;
+ } else {
+ temp = buffs0[x^S] + vec9;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs0[x^S] = temp;
+ temp = buffs1[x^S] + vec10;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs1[x^S] = temp;
+ }
+ }
+
+ if (!isMKABI)
+ for (x=0x8; x < 0x10; x++) {
+ vec9 = (s16)(((s32)buffs3[x^S] * (u32)env[1]) >> 0x10) ^ v2[0];
+ vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[3]) >> 0x10) ^ v2[1];
+ temp = bufft6[x^S] + vec9;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ bufft6[x^S] = temp;
+ temp = bufft7[x^S] + vec10;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ bufft7[x^S] = temp;
+ vec9 = (s16)(((s32)vec9 * (u32)env[5]) >> 0x10) ^ v2[2];
+ vec10 = (s16)(((s32)vec10 * (u32)env[5]) >> 0x10) ^ v2[3];
+ if (inst1 & 0x10) {
+ temp = buffs0[x^S] + vec10;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs0[x^S] = temp;
+ temp = buffs1[x^S] + vec9;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs1[x^S] = temp;
+ } else {
+ temp = buffs0[x^S] + vec9;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs0[x^S] = temp;
+ temp = buffs1[x^S] + vec10;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ buffs1[x^S] = temp;
+ }
+ }
+ bufft6 += adder; bufft7 += adder;
+ buffs0 += adder; buffs1 += adder;
+ buffs3 += adder; count -= adder;
+ env[0] += (u16)s5; env[1] += (u16)s5;
+ env[2] += (u16)s6; env[3] += (u16)s6;
+ env[4] += (u16)t3; env[5] += (u16)t3;
+ }
+}
+
+static void DUPLICATE2(u32 inst1, u32 inst2) {
+ unsigned short Count = (inst1 >> 16) & 0xff;
+ unsigned short In = inst1&0xffff;
+ unsigned short Out = (inst2>>16);
+
+ unsigned short buff[64];
+
+ memcpy(buff,BufferSpace+In,128);
+
+ while(Count) {
+ memcpy(BufferSpace+Out,buff,128);
+ Out+=128;
+ Count--;
+ }
+}
+/*
+static void INTERL2 (u32 inst1, u32 inst2) { // Make your own...
+ short Count = inst1 & 0xffff;
+ unsigned short Out = inst2 & 0xffff;
+ unsigned short In = (inst2 >> 16);
+
+ short *src,*dst,tmp;
+ src=(short *)&BufferSpace[In];
+ dst=(short *)&BufferSpace[Out];
+ while(Count)
+ {
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ *(dst++)=*(src++);
+ src++;
+ Count-=8;
+ }
+}
+*/
+
+static void INTERL2 (u32 inst1, u32 inst2) {
+ short Count = inst1 & 0xffff;
+ unsigned short Out = inst2 & 0xffff;
+ unsigned short In = (inst2 >> 16);
+
+ unsigned char *src,*dst/*,tmp*/;
+ src=(unsigned char *)(BufferSpace);//[In];
+ dst=(unsigned char *)(BufferSpace);//[Out];
+ while(Count) {
+ *(short *)(dst+(Out^S8)) = *(short *)(src+(In^S8));
+ Out += 2;
+ In += 4;
+ Count--;
+ }
+}
+
+static void INTERLEAVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u32 inL, inR;
+ u16 *outbuff;
+ u16 *inSrcR;
+ u16 *inSrcL;
+ u16 Left, Right, Left2, Right2;
+ u32 count;
+ count = ((inst1 >> 12) & 0xFF0);
+ if (count == 0) {
+ outbuff = (u16 *)(AudioOutBuffer+BufferSpace);
+ count = AudioCount;
+ } else {
+ outbuff = (u16 *)((inst1&0xFFFF)+BufferSpace);
+ }
+
+ inR = inst2 & 0xFFFF;
+ inL = (inst2 >> 16) & 0xFFFF;
+
+ inSrcR = (u16 *)(BufferSpace+inR);
+ inSrcL = (u16 *)(BufferSpace+inL);
+
+ for (u32 x = 0; x < (count/4); x++) {
+ Left=*(inSrcL++);
+ Right=*(inSrcR++);
+ Left2=*(inSrcL++);
+ Right2=*(inSrcR++);
+
+#ifdef M64P_BIG_ENDIAN
+ *(outbuff++)=Right;
+ *(outbuff++)=Left;
+ *(outbuff++)=Right2;
+ *(outbuff++)=Left2;
+#else
+ *(outbuff++)=Right2;
+ *(outbuff++)=Left2;
+ *(outbuff++)=Right;
+ *(outbuff++)=Left;
+#endif
+ }
+}
+
+static void ADDMIXER (u32 inst1, u32 inst2) {
+ short Count = (inst1 >> 12) & 0x00ff0;
+ u16 InBuffer = (inst2 >> 16);
+ u16 OutBuffer = inst2 & 0xffff;
+
+ s16 *inp, *outp;
+ s32 temp;
+ inp = (s16 *)(BufferSpace + InBuffer);
+ outp = (s16 *)(BufferSpace + OutBuffer);
+ for (int cntr = 0; cntr < Count; cntr+=2) {
+ temp = *outp + *inp;
+ if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
+ *(outp++) = temp;
+ inp++;
+ }
+}
+
+static void HILOGAIN (u32 inst1, u32 inst2) {
+ u16 cnt = inst1 & 0xffff;
+ u16 out = (inst2 >> 16) & 0xffff;
+ s16 hi = (s16)((inst1 >> 4) & 0xf000);
+ u16 lo = (inst1 >> 20) & 0xf;
+ s16 *src;
+
+ src = (s16 *)(BufferSpace+out);
+ s32 tmp, val;
+
+ while(cnt) {
+ val = (s32)*src;
+ //tmp = ((val * (s32)hi) + ((u64)(val * lo) << 16) >> 16);
+ tmp = ((val * (s32)hi) >> 16) + (u32)(val * lo);
+ if ((s32)tmp > 32767) tmp = 32767;
+ else if ((s32)tmp < -32768) tmp = -32768;
+ *src = tmp;
+ src++;
+ cnt -= 2;
+ }
+}
+
+static void FILTER2 (u32 inst1, u32 inst2) {
+ static int cnt = 0;
+ static s16 *lutt6;
+ static s16 *lutt5;
+ u8 *save = (rsp.RDRAM+(inst2&0xFFFFFF));
+ u8 t4 = (u8)((inst1 >> 0x10) & 0xFF);
+ int x;
+
+ if (t4 > 1) { // Then set the cnt variable
+ cnt = (inst1 & 0xFFFF);
+ lutt6 = (s16 *)save;
+// memcpy (dmem+0xFE0, rsp.RDRAM+(inst2&0xFFFFFF), 0x10);
+ return;
+ }
+
+ if (t4 == 0) {
+// memcpy (dmem+0xFB0, rsp.RDRAM+(inst2&0xFFFFFF), 0x20);
+ lutt5 = (short *)(save+0x10);
+ }
+
+ lutt5 = (short *)(save+0x10);
+
+// lutt5 = (short *)(dmem + 0xFC0);
+// lutt6 = (short *)(dmem + 0xFE0);
+ for (x = 0; x < 8; x++) {
+ s32 a;
+ a = (lutt5[x] + lutt6[x]) >> 1;
+ lutt5[x] = lutt6[x] = (short)a;
+ }
+ short *inp1, *inp2;
+ s32 out1[8];
+ s16 outbuff[0x3c0], *outp;
+ u32 inPtr = (u32)(inst1&0xffff);
+ inp1 = (short *)(save);
+ outp = outbuff;
+ inp2 = (short *)(BufferSpace+inPtr);
+ for (x = 0; x < cnt; x+=0x10) {
+ out1[1] = inp1[0]*lutt6[6];
+ out1[1] += inp1[3]*lutt6[7];
+ out1[1] += inp1[2]*lutt6[4];
+ out1[1] += inp1[5]*lutt6[5];
+ out1[1] += inp1[4]*lutt6[2];
+ out1[1] += inp1[7]*lutt6[3];
+ out1[1] += inp1[6]*lutt6[0];
+ out1[1] += inp2[1]*lutt6[1]; // 1
+
+ out1[0] = inp1[3]*lutt6[6];
+ out1[0] += inp1[2]*lutt6[7];
+ out1[0] += inp1[5]*lutt6[4];
+ out1[0] += inp1[4]*lutt6[5];
+ out1[0] += inp1[7]*lutt6[2];
+ out1[0] += inp1[6]*lutt6[3];
+ out1[0] += inp2[1]*lutt6[0];
+ out1[0] += inp2[0]*lutt6[1];
+
+ out1[3] = inp1[2]*lutt6[6];
+ out1[3] += inp1[5]*lutt6[7];
+ out1[3] += inp1[4]*lutt6[4];
+ out1[3] += inp1[7]*lutt6[5];
+ out1[3] += inp1[6]*lutt6[2];
+ out1[3] += inp2[1]*lutt6[3];
+ out1[3] += inp2[0]*lutt6[0];
+ out1[3] += inp2[3]*lutt6[1];
+
+ out1[2] = inp1[5]*lutt6[6];
+ out1[2] += inp1[4]*lutt6[7];
+ out1[2] += inp1[7]*lutt6[4];
+ out1[2] += inp1[6]*lutt6[5];
+ out1[2] += inp2[1]*lutt6[2];
+ out1[2] += inp2[0]*lutt6[3];
+ out1[2] += inp2[3]*lutt6[0];
+ out1[2] += inp2[2]*lutt6[1];
+
+ out1[5] = inp1[4]*lutt6[6];
+ out1[5] += inp1[7]*lutt6[7];
+ out1[5] += inp1[6]*lutt6[4];
+ out1[5] += inp2[1]*lutt6[5];
+ out1[5] += inp2[0]*lutt6[2];
+ out1[5] += inp2[3]*lutt6[3];
+ out1[5] += inp2[2]*lutt6[0];
+ out1[5] += inp2[5]*lutt6[1];
+
+ out1[4] = inp1[7]*lutt6[6];
+ out1[4] += inp1[6]*lutt6[7];
+ out1[4] += inp2[1]*lutt6[4];
+ out1[4] += inp2[0]*lutt6[5];
+ out1[4] += inp2[3]*lutt6[2];
+ out1[4] += inp2[2]*lutt6[3];
+ out1[4] += inp2[5]*lutt6[0];
+ out1[4] += inp2[4]*lutt6[1];
+
+ out1[7] = inp1[6]*lutt6[6];
+ out1[7] += inp2[1]*lutt6[7];
+ out1[7] += inp2[0]*lutt6[4];
+ out1[7] += inp2[3]*lutt6[5];
+ out1[7] += inp2[2]*lutt6[2];
+ out1[7] += inp2[5]*lutt6[3];
+ out1[7] += inp2[4]*lutt6[0];
+ out1[7] += inp2[7]*lutt6[1];
+
+ out1[6] = inp2[1]*lutt6[6];
+ out1[6] += inp2[0]*lutt6[7];
+ out1[6] += inp2[3]*lutt6[4];
+ out1[6] += inp2[2]*lutt6[5];
+ out1[6] += inp2[5]*lutt6[2];
+ out1[6] += inp2[4]*lutt6[3];
+ out1[6] += inp2[7]*lutt6[0];
+ out1[6] += inp2[6]*lutt6[1];
+ outp[1] = /*CLAMP*/((out1[1]+0x4000) >> 0xF);
+ outp[0] = /*CLAMP*/((out1[0]+0x4000) >> 0xF);
+ outp[3] = /*CLAMP*/((out1[3]+0x4000) >> 0xF);
+ outp[2] = /*CLAMP*/((out1[2]+0x4000) >> 0xF);
+ outp[5] = /*CLAMP*/((out1[5]+0x4000) >> 0xF);
+ outp[4] = /*CLAMP*/((out1[4]+0x4000) >> 0xF);
+ outp[7] = /*CLAMP*/((out1[7]+0x4000) >> 0xF);
+ outp[6] = /*CLAMP*/((out1[6]+0x4000) >> 0xF);
+ inp1 = inp2;
+ inp2 += 8;
+ outp += 8;
+ }
+// memcpy (rsp.RDRAM+(inst2&0xFFFFFF), dmem+0xFB0, 0x20);
+ memcpy (save, inp2-8, 0x10);
+ memcpy (BufferSpace+(inst1&0xffff), outbuff, cnt);
+}
+
+static void SEGMENT2 (u32 inst1, u32 inst2) {
+ if (isZeldaABI) {
+ FILTER2 (inst1, inst2);
+ return;
+ }
+ if ((inst1 & 0xffffff) == 0) {
+ isMKABI = true;
+ //SEGMENTS[(inst2>>24)&0xf] = (inst2 & 0xffffff);
+ } else {
+ isMKABI = false;
+ isZeldaABI = true;
+ FILTER2 (inst1, inst2);
+ }
+}
+
+static void UNKNOWN (u32 inst1, u32 inst2) {
+}
+/*
+void (*ABI2[0x20])(void) = {
+ SPNOOP, ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2, SPNOOP, SEGMENT2,
+ SETBUFF2, SPNOOP, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,
+ SPNOOP, INTERL2, ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
+ SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP
+};*/
+
+extern "C" const acmd_callback_t ABI2[0x20] = {
+ SPNOOP , ADPCM2, CLEARBUFF2, UNKNOWN, ADDMIXER, RESAMPLE2, UNKNOWN, SEGMENT2,
+ SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,
+ SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
+ HILOGAIN , SPNOOP, DUPLICATE2 , UNKNOWN , SPNOOP , SPNOOP , SPNOOP , SPNOOP
+};
+/*
+void (*ABI2[0x20])(void) = {
+ SPNOOP , ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2 , SPNOOP , SEGMENT2,
+ SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, SPNOOP, SETLOOP2,
+ SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
+ SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP
+};*/
+/* NOTES:
+
+ FILTER/SEGMENT - Still needs to be finished up... add FILTER?
+ UNKNOWWN #27 - Is this worth doing? Looks like a pain in the ass just for WaveRace64
+*/
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - ucode3.cpp *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+# include <string.h>
+# include <stdio.h>
+
+extern "C" {
+ #include "m64p_types.h"
+ #include "hle.h"
+ #include "alist_internal.h"
+}
+
+/*
+static void SPNOOP (u32 inst1, u32 inst2) {
+ DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));
+}
+*/
+
+extern const u16 ResampleLUT [0x200];
+
+extern u32 loopval;
+
+extern s16 Env_Dry;
+extern s16 Env_Wet;
+extern s16 Vol_Left;
+extern s16 Vol_Right;
+extern s16 VolTrg_Left;
+extern s32 VolRamp_Left;
+//extern u16 VolRate_Left;
+extern s16 VolTrg_Right;
+extern s32 VolRamp_Right;
+//extern u16 VolRate_Right;
+
+
+extern short hleMixerWorkArea[256];
+extern u16 adpcmtable[0x88];
+
+extern u8 BufferSpace[0x10000];
+
+/*
+static void SETVOL3 (u32 inst1, u32 inst2) { // Swapped Rate_Left and Vol
+ u8 Flags = (u8)(inst1 >> 0x10);
+ if (Flags & 0x4) { // 288
+ if (Flags & 0x2) { // 290
+ VolTrg_Left = *(s16*)&inst1;
+ VolRamp_Left = *(s32*)&inst2;
+ } else {
+ VolTrg_Right = *(s16*)&inst1;
+ VolRamp_Right = *(s32*)&inst2;
+ }
+ } else {
+ Vol_Left = *(s16*)&inst1;
+ Env_Dry = (s16)(*(s32*)&inst2 >> 0x10);
+ Env_Wet = *(s16*)&inst2;
+ }
+}
+*/
+static void SETVOL3 (u32 inst1, u32 inst2) {
+ u8 Flags = (u8)(inst1 >> 0x10);
+ if (Flags & 0x4) { // 288
+ if (Flags & 0x2) { // 290
+ Vol_Left = (s16)inst1; // 0x50
+ Env_Dry = (s16)(inst2 >> 0x10); // 0x4E
+ Env_Wet = (s16)inst2; // 0x4C
+ } else {
+ VolTrg_Right = (s16)inst1; // 0x46
+ //VolRamp_Right = (u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
+ VolRamp_Right = (s32)inst2; // 0x48/0x4A
+ }
+ } else {
+ VolTrg_Left = (s16)inst1; // 0x40
+ VolRamp_Left = (s32)inst2; // 0x42/0x44
+ }
+}
+
+static void ENVMIXER3 (u32 inst1, u32 inst2) {
+ u8 flags = (u8)((inst1 >> 16) & 0xff);
+ u32 addy = (inst2 & 0xFFFFFF);
+
+ short *inp=(short *)(BufferSpace+0x4F0);
+ short *out=(short *)(BufferSpace+0x9D0);
+ short *aux1=(short *)(BufferSpace+0xB40);
+ short *aux2=(short *)(BufferSpace+0xCB0);
+ short *aux3=(short *)(BufferSpace+0xE20);
+ s32 MainR;
+ s32 MainL;
+ s32 AuxR;
+ s32 AuxL;
+ int i1,o1,a1,a2,a3;
+ //unsigned short AuxIncRate=1;
+ short zero[8];
+ memset(zero,0,16);
+
+ s32 LAdder, LAcc, LVol;
+ s32 RAdder, RAcc, RVol;
+ s16 RSig, LSig; // Most significant part of the Ramp Value
+ s16 Wet, Dry;
+ s16 LTrg, RTrg;
+
+ Vol_Right = (s16)inst1;
+
+ if (flags & A_INIT) {
+ LAdder = VolRamp_Left / 8;
+ LAcc = 0;
+ LVol = Vol_Left;
+ LSig = (s16)(VolRamp_Left >> 16);
+
+ RAdder = VolRamp_Right / 8;
+ RAcc = 0;
+ RVol = Vol_Right;
+ RSig = (s16)(VolRamp_Right >> 16);
+
+ Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
+ LTrg = VolTrg_Left; RTrg = VolTrg_Right; // Save Current Left/Right Targets
+ } else {
+ memcpy((u8 *)hleMixerWorkArea, rsp.RDRAM+addy, 80);
+ Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
+ Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
+ LTrg = *(s16 *)(hleMixerWorkArea + 4); // 4-5
+ RTrg = *(s16 *)(hleMixerWorkArea + 6); // 6-7
+ LAdder = *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
+ RAdder = *(s32 *)(hleMixerWorkArea + 10); // 10-11
+ LAcc = *(s32 *)(hleMixerWorkArea + 12); // 12-13
+ RAcc = *(s32 *)(hleMixerWorkArea + 14); // 14-15
+ LVol = *(s32 *)(hleMixerWorkArea + 16); // 16-17
+ RVol = *(s32 *)(hleMixerWorkArea + 18); // 18-19
+ LSig = *(s16 *)(hleMixerWorkArea + 20); // 20-21
+ RSig = *(s16 *)(hleMixerWorkArea + 22); // 22-23
+ //u32 test = *(s32 *)(hleMixerWorkArea + 24); // 22-23
+ //if (test != 0x13371337)
+ }
+
+
+ //if(!(flags&A_AUX)) {
+ // AuxIncRate=0;
+ // aux2=aux3=zero;
+ //}
+
+ for (int y = 0; y < (0x170/2); y++) {
+
+ // Left
+ LAcc += LAdder;
+ LVol += (LAcc >> 16);
+ LAcc &= 0xFFFF;
+
+ // Right
+ RAcc += RAdder;
+ RVol += (RAcc >> 16);
+ RAcc &= 0xFFFF;
+// ****************************************************************
+ // Clamp Left
+ if (LSig >= 0) { // VLT
+ if (LVol > LTrg) {
+ LVol = LTrg;
+ }
+ } else { // VGE
+ if (LVol < LTrg) {
+ LVol = LTrg;
+ }
+ }
+
+ // Clamp Right
+ if (RSig >= 0) { // VLT
+ if (RVol > RTrg) {
+ RVol = RTrg;
+ }
+ } else { // VGE
+ if (RVol < RTrg) {
+ RVol = RTrg;
+ }
+ }
+// ****************************************************************
+ MainL = ((Dry * LVol) + 0x4000) >> 15;
+ MainR = ((Dry * RVol) + 0x4000) >> 15;
+
+ o1 = out [y^S];
+ a1 = aux1[y^S];
+ i1 = inp [y^S];
+
+ o1+=((i1*MainL)+0x4000)>>15;
+ a1+=((i1*MainR)+0x4000)>>15;
+
+// ****************************************************************
+
+ if(o1>32767) o1=32767;
+ else if(o1<-32768) o1=-32768;
+
+ if(a1>32767) a1=32767;
+ else if(a1<-32768) a1=-32768;
+
+// ****************************************************************
+
+ out[y^S]=o1;
+ aux1[y^S]=a1;
+
+// ****************************************************************
+ //if (!(flags&A_AUX)) {
+ a2 = aux2[y^S];
+ a3 = aux3[y^S];
+
+ AuxL = ((Wet * LVol) + 0x4000) >> 15;
+ AuxR = ((Wet * RVol) + 0x4000) >> 15;
+
+ a2+=((i1*AuxL)+0x4000)>>15;
+ a3+=((i1*AuxR)+0x4000)>>15;
+
+ if(a2>32767) a2=32767;
+ else if(a2<-32768) a2=-32768;
+
+ if(a3>32767) a3=32767;
+ else if(a3<-32768) a3=-32768;
+
+ aux2[y^S]=a2;
+ aux3[y^S]=a3;
+ }
+ //}
+
+ *(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
+ *(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
+ *(s16 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
+ *(s16 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
+ *(s32 *)(hleMixerWorkArea + 8) = LAdder; // 8-9 (hleMixerWorkArea is a 16bit pointer)
+ *(s32 *)(hleMixerWorkArea + 10) = RAdder; // 10-11
+ *(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13
+ *(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15
+ *(s32 *)(hleMixerWorkArea + 16) = LVol; // 16-17
+ *(s32 *)(hleMixerWorkArea + 18) = RVol; // 18-19
+ *(s16 *)(hleMixerWorkArea + 20) = LSig; // 20-21
+ *(s16 *)(hleMixerWorkArea + 22) = RSig; // 22-23
+ //*(u32 *)(hleMixerWorkArea + 24) = 0x13371337; // 22-23
+ memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
+}
+
+static void CLEARBUFF3 (u32 inst1, u32 inst2) {
+ u16 addr = (u16)(inst1 & 0xffff);
+ u16 count = (u16)(inst2 & 0xffff);
+ memset(BufferSpace+addr+0x4f0, 0, count);
+}
+
+static void MIXER3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u16 dmemin = (u16)(inst2 >> 0x10) + 0x4f0;
+ u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0;
+ //u8 flags = (u8)((inst1 >> 16) & 0xff);
+ s32 gain = (s16)(inst1 & 0xFFFF);
+ s32 temp;
+
+ for (int x=0; x < 0x170; x+=2) { // I think I can do this a lot easier
+ temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
+ temp += *(s16 *)(BufferSpace+dmemout+x);
+
+ if ((s32)temp > 32767)
+ temp = 32767;
+ if ((s32)temp < -32768)
+ temp = -32768;
+
+ *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
+ }
+}
+
+static void LOADBUFF3 (u32 inst1, u32 inst2) {
+ u32 v0;
+ u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
+ v0 = (inst2 & 0xfffffc);
+ u32 src = (inst1&0xffc)+0x4f0;
+ memcpy (BufferSpace+src, rsp.RDRAM+v0, cnt);
+}
+
+static void SAVEBUFF3 (u32 inst1, u32 inst2) {
+ u32 v0;
+ u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
+ v0 = (inst2 & 0xfffffc);
+ u32 src = (inst1&0xffc)+0x4f0;
+ memcpy (rsp.RDRAM+v0, BufferSpace+src, cnt);
+}
+
+static void LOADADPCM3 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
+ u32 v0;
+ v0 = (inst2 & 0xffffff);
+ //memcpy (dmem+0x3f0, rsp.RDRAM+v0, inst1&0xffff);
+ //assert ((inst1&0xffff) <= 0x80);
+ u16 *table = (u16 *)(rsp.RDRAM+v0);
+ for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
+ adpcmtable[(0x0+(x<<3))^S] = table[0];
+ adpcmtable[(0x1+(x<<3))^S] = table[1];
+
+ adpcmtable[(0x2+(x<<3))^S] = table[2];
+ adpcmtable[(0x3+(x<<3))^S] = table[3];
+
+ adpcmtable[(0x4+(x<<3))^S] = table[4];
+ adpcmtable[(0x5+(x<<3))^S] = table[5];
+
+ adpcmtable[(0x6+(x<<3))^S] = table[6];
+ adpcmtable[(0x7+(x<<3))^S] = table[7];
+ table += 8;
+ }
+}
+
+static void DMEMMOVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ u32 v0, v1;
+ u32 cnt;
+ v0 = (inst1 & 0xFFFF) + 0x4f0;
+ v1 = (inst2 >> 0x10) + 0x4f0;
+ u32 count = ((inst2+3) & 0xfffc);
+
+ //memcpy (dmem+v1, dmem+v0, count-1);
+ for (cnt = 0; cnt < count; cnt++) {
+ *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
+ }
+}
+
+static void SETLOOP3 (u32 inst1, u32 inst2) {
+ loopval = (inst2 & 0xffffff);
+}
+
+static void ADPCM3 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...
+ unsigned char Flags=(u8)(inst2>>0x1c)&0xff;
+ //unsigned short Gain=(u16)(inst1&0xffff);
+ unsigned int Address=(inst1 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
+ unsigned short inPtr=(inst2>>12)&0xf;
+ //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
+ short *out=(short *)(BufferSpace+(inst2&0xfff)+0x4f0);
+ //unsigned char *in=(unsigned char *)(BufferSpace+((inst2>>12)&0xf)+0x4f0);
+ short count=(short)((inst2 >> 16)&0xfff);
+ unsigned char icode;
+ unsigned char code;
+ int vscale;
+ unsigned short index;
+ unsigned short j;
+ int a[8];
+ short *book1,*book2;
+
+ memset(out,0,32);
+
+ if(!(Flags&0x1))
+ {
+ if(Flags&0x2)
+ {/*
+ for(int i=0;i<16;i++)
+ {
+ out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
+ }*/
+ memcpy(out,&rsp.RDRAM[loopval],32);
+ }
+ else
+ {/*
+ for(int i=0;i<16;i++)
+ {
+ out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
+ }*/
+ memcpy(out,&rsp.RDRAM[Address],32);
+ }
+ }
+
+ int l1=out[14^S];
+ int l2=out[15^S];
+ int inp1[8];
+ int inp2[8];
+ out+=16;
+ while(count>0)
+ {
+ // the first interation through, these values are
+ // either 0 in the case of A_INIT, from a special
+ // area of memory in the case of A_LOOP or just
+ // the values we calculated the last time
+
+ code=BufferSpace[(0x4f0+inPtr)^S8];
+ index=code&0xf;
+ index<<=4; // index into the adpcm code table
+ book1=(short *)&adpcmtable[index];
+ book2=book1+8;
+ code>>=4; // upper nibble is scale
+ vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format
+ // so this appears to be a fractional scale based
+ // on the 12 based inverse of the scale value. note
+ // that this could be negative, in which case we do
+ // not use the calculated vscale value... see the
+ // if(code>12) check below
+
+ inPtr++; // coded adpcm data lies next
+ j=0;
+ while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes
+ // which yields 8 short pcm values
+ {
+ icode=BufferSpace[(0x4f0+inPtr)^S8];
+ inPtr++;
+
+ inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed
+ if(code<12)
+ inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+
+ inp1[j]=(s16)((icode&0xf)<<12);
+ if(code<12)
+ inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+ }
+ j=0;
+ while(j<8)
+ {
+ icode=BufferSpace[(0x4f0+inPtr)^S8];
+ inPtr++;
+
+ inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed
+ if(code<12)
+ inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+
+ inp2[j]=(short)((icode&0xf)<<12);
+ if(code<12)
+ inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
+ /*else
+ int catchme=1;*/
+ j++;
+ }
+
+ a[0]= (int)book1[0]*(int)l1;
+ a[0]+=(int)book2[0]*(int)l2;
+ a[0]+=(int)inp1[0]*(int)2048;
+
+ a[1] =(int)book1[1]*(int)l1;
+ a[1]+=(int)book2[1]*(int)l2;
+ a[1]+=(int)book2[0]*inp1[0];
+ a[1]+=(int)inp1[1]*(int)2048;
+
+ a[2] =(int)book1[2]*(int)l1;
+ a[2]+=(int)book2[2]*(int)l2;
+ a[2]+=(int)book2[1]*inp1[0];
+ a[2]+=(int)book2[0]*inp1[1];
+ a[2]+=(int)inp1[2]*(int)2048;
+
+ a[3] =(int)book1[3]*(int)l1;
+ a[3]+=(int)book2[3]*(int)l2;
+ a[3]+=(int)book2[2]*inp1[0];
+ a[3]+=(int)book2[1]*inp1[1];
+ a[3]+=(int)book2[0]*inp1[2];
+ a[3]+=(int)inp1[3]*(int)2048;
+
+ a[4] =(int)book1[4]*(int)l1;
+ a[4]+=(int)book2[4]*(int)l2;
+ a[4]+=(int)book2[3]*inp1[0];
+ a[4]+=(int)book2[2]*inp1[1];
+ a[4]+=(int)book2[1]*inp1[2];
+ a[4]+=(int)book2[0]*inp1[3];
+ a[4]+=(int)inp1[4]*(int)2048;
+
+ a[5] =(int)book1[5]*(int)l1;
+ a[5]+=(int)book2[5]*(int)l2;
+ a[5]+=(int)book2[4]*inp1[0];
+ a[5]+=(int)book2[3]*inp1[1];
+ a[5]+=(int)book2[2]*inp1[2];
+ a[5]+=(int)book2[1]*inp1[3];
+ a[5]+=(int)book2[0]*inp1[4];
+ a[5]+=(int)inp1[5]*(int)2048;
+
+ a[6] =(int)book1[6]*(int)l1;
+ a[6]+=(int)book2[6]*(int)l2;
+ a[6]+=(int)book2[5]*inp1[0];
+ a[6]+=(int)book2[4]*inp1[1];
+ a[6]+=(int)book2[3]*inp1[2];
+ a[6]+=(int)book2[2]*inp1[3];
+ a[6]+=(int)book2[1]*inp1[4];
+ a[6]+=(int)book2[0]*inp1[5];
+ a[6]+=(int)inp1[6]*(int)2048;
+
+ a[7] =(int)book1[7]*(int)l1;
+ a[7]+=(int)book2[7]*(int)l2;
+ a[7]+=(int)book2[6]*inp1[0];
+ a[7]+=(int)book2[5]*inp1[1];
+ a[7]+=(int)book2[4]*inp1[2];
+ a[7]+=(int)book2[3]*inp1[3];
+ a[7]+=(int)book2[2]*inp1[4];
+ a[7]+=(int)book2[1]*inp1[5];
+ a[7]+=(int)book2[0]*inp1[6];
+ a[7]+=(int)inp1[7]*(int)2048;
+
+ for(j=0;j<8;j++)
+ {
+ a[j^S]>>=11;
+ if(a[j^S]>32767) a[j^S]=32767;
+ else if(a[j^S]<-32768) a[j^S]=-32768;
+ *(out++)=a[j^S];
+ //*(out+j)=a[j^S];
+ }
+ //out += 0x10;
+ l1=a[6];
+ l2=a[7];
+
+ a[0]= (int)book1[0]*(int)l1;
+ a[0]+=(int)book2[0]*(int)l2;
+ a[0]+=(int)inp2[0]*(int)2048;
+
+ a[1] =(int)book1[1]*(int)l1;
+ a[1]+=(int)book2[1]*(int)l2;
+ a[1]+=(int)book2[0]*inp2[0];
+ a[1]+=(int)inp2[1]*(int)2048;
+
+ a[2] =(int)book1[2]*(int)l1;
+ a[2]+=(int)book2[2]*(int)l2;
+ a[2]+=(int)book2[1]*inp2[0];
+ a[2]+=(int)book2[0]*inp2[1];
+ a[2]+=(int)inp2[2]*(int)2048;
+
+ a[3] =(int)book1[3]*(int)l1;
+ a[3]+=(int)book2[3]*(int)l2;
+ a[3]+=(int)book2[2]*inp2[0];
+ a[3]+=(int)book2[1]*inp2[1];
+ a[3]+=(int)book2[0]*inp2[2];
+ a[3]+=(int)inp2[3]*(int)2048;
+
+ a[4] =(int)book1[4]*(int)l1;
+ a[4]+=(int)book2[4]*(int)l2;
+ a[4]+=(int)book2[3]*inp2[0];
+ a[4]+=(int)book2[2]*inp2[1];
+ a[4]+=(int)book2[1]*inp2[2];
+ a[4]+=(int)book2[0]*inp2[3];
+ a[4]+=(int)inp2[4]*(int)2048;
+
+ a[5] =(int)book1[5]*(int)l1;
+ a[5]+=(int)book2[5]*(int)l2;
+ a[5]+=(int)book2[4]*inp2[0];
+ a[5]+=(int)book2[3]*inp2[1];
+ a[5]+=(int)book2[2]*inp2[2];
+ a[5]+=(int)book2[1]*inp2[3];
+ a[5]+=(int)book2[0]*inp2[4];
+ a[5]+=(int)inp2[5]*(int)2048;
+
+ a[6] =(int)book1[6]*(int)l1;
+ a[6]+=(int)book2[6]*(int)l2;
+ a[6]+=(int)book2[5]*inp2[0];
+ a[6]+=(int)book2[4]*inp2[1];
+ a[6]+=(int)book2[3]*inp2[2];
+ a[6]+=(int)book2[2]*inp2[3];
+ a[6]+=(int)book2[1]*inp2[4];
+ a[6]+=(int)book2[0]*inp2[5];
+ a[6]+=(int)inp2[6]*(int)2048;
+
+ a[7] =(int)book1[7]*(int)l1;
+ a[7]+=(int)book2[7]*(int)l2;
+ a[7]+=(int)book2[6]*inp2[0];
+ a[7]+=(int)book2[5]*inp2[1];
+ a[7]+=(int)book2[4]*inp2[2];
+ a[7]+=(int)book2[3]*inp2[3];
+ a[7]+=(int)book2[2]*inp2[4];
+ a[7]+=(int)book2[1]*inp2[5];
+ a[7]+=(int)book2[0]*inp2[6];
+ a[7]+=(int)inp2[7]*(int)2048;
+
+ for(j=0;j<8;j++)
+ {
+ a[j^S]>>=11;
+ if(a[j^S]>32767) a[j^S]=32767;
+ else if(a[j^S]<-32768) a[j^S]=-32768;
+ *(out++)=a[j^S];
+ //*(out+j+0x1f8)=a[j^S];
+ }
+ l1=a[6];
+ l2=a[7];
+
+ count-=32;
+ }
+ out-=16;
+ memcpy(&rsp.RDRAM[Address],out,32);
+}
+
+static void RESAMPLE3 (u32 inst1, u32 inst2) {
+ unsigned char Flags=(u8)((inst2>>0x1e));
+ unsigned int Pitch=((inst2>>0xe)&0xffff)<<1;
+ u32 addy = (inst1 & 0xffffff);
+ unsigned int Accum=0;
+ unsigned int location;
+ s16 *lut;
+ short *dst;
+ s16 *src;
+ dst=(short *)(BufferSpace);
+ src=(s16 *)(BufferSpace);
+ u32 srcPtr=((((inst2>>2)&0xfff)+0x4f0)/2);
+ u32 dstPtr;//=(AudioOutBuffer/2);
+ s32 temp;
+ s32 accum;
+
+ //if (addy > (1024*1024*8))
+ // addy = (inst2 & 0xffffff);
+
+ srcPtr -= 4;
+
+ if (inst2 & 0x3) {
+ dstPtr = 0x660/2;
+ } else {
+ dstPtr = 0x4f0/2;
+ }
+
+ if ((Flags & 0x1) == 0) {
+ for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
+ src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
+ Accum = *(u16 *)(rsp.RDRAM+addy+10);
+ } else {
+ for (int x=0; x < 4; x++)
+ src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
+ }
+
+ for(int i=0;i < 0x170/2;i++) {
+ location = (((Accum * 0x40) >> 0x10) * 8);
+ //location = (Accum >> 0xa) << 0x3;
+ lut = (s16 *)(((u8 *)ResampleLUT) + location);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
+ accum = (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
+ accum += (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
+ accum += (s32)(temp >> 15);
+
+ temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
+ accum += (s32)(temp >> 15);
+/* temp = ((s64)*(s16*)(src+((srcPtr+0)^S))*((s64)((s16)lut[0]<<1)));
+ if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
+ else temp = (temp^0x8000);
+ temp = (s32)(temp >> 16);
+ if ((s32)temp > 32767) temp = 32767;
+ if ((s32)temp < -32768) temp = -32768;
+ accum = (s32)(s16)temp;
+
+ temp = ((s64)*(s16*)(src+((srcPtr+1)^S))*((s64)((s16)lut[1]<<1)));
+ if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
+ else temp = (temp^0x8000);
+ temp = (s32)(temp >> 16);
+ if ((s32)temp > 32767) temp = 32767;
+ if ((s32)temp < -32768) temp = -32768;
+ accum += (s32)(s16)temp;
+
+ temp = ((s64)*(s16*)(src+((srcPtr+2)^S))*((s64)((s16)lut[2]<<1)));
+ if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
+ else temp = (temp^0x8000);
+ temp = (s32)(temp >> 16);
+ if ((s32)temp > 32767) temp = 32767;
+ if ((s32)temp < -32768) temp = -32768;
+ accum += (s32)(s16)temp;
+
+ temp = ((s64)*(s16*)(src+((srcPtr+3)^S))*((s64)((s16)lut[3]<<1)));
+ if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
+ else temp = (temp^0x8000);
+ temp = (s32)(temp >> 16);
+ if ((s32)temp > 32767) temp = 32767;
+ if ((s32)temp < -32768) temp = -32768;
+ accum += (s32)(s16)temp;*/
+
+ if (accum > 32767) accum = 32767;
+ if (accum < -32768) accum = -32768;
+
+ dst[dstPtr^S] = (accum);
+ dstPtr++;
+ Accum += Pitch;
+ srcPtr += (Accum>>16);
+ Accum&=0xffff;
+ }
+ for (int x=0; x < 4; x++)
+ ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
+ *(u16 *)(rsp.RDRAM+addy+10) = Accum;
+}
+
+static void INTERLEAVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
+ //u32 inL, inR;
+ u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem);
+ u16 *inSrcR;
+ u16 *inSrcL;
+ u16 Left, Right, Left2, Right2;
+
+ //inR = inst2 & 0xFFFF;
+ //inL = (inst2 >> 16) & 0xFFFF;
+
+ inSrcR = (u16 *)(BufferSpace+0xb40);
+ inSrcL = (u16 *)(BufferSpace+0x9d0);
+
+ for (int x = 0; x < (0x170/4); x++) {
+ Left=*(inSrcL++);
+ Right=*(inSrcR++);
+ Left2=*(inSrcL++);
+ Right2=*(inSrcR++);
+
+#ifdef M64P_BIG_ENDIAN
+ *(outbuff++)=Right;
+ *(outbuff++)=Left;
+ *(outbuff++)=Right2;
+ *(outbuff++)=Left2;
+#else
+ *(outbuff++)=Right2;
+ *(outbuff++)=Left2;
+ *(outbuff++)=Right;
+ *(outbuff++)=Left;
+#endif
+/*
+ Left=*(inSrcL++);
+ Right=*(inSrcR++);
+ *(outbuff++)=(u16)Left;
+ Left >>= 16;
+ *(outbuff++)=(u16)Right;
+ Right >>= 16;
+ *(outbuff++)=(u16)Left;
+ *(outbuff++)=(u16)Right;*/
+ }
+}
+
+//static void UNKNOWN (u32 inst1, u32 inst2);
+/*
+typedef struct {
+ unsigned char sync;
+
+ unsigned char error_protection : 1; // 0=yes, 1=no
+ unsigned char lay : 2; // 4-lay = layerI, II or III
+ unsigned char version : 1; // 3=mpeg 1.0, 2=mpeg 2.5 0=mpeg 2.0
+ unsigned char sync2 : 4;
+
+ unsigned char extension : 1; // Unknown
+ unsigned char padding : 1; // padding
+ unsigned char sampling_freq : 2; // see table below
+ unsigned char bitrate_index : 4; // see table below
+
+ unsigned char emphasis : 2; //see table below
+ unsigned char original : 1; // 0=no 1=yes
+ unsigned char copyright : 1; // 0=no 1=yes
+ unsigned char mode_ext : 2; // used with "joint stereo" mode
+ unsigned char mode : 2; // Channel Mode
+} mp3struct;
+
+mp3struct mp3;
+FILE *mp3dat;
+*/
+
+static void WHATISTHIS (u32 inst1, u32 inst2) {
+}
+
+//static FILE *fp = fopen ("d:\\mp3info.txt", "wt");
+u32 setaddr;
+static void MP3ADDY (u32 inst1, u32 inst2) {
+ setaddr = (inst2 & 0xffffff);
+}
+
+extern "C" {
+ void rsp_run(void);
+ void mp3setup (unsigned int inst1, unsigned int inst2, unsigned int t8);
+}
+
+extern u32 base, dmembase;
+extern "C" {
+ extern char *pDMEM;
+}
+void MP3 (u32 inst1, u32 inst2);
+/*
+ {
+// return;
+ // Setup Registers...
+ mp3setup (inst1, inst2, 0xFA0);
+
+ // Setup Memory Locations...
+ //u32 base = ((u32*)dmem)[0xFD0/4]; // Should be 000291A0
+ memcpy (BufferSpace, dmembase+rsp.RDRAM, 0x10);
+ ((u32*)BufferSpace)[0x0] = base;
+ ((u32*)BufferSpace)[0x008/4] += base;
+ ((u32*)BufferSpace)[0xFFC/4] = loopval;
+ ((u32*)BufferSpace)[0xFF8/4] = dmembase;
+
+ memcpy (imem+0x238, rsp.RDRAM+((u32*)BufferSpace)[0x008/4], 0x9C0);
+ ((u32*)BufferSpace)[0xFF4/4] = setaddr;
+ pDMEM = (char *)BufferSpace;
+ rsp_run (void);
+ dmembase = ((u32*)BufferSpace)[0xFF8/4];
+ loopval = ((u32*)BufferSpace)[0xFFC/4];
+//0x1A98 SW S1, 0x0FF4 (R0)
+//0x1A9C SW S0, 0x0FF8 (R0)
+//0x1AA0 SW T7, 0x0FFC (R0)
+//0x1AA4 SW T3, 0x0FF0 (R0)
+ //fprintf (fp, "mp3: inst1: %08X, inst2: %08X\n", inst1, inst2);
+}*/
+/*
+FFT = Fast Fourier Transform
+DCT = Discrete Cosine Transform
+MPEG-1 Layer 3 retains Layer 2's 1152-sample window, as well as the FFT polyphase filter for
+backward compatibility, but adds a modified DCT filter. DCT's advantages over DFTs (discrete
+Fourier transforms) include half as many multiply-accumulate operations and half the
+generated coefficients because the sinusoidal portion of the calculation is absent, and DCT
+generally involves simpler math. The finite lengths of a conventional DCTs' bandpass impulse
+responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks
+and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also
+have a higher transform coding gain than the standard DCT, and their basic functions
+correspond to better bandpass response.
+
+MPEG-1 Layer 3's DCT sub-bands are unequally sized, and correspond to the human auditory
+system's critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate
+bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally,
+Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for
+additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates
+achieve near-CD quality, an important specification to enable dual-channel ISDN
+(integrated-services-digital-network) to be the future high-bandwidth pipe to the home.
+
+*/
+static void DISABLE (u32 inst1, u32 inst2) {
+ //MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK);
+ //ChangeABI (5);
+}
+
+
+extern "C" const acmd_callback_t ABI3[0x10] = {
+ DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3,
+ MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3
+};
+
+
--- /dev/null
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Mupen64plus-rsp-hle - ucode3mp3.h *
+ * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
+ * Copyright (C) 2009 Richard Goedeken *
+ * Copyright (C) 2002 Hacktarux *
+ * *
+ * 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., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+# include <string.h>
+# include <stdio.h>
+
+extern "C" {
+ #include "hle.h"
+ #include "alist_internal.h"
+}
+
+static const u16 DeWindowLUT [0x420] = {
+ 0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E,
+ 0x7FFF, 0x3FF2, 0x0B37, 0x08CA, 0x037A, 0x00C8, 0x005D, 0x000D,
+ 0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E,
+ 0x7FFF, 0x3FF2, 0x0B37, 0x08CA, 0x037A, 0x00C8, 0x005D, 0x000D,
+ 0x0000, 0xFFF2, 0x005F, 0xFF1D, 0x0369, 0xF697, 0x0A2A, 0xBCE7,
+ 0x7FEB, 0x3CCB, 0x0C2B, 0x082B, 0x0385, 0x00AF, 0x005B, 0x000B,
+ 0x0000, 0xFFF2, 0x005F, 0xFF1D, 0x0369, 0xF697, 0x0A2A, 0xBCE7,
+ 0x7FEB, 0x3CCB, 0x0C2B, 0x082B, 0x0385, 0x00AF, 0x005B, 0x000B,
+ 0x0000, 0xFFF1, 0x0061, 0xFF02, 0x0354, 0xF5F9, 0x0905, 0xB9C4,
+ 0x7FB0, 0x39A4, 0x0D08, 0x078C, 0x038C, 0x0098, 0x0058, 0x000A,
+ 0x0000, 0xFFF1, 0x0061, 0xFF02, 0x0354, 0xF5F9, 0x0905, 0xB9C4,
+ 0x7FB0, 0x39A4, 0x0D08, 0x078C, 0x038C, 0x0098, 0x0058, 0x000A,
+ 0x0000, 0xFFEF, 0x0062, 0xFEE6, 0x033B, 0xF55C, 0x07C8, 0xB6A4,
+ 0x7F4D, 0x367E, 0x0DCE, 0x06EE, 0x038F, 0x0080, 0x0056, 0x0009,
+ 0x0000, 0xFFEF, 0x0062, 0xFEE6, 0x033B, 0xF55C, 0x07C8, 0xB6A4,
+ 0x7F4D, 0x367E, 0x0DCE, 0x06EE, 0x038F, 0x0080, 0x0056, 0x0009,
+ 0x0000, 0xFFEE, 0x0063, 0xFECA, 0x031C, 0xF4C3, 0x0671, 0xB38C,
+ 0x7EC2, 0x335D, 0x0E7C, 0x0652, 0x038E, 0x006B, 0x0053, 0x0008,
+ 0x0000, 0xFFEE, 0x0063, 0xFECA, 0x031C, 0xF4C3, 0x0671, 0xB38C,
+ 0x7EC2, 0x335D, 0x0E7C, 0x0652, 0x038E, 0x006B, 0x0053, 0x0008,
+ 0x0000, 0xFFEC, 0x0064, 0xFEAC, 0x02F7, 0xF42C, 0x0502, 0xB07C,
+ 0x7E12, 0x3041, 0x0F14, 0x05B7, 0x038A, 0x0056, 0x0050, 0x0007,
+ 0x0000, 0xFFEC, 0x0064, 0xFEAC, 0x02F7, 0xF42C, 0x0502, 0xB07C,
+ 0x7E12, 0x3041, 0x0F14, 0x05B7, 0x038A, 0x0056, 0x0050, 0x0007,
+ 0x0000, 0xFFEB, 0x0064, 0xFE8E, 0x02CE, 0xF399, 0x037A, 0xAD75,
+ 0x7D3A, 0x2D2C, 0x0F97, 0x0520, 0x0382, 0x0043, 0x004D, 0x0007,
+ 0x0000, 0xFFEB, 0x0064, 0xFE8E, 0x02CE, 0xF399, 0x037A, 0xAD75,
+ 0x7D3A, 0x2D2C, 0x0F97, 0x0520, 0x0382, 0x0043, 0x004D, 0x0007,
+ 0xFFFF, 0xFFE9, 0x0063, 0xFE6F, 0x029E, 0xF30B, 0x01D8, 0xAA7B,
+ 0x7C3D, 0x2A1F, 0x1004, 0x048B, 0x0377, 0x0030, 0x004A, 0x0006,
+ 0xFFFF, 0xFFE9, 0x0063, 0xFE6F, 0x029E, 0xF30B, 0x01D8, 0xAA7B,
+ 0x7C3D, 0x2A1F, 0x1004, 0x048B, 0x0377, 0x0030, 0x004A, 0x0006,
+ 0xFFFF, 0xFFE7, 0x0062, 0xFE4F, 0x0269, 0xF282, 0x001F, 0xA78D,
+ 0x7B1A, 0x271C, 0x105D, 0x03F9, 0x036A, 0x001F, 0x0046, 0x0006,
+ 0xFFFF, 0xFFE7, 0x0062, 0xFE4F, 0x0269, 0xF282, 0x001F, 0xA78D,
+ 0x7B1A, 0x271C, 0x105D, 0x03F9, 0x036A, 0x001F, 0x0046, 0x0006,
+ 0xFFFF, 0xFFE4, 0x0061, 0xFE2F, 0x022F, 0xF1FF, 0xFE4C, 0xA4AF,
+ 0x79D3, 0x2425, 0x10A2, 0x036C, 0x0359, 0x0010, 0x0043, 0x0005,
+ 0xFFFF, 0xFFE4, 0x0061, 0xFE2F, 0x022F, 0xF1FF, 0xFE4C, 0xA4AF,
+ 0x79D3, 0x2425, 0x10A2, 0x036C, 0x0359, 0x0010, 0x0043, 0x0005,
+ 0xFFFF, 0xFFE2, 0x005E, 0xFE10, 0x01EE, 0xF184, 0xFC61, 0xA1E1,
+ 0x7869, 0x2139, 0x10D3, 0x02E3, 0x0346, 0x0001, 0x0040, 0x0004,
+ 0xFFFF, 0xFFE2, 0x005E, 0xFE10, 0x01EE, 0xF184, 0xFC61, 0xA1E1,
+ 0x7869, 0x2139, 0x10D3, 0x02E3, 0x0346, 0x0001, 0x0040, 0x0004,
+ 0xFFFF, 0xFFE0, 0x005B, 0xFDF0, 0x01A8, 0xF111, 0xFA5F, 0x9F27,
+ 0x76DB, 0x1E5C, 0x10F2, 0x025E, 0x0331, 0xFFF3, 0x003D, 0x0004,
+ 0xFFFF, 0xFFE0, 0x005B, 0xFDF0, 0x01A8, 0xF111, 0xFA5F, 0x9F27,
+ 0x76DB, 0x1E5C, 0x10F2, 0x025E, 0x0331, 0xFFF3, 0x003D, 0x0004,
+ 0xFFFF, 0xFFDE, 0x0057, 0xFDD0, 0x015B, 0xF0A7, 0xF845, 0x9C80,
+ 0x752C, 0x1B8E, 0x1100, 0x01DE, 0x0319, 0xFFE7, 0x003A, 0x0003,
+ 0xFFFF, 0xFFDE, 0x0057, 0xFDD0, 0x015B, 0xF0A7, 0xF845, 0x9C80,
+ 0x752C, 0x1B8E, 0x1100, 0x01DE, 0x0319, 0xFFE7, 0x003A, 0x0003,
+ 0xFFFE, 0xFFDB, 0x0053, 0xFDB0, 0x0108, 0xF046, 0xF613, 0x99EE,
+ 0x735C, 0x18D1, 0x10FD, 0x0163, 0x0300, 0xFFDC, 0x0037, 0x0003,
+ 0xFFFE, 0xFFDB, 0x0053, 0xFDB0, 0x0108, 0xF046, 0xF613, 0x99EE,
+ 0x735C, 0x18D1, 0x10FD, 0x0163, 0x0300, 0xFFDC, 0x0037, 0x0003,
+ 0xFFFE, 0xFFD8, 0x004D, 0xFD90, 0x00B0, 0xEFF0, 0xF3CC, 0x9775,
+ 0x716C, 0x1624, 0x10EA, 0x00EE, 0x02E5, 0xFFD2, 0x0033, 0x0003,
+ 0xFFFE, 0xFFD8, 0x004D, 0xFD90, 0x00B0, 0xEFF0, 0xF3CC, 0x9775,
+ 0x716C, 0x1624, 0x10EA, 0x00EE, 0x02E5, 0xFFD2, 0x0033, 0x0003,
+ 0xFFFE, 0xFFD6, 0x0047, 0xFD72, 0x0051, 0xEFA6, 0xF16F, 0x9514,
+ 0x6F5E, 0x138A, 0x10C8, 0x007E, 0x02CA, 0xFFC9, 0x0030, 0x0003,
+ 0xFFFE, 0xFFD6, 0x0047, 0xFD72, 0x0051, 0xEFA6, 0xF16F, 0x9514,
+ 0x6F5E, 0x138A, 0x10C8, 0x007E, 0x02CA, 0xFFC9, 0x0030, 0x0003,
+ 0xFFFE, 0xFFD3, 0x0040, 0xFD54, 0xFFEC, 0xEF68, 0xEEFC, 0x92CD,
+ 0x6D33, 0x1104, 0x1098, 0x0014, 0x02AC, 0xFFC0, 0x002D, 0x0002,
+ 0xFFFE, 0xFFD3, 0x0040, 0xFD54, 0xFFEC, 0xEF68, 0xEEFC, 0x92CD,
+ 0x6D33, 0x1104, 0x1098, 0x0014, 0x02AC, 0xFFC0, 0x002D, 0x0002,
+ 0x0030, 0xFFC9, 0x02CA, 0x007E, 0x10C8, 0x138A, 0x6F5E, 0x9514,
+ 0xF16F, 0xEFA6, 0x0051, 0xFD72, 0x0047, 0xFFD6, 0xFFFE, 0x0003,
+ 0x0030, 0xFFC9, 0x02CA, 0x007E, 0x10C8, 0x138A, 0x6F5E, 0x9514,
+ 0xF16F, 0xEFA6, 0x0051, 0xFD72, 0x0047, 0xFFD6, 0xFFFE, 0x0003,
+ 0x0033, 0xFFD2, 0x02E5, 0x00EE, 0x10EA, 0x1624, 0x716C, 0x9775,
+ 0xF3CC, 0xEFF0, 0x00B0, 0xFD90, 0x004D, 0xFFD8, 0xFFFE, 0x0003,
+ 0x0033, 0xFFD2, 0x02E5, 0x00EE, 0x10EA, 0x1624, 0x716C, 0x9775,
+ 0xF3CC, 0xEFF0, 0x00B0, 0xFD90, 0x004D, 0xFFD8, 0xFFFE, 0x0003,
+ 0x0037, 0xFFDC, 0x0300, 0x0163, 0x10FD, 0x18D1, 0x735C, 0x99EE,
+ 0xF613, 0xF046, 0x0108, 0xFDB0, 0x0053, 0xFFDB, 0xFFFE, 0x0003,
+ 0x0037, 0xFFDC, 0x0300, 0x0163, 0x10FD, 0x18D1, 0x735C, 0x99EE,
+ 0xF613, 0xF046, 0x0108, 0xFDB0, 0x0053, 0xFFDB, 0xFFFE, 0x0003,
+ 0x003A, 0xFFE7, 0x0319, 0x01DE, 0x1100, 0x1B8E, 0x752C, 0x9C80,
+ 0xF845, 0xF0A7, 0x015B, 0xFDD0, 0x0057, 0xFFDE, 0xFFFF, 0x0003,
+ 0x003A, 0xFFE7, 0x0319, 0x01DE, 0x1100, 0x1B8E, 0x752C, 0x9C80,
+ 0xF845, 0xF0A7, 0x015B, 0xFDD0, 0x0057, 0xFFDE, 0xFFFF, 0x0004,
+ 0x003D, 0xFFF3, 0x0331, 0x025E, 0x10F2, 0x1E5C, 0x76DB, 0x9F27,
+ 0xFA5F, 0xF111, 0x01A8, 0xFDF0, 0x005B, 0xFFE0, 0xFFFF, 0x0004,
+ 0x003D, 0xFFF3, 0x0331, 0x025E, 0x10F2, 0x1E5C, 0x76DB, 0x9F27,
+ 0xFA5F, 0xF111, 0x01A8, 0xFDF0, 0x005B, 0xFFE0, 0xFFFF, 0x0004,
+ 0x0040, 0x0001, 0x0346, 0x02E3, 0x10D3, 0x2139, 0x7869, 0xA1E1,
+ 0xFC61, 0xF184, 0x01EE, 0xFE10, 0x005E, 0xFFE2, 0xFFFF, 0x0004,
+ 0x0040, 0x0001, 0x0346, 0x02E3, 0x10D3, 0x2139, 0x7869, 0xA1E1,
+ 0xFC61, 0xF184, 0x01EE, 0xFE10, 0x005E, 0xFFE2, 0xFFFF, 0x0005,
+ 0x0043, 0x0010, 0x0359, 0x036C, 0x10A2, 0x2425, 0x79D3, 0xA4AF,
+ 0xFE4C, 0xF1FF, 0x022F, 0xFE2F, 0x0061, 0xFFE4, 0xFFFF, 0x0005,
+ 0x0043, 0x0010, 0x0359, 0x036C, 0x10A2, 0x2425, 0x79D3, 0xA4AF,
+ 0xFE4C, 0xF1FF, 0x022F, 0xFE2F, 0x0061, 0xFFE4, 0xFFFF, 0x0006,
+ 0x0046, 0x001F, 0x036A, 0x03F9, 0x105D, 0x271C, 0x7B1A, 0xA78D,
+ 0x001F, 0xF282, 0x0269, 0xFE4F, 0x0062, 0xFFE7, 0xFFFF, 0x0006,
+ 0x0046, 0x001F, 0x036A, 0x03F9, 0x105D, 0x271C, 0x7B1A, 0xA78D,
+ 0x001F, 0xF282, 0x0269, 0xFE4F, 0x0062, 0xFFE7, 0xFFFF, 0x0006,
+ 0x004A, 0x0030, 0x0377, 0x048B, 0x1004, 0x2A1F, 0x7C3D, 0xAA7B,
+ 0x01D8, 0xF30B, 0x029E, 0xFE6F, 0x0063, 0xFFE9, 0xFFFF, 0x0006,
+ 0x004A, 0x0030, 0x0377, 0x048B, 0x1004, 0x2A1F, 0x7C3D, 0xAA7B,
+ 0x01D8, 0xF30B, 0x029E, 0xFE6F, 0x0063, 0xFFE9, 0xFFFF, 0x0007,
+ 0x004D, 0x0043, 0x0382, 0x0520, 0x0F97, 0x2D2C, 0x7D3A, 0xAD75,
+ 0x037A, 0xF399, 0x02CE, 0xFE8E, 0x0064, 0xFFEB, 0x0000, 0x0007,
+ 0x004D, 0x0043, 0x0382, 0x0520, 0x0F97, 0x2D2C, 0x7D3A, 0xAD75,
+ 0x037A, 0xF399, 0x02CE, 0xFE8E, 0x0064, 0xFFEB, 0x0000, 0x0007,
+ 0x0050, 0x0056, 0x038A, 0x05B7, 0x0F14, 0x3041, 0x7E12, 0xB07C,
+ 0x0502, 0xF42C, 0x02F7, 0xFEAC, 0x0064, 0xFFEC, 0x0000, 0x0007,
+ 0x0050, 0x0056, 0x038A, 0x05B7, 0x0F14, 0x3041, 0x7E12, 0xB07C,
+ 0x0502, 0xF42C, 0x02F7, 0xFEAC, 0x0064, 0xFFEC, 0x0000, 0x0008,
+ 0x0053, 0x006B, 0x038E, 0x0652, 0x0E7C, 0x335D, 0x7EC2, 0xB38C,
+ 0x0671, 0xF4C3, 0x031C, 0xFECA, 0x0063, 0xFFEE, 0x0000, 0x0008,
+ 0x0053, 0x006B, 0x038E, 0x0652, 0x0E7C, 0x335D, 0x7EC2, 0xB38C,
+ 0x0671, 0xF4C3, 0x031C, 0xFECA, 0x0063, 0xFFEE, 0x0000, 0x0009,
+ 0x0056, 0x0080, 0x038F, 0x06EE, 0x0DCE, 0x367E, 0x7F4D, 0xB6A4,
+ 0x07C8, 0xF55C, 0x033B, 0xFEE6, 0x0062, 0xFFEF, 0x0000, 0x0009,
+ 0x0056, 0x0080, 0x038F, 0x06EE, 0x0DCE, 0x367E, 0x7F4D, 0xB6A4,
+ 0x07C8, 0xF55C, 0x033B, 0xFEE6, 0x0062, 0xFFEF, 0x0000, 0x000A,
+ 0x0058, 0x0098, 0x038C, 0x078C, 0x0D08, 0x39A4, 0x7FB0, 0xB9C4,
+ 0x0905, 0xF5F9, 0x0354, 0xFF02, 0x0061, 0xFFF1, 0x0000, 0x000A,
+ 0x0058, 0x0098, 0x038C, 0x078C, 0x0D08, 0x39A4, 0x7FB0, 0xB9C4,
+ 0x0905, 0xF5F9, 0x0354, 0xFF02, 0x0061, 0xFFF1, 0x0000, 0x000B,
+ 0x005B, 0x00AF, 0x0385, 0x082B, 0x0C2B, 0x3CCB, 0x7FEB, 0xBCE7,
+ 0x0A2A, 0xF697, 0x0369, 0xFF1D, 0x005F, 0xFFF2, 0x0000, 0x000B,
+ 0x005B, 0x00AF, 0x0385, 0x082B, 0x0C2B, 0x3CCB, 0x7FEB, 0xBCE7,
+ 0x0A2A, 0xF697, 0x0369, 0xFF1D, 0x005F, 0xFFF2, 0x0000, 0x000D,
+ 0x005D, 0x00C8, 0x037A, 0x08CA, 0x0B37, 0x3FF2, 0x7FFF, 0xC00E,
+ 0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x000D,
+ 0x005D, 0x00C8, 0x037A, 0x08CA, 0x0B37, 0x3FF2, 0x7FFF, 0xC00E,
+ 0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x0000
+};
+
+//static u16 myVector[32][8];
+
+static u8 mp3data[0x1000];
+
+static s32 v[32];
+
+static void MP3AB0 () {
+ // Part 2 - 100% Accurate
+ const u16 LUT2[8] = { 0xFEC4, 0xF4FA, 0xC5E4, 0xE1C4,
+ 0x1916, 0x4A50, 0xA268, 0x78AE };
+ const u16 LUT3[4] = { 0xFB14, 0xD4DC, 0x31F2, 0x8E3A };
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ v[16+i] = v[0+i] + v[8+i];
+ v[24+i] = ((v[0+i] - v[8+i]) * LUT2[i]) >> 0x10;
+ }
+
+ // Part 3: 4-wide butterflies
+
+ for (i=0; i < 4; i++) {
+ v[0+i] = v[16+i] + v[20+i];
+ v[4+i] = ((v[16+i] - v[20+i]) * LUT3[i]) >> 0x10;
+
+ v[8+i] = v[24+i] + v[28+i];
+ v[12+i] = ((v[24+i] - v[28+i]) * LUT3[i]) >> 0x10;
+ }
+
+ // Part 4: 2-wide butterflies - 100% Accurate
+
+ for (i = 0; i < 16; i+=4) {
+ v[16+i] = v[0+i] + v[2+i];
+ v[18+i] = ((v[0+i] - v[2+i]) * 0xEC84) >> 0x10;
+
+ v[17+i] = v[1+i] + v[3+i];
+ v[19+i] = ((v[1+i] - v[3+i]) * 0x61F8) >> 0x10;
+ }
+}
+
+static void InnerLoop ();
+
+static u32 inPtr, outPtr;
+
+static u32 t6;// = 0x08A0; // I think these are temporary storage buffers
+static u32 t5;// = 0x0AC0;
+static u32 t4;// = (inst1 & 0x1E);
+
+void MP3 (u32 inst1, u32 inst2) {
+ // Initialization Code
+ u32 readPtr; // s5
+ u32 writePtr; // s6
+ //u32 Count = 0x0480; // s4
+ u32 tmp;
+ //u32 inPtr, outPtr;
+
+ t6 = 0x08A0; // I think these are temporary storage buffers
+ t5 = 0x0AC0;
+ t4 = (inst1 & 0x1E);
+
+ writePtr = inst2 & 0xFFFFFF;
+ readPtr = writePtr;
+ memcpy (mp3data+0xCE8, rsp.RDRAM+readPtr, 8); // Just do that for efficiency... may remove and use directly later anyway
+ readPtr += 8; // This must be a header byte or whatnot
+
+ for (int cnt = 0; cnt < 0x480; cnt += 0x180) {
+ memcpy (mp3data+0xCF0, rsp.RDRAM+readPtr, 0x180); // DMA: 0xCF0 <- RDRAM[s5] : 0x180
+ inPtr = 0xCF0; // s7
+ outPtr = 0xE70; // s3
+// --------------- Inner Loop Start --------------------
+ for (int cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40) {
+ t6 &= 0xFFE0;
+ t5 &= 0xFFE0;
+ t6 |= t4;
+ t5 |= t4;
+ InnerLoop ();
+ t4 = (t4-2)&0x1E;
+ tmp = t6;
+ t6 = t5;
+ t5 = tmp;
+ //outPtr += 0x40;
+ inPtr += 0x40;
+ }
+// --------------- Inner Loop End --------------------
+ memcpy (rsp.RDRAM+writePtr, mp3data+0xe70, 0x180);
+ writePtr += 0x180;
+ readPtr += 0x180;
+ }
+}
+
+
+
+static void InnerLoop () {
+ // Part 1: 100% Accurate
+
+ int i;
+ v[0] = *(s16 *)(mp3data+inPtr+(0x00^S16)); v[31] = *(s16 *)(mp3data+inPtr+(0x3E^S16)); v[0] += v[31];
+ v[1] = *(s16 *)(mp3data+inPtr+(0x02^S16)); v[30] = *(s16 *)(mp3data+inPtr+(0x3C^S16)); v[1] += v[30];
+ v[2] = *(s16 *)(mp3data+inPtr+(0x06^S16)); v[28] = *(s16 *)(mp3data+inPtr+(0x38^S16)); v[2] += v[28];
+ v[3] = *(s16 *)(mp3data+inPtr+(0x04^S16)); v[29] = *(s16 *)(mp3data+inPtr+(0x3A^S16)); v[3] += v[29];
+
+ v[4] = *(s16 *)(mp3data+inPtr+(0x0E^S16)); v[24] = *(s16 *)(mp3data+inPtr+(0x30^S16)); v[4] += v[24];
+ v[5] = *(s16 *)(mp3data+inPtr+(0x0C^S16)); v[25] = *(s16 *)(mp3data+inPtr+(0x32^S16)); v[5] += v[25];
+ v[6] = *(s16 *)(mp3data+inPtr+(0x08^S16)); v[27] = *(s16 *)(mp3data+inPtr+(0x36^S16)); v[6] += v[27];
+ v[7] = *(s16 *)(mp3data+inPtr+(0x0A^S16)); v[26] = *(s16 *)(mp3data+inPtr+(0x34^S16)); v[7] += v[26];
+
+ v[8] = *(s16 *)(mp3data+inPtr+(0x1E^S16)); v[16] = *(s16 *)(mp3data+inPtr+(0x20^S16)); v[8] += v[16];
+ v[9] = *(s16 *)(mp3data+inPtr+(0x1C^S16)); v[17] = *(s16 *)(mp3data+inPtr+(0x22^S16)); v[9] += v[17];
+ v[10]= *(s16 *)(mp3data+inPtr+(0x18^S16)); v[19] = *(s16 *)(mp3data+inPtr+(0x26^S16)); v[10]+= v[19];
+ v[11]= *(s16 *)(mp3data+inPtr+(0x1A^S16)); v[18] = *(s16 *)(mp3data+inPtr+(0x24^S16)); v[11]+= v[18];
+
+ v[12]= *(s16 *)(mp3data+inPtr+(0x10^S16)); v[23] = *(s16 *)(mp3data+inPtr+(0x2E^S16)); v[12]+= v[23];
+ v[13]= *(s16 *)(mp3data+inPtr+(0x12^S16)); v[22] = *(s16 *)(mp3data+inPtr+(0x2C^S16)); v[13]+= v[22];
+ v[14]= *(s16 *)(mp3data+inPtr+(0x16^S16)); v[20] = *(s16 *)(mp3data+inPtr+(0x28^S16)); v[14]+= v[20];
+ v[15]= *(s16 *)(mp3data+inPtr+(0x14^S16)); v[21] = *(s16 *)(mp3data+inPtr+(0x2A^S16)); v[15]+= v[21];
+
+ // Part 2-4
+
+ MP3AB0 ();
+
+ // Part 5 - 1-Wide Butterflies - 100% Accurate but need SSVs!!!
+
+ u32 t0 = t6 + 0x100;
+ u32 t1 = t6 + 0x200;
+ u32 t2 = t5 + 0x100;
+ u32 t3 = t5 + 0x200;
+ /*RSP_GPR[0x8].W = t0;
+ RSP_GPR[0x9].W = t1;
+ RSP_GPR[0xA].W = t2;
+ RSP_GPR[0xB].W = t3;
+
+ RSP_Vect[0].DW[1] = 0xB504A57E00016A09;
+ RSP_Vect[0].DW[0] = 0x0002D4130005A827;
+*/
+
+ // 0x13A8
+ v[1] = 0;
+ v[11] = ((v[16] - v[17]) * 0xB504) >> 0x10;
+
+ v[16] = -v[16] -v[17];
+ v[2] = v[18] + v[19];
+ // ** Store v[11] -> (T6 + 0)**
+ *(s16 *)(mp3data+((t6+(short)0x0))) = (short)v[11];
+
+
+ v[11] = -v[11];
+ // ** Store v[16] -> (T3 + 0)**
+ *(s16 *)(mp3data+((t3+(short)0x0))) = (short)v[16];
+ // ** Store v[11] -> (T5 + 0)**
+ *(s16 *)(mp3data+((t5+(short)0x0))) = (short)v[11];
+ // 0x13E8 - Verified....
+ v[2] = -v[2];
+ // ** Store v[2] -> (T2 + 0)**
+ *(s16 *)(mp3data+((t2+(short)0x0))) = (short)v[2];
+ v[3] = (((v[18] - v[19]) * 0x16A09) >> 0x10) + v[2];
+ // ** Store v[3] -> (T0 + 0)**
+ *(s16 *)(mp3data+((t0+(short)0x0))) = (short)v[3];
+ // 0x1400 - Verified
+ v[4] = -v[20] -v[21];
+ v[6] = v[22] + v[23];
+ v[5] = ((v[20] - v[21]) * 0x16A09) >> 0x10;
+ // ** Store v[4] -> (T3 + 0xFF80)
+ *(s16 *)(mp3data+((t3+(short)0xFF80))) = (short)v[4];
+ v[7] = ((v[22] - v[23]) * 0x2D413) >> 0x10;
+ v[5] = v[5] - v[4];
+ v[7] = v[7] - v[5];
+ v[6] = v[6] + v[6];
+ v[5] = v[5] - v[6];
+ v[4] = -v[4] - v[6];
+ // *** Store v[7] -> (T1 + 0xFF80)
+ *(s16 *)(mp3data+((t1+(short)0xFF80))) = (short)v[7];
+ // *** Store v[4] -> (T2 + 0xFF80)
+ *(s16 *)(mp3data+((t2+(short)0xFF80))) = (short)v[4];
+ // *** Store v[5] -> (T0 + 0xFF80)
+ *(s16 *)(mp3data+((t0+(short)0xFF80))) = (short)v[5];
+ v[8] = v[24] + v[25];
+
+
+ v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10;
+ v[2] = v[8] + v[9];
+ v[11] = ((v[26] - v[27]) * 0x2D413) >> 0x10;
+ v[13] = ((v[28] - v[29]) * 0x2D413) >> 0x10;
+
+ v[10] = v[26] + v[27]; v[10] = v[10] + v[10];
+ v[12] = v[28] + v[29]; v[12] = v[12] + v[12];
+ v[14] = v[30] + v[31];
+ v[3] = v[8] + v[10];
+ v[14] = v[14] + v[14];
+ v[13] = (v[13] - v[2]) + v[12];
+ v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - (v[11] + v[2]);
+ v[14] = -(v[14] + v[14]) + v[3];
+ v[17] = v[13] - v[10];
+ v[9] = v[9] + v[14];
+ // ** Store v[9] -> (T6 + 0x40)
+ *(s16 *)(mp3data+((t6+(short)0x40))) = (short)v[9];
+ v[11] = v[11] - v[13];
+ // ** Store v[17] -> (T0 + 0xFFC0)
+ *(s16 *)(mp3data+((t0+(short)0xFFC0))) = (short)v[17];
+ v[12] = v[8] - v[12];
+ // ** Store v[11] -> (T0 + 0x40)
+ *(s16 *)(mp3data+((t0+(short)0x40))) = (short)v[11];
+ v[8] = -v[8];
+ // ** Store v[15] -> (T1 + 0xFFC0)
+ *(s16 *)(mp3data+((t1+(short)0xFFC0))) = (short)v[15];
+ v[10] = -v[10] -v[12];
+ // ** Store v[12] -> (T2 + 0x40)
+ *(s16 *)(mp3data+((t2+(short)0x40))) = (short)v[12];
+ // ** Store v[8] -> (T3 + 0xFFC0)
+ *(s16 *)(mp3data+((t3+(short)0xFFC0))) = (short)v[8];
+ // ** Store v[14] -> (T5 + 0x40)
+ *(s16 *)(mp3data+((t5+(short)0x40))) = (short)v[14];
+ // ** Store v[10] -> (T2 + 0xFFC0)
+ *(s16 *)(mp3data+((t2+(short)0xFFC0))) = (short)v[10];
+ // 0x14FC - Verified...
+
+ // Part 6 - 100% Accurate
+
+ v[0] = *(s16 *)(mp3data+inPtr+(0x00^S16)); v[31] = *(s16 *)(mp3data+inPtr+(0x3E^S16)); v[0] -= v[31];
+ v[1] = *(s16 *)(mp3data+inPtr+(0x02^S16)); v[30] = *(s16 *)(mp3data+inPtr+(0x3C^S16)); v[1] -= v[30];
+ v[2] = *(s16 *)(mp3data+inPtr+(0x06^S16)); v[28] = *(s16 *)(mp3data+inPtr+(0x38^S16)); v[2] -= v[28];
+ v[3] = *(s16 *)(mp3data+inPtr+(0x04^S16)); v[29] = *(s16 *)(mp3data+inPtr+(0x3A^S16)); v[3] -= v[29];
+
+ v[4] = *(s16 *)(mp3data+inPtr+(0x0E^S16)); v[24] = *(s16 *)(mp3data+inPtr+(0x30^S16)); v[4] -= v[24];
+ v[5] = *(s16 *)(mp3data+inPtr+(0x0C^S16)); v[25] = *(s16 *)(mp3data+inPtr+(0x32^S16)); v[5] -= v[25];
+ v[6] = *(s16 *)(mp3data+inPtr+(0x08^S16)); v[27] = *(s16 *)(mp3data+inPtr+(0x36^S16)); v[6] -= v[27];
+ v[7] = *(s16 *)(mp3data+inPtr+(0x0A^S16)); v[26] = *(s16 *)(mp3data+inPtr+(0x34^S16)); v[7] -= v[26];
+
+ v[8] = *(s16 *)(mp3data+inPtr+(0x1E^S16)); v[16] = *(s16 *)(mp3data+inPtr+(0x20^S16)); v[8] -= v[16];
+ v[9] = *(s16 *)(mp3data+inPtr+(0x1C^S16)); v[17] = *(s16 *)(mp3data+inPtr+(0x22^S16)); v[9] -= v[17];
+ v[10]= *(s16 *)(mp3data+inPtr+(0x18^S16)); v[19] = *(s16 *)(mp3data+inPtr+(0x26^S16)); v[10]-= v[19];
+ v[11]= *(s16 *)(mp3data+inPtr+(0x1A^S16)); v[18] = *(s16 *)(mp3data+inPtr+(0x24^S16)); v[11]-= v[18];
+
+ v[12]= *(s16 *)(mp3data+inPtr+(0x10^S16)); v[23] = *(s16 *)(mp3data+inPtr+(0x2E^S16)); v[12]-= v[23];
+ v[13]= *(s16 *)(mp3data+inPtr+(0x12^S16)); v[22] = *(s16 *)(mp3data+inPtr+(0x2C^S16)); v[13]-= v[22];
+ v[14]= *(s16 *)(mp3data+inPtr+(0x16^S16)); v[20] = *(s16 *)(mp3data+inPtr+(0x28^S16)); v[14]-= v[20];
+ v[15]= *(s16 *)(mp3data+inPtr+(0x14^S16)); v[21] = *(s16 *)(mp3data+inPtr+(0x2A^S16)); v[15]-= v[21];
+
+ //0, 1, 3, 2, 7, 6, 4, 5, 7, 6, 4, 5, 0, 1, 3, 2
+ const u16 LUT6[16] = { 0xFFB2, 0xFD3A, 0xF10A, 0xF854,
+ 0xBDAE, 0xCDA0, 0xE76C, 0xDB94,
+ 0x1920, 0x4B20, 0xAC7C, 0x7C68,
+ 0xABEC, 0x9880, 0xDAE8, 0x839C };
+ for (i = 0; i < 16; i++) {
+ v[0+i] = (v[0+i] * LUT6[i]) >> 0x10;
+ }
+ v[0] = v[0] + v[0]; v[1] = v[1] + v[1];
+ v[2] = v[2] + v[2]; v[3] = v[3] + v[3]; v[4] = v[4] + v[4];
+ v[5] = v[5] + v[5]; v[6] = v[6] + v[6]; v[7] = v[7] + v[7];
+ v[12] = v[12] + v[12]; v[13] = v[13] + v[13]; v[15] = v[15] + v[15];
+
+ MP3AB0 ();
+
+ // Part 7: - 100% Accurate + SSV - Unoptimized
+
+ v[0] = ( v[17] + v[16] ) >> 1;
+ v[1] = ((v[17] * (int)((short)0xA57E * 2)) + (v[16] * 0xB504)) >> 0x10;
+ v[2] = -v[18] -v[19];
+ v[3] = ((v[18] - v[19]) * 0x16A09) >> 0x10;
+ v[4] = v[20] + v[21] + v[0];
+ v[5] = (((v[20] - v[21]) * 0x16A09) >> 0x10) + v[1];
+ v[6] = (((v[22] + v[23]) << 1) + v[0]) - v[2];
+ v[7] = (((v[22] - v[23]) * 0x2D413) >> 0x10) + v[0] + v[1] + v[3];
+ // 0x16A8
+ // Save v[0] -> (T3 + 0xFFE0)
+ *(s16 *)(mp3data+((t3+(short)0xFFE0))) = (short)-v[0];
+ v[8] = v[24] + v[25];
+ v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10;
+ v[10] = ((v[26] + v[27]) << 1) + v[8];
+ v[11] = (((v[26] - v[27]) * 0x2D413) >> 0x10) + v[8] + v[9];
+ v[12] = v[4] - ((v[28] + v[29]) << 1);
+ // ** Store v12 -> (T2 + 0x20)
+ *(s16 *)(mp3data+((t2+(short)0x20))) = (short)v[12];
+ v[13] = (((v[28] - v[29]) * 0x2D413) >> 0x10) - v[12] - v[5];
+ v[14] = v[30] + v[31];
+ v[14] = v[14] + v[14];
+ v[14] = v[14] + v[14];
+ v[14] = v[6] - v[14];
+ v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - v[7];
+ // Store v14 -> (T5 + 0x20)
+ *(s16 *)(mp3data+((t5+(short)0x20))) = (short)v[14];
+ v[14] = v[14] + v[1];
+ // Store v[14] -> (T6 + 0x20)
+ *(s16 *)(mp3data+((t6+(short)0x20))) = (short)v[14];
+ // Store v[15] -> (T1 + 0xFFE0)
+ *(s16 *)(mp3data+((t1+(short)0xFFE0))) = (short)v[15];
+ v[9] = v[9] + v[10];
+ v[1] = v[1] + v[6];
+ v[6] = v[10] - v[6];
+ v[1] = v[9] - v[1];
+ // Store v[6] -> (T5 + 0x60)
+ *(s16 *)(mp3data+((t5+(short)0x60))) = (short)v[6];
+ v[10] = v[10] + v[2];
+ v[10] = v[4] - v[10];
+ // Store v[10] -> (T2 + 0xFFA0)
+ *(s16 *)(mp3data+((t2+(short)0xFFA0))) = (short)v[10];
+ v[12] = v[2] - v[12];
+ // Store v[12] -> (T2 + 0xFFE0)
+ *(s16 *)(mp3data+((t2+(short)0xFFE0))) = (short)v[12];
+ v[5] = v[4] + v[5];
+ v[4] = v[8] - v[4];
+ // Store v[4] -> (T2 + 0x60)
+ *(s16 *)(mp3data+((t2+(short)0x60))) = (short)v[4];
+ v[0] = v[0] - v[8];
+ // Store v[0] -> (T3 + 0xFFA0)
+ *(s16 *)(mp3data+((t3+(short)0xFFA0))) = (short)v[0];
+ v[7] = v[7] - v[11];
+ // Store v[7] -> (T1 + 0xFFA0)
+ *(s16 *)(mp3data+((t1+(short)0xFFA0))) = (short)v[7];
+ v[11] = v[11] - v[3];
+ // Store v[1] -> (T6 + 0x60)
+ *(s16 *)(mp3data+((t6+(short)0x60))) = (short)v[1];
+ v[11] = v[11] - v[5];
+ // Store v[11] -> (T0 + 0x60)
+ *(s16 *)(mp3data+((t0+(short)0x60))) = (short)v[11];
+ v[3] = v[3] - v[13];
+ // Store v[3] -> (T0 + 0x20)
+ *(s16 *)(mp3data+((t0+(short)0x20))) = (short)v[3];
+ v[13] = v[13] + v[2];
+ // Store v[13] -> (T0 + 0xFFE0)
+ *(s16 *)(mp3data+((t0+(short)0xFFE0))) = (short)v[13];
+ //v[2] = ;
+ v[2] = (v[5] - v[2]) - v[9];
+ // Store v[2] -> (T0 + 0xFFA0)
+ *(s16 *)(mp3data+((t0+(short)0xFFA0))) = (short)v[2];
+ // 0x7A8 - Verified...
+
+ // Step 8 - Dewindowing
+
+ //u64 *DW = (u64 *)&DeWindowLUT[0x10-(t4>>1)];
+ u32 offset = 0x10-(t4>>1);
+
+ u32 addptr = t6 & 0xFFE0;
+ offset = 0x10-(t4>>1);
+
+ s32 v2=0, v4=0, v6=0, v8=0;
+ //s32 z2=0, z4=0, z6=0, z8=0;
+
+ offset = 0x10-(t4>>1);// + x*0x40;
+ int x;
+ for (x = 0; x < 8; x++) {
+ v2 = v4 = v6 = v8 = 0;
+
+ //addptr = t1;
+
+ for (i = 7; i >= 0; i--) {
+ v2 += ((int)*(s16 *)(mp3data+(addptr)+0x00) * (short)DeWindowLUT[offset+0x00] + 0x4000) >> 0xF;
+ v4 += ((int)*(s16 *)(mp3data+(addptr)+0x10) * (short)DeWindowLUT[offset+0x08] + 0x4000) >> 0xF;
+ v6 += ((int)*(s16 *)(mp3data+(addptr)+0x20) * (short)DeWindowLUT[offset+0x20] + 0x4000) >> 0xF;
+ v8 += ((int)*(s16 *)(mp3data+(addptr)+0x30) * (short)DeWindowLUT[offset+0x28] + 0x4000) >> 0xF;
+ addptr+=2; offset++;
+ }
+ s32 v0 = v2 + v4;
+ s32 v18 = v6 + v8;
+ //Clamp(v0);
+ //Clamp(v18);
+ // clamp???
+ *(s16 *)(mp3data+(outPtr^S16)) = v0;
+ *(s16 *)(mp3data+((outPtr+2)^S16)) = v18;
+ outPtr+=4;
+ addptr += 0x30;
+ offset += 0x38;
+ }
+
+ offset = 0x10-(t4>>1) + 8*0x40;
+ v2 = v4 = 0;
+ for (i = 0; i < 4; i++) {
+ v2 += ((int)*(s16 *)(mp3data+(addptr)+0x00) * (short)DeWindowLUT[offset+0x00] + 0x4000) >> 0xF;
+ v2 += ((int)*(s16 *)(mp3data+(addptr)+0x10) * (short)DeWindowLUT[offset+0x08] + 0x4000) >> 0xF;
+ addptr+=2; offset++;
+ v4 += ((int)*(s16 *)(mp3data+(addptr)+0x00) * (short)DeWindowLUT[offset+0x00] + 0x4000) >> 0xF;
+ v4 += ((int)*(s16 *)(mp3data+(addptr)+0x10) * (short)DeWindowLUT[offset+0x08] + 0x4000) >> 0xF;
+ addptr+=2; offset++;
+ }
+ s32 mult6 = *(s32 *)(mp3data+0xCE8);
+ s32 mult4 = *(s32 *)(mp3data+0xCEC);
+ if (t4 & 0x2) {
+ v2 = (v2 * *(u32 *)(mp3data+0xCE8)) >> 0x10;
+ *(s16 *)(mp3data+(outPtr^S16)) = v2;
+ } else {
+ v4 = (v4 * *(u32 *)(mp3data+0xCE8)) >> 0x10;
+ *(s16 *)(mp3data+(outPtr^S16)) = v4;
+ mult4 = *(u32 *)(mp3data+0xCE8);
+ }
+ addptr -= 0x50;
+
+ for (x = 0; x < 8; x++) {
+ v2 = v4 = v6 = v8 = 0;
+
+ offset = (0x22F-(t4>>1) + x*0x40);
+
+ for (i = 0; i < 4; i++) {
+ v2 += ((int)*(s16 *)(mp3data+(addptr )+0x20) * (short)DeWindowLUT[offset+0x00] + 0x4000) >> 0xF;
+ v2 -= ((int)*(s16 *)(mp3data+((addptr+2))+0x20) * (short)DeWindowLUT[offset+0x01] + 0x4000) >> 0xF;
+ v4 += ((int)*(s16 *)(mp3data+(addptr )+0x30) * (short)DeWindowLUT[offset+0x08] + 0x4000) >> 0xF;
+ v4 -= ((int)*(s16 *)(mp3data+((addptr+2))+0x30) * (short)DeWindowLUT[offset+0x09] + 0x4000) >> 0xF;
+ v6 += ((int)*(s16 *)(mp3data+(addptr )+0x00) * (short)DeWindowLUT[offset+0x20] + 0x4000) >> 0xF;
+ v6 -= ((int)*(s16 *)(mp3data+((addptr+2))+0x00) * (short)DeWindowLUT[offset+0x21] + 0x4000) >> 0xF;
+ v8 += ((int)*(s16 *)(mp3data+(addptr )+0x10) * (short)DeWindowLUT[offset+0x28] + 0x4000) >> 0xF;
+ v8 -= ((int)*(s16 *)(mp3data+((addptr+2))+0x10) * (short)DeWindowLUT[offset+0x29] + 0x4000) >> 0xF;
+ addptr+=4; offset+=2;
+ }
+ s32 v0 = v2 + v4;
+ s32 v18 = v6 + v8;
+ //Clamp(v0);
+ //Clamp(v18);
+ // clamp???
+ *(s16 *)(mp3data+((outPtr+2)^S16)) = v0;
+ *(s16 *)(mp3data+((outPtr+4)^S16)) = v18;
+ outPtr+=4;
+ addptr -= 0x50;
+ }
+
+ int tmp = outPtr;
+ s32 hi0 = mult6;
+ s32 hi1 = mult4;
+ s32 v;
+
+ hi0 = (int)hi0 >> 0x10;
+ hi1 = (int)hi1 >> 0x10;
+ for (i = 0; i < 8; i++) {
+ // v0
+ v = (*(s16 *)(mp3data+((tmp-0x40)^S16)) * hi0);
+ if (v > 32767) v = 32767; else if (v < -32767) v = -32767;
+ *(s16 *)((u8 *)mp3data+((tmp-0x40)^S16)) = (s16)v;
+ // v17
+ v = (*(s16 *)(mp3data+((tmp-0x30)^S16)) * hi0);
+ if (v > 32767) v = 32767; else if (v < -32767) v = -32767;
+ *(s16 *)((u8 *)mp3data+((tmp-0x30)^S16)) = v;
+ // v2
+ v = (*(s16 *)(mp3data+((tmp-0x1E)^S16)) * hi1);
+ if (v > 32767) v = 32767; else if (v < -32767) v = -32767;
+ *(s16 *)((u8 *)mp3data+((tmp-0x1E)^S16)) = v;
+ // v4
+ v = (*(s16 *)(mp3data+((tmp-0xE)^S16)) * hi1);
+ if (v > 32767) v = 32767; else if (v < -32767) v = -32767;
+ *(s16 *)((u8 *)mp3data+((tmp-0xE)^S16)) = v;
+ tmp += 2;
+ }
+}
+