an attempt to move docs to trunk. god tortoisesvn was an ass to do this with tortoisesvn and google code (core pdf was refused multiple times) NOTE: docs/WiiMote/Core V2.1 + EDR.pdf is still missing deu to googlecode hating me

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3491 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
daco65
2009-06-18 16:07:45 +00:00
parent 5d590d5934
commit b92be31df0
36 changed files with 14366 additions and 1 deletions

213
docs/DSP/AX.c Normal file
View File

@ -0,0 +1,213 @@
//
// Pseudo C
//
//
// DSP:
//
// Memory USAGE
0x0B80 to 0x0C40 CurrentPB
0x0B87
0x0E15 SrcSelectFunction // perhaps CMD0 setups some kind of jmp table at this addresses
0x0E16 CoefFunction
0x0E14 MixCtrlFunction
0x0e17 TmpBuffer exceptions
0x0e18 TmpBuffer exceptions
0x0e19 TmpBuffer exceptions
// instrcution memory
0x0B31 to 0x0B33 some kind of JMP-Table to handle srcSelect ???
0x0B34 to 0x0B36 some kind of JMP-Table to handle coefSelect ???
0x0B11 to 0x0B1F some kind of JMP-Table to handle mixerCtrl ???
void CMD2()
{
// 0x1BC
int_addrPB = (*r00 << 16) | *(r00+1)
DMA_From_Memory(0x0B80, _addrPB, 0xC0); // read first PB to 0x0B80
// 0x1C7
*0x0E08 = 0x0000
*0x0E09 = 0x0140
*0x0E0A = 0x0280
*0x0E0B = 0x0400
*0x0E0C = 0x0540
*0x0E0D = 0x0680
*0x0E0E = 0x07C0
*0x0E0F = 0x0900
*0x0E10 = 0x0A40
// 0x1E4
WaitForDMATransfer()
// 0x1E6
Addr = (*0x0BA7 << 16) | *0x0BA8
DMA_From_Memory(0x03C0, Addr, 0x80); // Copy Update Data to 0x03C0 (AXPBUPDATE dataHi, dataLo)
// 0x1F4
R03 = (*0x0B84) + 0x0B31 // AXPB->srcSelect + 0x0B31 ??? some kind of flag handling ??? SRCSEL can be 0x0 to 0x2
AC0.M = *R03
*0x0E15 = *AC0.M
// 0x1FD
R03 = (*0x0B85) + 0x0B34 // AXPB->coefSelect + 0x0B34 ??? some kind of flag handling ??? COEF can be 0x0 to 0x2
AC0.M = *R03
*0x0E16 = *AC0.M
// 0x206
R03 = (*0x0B86) + 0x0B11 // AXPB->mixerCtrl + 0x0B36 ??? some kind of flag handling ??? MIXCTRL can be 0x0 to 0xE
AC0.M = *R03
*0x0E14 = *AC0.M
// 0x20F
if (*0x0B9B == 0) // AXPBITD->flag (on or off for this voice)
{
// jmp to 0x23a
*0x0E42 = 0x0CE0
*0x0E40 = 0x0CE0
*0x0E41 = 0x0CE0
*0x0E43 = 0x0CE0
WaitForDMATransfer()
}
else
{
// code at 0x216
*0x0E40 = *0x0B9E + 0x0CC0 // AXPBITD->shiftL
*0x0E41 = *0x0B9F + 0x0CC0 // AXPBITD->shiftR
*0x0E42 = 0xCE0
*0x0E43 = 0xCE0
WaitForDMATransfer()
// 0x22a
Addr = (*0x0B9C << 16) | *0x0B9D
DMA_From_Memory(0x0CC0, Addr, 0x40); // (AXPBITD->bufferHi << 16 | AXPBITD->bufferLo) -> 0xCC0
WaitForDMATransfer()
}
}
void CMD0()
{
}
void CMD3()
{
0x0E07 = R00
R00 = 0x0BA2 // AXPBUPDATE->updNum
R01 = 0x03C0
*0x0E04 = 0x05
AC1 = 0
AC0 = 0
AX0.H = *R00++ // AXPBUPDATE->updNum[0]
AC1.M = 0x0B80
// 0x256
for (i=0; i<AX0.H; i++)
{
AC0.M = *R01++
AC0.M = AC0.M + AC1.M
AX1.L = *R01++
R02 = AC0.M
*R02 = AX1.L
}
// 0x25c
R03 = 0x0E05
*R03++ = R01
*R03++ = R02
// 0x260
AC0.M = *0x0B87 // AXPB->state
if (AC0.M == 1)
{
// JMP 0x267 (AX_PB_STATE_RUN)
*0x0E1C = *0x0E42
CALLR *0x0E15 // Load Sample (SrcSelectFunction)
// 0x270
AC0.M = *0xBB3 // AXPBVE->currentDelta (.15 volume at start of frame)
AC1.M = *0xBB2 // AXPBVE->currentVolume
// 0x278
AX0.L = AC1.M
AC1.M = AC1.M + AC0.M
AC0.M = AC0.M << 1
SET15 // ????
AX1.H = AC0.M
AC0.M = AX0.L
AX0.L = 0x8000
R00 = 0x0E44
// 0x27f
// scale volume table
.
.
.
/* for (int i=0; i<32; i++)
{
*R00++ = AC0.M;
prod = AX0.L * AX1.H
*R00++ = AC1.M;
AC0 = AC0 + prod
prod = AX0.L * AX1.H
*R00++ = AC0.M;
AC1 = AC1 + prod
prod = AX0.L * AX1.H
}*/
// 0x29f
*0xBB2 = CurrentVolume
// 0x2a1
// mutiply volume with sample
.
.
.
// 0x2ea
// Call mixer
// 0x02f0
}
else
{
// JMP 0x332
.
.
.
.
}
}
// ===============================================================
void Func_0x065D()
{
}

2703
docs/DSP/Crazy Taxi.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSP_InterC", "DSP_InterC\DSP_InterC.vcproj", "{A010425E-9D5E-461E-910D-0804C2A944D5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A010425E-9D5E-461E-910D-0804C2A944D5}.Debug|Win32.ActiveCfg = Debug|Win32
{A010425E-9D5E-461E-910D-0804C2A944D5}.Debug|Win32.Build.0 = Debug|Win32
{A010425E-9D5E-461E-910D-0804C2A944D5}.Release|Win32.ActiveCfg = Release|Win32
{A010425E-9D5E-461E-910D-0804C2A944D5}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,320 @@
/*====================================================================
filename: opcodes.h
project: GameCube DSP Tool (gcdsp)
created: 2005.03.04
mail: duddie@walla.com
Copyright (c) 2005 Duddie
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/
//
//
// At the moment just ls and sl are using the prolog
// perhaps all actions on r03 must be in the prolog
//
#include <stdafx.h>
#include "OutBuffer.h"
//
void dsp_op_ext_r_epi(uint16 _Opcode)
{
uint8 op = (_Opcode >> 2) & 0x3;
uint8 reg = _Opcode & 0x3;
switch (op)
{
case 0x00:
OutBuffer::AddCode("Error: dsp_op_ext_r_epi");
break;
case 0x01:
OutBuffer::AddCode("%s--", OutBuffer::GetRegName(reg));
// g_dsp.r[reg]--;
break;
case 0x02:
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(reg));
//g_dsp.r[reg]++;
break;
case 0x03:
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(reg), OutBuffer::GetRegName(reg+4));
// g_dsp.r[reg] += g_dsp.r[reg + 4];
break;
}
}
void dsp_op_ext_mv(uint16 _Opcode)
{
uint8 sreg = _Opcode & 0x3;
uint8 dreg = ((_Opcode >> 2) & 0x3);
OutBuffer::AddCode("%s = %s", OutBuffer::GetRegName(dreg + 0x18), OutBuffer::GetRegName(sreg + 0x1c));
// g_dsp.r[dreg + 0x18] = g_dsp.r[sreg + 0x1c];
}
void dsp_op_ext_s(uint16 _Opcode)
{
uint8 dreg = _Opcode & 0x3;
uint8 sreg = ((_Opcode >> 3) & 0x3) + 0x1c;
OutBuffer::AddCode("WriteDMEM(%s, %s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg));
// dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
if (_Opcode & 0x04)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(dreg+4));
// g_dsp.r[dreg] += g_dsp.r[dreg + 4];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(dreg));
//g_dsp.r[dreg]++;
}
}
void dsp_op_ext_l(uint16 _Opcode)
{
uint8 sreg = _Opcode & 0x3;
uint8 dreg = ((_Opcode >> 3) & 0x7) + 0x18;
OutBuffer::AddCode("%s = ReadDMEM(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(sreg));
// uint16 val = dsp_dmem_read(g_dsp.r[sreg]);
// g_dsp.r[dreg] = val;
if (_Opcode & 0x04)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(sreg), OutBuffer::GetRegName(sreg+4));
// g_dsp.r[sreg] += g_dsp.r[sreg + 4];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(sreg));
// g_dsp.r[sreg]++;
}
}
void dsp_op_ext_ls_pro(uint16 _Opcode)
{
uint8 areg = (_Opcode & 0x1) + 0x1e;
OutBuffer::AddCode("WriteDMEM(%s, %s)", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(areg));
// dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]);
if (_Opcode & 0x8)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(0x07));
// g_dsp.r[0x03] += g_dsp.r[0x07];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x03));
// g_dsp.r[0x03]++;
}
}
void dsp_op_ext_ls_epi(uint16 _Opcode)
{
uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18;
OutBuffer::AddCode("%s = ReadDMEM(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(0x00));
// uint16 val = dsp_dmem_read(g_dsp.r[0x00]);
// dsp_op_write_reg(dreg, val);
if (_Opcode & 0x4)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x00), OutBuffer::GetRegName(0x04));
// g_dsp.r[0x00] += g_dsp.r[0x04];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x00));
// g_dsp.r[0x00]++;
}
}
void dsp_op_ext_sl_pro(uint16 _Opcode)
{
uint8 areg = (_Opcode & 0x1) + 0x1e;
OutBuffer::AddCode("WriteDMEM(%s, %s)", OutBuffer::GetRegName(0x00), OutBuffer::GetRegName(areg));
// dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
if (_Opcode & 0x4)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x00), OutBuffer::GetRegName(0x04));
// g_dsp.r[0x00] += g_dsp.r[0x04];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x00));
// g_dsp.r[0x00]++;
}
}
void dsp_op_ext_sl_epi(uint16 _Opcode)
{
uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18;
OutBuffer::AddCode("%s = ReadDMEM(%s)", OutBuffer::GetRegName(dreg), OutBuffer::GetRegName(0x03));
// uint16 val = dsp_dmem_read(g_dsp.r[0x03]);
// dsp_op_write_reg(dreg, val);
if (_Opcode & 0x8)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(0x07));
// g_dsp.r[0x03] += g_dsp.r[0x07];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x03));
// g_dsp.r[0x03]++;
}
}
void dsp_op_ext_ld(uint16 _Opcode)
{
uint8 dreg1 = (((_Opcode >> 5) & 0x1) << 1) + 0x18;
uint8 dreg2 = (((_Opcode >> 4) & 0x1) << 1) + 0x19;
uint8 sreg = _Opcode & 0x3;
OutBuffer::AddCode("%s = ReadDMEM(%s)", OutBuffer::GetRegName(dreg1), OutBuffer::GetRegName(sreg));
OutBuffer::AddCode("%s = ReadDMEM(%s)", OutBuffer::GetRegName(dreg2), OutBuffer::GetRegName(0x03));
// g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
// g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]);
if (_Opcode & 0x04)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(sreg), OutBuffer::GetRegName(sreg + 0x04));
// g_dsp.r[sreg] += g_dsp.r[sreg + 0x04];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(sreg));
// g_dsp.r[sreg]++;
}
if (_Opcode & 0x08)
{
OutBuffer::AddCode("%s += %s", OutBuffer::GetRegName(0x03), OutBuffer::GetRegName(sreg + 0x07));
// g_dsp.r[0x03] += g_dsp.r[0x07];
}
else
{
OutBuffer::AddCode("%s++", OutBuffer::GetRegName(0x03));
// g_dsp.r[0x03]++;
}
}
// ================================================================================
//
//
//
// ================================================================================
void dsp_op_ext_ops_pro(uint16 _Opcode)
{
if ((_Opcode & 0xFF) == 0){return;}
switch ((_Opcode >> 4) & 0xf)
{
case 0x00:
dsp_op_ext_r_epi(_Opcode);
break;
case 0x01:
dsp_op_ext_mv(_Opcode);
break;
case 0x02:
case 0x03:
dsp_op_ext_s(_Opcode);
break;
case 0x04:
case 0x05:
case 0x06:
case 0x07:
dsp_op_ext_l(_Opcode);
break;
case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
if (_Opcode & 0x2)
{
dsp_op_ext_sl_pro(_Opcode);
}
else
{
dsp_op_ext_ls_pro(_Opcode);
}
return;
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
dsp_op_ext_ld(_Opcode);
break;
}
}
void dsp_op_ext_ops_epi(uint16 _Opcode)
{
if ((_Opcode & 0xFF) == 0){return;}
switch ((_Opcode >> 4) & 0xf)
{
case 0x08:
case 0x09:
case 0x0a:
case 0x0b:
if (_Opcode & 0x2)
{
dsp_op_ext_sl_epi(_Opcode);
}
else
{
dsp_op_ext_ls_epi(_Opcode);
}
return;
}
}

View File

@ -0,0 +1,33 @@
/*====================================================================
filename: opcodes.h
project: GameCube DSP Tool (gcdsp)
created: 2005.03.04
mail: duddie@walla.com
Copyright (c) 2005 Duddie
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/
#ifndef _GDSP_EXT_OP_H
#define _GDSP_EXT_OP_H
void dsp_op_ext_ops_pro(uint16 _Opcode);
void dsp_op_ext_ops_epi(uint16 _Opcode);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
/*====================================================================
filename: gdsp_opcodes.h
project: GCemu
created: 2004-6-18
mail: duddie@walla.com
Copyright (c) 2005 Duddie & Tratax
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/
#ifndef _GDSP_OPCODES_H
#define _GDSP_OPCODES_H
void dsp_op0(uint16 opc);
void dsp_op1(uint16 opc);
void dsp_op2(uint16 opc);
void dsp_op3(uint16 opc);
void dsp_op4(uint16 opc);
void dsp_op5(uint16 opc);
void dsp_op6(uint16 opc);
void dsp_op7(uint16 opc);
void dsp_op8(uint16 opc);
void dsp_op9(uint16 opc);
void dsp_opab(uint16 opc);
void dsp_opcd(uint16 opc);
void dsp_ope(uint16 opc);
void dsp_opf(uint16 opc);
#define R_SR 0x13
#define FLAG_ENABLE_INTERUPT 11
#endif

View File

@ -0,0 +1,52 @@
// DSP_InterC.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "DSPOpcodes.h"
uint16 g_IMemory[0x1000];
uint16 g_currentAddress;
uint16 FetchOpcode()
{
uint16 value = swap16(g_IMemory[g_currentAddress & 0x0FFF]);
g_currentAddress++;
return value;
}
void DecodeOpcode(uint16 op);
void Decode(uint16 startAddress, uint16 endAddress)
{
g_currentAddress = startAddress;
while (g_currentAddress < endAddress)
{
uint16 oldPC = g_currentAddress;
uint16 op = FetchOpcode();
OutBuffer::Add("// l_%4X:", oldPC);
DecodeOpcode(op);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
FILE* pFile = fopen("c:\\_\\dsp_rom.bin", "rb");
if (pFile == NULL)
return -1;
fread(g_IMemory, 0x1000, 1, pFile);
fclose(pFile);
//////
OutBuffer::Init();
Decode(0x80e7, 0x81f9);
return 0;
}

View File

@ -0,0 +1,249 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="DSP_InterC"
ProjectGUID="{A010425E-9D5E-461E-910D-0804C2A944D5}"
RootNamespace="DSP_InterC"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
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="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=".\DSP_InterC.cpp"
>
</File>
<File
RelativePath=".\DSPExt.cpp"
>
</File>
<File
RelativePath=".\DSPExt.h"
>
</File>
<File
RelativePath=".\DSPOpcodes.cpp"
>
</File>
<File
RelativePath=".\DSPOpcodes.h"
>
</File>
<File
RelativePath=".\OutBuffer.cpp"
>
</File>
<File
RelativePath=".\OutBuffer.h"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\targetver.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,155 @@
// stdafx.cpp : source file that includes just the standard includes
// DSP_InterC.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#include <stdarg.h>
#include <stdio.h>
namespace OutBuffer
{
void Init()
{
}
void Add(const char* _fmt, ...)
{
static char Msg[2048];
va_list ap;
va_start(ap, _fmt);
vsprintf(Msg, _fmt, ap);
va_end(ap);
printf("%s\n", Msg);
}
void AddCode(const char* _fmt, ...)
{
static char Msg[2048];
va_list ap;
va_start(ap, _fmt);
vsprintf(Msg, _fmt, ap);
va_end(ap);
printf(" %s;\n", Msg);
}
// predefined labels
typedef struct pdlabel_t
{
uint16 addr;
const char* name;
const char* description;
} pdlabels_t;
pdlabel_t regnames[] =
{
{0x00, "R00", "Register 00",},
{0x01, "R01", "Register 01",},
{0x02, "R02", "Register 02",},
{0x03, "R03", "Register 03",},
{0x04, "R04", "Register 04",},
{0x05, "R05", "Register 05",},
{0x06, "R06", "Register 06",},
{0x07, "R07", "Register 07",},
{0x08, "R08", "Register 08",},
{0x09, "R09", "Register 09",},
{0x0a, "R10", "Register 10",},
{0x0b, "R11", "Register 11",},
{0x0c, "ST0", "Call stack",},
{0x0d, "ST1", "Data stack",},
{0x0e, "ST2", "Loop address stack",},
{0x0f, "ST3", "Loop counter",},
{0x00, "ACH0", "Accumulator High 0",},
{0x11, "ACH1", "Accumulator High 1",},
{0x12, "CR", "Config Register",},
{0x13, "SR", "Special Register",},
{0x14, "PROD_l", "PROD L",},
{0x15, "PROD_m1", "PROD M1",},
{0x16, "PROD_h", "PROD H",},
{0x17, "PROD_m2", "PROD M2",},
{0x18, "AX0_l", "Additional Accumulators Low 0",},
{0x19, "AX1_l", "Additional Accumulators Low 1",},
{0x1a, "AX0_h", "Additional Accumulators High 0",},
{0x1b, "AX1_h", "Additional Accumulators High 1",},
{0x1c, "AC0_l", "Register 28",},
{0x1d, "AC1_l", "Register 29",},
{0x1e, "AC0_m", "Register 00",},
{0x1f, "AC1_m", "Register 00",},
// additional to resolve special names
{0x20, "ACC0", "Accumulators 0",},
{0x21, "ACC1", "Accumulators 1",},
{0x22, "AX0", "Additional Accumulators 0",},
{0x23, "AX1", "Additional Accumulators 1",},
};
const pdlabel_t pdlabels[] =
{
{0xffa0, "COEF_A1_0", "COEF_A1_0",},
{0xffa1, "COEF_A2_0", "COEF_A2_0",},
{0xffa2, "COEF_A1_1", "COEF_A1_1",},
{0xffa3, "COEF_A2_1", "COEF_A2_1",},
{0xffa4, "COEF_A1_2", "COEF_A1_2",},
{0xffa5, "COEF_A2_2", "COEF_A2_2",},
{0xffa6, "COEF_A1_3", "COEF_A1_3",},
{0xffa7, "COEF_A2_3", "COEF_A2_3",},
{0xffa8, "COEF_A1_4", "COEF_A1_4",},
{0xffa9, "COEF_A2_4", "COEF_A2_4",},
{0xffaa, "COEF_A1_5", "COEF_A1_5",},
{0xffab, "COEF_A2_5", "COEF_A2_5",},
{0xffac, "COEF_A1_6", "COEF_A1_6",},
{0xffad, "COEF_A2_6", "COEF_A2_6",},
{0xffae, "COEF_A1_7", "COEF_A1_7",},
{0xffaf, "COEF_A2_7", "COEF_A2_7",},
{0xffc9, "DSCR", "DSP DMA Control Reg",},
{0xffcb, "DSBL", "DSP DMA Block Length",},
{0xffcd, "DSPA", "DSP DMA DMEM Address",},
{0xffce, "DSMAH", "DSP DMA Mem Address H",},
{0xffcf, "DSMAL", "DSP DMA Mem Address L",},
{0xffd1, "SampleFormat", "SampleFormat",},
{0xffd3, "Unk Zelda", "Unk Zelda writes to it",},
{0xffd4, "ACSAH", "Accelerator start address H",},
{0xffd5, "ACSAL", "Accelerator start address L",},
{0xffd6, "ACEAH", "Accelerator end address H",},
{0xffd7, "ACEAL", "Accelerator end address L",},
{0xffd8, "ACCAH", "Accelerator current address H",},
{0xffd9, "ACCAL", "Accelerator current address L",},
{0xffda, "pred_scale", "pred_scale",},
{0xffdb, "yn1", "yn1",},
{0xffdc, "yn2", "yn2",},
{0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",},
{0xffde, "GAIN", "Gain",},
{0xffef, "AMDM", "ARAM DMA Request Mask",},
{0xfffb, "DIRQ", "DSP IRQ Request",},
{0xfffc, "DMBH", "DSP Mailbox H",},
{0xfffd, "DMBL", "DSP Mailbox L",},
{0xfffe, "CMBH", "CPU Mailbox H",},
{0xffff, "CMBL", "CPU Mailbox L",},
};
const char* GetRegName(uint16 reg)
{
return regnames[reg].name;
}
const char* GetMemName(uint16 addr)
{
static char Buffer[1024];
for (int i=0; i<sizeof(pdlabels); i++)
{
if (pdlabels[i].addr == addr)
return pdlabels[i].name;
}
sprintf(Buffer, "0x%4x", addr);
return Buffer;
}
}

View File

@ -0,0 +1,23 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
namespace OutBuffer
{
void Init();
void Add(const char* _fmt, ...);
void AddCode(const char* _fmt, ...);
const char* GetRegName(uint16 reg);
const char* GetMemName(uint16 addr);
}
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,33 @@
========================================================================
CONSOLE APPLICATION : DSP_InterC Project Overview
========================================================================
AppWizard has created this DSP_InterC application for you.
This file contains a summary of what you will find in each of the files that
make up your DSP_InterC application.
DSP_InterC.vcproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
DSP_InterC.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named DSP_InterC.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,234 @@
/*====================================================================
filename: opcodes.h
project: GameCube DSP Tool (gcdsp)
created: 2005.03.04
mail: duddie@walla.com
Copyright (c) 2005 Duddie
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/
#ifndef _GDSP_OPCODES_HELPER_H
#define _GDSP_OPCODES_HELPER_H
#include "Globals.h"
#include "gdsp_opcodes.h"
#include "gdsp_memory.h"
#include "gdsp_interpreter.h"
#include "gdsp_registers.h"
#include "gdsp_ext_op.h"
// ---------------------------------------------------------------------------------------
//
// --- SR
//
// ---------------------------------------------------------------------------------------
inline void dsp_SR_set_flag(uint8 flag)
{
g_dsp.r[R_SR] |= (1 << flag);
}
inline bool dsp_SR_is_flag_set(uint8 flag)
{
return((g_dsp.r[R_SR] & (1 << flag)) > 0);
}
// ---------------------------------------------------------------------------------------
//
// --- reg
//
// ---------------------------------------------------------------------------------------
inline uint16 dsp_op_read_reg(uint8 reg)
{
uint16 val;
switch (reg & 0x1f)
{
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
val = dsp_reg_load_stack(reg - 0x0c);
break;
default:
val = g_dsp.r[reg];
break;
}
return(val);
}
inline void dsp_op_write_reg(uint8 reg, uint16 val)
{
switch (reg & 0x1f)
{
case 0x0c:
case 0x0d:
case 0x0e:
case 0x0f:
dsp_reg_store_stack(reg - 0x0c, val);
break;
default:
g_dsp.r[reg] = val;
break;
}
}
// ---------------------------------------------------------------------------------------
//
// --- prod
//
// ---------------------------------------------------------------------------------------
inline sint64 dsp_get_long_prod()
{
sint64 val;
sint64 low_prod;
val = (sint8)g_dsp.r[0x16];
val <<= 32;
low_prod = g_dsp.r[0x15];
low_prod += g_dsp.r[0x17];
low_prod <<= 16;
low_prod |= g_dsp.r[0x14];
val += low_prod;
return(val);
}
inline void dsp_set_long_prod(sint64 val)
{
g_dsp.r[0x14] = (uint16)val;
val >>= 16;
g_dsp.r[0x15] = (uint16)val;
val >>= 16;
g_dsp.r[0x16] = (uint16)val;
g_dsp.r[0x17] = 0;
}
// ---------------------------------------------------------------------------------------
//
// --- acc
//
// ---------------------------------------------------------------------------------------
inline sint64 dsp_get_long_acc(uint8 reg)
{
_dbg_assert_(reg < 2);
sint64 val;
sint64 low_acc;
val = (sint8)g_dsp.r[0x10 + reg];
val <<= 32;
low_acc = g_dsp.r[0x1e + reg];
low_acc <<= 16;
low_acc |= g_dsp.r[0x1c + reg];
val |= low_acc;
return(val);
}
inline uint64 dsp_get_ulong_acc(uint8 reg)
{
_dbg_assert_(reg < 2);
uint64 val;
uint64 low_acc;
val = (uint8)g_dsp.r[0x10 + reg];
val <<= 32;
low_acc = g_dsp.r[0x1e + reg];
low_acc <<= 16;
low_acc |= g_dsp.r[0x1c + reg];
val |= low_acc;
return(val);
}
inline void dsp_set_long_acc(uint8 _reg, sint64 val)
{
_dbg_assert_(_reg < 2);
g_dsp.r[0x1c + _reg] = (uint16)val;
val >>= 16;
g_dsp.r[0x1e + _reg] = (uint16)val;
val >>= 16;
g_dsp.r[0x10 + _reg] = (uint16)val;
}
inline sint16 dsp_get_acc_l(uint8 _reg)
{
_dbg_assert_(_reg < 2);
return(g_dsp.r[0x1c + _reg]);
}
inline sint16 dsp_get_acc_m(uint8 _reg)
{
_dbg_assert_(_reg < 2);
return(g_dsp.r[0x1e + _reg]);
}
inline sint16 dsp_get_acc_h(uint8 _reg)
{
_dbg_assert_(_reg < 2);
return(g_dsp.r[0x10 + _reg]);
}
// ---------------------------------------------------------------------------------------
//
// --- acx
//
// ---------------------------------------------------------------------------------------
inline sint64 dsp_get_long_acx(uint8 _reg)
{
_dbg_assert_(_reg < 2);
sint64 val = (sint16)g_dsp.r[0x1a + _reg];
val <<= 16;
sint64 low_acc = g_dsp.r[0x18 + _reg];
val |= low_acc;
return(val);
}
inline sint16 dsp_get_ax_l(uint8 _reg)
{
_dbg_assert_(_reg < 2);
return(g_dsp.r[0x18 + _reg]);
}
inline sint16 dsp_get_ax_h(uint8 _reg)
{
_dbg_assert_(_reg < 2);
return(g_dsp.r[0x1a + _reg]);
}
#endif

View File

@ -0,0 +1,23 @@
// stdafx.cpp : source file that includes just the standard includes
// DSP_InterC.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
#include <stdarg.h>
void ErrorLog(const char* _fmt, ...)
{
char Msg[512];
va_list ap;
va_start(ap, _fmt);
vsprintf(Msg, _fmt, ap);
va_end(ap);
printf("Error");
}

View File

@ -0,0 +1,39 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;
typedef unsigned int uint;
typedef signed char sint8;
typedef signed short sint16;
typedef signed int sint32;
typedef signed long long sint64;
extern uint16 FetchOpcode();
extern void ErrorLog(const char* _fmt, ...);
inline uint16 swap16(uint16 x)
{
return((x >> 8) | (x << 8));
}
#include "OutBuffer.h"
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,13 @@
#pragma once
// The following macros define the minimum required platform. The minimum required platform
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
// your application. The macros work by enabling all features available on platform versions up to and
// including the version specified.
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
#endif

3088
docs/DSP/DSP_UC_Zelda.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
docs/DSP/GC DSP.pdf Normal file

Binary file not shown.

226
docs/DSP/SrcSelect_.c Normal file
View File

@ -0,0 +1,226 @@
// Init Hardware PCM decoder
/*
06a3 0082 0bb8 LRI $R02, #0x0bb8
06a5 195e LRRI $AC0.M, @$R02
06a6 2ed1 SRS @SampleFormat, $AC0.M
06a7 195e LRRI $AC0.M, @$R02
06a8 2ed4 SRS @ACSAH, $AC0.M
06a9 195e LRRI $AC0.M, @$R02
06aa 2ed5 SRS @ACSAL, $AC0.M
06ab 195e LRRI $AC0.M, @$R02
06ac 2ed6 SRS @ACEAH, $AC0.M
06ad 195e LRRI $AC0.M, @$R02
06ae 2ed7 SRS @ACEAL, $AC0.M
06af 195e LRRI $AC0.M, @$R02
06b0 2ed8 SRS @ACCAH, $AC0.M
06b1 195e LRRI $AC0.M, @$R02
06b2 2ed9 SRS @ACCAL, $AC0.M
06b3 195e LRRI $AC0.M, @$R02
06b4 2ea0 SRS @COEF_A1_0, $AC0.M
06b5 195e LRRI $AC0.M, @$R02
06b6 2ea1 SRS @COEF_A2_0, $AC0.M
06b7 195e LRRI $AC0.M, @$R02
06b8 2ea2 SRS @COEF_A1_1, $AC0.M
06b9 195e LRRI $AC0.M, @$R02
06ba 2ea3 SRS @COEF_A2_1, $AC0.M
06bb 195e LRRI $AC0.M, @$R02
06bc 2ea4 SRS @COEF_A1_2, $AC0.M
06bd 195e LRRI $AC0.M, @$R02
06be 2ea5 SRS @COEF_A2_2, $AC0.M
06bf 195e LRRI $AC0.M, @$R02
06c0 2ea6 SRS @COEF_A1_3, $AC0.M
06c1 195e LRRI $AC0.M, @$R02
06c2 2ea7 SRS @COEF_A2_3, $AC0.M
06c3 195e LRRI $AC0.M, @$R02
06c4 2ea8 SRS @COEF_A1_4, $AC0.M
06c5 195e LRRI $AC0.M, @$R02
06c6 2ea9 SRS @COEF_A2_4, $AC0.M
06c7 195e LRRI $AC0.M, @$R02
06c8 2eaa SRS @COEF_A1_5, $AC0.M
06c9 195e LRRI $AC0.M, @$R02
06ca 2eab SRS @COEF_A2_5, $AC0.M
06cb 195e LRRI $AC0.M, @$R02
06cc 2eac SRS @COEF_A1_6, $AC0.M
06cd 195e LRRI $AC0.M, @$R02
06ce 2ead SRS @COEF_A2_6, $AC0.M
06cf 195e LRRI $AC0.M, @$R02
06d0 2eae SRS @COEF_A1_7, $AC0.M
06d1 195e LRRI $AC0.M, @$R02
06d2 2eaf SRS @COEF_A2_7, $AC0.M
06d3 195e LRRI $AC0.M, @$R02
06d4 2ede SRS @GAIN, $AC0.M
06d5 195e LRRI $AC0.M, @$R02
06d6 2eda SRS @pred_scale, $AC0.M
06d7 195e LRRI $AC0.M, @$R02
06d8 2edb SRS @yn1, $AC0.M
06d9 195e LRRI $AC0.M, @$R02
06da 2edc SRS @yn2, $AC0.M
*/
/// hmmmmmm
/*
06db 8c00 CLR15
06dc 8a00 M2
06dd 8e00 S40
*/
///
AX0.L = *0xe16
AX1.H = ratioHi // sample ratio from AXPBSRC
AX1.L = ratioLo // sample ratio from AXPBSRC
AC0 = 0
AC0.L = currentAddressFrac // AXPBSRC
*0x0e48 = last_samples[0]
*0x0e49 = last_samples[1]
*0x0e4A = last_samples[2]
*0x0e4B = last_samples[3]
AC1.M = AX1.L
ACC = ACC >> 0x05
AC1 = AC1 + AC0
R04 = AC1.M
R05 = AC1.L
AC1 = AC1 + 0xe0 // ?????? AC1 = AC1 - 2097152 (because 0xe0 is converted to signed and shift << 16)
AC1 = AC1 >> 16
AC1 = -AC1
R06 = -AC1
//////////////
AC1 = 0
AC1.L = R05
AC1 = AC1 << 2
R05 = AC1.M
// 0x06fc
AX.0 = 0x1fc
AC0 = 0xe48
R01 = 0xFFDD
R03 = 0x0D80
// 0x0704
for (i=0; i<R04; i++)
{
AC0 = AC0 + AX1
*R03++ = AC0.M
AC1.M = AC0.L
LSR $AC1.M, #0x79
AC1 = AC1 & AX0.H
AC1 += AX0.L
*R03++ = AC1
*R00++ = *ADPCM_DECODER
*R00++ = *ADPCM_DECODER
*R00++ = *ADPCM_DECODER
*R00++ = *ADPCM_DECODER
}
/*
0704 0064 0715 BLOOP $R04, 0x0715
0706 1827 LRR $R07, @$R01
0707 1b07 SRRI @$R00, $R07
0708 4a00 ADDAX $AC0.M, $AX1.L
0709 1ffc MRR $AC1.M, $AC0.L
070a 1827 LRR $R07, @$R01
070b 1b07 SRRI @$R00, $R07
070c 1579 LSR $AC1.M, #0x79
070d 3500 ANDR $AC1.M, $R00
070e 1827 LRR $R07, @$R01
070f 1b07 SRRI @$R00, $R07
0710 4100 ADDR $AC1.M, $AX0.L
0711 1b7e SRRI @$R03, $AC0.M
0712 1827 LRR $R07, @$R01
0713 1b07 SRRI @$R00, $R07
0714 1b7f SRRI @$R03, $AC1.M
0715 0000 NOP */
// 0x0715
// prolly copies the "rest"
for (i=0; i<r05; i++)
{
R07 = *ADPCM_DECODER
*R00++ = R07
}
// 0x71c
R03--
AC1 = *R03
/* 071c 0007 DAR $R03
071d 187f LRR $AC1.M, @$R03 */
for (i<0; i<r06; i++)
{
AC0 = AX1
*R03++ = AC1.M
}
/*
071e 0066 0724 BLOOP $R06, 0x0724
0720 4a3b ADDAX<41>S $AC0.M, $AX1.L : @$R03, $AC1.M
0721 1ffc MRR $AC1.M, $AC0.L
0722 1579 LSR $AC1.M, #0x79
0723 3533 ANDR<44>S $AC1.M, $R00 : @$R03, $AC0.M
0724 4100 ADDR $AC1.M, $AX0.L
*/
0725 1b7f SRRI @$R03, $AC1.M
0726 0004 DAR $R00
0727 189f LRRD $AC1.M, @$R00
0728 1adf SRRD @$R02, $AC1.M
0729 189f LRRD $AC1.M, @$R00
072a 1adf SRRD @$R02, $AC1.M
072b 189f LRRD $AC1.M, @$R00
072c 1adf SRRD @$R02, $AC1.M
072d 189f LRRD $AC1.M, @$R00
072e 1adf SRRD @$R02, $AC1.M
072f 1adc SRRD @$R02, $AC0.L
0730 0082 0bd2 LRI $R02, #0x0bd2
0732 27dc LRS $AC1.M, @yn2
0733 1adf SRRD @$R02, $AC1.M
0734 27db LRS $AC1.M, @yn1
0735 1adf SRRD @$R02, $AC1.M
0736 27da LRS $AC1.M, @pred_scale
0737 1adf SRRD @$R02, $AC1.M
0738 0082 0bbe LRI $R02, #0x0bbe
073a 27d9 LRS $AC1.M, @ACCAL
073b 1adf SRRD @$R02, $AC1.M
073c 27d8 LRS $AC1.M, @ACCAH
073d 1adf SRRD @$R02, $AC1.M
073e 8f00 S16
073f 00c1 0e42 LR $R01, @0x0e42
0741 0082 0d80 LRI $R02, #0x0d80
0743 1940 LRRI $R00, @$R02
0744 1943 LRRI $R03, @$R02
0745 80f0 NX<EFBFBD>LDX : $AX1.L, $AX1.H, @$R01
0746 b8c0 MULX<EFBFBD>LDX $AX0.H, $AX1.H : $AX0.L, $AX0.H, @$R00
0747 111f 074f BLOOPI #0x1f, 0x074f
0749 a6f0 MULXMV<EFBFBD>LDX $AX0.L, $AX1.L, $AC0.M : $AX1.L, $AX1.H, @$R01
074a bcf0 MULXAC<EFBFBD>LDX $AX0.H, $AX1.H, $AC0.M : $AX1.L, $AX1.H, @$R01
074b 1940 LRRI $R00, @$R02
074c 1943 LRRI $R03, @$R02
074d bcf0 MULXAC<EFBFBD>LDX $AX0.H, $AX1.H, $AC0.M : $AX1.L, $AX1.H, @$R01
074e 4ec0 ADDP<EFBFBD>LDX $AC0.M : $AX0.L, $AX0.H, @$R00
074f b831 MULX<EFBFBD>S $AX0.H, $AX1.H : @$R01, $AC0.M
0750 a6f0 MULXMV<EFBFBD>LDX $AX0.L, $AX1.L, $AC0.M : $AX1.L, $AX1.H, @$R01
0751 bcf0 MULXAC<EFBFBD>LDX $AX0.H, $AX1.H, $AC0.M : $AX1.L, $AX1.H, @$R01
0752 bc00 MULXAC $AX0.H, $AX1.H, $AC0.M
0753 4e00 ADDP $AC0.M
0754 1b3e SRRI @$R01, $AC0.M
0755 00e1 0e42 SR @0x0e42, $R01
0757 02df RET

45
docs/DSP/Zelda.txt Normal file
View File

@ -0,0 +1,45 @@
CPU:
---------------------------------------------------------------------------------------
void DSPSendCommands2(_pBuffer, _NumberOfMessages, _StartWork)
{
while (!DSP_Running_Check());
OldInterrupts = OSDisableInterrupts();
if (DSPCheckMailToDSP() != 0)
{
OSRestoreInterrupts();
return -1;
}
DSPSendMailToDSP(_NumberOfMessages)
DSPAssertInt()
while (DSPCheckMailToDSP() != 0) {}
if (_NumberOfMessages == 0)
_NumberOfMessages = 1
if (_StartWork != 0)
{
r28 = DSPStartWork(*_pBuffer, _StartWork)
}
_StartWork = 0
while(Count != _NumberOfMessages)
{
DSPSendMailToDSP(Buffer[Count])
while (DSPCheckMailToDSP() != 0) {}
Count++
}
OSRestoreInterrupts(OldInterrupts)
return r28;
}

2047
docs/DSP/dsp_rom.txt Normal file

File diff suppressed because it is too large Load Diff

423
docs/DSP/wwdsp.c Normal file
View File

@ -0,0 +1,423 @@
/* important variables */
short mem[0x1000];
#define v_0341 mem[0x0341] /* op#2 saves a copy of 344 here */
#define v_0343 mem[0x0343] /* message type? */
#define v_0344 mem[0x0344] /* low byte of first word of message */
#define v_0345 mem[0x0345] /* copy of second word of message */
#define a_0346 mem[0x0346] /* buffer for message contents, size unknown */
#define v_034e mem[0x034e] /* init to 0, later set to most recent value written in a_04fc */
#define v_0350 mem[0x0350] /* init to 0x0280 (write location of messages) */
#define v_0351 mem[0x0351] /* init to 0x0280 (read location?) */
#define v_0352 mem[0x0352] /* init to 0 (number of messages pending?) */
#define v_0355 mem[0x0355] /* used by op#2, init to 0 */
#define a_0356 (mem+0x0356) /* message contents */
#define a_0388 (mem+0x388) /* where op 2 keeps its message */
#define a_038e (mem+0x38e) /* op#2 saves a copy of 345 here */
#define a_03a8 (mem+0x3a8) /* where op#2 dmas in its data, at least 0x80 */
#define v_03fa mem[0x03fa] /* temp for ax0.h during exception */
#define v_03fb mem[0x03fb] /* temp for ar0 during exception */
#define v_03fc mem[0x03fc] /* temp for r08 during exception */
#define v_03fd mem[0x03fd] /* temp for ac0.h during exception */
#define v_03fe mem[0x03fe] /* temp for ac0.m during exception */
#define v_03ff mem[0x03ff] /* temp for ac0.l during exception */
#define a_04e8 (mem+0x04e8) /* 4 element array */
#define a_04ec (mem+0x04ec) /* 4 element array (empty) */
#define a_04f0 (mem+0x04f0) /* 4 element array */
#define a_04f4 (mem+0x04f4) /* 4 element array (empty) */
#define a_04fc (mem+0x04fc) /* 16 element array, written by messages */
#define a_09a0 (mem+0x09a0) /* 0x50 element array, used by op#2, cleared */
#define a_0a00 (mem+0x0a00) /* 0x50 element array, used by op#2, cleared */
#define a_0b00 (mem+0x0b00) /* array from 0x0b00-0x0bff, involves accelerator? */
#define a_0ca0 (mem+0x0ca0) /* 0x50 element array, used by op#2, cleared */
#define a_0d00 (mem+0x0d00) /* 0x50 element array, used by op#2, cleared */
#define a_0d60 (mem+0x0d60) /* 0x50 element array, used by op#2, cleared */
#define a_0f40 (mem+0x0f40) /* 0x50 element array, used by op#2, cleared */
/* reset exception vector 0x0000 */
void main() {
/* JMP 0x0012 */
/* various inits */
SBCLR(5); /* disable interrupts? */
fcn_0057(); /* init hardware stuff */
for(ac1.m=0x1000,ac0.m=0;ac1.m>0;ac1.m--) mem[ac0.m++]=0; /* clear all vars */
fcn_0688(); /* init some vars */
fcn_04c0(); /* set something up related to the accelerator at a_0b00 */
fcn_0e14(); /* set up a table */
fcn_066a(0); /* send a message */
fcn_0674(0x1111); /* send a message */
v_034e=0;
SBSET(5); /* enable interrupts? */
/* jump to 0x06c5 */
mainloop:
while (v_0352) ; /* while no messages pending */
SBCLR(5); /* do not distrub */
v_0352--; /* important that this be atomic */
SBSET(5);
t=v_0351;
size=mem[t++];
if (!(size&0x8000)) { /* size > 0x7fff invalid */
if (size==0) { /* die on message of length 0? */
/* jump to 0x06f5 */
/* jump to 0x05f0 */
/* TODO: analysis of HALT */
HALT();
}
for (i=size,j=0;i>0;i--) {
a_0356[j++]=mem[t++];
a_0356[j++]=mem[t++];
}
v_0351=t;
/* jump to 0x002f */
/* actual command handling */
v_0345=a_0356[1];
v_0344=a_0356[0]&0x00ff;
v_0343=(a_0346[0]>>7)&0x7e;
/* jump table at 0x75 used here */
switch (v_0343>>1) {
// 0x43
case 0:
case 10:
case 11:
case 12:
case 14:
case 15:
/* invalid command? */
config=0x00ff;
fcn_066a(0x04); /* send off a message */
fcn_0674(a_0356[0]); /* send first word of command as a message */
goto mainloop;
break;
case 1:
/* jmp 0x0095 */
break;
case 2:
/* jmp 0x0243 */
sub_0243();
break;
case 3:
/* jmp 0x0073 */
break;
case 4:
/* jmp 0x580 */
break;
case 5:
/* jmp 0x592 */
break;
case 6:
/* jmp 0x469 */
break;
case 7:
/* jmp 0x41d */
break;
case 8: /* mix */
/* jmp 0x0485 */
fcn_0067(fcn_0067(0x0346)); /* read message twice? */
/* take in the two buffers to mix */
fcn_0525(mem[0x344],mem[0x346],mem[0x347],0x400); /* size, addrH, addrL, dsp addr */
fcn_0525(mem[0x344],mem[0x348],mem[0x349],0x800);
S16(); /* saturate all adds, multiplies to 16 bits? */
i=mem[0x0344];
src1=0x400;
src2=0x800;
scale=mem[0x345];
prod=scale*mem[src2++];
val2=mem[src2++];
do {
val1=mem[src1];
val1+=prod;
prod=scale*val2;
mem[src1]=val1;
val2=mem[src2];
src1++;
src2++;
} while (--i);
S40();
/* dma out mixed buf */
fcn_0523(mem[0x344],mem[0x346],mem[0x347],0x400);
break;
case 9:
/* jmp 0x44d */
break;
case 13:
/* jmp 0x00b2 */
break;
}
}
v_0351=t;
goto mainloop;
}
/* message in MBOX exception vector? 0x000e */
void exception() {
/* JMP 0x05b8 */
SBCLR(5);
S40();
/* save ax0.h,ac0.h,ac0.m, and ac0.l */
if ((tH=register_fffe)&0x8000) { /* CPU mailbox H */
if (!(tsize=register_ffff)) { /* CPU mailbox L */
/* empty message? */
while (!((tH=register_fffe)&0x8000)) ;
tH&=0xf;
v_034e=(tH+1)<<4;
a_04fc[tH]=register_ffff;
} else { /* nonempty message? */
/* jump to 0x0692 */
/* save ar0, r08 */
t=v_0350;
mem[t++]=tsize;
do {
while (!((tH=register_fffe)&0x8000)) ;
mem[t++]=tH;
mem[t++]=register_ffff;
} while (--tsize);
v_0350=t;
v_0352++;
/* restore ar0, r08 */
/* jump to 0x05e6 */
}
} else { /* interrupt without message? */
/* jump to 0x06b9 */
/* save ar0, r08 */
mem[v_0350]=0; /* empty message */
/* jump to 0x06ab */
v_0350++;
v_0352++;
/* restore ar0, r08 */
/* jump to 0x05e6 */
}
/* 0x05e6 */
/* restore ax0.h,ac0.h,ac0.m, and ac0.l */
SBSET(5);
/* RTI */
}
/* set up some registers */
void fcn_0057() {
SBCLR(2);
SBCLR(3);
SBCLR(4);
SBCLR(6);
S40(); /* 40-bit mode */
CLR15();
M0(); /* don't multiply result by 2 */
r08=-1;
r09=-1;
r0a=-1;
r0b=-1;
config=0xff;
}
void fcn_0688() {
v_0350=0x0280;
v_0351=0x0280;
v_0352=0;
}
void fcn_04c0() {
config=0xff;
for(i=0xff,ar0=0xb00;i>0;i--) mem[ar0++]=0;
mem[ar0++]=0; /* get the last one */
fcn_0573(0x0b00,0x0100,0);
}
/* a=an address in ac1.m, l=a length in ar0, v=a value? in ac0.m */
void fcn_0573(short a, short l, short v) {
fcn_0561(a,l,0x0001);
}
/* a=an address in ac1.m, l=a length in ar0, v=a value? in ac0.m, f is a flag? in ac0.h */
/* return is in ax0.h */
short fcn_0561(short a, short l, short v, short f) {
register_ffd1=0x0a; /* unknown reg, accel? */
register_ffd6=-1; /* accel end addr H */
register_ffd7=-1; /* accel end addr L */
register_ffd8=v>>1; /*
register_ffd9=?; /* has a value from way back? */
return f;
}
/* initializes some tables that look useful... */
void fcn_0e14() {
a_04e8[0]=0x8240;
a_04e8[1]=0x7fff;
a_04e8[2]=0x7dbf;
a_04e8[3]=0x843f;
a_04f0[0]=0xb23b;
a_04f0[1]=0x7fff;
a_04f0[2]=0x4dc4;
a_04f0[3]=0xd808;
a_04ec[0]=a_04ec[1]=a_04ec[2]=a_04ec[3]=0;
a_04f4[0]=a_04f4[1]=a_04f4[2]=a_04f4[3]=0;
}
/* send a message via DSP MBOX */
void fcn_066a(short m) {
fcn_0682(); /* wait for empty mbox */
register_fffc=0xdcd1;
register_fffd=m;
register_fffb=1; /* IRQ */
fcn_0682();
}
/* wait for dsp mbox empty */
void fcn_0682() {
while (register_fffc&0x8000);
}
void fcn_0674(short m) {
fcn_0682();
register_fffc=0xf355;
register_fffd=m;
fcn_0682();
}
/* a=address in ar0 */
/* fetch a message body (up to zero)? */
short fcn_0067(short a) {
i=0x0357;
j=a;
do {
mem[j++]=mem[i++];
mem[j++]=mem[i];
} while (mem[i++]);
return a;
}
/* dma in, I assume */
/* size=words to transfer in ar0, addrL=low word of RAM address in ac0.l, addrH=high word of RAM address in ac0.m, dspaddr=dsp address in ac1.m */
void fcn_0525(short size, short addrH, short addrL, short dspaddr) {
register_ffcd=dspaddr; /* dsp address */
register_ffc9=0; /* direction: ram->dsp */
register_ffce=addrH; /* memory address H */
register_ffcf=addrL; /* memory address L */
register_ffcb=size<<1; /* bytes to transfer (size must be in words) */
fcn_0536(); /* dma wait */
}
/* dma wait? */
void fcn_0536() {
while (!(register_ffc9&4));
}
/* dma out, I assume */
/* size=words to transfer in ar0, addrL=low word of RAM address is ac0.l, addrH=high word of RAM address in ac0.m, dspaddr=dsp address in ac1.m */
/* shares code with fcn_0525 */
void fcn_0523(short size, short addrH, short addrL, shot dspaddr) {
register_ffcd=dspaddr;
/* jump back into 0525 */
register_ffc9=1; /* direction dsp->ram */
register_ffce=addrH;
register_ffcf=addrL;
register_ffcb=size<<1;
fcn_0536();
}
/* huge subroutine, op #2 */
void sub_0243() {
fcn_0067(0x0388); /* called in an indirect manner... */
v_0341=v_0344; /* low byte first word of message */
v_038e=v_0345;
v_0355=0;
fcn_022a(); /* get stuffs */
fcn_05a4(); /* write to accel */
for (i=v_0341;i>0i--) {
fcn_0102();
}
}
void fcn_022a() {
/* something else must set 386, 387 */
fcn_0525(0x0040,v_0386,v_0387,0x03a8);
}
void fcn_05a4() {
register_ffd4=-1;
register_ffd5=-1;
register_ffd6=-1;
register_ffd7=-1;
}
void fcn_0102() {
for (i=0;i<0x50;i++) a_0d00[i]=0;
for (i=0;i<0x50;i++) a_0d60[i]=0;
fcn_0e3f();
for (i=0;i<0x50;i++) a_0ca0[i]=0;
for (i=0;i<0x50;i++) a_0f40[i]=0;
for (i=0;i<0x50;i++) a_0fa0[i]=0;
for (i=0;i<0x50;i++) a_0a00[i]=0;
for (i=0;i<0x50;i++) a_09a0[i]=0;
}
void fcn_0e3f() {
fcn_00fa(0x0f40,0x0b00,0x50,0x6784);
fcn_0ba4(0x04e8,0x0b00,0x04ec);
}
/* addr1=address in ar0, addr2=address in ar3, size=size of table at addr1 in ac1.m, val=in ax0.l */
void fcn_00fa(short addr1, short addr2, short size, short val) {
M2(); /* all multiplications 2x */
tmp=mem[addr1++];
prod=val*tmp*2;
tmp=mem[addr1++];
ac0.m=prod;
prod=val*tmp*2;
tmp=mem[addr1++];
do {
ac0.m=prod;
prod=val*tmp*2;
mem[addr2]=ac0.m;
tmp=mem[addr1];
addr1++;
addr2++;
} while (--size);
M0();
}
/* addr1=address in ar0 (source 4 element table?), addr2=address in ar1 (accelerator?), addr3=address in ar2 (destination 4 element table?) */
void fcn_00ba4(short addr1, short addr2, short addr3) {
}

34
docs/DSP/zeldaNotes.txt Normal file
View File

@ -0,0 +1,34 @@
DSP startup sequence:
DspBoot called with (JASystem::TAudioThread::syncDSP()) as a parameter.
DSP lib initialized
A Dsp task is created:
init callback = DspHandShake()
req callback = JASystem::TAudioThread::syncDSP()
Task is pushed as first task and executed
DSP send DSP_INIT command (0xDCD10003)
__DSPHandler receive the command
task's init callback (DspHandShake) is called
1 mail is read from dsp (and discarded)
DSP flag is set as running
AIRegisterDMACallback(JASystem::TAudioThread::syncAudio((void))
AIStartDMA() to initialize dma in AI module
-----------------------------------
DSP run sequence:
__DSPHandler receive command DSP_RESUME
callback JASystem::TAudioThread::syncDSP called and pull 1 mail
A message is send by OSSendMessage(1)
JASystem::TAudioThread::audioproc receive OSMessage:
0=update dac
1=update dsp
2=nop ?
3=exit thread
dsp is updated