LINK: Add AdaMN's work for reference
git-svn-id: https://svn.code.sf.net/p/vbam/code/branches/adamn-link@1140 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
b2d9c51e5f
commit
ed7e1247b1
Binary file not shown.
|
@ -24,7 +24,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseOfMfc>Static</UseOfMfc>
|
<UseOfMfc>Static</UseOfMfc>
|
||||||
<CharacterSet>NotSet</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
@ -49,13 +49,13 @@
|
||||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)_temp\</IntDir>
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)_temp\</IntDir>
|
||||||
<PreBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</PreBuildEventUseInBuild>
|
<PreBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PreBuildEventUseInBuild>
|
||||||
<PreLinkEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PreLinkEventUseInBuild>
|
<PreLinkEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PreLinkEventUseInBuild>
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||||
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PostBuildEventUseInBuild>
|
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PostBuildEventUseInBuild>
|
||||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)_temp\</IntDir>
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)_temp\</IntDir>
|
||||||
<PreBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</PreBuildEventUseInBuild>
|
<PreBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</PreBuildEventUseInBuild>
|
||||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
@ -66,9 +66,9 @@
|
||||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" />
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" />
|
||||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" />
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" />
|
||||||
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files (x86)\OpenAL 1.1 SDK\libs\Win32;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86;$(LibraryPath)</LibraryPath>
|
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%programfiles%\OpenAL 1.1 SDK\libs\Win32;$(DXSDK_DIR)\lib\x86;$(LibraryPath)</LibraryPath>
|
||||||
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">C:\Program Files (x86)\OpenAL 1.1 SDK\libs\Win32;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86;$(LibraryPath)</LibraryPath>
|
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">C:\Program Files (x86)\OpenAL 1.1 SDK\libs\Win32;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86;$(LibraryPath)</LibraryPath>
|
||||||
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files (x86)\OpenAL 1.1 SDK\include;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath)</IncludePath>
|
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%programfiles%\OpenAL 1.1 SDK\include;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
||||||
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">C:\Program Files (x86)\OpenAL 1.1 SDK\include;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath)</IncludePath>
|
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">C:\Program Files (x86)\OpenAL 1.1 SDK\include;C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;$(IncludePath)</IncludePath>
|
||||||
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%programfiles%\OpenAL 1.1 SDK\include;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%programfiles%\OpenAL 1.1 SDK\include;$(DXSDK_DIR)\Include;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%programfiles%\OpenAL 1.1 SDK\libs\Win32;$(DXSDK_DIR)\lib\x86;$(LibraryPath)</LibraryPath>
|
<LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%programfiles%\OpenAL 1.1 SDK\libs\Win32;$(DXSDK_DIR)\lib\x86;$(LibraryPath)</LibraryPath>
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||||
<PrecompiledHeader>
|
<PrecompiledHeader>
|
||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -124,6 +124,7 @@
|
||||||
<DataExecutionPrevention>
|
<DataExecutionPrevention>
|
||||||
</DataExecutionPrevention>
|
</DataExecutionPrevention>
|
||||||
<MinimumRequiredVersion>5.0</MinimumRequiredVersion>
|
<MinimumRequiredVersion>5.0</MinimumRequiredVersion>
|
||||||
|
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
@ -177,6 +178,7 @@
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||||
|
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||||
</Link>
|
</Link>
|
||||||
<NASM>
|
<NASM>
|
||||||
<Optimization>1</Optimization>
|
<Optimization>1</Optimization>
|
||||||
|
@ -709,7 +711,7 @@
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<UserProperties RESOURCE_FILE="\Users\Shawn\Desktop\shuffle2proj\vba-m\src\win32\VBA.rc" />
|
<UserProperties RESOURCE_FILE="" />
|
||||||
</VisualStudio>
|
</VisualStudio>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
|
@ -61,6 +61,7 @@ extern int systemGetSensorY();
|
||||||
extern bool systemCanChangeSoundQuality();
|
extern bool systemCanChangeSoundQuality();
|
||||||
extern void systemShowSpeed(int);
|
extern void systemShowSpeed(int);
|
||||||
extern void system10Frames(int);
|
extern void system10Frames(int);
|
||||||
|
extern void system1Frames(int rate, int count);
|
||||||
extern void systemFrame();
|
extern void systemFrame();
|
||||||
extern void systemGbBorderOn();
|
extern void systemGbBorderOn();
|
||||||
|
|
||||||
|
@ -86,6 +87,9 @@ extern int systemFrameSkip;
|
||||||
extern int systemSaveUpdateCounter;
|
extern int systemSaveUpdateCounter;
|
||||||
extern int systemSpeed;
|
extern int systemSpeed;
|
||||||
|
|
||||||
|
extern int lastSA;
|
||||||
|
extern int lastSR;
|
||||||
|
|
||||||
#define SYSTEM_SAVE_UPDATED 30
|
#define SYSTEM_SAVE_UPDATED 30
|
||||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
#include "../system.h"
|
||||||
|
|
||||||
unsigned const vol_reg = 0xFF24;
|
unsigned const vol_reg = 0xFF24;
|
||||||
unsigned const stereo_reg = 0xFF25;
|
unsigned const stereo_reg = 0xFF25;
|
||||||
|
@ -318,6 +319,9 @@ void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
|
||||||
int old_data = regs [reg];
|
int old_data = regs [reg];
|
||||||
regs [reg] = data;
|
regs [reg] = data;
|
||||||
|
|
||||||
|
//if(lastSA>=0x70 && lastSA<=0x75)
|
||||||
|
//log("CH3 Addr:%04X = %04X Regs[%d]:%02X->%02X\n",lastSA,lastSR,reg,old_data,data);
|
||||||
|
|
||||||
if ( addr < vol_reg )
|
if ( addr < vol_reg )
|
||||||
{
|
{
|
||||||
// Oscillator
|
// Oscillator
|
||||||
|
|
|
@ -38,6 +38,7 @@ inline void Gb_Osc::update_amp( blip_time_t time, int new_amp )
|
||||||
{
|
{
|
||||||
last_amp = new_amp;
|
last_amp = new_amp;
|
||||||
med_synth->offset( time, delta, output );
|
med_synth->offset( time, delta, output );
|
||||||
|
//good_synth->offset( time, delta, output );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,12 +281,12 @@ inline void Gb_Wave::write_register( int frame_phase, int reg, int old_data, int
|
||||||
|
|
||||||
switch ( reg )
|
switch ( reg )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0: //NR30
|
||||||
if ( !dac_enabled() )
|
if ( !dac_enabled() )
|
||||||
enabled = false;
|
enabled = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1: //NR31
|
||||||
length_ctr = max_len - data;
|
length_ctr = max_len - data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -571,9 +572,9 @@ void Gb_Noise::run( blip_time_t time, blip_time_t end_time )
|
||||||
void Gb_Wave::run( blip_time_t time, blip_time_t end_time )
|
void Gb_Wave::run( blip_time_t time, blip_time_t end_time )
|
||||||
{
|
{
|
||||||
// Calc volume
|
// Calc volume
|
||||||
static byte const volumes [8] = { 0, 4, 2, 1, 3, 3, 3, 3 };
|
static byte const volumes [8] = { 0, 4, 2, 1, 3, 3, 3, 3 }; //4 = 100%
|
||||||
int const volume_shift = 2;
|
int const volume_shift = 2;
|
||||||
int const volume_idx = regs [2] >> 5 & (agb_mask | 3); // 2 bits on DMG/CGB, 3 on AGB
|
int const volume_idx = regs [2] >> 5 & (agb_mask | 3); // 2 bits on DMG/CGB, 3 on AGB //AdamN: osc.regs[2]=apu.regs[12] (NR32)
|
||||||
int const volume_mul = volumes [volume_idx];
|
int const volume_mul = volumes [volume_idx];
|
||||||
|
|
||||||
// Determine what will be generated
|
// Determine what will be generated
|
||||||
|
@ -585,10 +586,10 @@ void Gb_Wave::run( blip_time_t time, blip_time_t end_time )
|
||||||
if ( dac_enabled() )
|
if ( dac_enabled() )
|
||||||
{
|
{
|
||||||
// Play inaudible frequencies as constant amplitude
|
// Play inaudible frequencies as constant amplitude
|
||||||
amp = 8 << 4; // really depends on average of all samples in wave
|
amp = 8 << 4; // really depends on average of all samples in wave //AdamN: can we use this->last_amp instead?
|
||||||
|
|
||||||
// if delay is larger, constant amplitude won't start yet
|
// if delay is larger, constant amplitude won't start yet
|
||||||
if ( frequency() <= 0x7FB || delay > 15 * clk_mul )
|
if ( frequency() <= 0x7FB || delay > 15 * clk_mul ) //2043
|
||||||
{
|
{
|
||||||
if ( volume_mul )
|
if ( volume_mul )
|
||||||
playing = (int) enabled;
|
playing = (int) enabled;
|
||||||
|
@ -609,13 +610,14 @@ void Gb_Wave::run( blip_time_t time, blip_time_t end_time )
|
||||||
|
|
||||||
// wave size and bank
|
// wave size and bank
|
||||||
int const size20_mask = 0x20;
|
int const size20_mask = 0x20;
|
||||||
int const flags = regs [0] & agb_mask;
|
int const flags = regs [0] & agb_mask; //AdamN: osc.regs[0]=apu.regs[10] (NR30)
|
||||||
int const wave_mask = (flags & size20_mask) | 0x1F;
|
int const wave_mask = (flags & size20_mask) | 0x1F; //AdamN: Bank Dimension
|
||||||
int swap_banks = 0;
|
int swap_banks = 0;
|
||||||
if ( flags & bank40_mask )
|
if ( flags & bank40_mask ) //AdamN: Bank 1
|
||||||
{
|
{
|
||||||
swap_banks = flags & size20_mask;
|
swap_banks = flags & size20_mask; //AdamN: Bank Dimension, swap_banks = Use 2 Banks (64 digits)
|
||||||
wave += bank_size/2 - (swap_banks >> 1);
|
wave += bank_size/2 - (swap_banks >> 1);
|
||||||
|
//wave = &this->wave_ram[bank_size/2 - (swap_banks >> 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ph = this->phase ^ swap_banks;
|
int ph = this->phase ^ swap_banks;
|
||||||
|
@ -640,13 +642,14 @@ void Gb_Wave::run( blip_time_t time, blip_time_t end_time )
|
||||||
ph = (ph + 1) & wave_mask;
|
ph = (ph + 1) & wave_mask;
|
||||||
|
|
||||||
// Scale by volume
|
// Scale by volume
|
||||||
int amp = (nybble * volume_mul) >> (volume_shift + 4);
|
int amp = (nybble * volume_mul) >> (volume_shift + 4); //AdamN: should we use +dac_bias in here?
|
||||||
|
|
||||||
int delta = amp - lamp;
|
int delta = amp - lamp;
|
||||||
if ( delta )
|
if ( delta )
|
||||||
{
|
{
|
||||||
lamp = amp;
|
lamp = amp;
|
||||||
med_synth->offset_inline( time, delta, out );
|
med_synth->offset_inline( time, delta, out );
|
||||||
|
//good_synth->offset_inline( time, delta, out );
|
||||||
}
|
}
|
||||||
time += per;
|
time += per;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,11 +165,11 @@ private:
|
||||||
int period() const { return (2048 - frequency()) * (2 * clk_mul); }
|
int period() const { return (2048 - frequency()) * (2 * clk_mul); }
|
||||||
|
|
||||||
// Non-zero if DAC is enabled
|
// Non-zero if DAC is enabled
|
||||||
int dac_enabled() const { return regs [0] & 0x80; }
|
int dac_enabled() const { return regs [0] & 0x80; } //AdamN: osc.regs[0]=apu.regs[10]
|
||||||
|
|
||||||
void corrupt_wave();
|
void corrupt_wave();
|
||||||
|
|
||||||
BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; }
|
BOOST::uint8_t* wave_bank() const { return &wave_ram [(~regs [0] & bank40_mask) >> 2 & agb_mask]; } //AdamN: osc.regs[0]=apu.regs[10]
|
||||||
|
|
||||||
// Wave index that would be accessed, or -1 if no access would occur
|
// Wave index that would be accessed, or -1 if no access would occur
|
||||||
int access( unsigned addr ) const;
|
int access( unsigned addr ) const;
|
||||||
|
|
166
src/gb/GB.cpp
166
src/gb/GB.cpp
|
@ -14,6 +14,8 @@
|
||||||
#include "gbSGB.h"
|
#include "gbSGB.h"
|
||||||
#include "gbSound.h"
|
#include "gbSound.h"
|
||||||
#include "../Util.h"
|
#include "../Util.h"
|
||||||
|
#include "../gba/GBALink.h"
|
||||||
|
//#include "../gba/Globals.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define _stricmp strcasecmp
|
#define _stricmp strcasecmp
|
||||||
|
@ -790,16 +792,81 @@ void gbWriteMemory(register u16 address, register u8 value)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x01: {
|
case 0x01: {
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(gbMemory[0xff01]!=value)
|
||||||
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
log("SioSB(%04X) : %02X %02X->%02X %d\n", PC.W-2, gbMemory[0xff02], gbMemory[0xff01], value, GetTickCount() ); //register_LY
|
||||||
|
}
|
||||||
|
#endif
|
||||||
gbMemory[0xff01] = value;
|
gbMemory[0xff01] = value;
|
||||||
|
//if(value==0xff/*0x00*/) LinkFirstTime = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// serial control
|
// serial control
|
||||||
case 0x02: {
|
case 0x02: {
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(gbMemory[0xff02]!=value)
|
||||||
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
log("SioSC(%04X) : %02X->%02X %02X %d\n", PC.W-2, gbMemory[0xff02], value, gbMemory[0xff01], GetTickCount() ); //register_LY
|
||||||
|
}
|
||||||
|
#endif
|
||||||
gbSerialOn = (value & 0x80);
|
gbSerialOn = (value & 0x80);
|
||||||
|
//if(gba_link_enabled && lanlink.connected)
|
||||||
|
if( EmuReseted ||(gbMemory[0xff02] & 0x7c)||(value & 0x7c)||(!(value & 0x81)) ) { //trying to detect whether the game has exited multiplay mode, pokemon blue start w/ 0x7e while pocket racing start w/ 0x7c
|
||||||
|
LinkFirstTime = true;
|
||||||
|
if( EmuReseted ||(gbMemory[0xff02] & 0x7c)||(value & 0x7c) )
|
||||||
|
if(lanlink.connected)
|
||||||
|
if(linkid) lc.DiscardData();
|
||||||
|
else ls.DiscardData(1);
|
||||||
|
}
|
||||||
|
EmuReseted = false;
|
||||||
gbMemory[0xff02] = value;
|
gbMemory[0xff02] = value;
|
||||||
if(gbSerialOn) {
|
if(gbSerialOn) {
|
||||||
gbSerialTicks = GBSERIAL_CLOCK_TICKS;
|
gbSerialTicks = GBSERIAL_CLOCK_TICKS;
|
||||||
|
|
||||||
|
LinkIsWaiting = true;
|
||||||
|
|
||||||
|
//Do data exchange, master initiate the transfer
|
||||||
|
//may cause visual artifact if not processed immediately, is it due to IRQ stuff or invalid data being exchanged?
|
||||||
|
if( (value & 1) /*|| (!LinkFirstTime)*/ ) { //&& !linkid //internal clock
|
||||||
|
if(gbSerialFunction) {
|
||||||
|
gbSIO_SC = value;
|
||||||
|
LogStrPush("gbWrite");
|
||||||
|
//if(linkid /*&& (value & 1)*/) {gbMemory[0xff01] = 0xff; LinkFirstTime = true;} else
|
||||||
|
gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]); //gbSerialFunction/gbStartLink/gbPrinter
|
||||||
|
LogStrPop(7);
|
||||||
|
} else gbMemory[0xff01]=0xff;
|
||||||
|
//gbSerialTicks = GBSERIAL_CLOCK_TICKS; //1; //0; //wrong value in gbSerialTicks could cause visual artifact
|
||||||
|
gbMemory[0xff02] &= 0x7f;
|
||||||
|
gbSerialOn = 0;
|
||||||
|
//if(register_IE & 8)
|
||||||
|
gbMemory[0xff0f] = register_IF |= 8;
|
||||||
|
//gbSerialBits = 0;
|
||||||
|
//LinkFirstTime = false;
|
||||||
|
//if(!(value & 1)) LinkFirstTime = true;
|
||||||
|
} /*else //external clock
|
||||||
|
{
|
||||||
|
u16 dat = 0;
|
||||||
|
//if(gbSerialFunction)
|
||||||
|
{
|
||||||
|
gbSIO_SC = value;
|
||||||
|
LogStrPush("gbWrite");
|
||||||
|
dat = gbLinkUpdate(gbMemory[0xff01]);
|
||||||
|
gbMemory[0xff01] = (dat >> 8); //gbSerialFunction/gbStartLink/gbPrinter
|
||||||
|
LogStrPop(7);
|
||||||
|
}
|
||||||
|
if(dat & 1) {
|
||||||
|
//gbSerialTicks = GBSERIAL_CLOCK_TICKS; //1; //0; //wrong value in gbSerialTicks could cause visual artifact
|
||||||
|
gbMemory[0xff02] &= 0x7f;
|
||||||
|
gbSerialOn = 0;
|
||||||
|
//if(register_IE & 8)
|
||||||
|
gbMemory[0xff0f] = register_IF |= 8;
|
||||||
|
//gbSerialBits = 0;
|
||||||
|
//LinkFirstTime = false;
|
||||||
|
//if(!(value & 1)) LinkFirstTime = true;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
#ifdef OLD_GB_LINK
|
#ifdef OLD_GB_LINK
|
||||||
if(linkConnected) {
|
if(linkConnected) {
|
||||||
if(value & 1) {
|
if(value & 1) {
|
||||||
|
@ -2174,6 +2241,8 @@ void gbGetHardwareType()
|
||||||
|
|
||||||
void gbReset()
|
void gbReset()
|
||||||
{
|
{
|
||||||
|
EmuReseted = true;
|
||||||
|
LinkFirstTime = true;
|
||||||
gbGetHardwareType();
|
gbGetHardwareType();
|
||||||
|
|
||||||
oldRegister_WY = 146;
|
oldRegister_WY = 146;
|
||||||
|
@ -4487,6 +4556,8 @@ void gbDrawLine()
|
||||||
|
|
||||||
void gbEmulate(int ticksToStop)
|
void gbEmulate(int ticksToStop)
|
||||||
{
|
{
|
||||||
|
if(EmuCtr>0) {log("Emu inside Emu:%d\n",EmuCtr);return;}
|
||||||
|
|
||||||
gbRegister tempRegister;
|
gbRegister tempRegister;
|
||||||
u8 tempValue;
|
u8 tempValue;
|
||||||
s8 offset;
|
s8 offset;
|
||||||
|
@ -4916,8 +4987,9 @@ void gbEmulate(int ticksToStop)
|
||||||
gbFrameCount++;
|
gbFrameCount++;
|
||||||
systemFrame();
|
systemFrame();
|
||||||
|
|
||||||
if((gbFrameCount % 10) == 0)
|
/*if((gbFrameCount % 10) == 0)
|
||||||
system10Frames(60);
|
system10Frames(60);*/
|
||||||
|
system1Frames(60, gbFrameCount);
|
||||||
|
|
||||||
if(gbFrameCount >= 60) {
|
if(gbFrameCount >= 60) {
|
||||||
u32 currentTime = systemGetClock();
|
u32 currentTime = systemGetClock();
|
||||||
|
@ -5186,8 +5258,9 @@ void gbEmulate(int ticksToStop)
|
||||||
|
|
||||||
systemFrame();
|
systemFrame();
|
||||||
|
|
||||||
if((gbFrameCount % 10) == 0)
|
/*if((gbFrameCount % 10) == 0)
|
||||||
system10Frames(60);
|
system10Frames(60);*/
|
||||||
|
system1Frames(60, gbFrameCount);
|
||||||
|
|
||||||
if(gbFrameCount >= 60) {
|
if(gbFrameCount >= 60) {
|
||||||
u32 currentTime = systemGetClock();
|
u32 currentTime = systemGetClock();
|
||||||
|
@ -5206,7 +5279,33 @@ void gbEmulate(int ticksToStop)
|
||||||
gbMemory[0xff41] = register_STAT;
|
gbMemory[0xff41] = register_STAT;
|
||||||
|
|
||||||
// serial emulation
|
// serial emulation
|
||||||
if(gbSerialOn) {
|
gbSerialOn = (gbMemory[0xff02] & 0x80);
|
||||||
|
/*if(gba_link_enabled && lanlink.connected && (register_LY>=144)) {
|
||||||
|
//if(gbSerialOn)
|
||||||
|
{
|
||||||
|
u16 dat = 0;
|
||||||
|
if(gbSerialFunction) { // external device
|
||||||
|
gbSIO_SC = gbMemory[0xff02];
|
||||||
|
LogStrPush("gbEmu");
|
||||||
|
if(!LinkFirstTime) dat = (gbSerialFunction(gbMemory[0xff01]) << 8) | 1; else
|
||||||
|
dat = gbLinkUpdate(gbMemory[0xff01]);
|
||||||
|
gbMemory[0xff01] = (dat >> 8);
|
||||||
|
LogStrPop(5);
|
||||||
|
if(gbSerialOn && (dat & 1)) {
|
||||||
|
gbMemory[0xff02] &= 0x7f;
|
||||||
|
gbSerialOn = 0;
|
||||||
|
//if(register_IE & 8)
|
||||||
|
gbMemory[0xff0f] = register_IF |= 8;
|
||||||
|
}
|
||||||
|
} //else gbMemory[0xff01] = 0xff;
|
||||||
|
}
|
||||||
|
gbSerialTicks = 1; //GBSERIAL_CLOCK_TICKS; //0; //seems to cause varies visual artifact if gbSerialTicks value isn't right
|
||||||
|
gbSerialBits = 0;
|
||||||
|
}*/
|
||||||
|
static int SIOctr = 0;
|
||||||
|
SIOctr++;
|
||||||
|
if(!lanlink.speed || (SIOctr % 5))
|
||||||
|
if(gbSerialOn) { //Transfer Started
|
||||||
#ifdef OLD_GB_LINK
|
#ifdef OLD_GB_LINK
|
||||||
if(linkConnected) {
|
if(linkConnected) {
|
||||||
gbSerialTicks -= clockTicks;
|
gbSerialTicks -= clockTicks;
|
||||||
|
@ -5229,7 +5328,7 @@ void gbEmulate(int ticksToStop)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
if(gbMemory[0xff02] & 1) {
|
if(gbMemory[0xff02] & 1) { //internal clocks (master)
|
||||||
gbSerialTicks -= clockTicks;
|
gbSerialTicks -= clockTicks;
|
||||||
|
|
||||||
// overflow
|
// overflow
|
||||||
|
@ -5238,16 +5337,61 @@ void gbEmulate(int ticksToStop)
|
||||||
// gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
|
// gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
|
||||||
// increment number of shifted bits
|
// increment number of shifted bits
|
||||||
gbSerialBits++;
|
gbSerialBits++;
|
||||||
if(gbSerialBits == 8) {
|
if(gbSerialBits >= 8) {
|
||||||
// end of transmission
|
// end of transmission
|
||||||
if(gbSerialFunction) // external device
|
/*if(gbSerialFunction) { // external device
|
||||||
gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]);
|
gbSIO_SC = gbMemory[0xff02];
|
||||||
else
|
LogStrPush("gbEmu");
|
||||||
gbMemory[0xff01] = 0xff;
|
gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]); //gbStartLik/gbPrinter
|
||||||
|
LogStrPop(5);
|
||||||
|
LinkFirstTime = false;
|
||||||
|
} else
|
||||||
|
gbMemory[0xff01] = 0xff;*/
|
||||||
gbSerialTicks = 0;
|
gbSerialTicks = 0;
|
||||||
|
//if(!linkid)
|
||||||
|
/*{
|
||||||
gbMemory[0xff02] &= 0x7f;
|
gbMemory[0xff02] &= 0x7f;
|
||||||
gbSerialOn = 0;
|
gbSerialOn = 0;
|
||||||
gbMemory[0xff0f] = register_IF |= 8;
|
gbMemory[0xff0f] = register_IF |= 8;
|
||||||
|
}*/
|
||||||
|
gbSerialBits = 0;
|
||||||
|
} else
|
||||||
|
gbSerialTicks += GBSERIAL_CLOCK_TICKS;
|
||||||
|
}
|
||||||
|
} else //external clocks (slave)
|
||||||
|
{
|
||||||
|
gbSerialTicks -= clockTicks;
|
||||||
|
|
||||||
|
// overflow
|
||||||
|
while(gbSerialTicks <= 0) {
|
||||||
|
// shift serial byte to right and put a 1 bit in its place
|
||||||
|
// gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
|
||||||
|
// increment number of shifted bits
|
||||||
|
gbSerialBits++;
|
||||||
|
if(gbSerialBits >= 8) {
|
||||||
|
// end of transmission
|
||||||
|
u16 dat = 0;
|
||||||
|
if(!LinkIsWaiting) {
|
||||||
|
if(lanlink.connected)
|
||||||
|
if(linkid) lc.DiscardData();
|
||||||
|
else ls.DiscardData(1);
|
||||||
|
} else
|
||||||
|
if(gbSerialFunction) { // external device
|
||||||
|
gbSIO_SC = gbMemory[0xff02];
|
||||||
|
LogStrPush("gbEmu");
|
||||||
|
if(!LinkFirstTime) dat = (gbSerialFunction(gbMemory[0xff01]) << 8) | 1; else //external clock not suppose to start a transfer, but there are time where both side using external clock and couldn't communicate properly
|
||||||
|
dat = gbLinkUpdate(gbMemory[0xff01]);
|
||||||
|
gbMemory[0xff01] = (dat >> 8);
|
||||||
|
LogStrPop(5);
|
||||||
|
} //else
|
||||||
|
//gbMemory[0xff01] = 0xff;
|
||||||
|
gbSerialTicks = 0;
|
||||||
|
if(dat & 1) //if(linkid)
|
||||||
|
{
|
||||||
|
gbMemory[0xff02] &= 0x7f;
|
||||||
|
gbSerialOn = 0;
|
||||||
|
gbMemory[0xff0f] = register_IF |= 8;
|
||||||
|
}
|
||||||
gbSerialBits = 0;
|
gbSerialBits = 0;
|
||||||
} else
|
} else
|
||||||
gbSerialTicks += GBSERIAL_CLOCK_TICKS;
|
gbSerialTicks += GBSERIAL_CLOCK_TICKS;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef GBGLOBALS_H
|
#ifndef GBGLOBALS_H
|
||||||
#define GBGLOBALS_H
|
#define GBGLOBALS_H
|
||||||
|
|
||||||
|
#define VERBOSE_SIO 2048
|
||||||
|
|
||||||
extern int gbRomSizeMask;
|
extern int gbRomSizeMask;
|
||||||
extern int gbRomSize;
|
extern int gbRomSize;
|
||||||
extern int gbRamSize;
|
extern int gbRamSize;
|
||||||
|
|
|
@ -657,7 +657,7 @@ static void count(u32 opcode, int cond_res)
|
||||||
#define OP_MVN \
|
#define OP_MVN \
|
||||||
EMIT1(not, eax) \
|
EMIT1(not, eax) \
|
||||||
EMIT2(mov, eax, REGREF1(esi))
|
EMIT2(mov, eax, REGREF1(esi))
|
||||||
#define OP_MVNS CHECK_PC(OP_MVN EMIT2(test,eax,eax), SETCOND_LOGICAL)
|
#define OP_MVNS CHECK_PC(OP_MVN EMIT2(test,eax,eax), SETCOND_LOGICAL) //AdamN: NOT eax doesn't affect any flags in x86 so need to add TEST for SETCOND_LOGICAL to works properly
|
||||||
|
|
||||||
// ALU cleanup macro
|
// ALU cleanup macro
|
||||||
#define ALU_FINISH ALU_TRAILER
|
#define ALU_FINISH ALU_TRAILER
|
||||||
|
|
381
src/gba/GBA.cpp
381
src/gba/GBA.cpp
|
@ -22,6 +22,10 @@
|
||||||
#include "agbprint.h"
|
#include "agbprint.h"
|
||||||
#include "GBALink.h"
|
#include "GBALink.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER //#ifdef _WIN32
|
||||||
|
#include "../Win32/WinHelper.h" // AdamN: for CCriticalSection
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef PROFILING
|
#ifdef PROFILING
|
||||||
#include "prof/prof.h"
|
#include "prof/prof.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,6 +36,8 @@
|
||||||
|
|
||||||
extern int emulating;
|
extern int emulating;
|
||||||
|
|
||||||
|
extern bool AppTerminated = false;
|
||||||
|
|
||||||
int SWITicks = 0;
|
int SWITicks = 0;
|
||||||
int IRQTicks = 0;
|
int IRQTicks = 0;
|
||||||
|
|
||||||
|
@ -59,6 +65,9 @@ bool cpuFlashEnabled = true;
|
||||||
bool cpuEEPROMEnabled = true;
|
bool cpuEEPROMEnabled = true;
|
||||||
bool cpuEEPROMSensorEnabled = false;
|
bool cpuEEPROMSensorEnabled = false;
|
||||||
|
|
||||||
|
bool breakpt = false;
|
||||||
|
u32 breakaddr = 0xffffffff;
|
||||||
|
|
||||||
u32 cpuPrefetch[2];
|
u32 cpuPrefetch[2];
|
||||||
|
|
||||||
int cpuTotalTicks = 0;
|
int cpuTotalTicks = 0;
|
||||||
|
@ -815,7 +824,7 @@ static bool CPUReadState(gzFile gzFile)
|
||||||
THUMB_PREFETCH;
|
THUMB_PREFETCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204));
|
CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204)); //WAITCNT
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1779,7 +1788,8 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
#endif
|
#endif
|
||||||
if(useBios) {
|
if(useBios) {
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
if(systemVerbose & VERBOSE_SWI) {
|
//if(comment>0x2A) //AdamN: what is the idea of flooding the log with all interrupts?? having a stats showing how many times each interrupt being called might be more usefull than flooding
|
||||||
|
if(systemVerbose & VERBOSE_SWI) { //AdamN: trying to capture only the impossible (should be logged even when logging not enabled tho)
|
||||||
log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
||||||
armState ? armNextPC - 4: armNextPC -2,
|
armState ? armNextPC - 4: armNextPC -2,
|
||||||
reg[0].I,
|
reg[0].I,
|
||||||
|
@ -1827,31 +1837,31 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
stopState = true;
|
stopState = true;
|
||||||
cpuNextEvent = cpuTotalTicks;
|
cpuNextEvent = cpuTotalTicks;
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04: //AdamN: IntrWait
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
if(systemVerbose & VERBOSE_SWI) {
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
|
log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
|
||||||
reg[0].I,
|
reg[0].I,
|
||||||
reg[1].I,
|
reg[1].I, //AdamN: Interrupt flag(s) to wait for (same format as IE/IF registers)
|
||||||
VCOUNT);
|
VCOUNT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
CPUSoftwareInterrupt();
|
CPUSoftwareInterrupt(); //AdamN: Forcefully sets IME=1 and wait in Halt state until one (or more) of the specified interrupt(s) occurs.
|
||||||
break;
|
break;
|
||||||
case 0x05:
|
case 0x05: //AdamN: this VBlankIntrWait oftenly called (every 1/60 sec) so it should be handled properly
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
if(systemVerbose & VERBOSE_SWI) {
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
log("VBlankIntrWait: (VCOUNT = %2d)\n",
|
log("VBlankIntrWait: (VCOUNT = %2d)\n",
|
||||||
VCOUNT);
|
VCOUNT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
CPUSoftwareInterrupt();
|
CPUSoftwareInterrupt(); //AdamN: set r0=1,r1=1 then execute IntrWait
|
||||||
break;
|
break;
|
||||||
case 0x06:
|
case 0x06: //AdamN: Div oftenly called so it should be handled properly
|
||||||
CPUSoftwareInterrupt();
|
BIOS_Div(); //CPUSoftwareInterrupt();
|
||||||
break;
|
break;
|
||||||
case 0x07:
|
case 0x07: //AdamN: DivArm
|
||||||
CPUSoftwareInterrupt();
|
BIOS_DivARM(); //CPUSoftwareInterrupt();
|
||||||
break;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
BIOS_Sqrt();
|
BIOS_Sqrt();
|
||||||
|
@ -1862,7 +1872,7 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
BIOS_ArcTan2();
|
BIOS_ArcTan2();
|
||||||
break;
|
break;
|
||||||
case 0x0B:
|
case 0x0B: //AdamN: CpuSet oftenly called so it should be handled properly
|
||||||
{
|
{
|
||||||
int len = (reg[2].I & 0x1FFFFF) >>1;
|
int len = (reg[2].I & 0x1FFFFF) >>1;
|
||||||
if (!(((reg[0].I & 0xe000000) == 0) ||
|
if (!(((reg[0].I & 0xe000000) == 0) ||
|
||||||
|
@ -1888,7 +1898,7 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
}
|
}
|
||||||
BIOS_CpuSet();
|
BIOS_CpuSet();
|
||||||
break;
|
break;
|
||||||
case 0x0C:
|
case 0x0C: //AdamN: CpuFastSet oftenly called so it should be handled properly
|
||||||
{
|
{
|
||||||
int len = (reg[2].I & 0x1FFFFF) >>5;
|
int len = (reg[2].I & 0x1FFFFF) >>5;
|
||||||
if (!(((reg[0].I & 0xe000000) == 0) ||
|
if (!(((reg[0].I & 0xe000000) == 0) ||
|
||||||
|
@ -2005,7 +2015,7 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
#ifdef GBA_LOGGING
|
#ifdef GBA_LOGGING
|
||||||
if(systemVerbose & VERBOSE_SWI) {
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
|
log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
|
||||||
reg[0].I,
|
reg[0].I, //AdamN: r0=BIAS Level (0=Level 000h, any other value=Level 200h), r1=Delay Count on NDS (GBA uses a fixed delay count of 8)
|
||||||
VCOUNT);
|
VCOUNT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2014,10 +2024,147 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
else
|
else
|
||||||
soundResume();
|
soundResume();
|
||||||
break;
|
break;
|
||||||
|
/*case 0x1A: //AdamN: SoundDriverInit, calling sequences after SoundDriverInit then SoundChannelClear then SoundDriverMode, then repeated SoundDriverVSync+SoundDriverMain
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("SoundDriverInit: 0x%08x (VCOUNT = %2d)\n",
|
||||||
|
reg[0].I, //AdamN: Pointer to SoundArea structure
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CPUSoftwareInterrupt();
|
||||||
|
break;*/
|
||||||
|
case 0x1B: //AdamN: SoundDriverMode
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("SoundDriverMode: 0x%08x (VCOUNT = %2d)\n",
|
||||||
|
reg[0].I, //AdamN: Sound driver operation mode
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x1C: //AdamN: SoundDriverMain (no param)
|
||||||
|
//CPUSoftwareInterrupt(); //AdamN: Call (using/after SoundDriverVSync) every 1/60 of a second, immediately after the V-Blank interrupt. After that, this routine is called after BG and OBJ processing is executed.
|
||||||
|
break;
|
||||||
|
case 0x1D: //AdamN: SoundDriverVSync
|
||||||
|
//CPUSoftwareInterrupt(); //AdamN: Resets the sound DMA (no param) to sync the BIOS sound driver
|
||||||
|
break;
|
||||||
|
case 0x1E: //AdamN: SoundChannelClear
|
||||||
|
//CPUSoftwareInterrupt(); //AdamN: Clears all direct sound channels and stops the sound (no param)
|
||||||
|
break;
|
||||||
case 0x1F:
|
case 0x1F:
|
||||||
BIOS_MidiKey2Freq();
|
BIOS_MidiKey2Freq();
|
||||||
break;
|
break;
|
||||||
case 0x2A:
|
case 0x20: //AdamN: SoundWhatever0/MusicPlayerOpen
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("MusicPlayerOpen: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
||||||
|
armState ? armNextPC - 4: armNextPC -2,
|
||||||
|
reg[0].I,
|
||||||
|
reg[1].I,
|
||||||
|
reg[2].I,
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x21: //AdamN: SoundWhatever1/MusicPlayerStart
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("MusicPlayerStart: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
||||||
|
armState ? armNextPC - 4: armNextPC -2,
|
||||||
|
reg[0].I,
|
||||||
|
reg[1].I,
|
||||||
|
reg[2].I,
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x22: //AdamN: SoundWhatever2/MusicPlayerStop
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("MusicPlayerStop: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
||||||
|
armState ? armNextPC - 4: armNextPC -2,
|
||||||
|
reg[0].I,
|
||||||
|
reg[1].I,
|
||||||
|
reg[2].I,
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x23: //AdamN: SoundWhatever3/MusicPlayerContinue
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("MusicPlayerContinue: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
||||||
|
armState ? armNextPC - 4: armNextPC -2,
|
||||||
|
reg[0].I,
|
||||||
|
reg[1].I,
|
||||||
|
reg[2].I,
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x24: //AdamN: SoundWhatever4/MusicPlayerFadeOut
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("MusicPlayerFadeOut: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
|
||||||
|
armState ? armNextPC - 4: armNextPC -2,
|
||||||
|
reg[0].I,
|
||||||
|
reg[1].I,
|
||||||
|
reg[2].I,
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x25: //AdamN: MultiBoot
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("MultiBoot: 0x%08x,0x%08x (VCOUNT = %2d)\n",
|
||||||
|
reg[0].I, //AdamN: Pointer to MultiBootParam structure
|
||||||
|
reg[1].I, //AdamN: Transfer Mode
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x26: //AdamN: HardReset
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("HardReset: (VCOUNT = %2d)\n",
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CPUSoftwareInterrupt(); //Fully reset to Nintendo intro (no param)
|
||||||
|
break;
|
||||||
|
case 0x27: //AdamN: CustomHalt
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("CustomHalt: 0x%08x (VCOUNT = %2d)\n",
|
||||||
|
reg[2].I, //AdamN: 8bit param (00h=Halt, 80h=Stop)
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CPUSoftwareInterrupt();
|
||||||
|
break;
|
||||||
|
case 0x28: //AdamN: SoundDriverVSyncOff
|
||||||
|
//CPUSoftwareInterrupt(); //AdamN: Stop sound DMA (no param) to prevent sound DMA from overflowing and playing noise when the game loading (as SoundDriverVSync might missed the 1/60sec interval)
|
||||||
|
break;
|
||||||
|
case 0x29: //AdamN: SoundDriverVSyncOn
|
||||||
|
//CPUSoftwareInterrupt(); //AdamN: Restarts the sound DMA stopped with SoundDriverVSyncOff (no param) to restore sound driver operation
|
||||||
|
break;
|
||||||
|
case 0x2A: //AdamN: SoundGetJumpList
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SWI) {
|
||||||
|
log("SoundGetJumpList: 0x%08x (VCOUNT = %2d)\n",
|
||||||
|
reg[0].I, //AdamN: Destination address (must be aligned by 4) (120h bytes buffer)
|
||||||
|
VCOUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
BIOS_SndDriverJmpTableCopy();
|
BIOS_SndDriverJmpTableCopy();
|
||||||
// let it go, because we don't really emulate this function
|
// let it go, because we don't really emulate this function
|
||||||
default:
|
default:
|
||||||
|
@ -2034,11 +2181,12 @@ void CPUSoftwareInterrupt(int comment)
|
||||||
|
|
||||||
if(!disableMessage) {
|
if(!disableMessage) {
|
||||||
systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION,
|
systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION,
|
||||||
N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."),
|
N_("Unsupported BIOS Function %02X called from %08x. A BIOS file is needed in order to get correct behaviour."),
|
||||||
comment,
|
comment,
|
||||||
armMode ? armNextPC - 4: armNextPC - 2);
|
armMode ? armNextPC - 4: armNextPC - 2);
|
||||||
disableMessage = true;
|
disableMessage = true;
|
||||||
}
|
}
|
||||||
|
//CPUSoftwareInterrupt(); //AdamN: not needed as it could cause the game to stop when there are no bios file
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2405,6 +2553,9 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
{ // we need to place the following code in { } because we declare & initialize variables in a case statement
|
{ // we need to place the following code in { } because we declare & initialize variables in a case statement
|
||||||
|
/*if((value & 4)&&((DISPCNT & 0x0010)!=(value & 0x0010))) {
|
||||||
|
log("DISPCNT(%08x) : %04X->%04X %04X R0=%08X R1=%08X R2=%08X R14=%08X Z=%d (VCOUNT = %d)\n", armState ? armNextPC - 4: armNextPC -2, DISPCNT, value, DISPSTAT, reg[0].I, reg[1].I, reg[2].I, reg[14].I, Z_FLAG, VCOUNT);
|
||||||
|
}*/
|
||||||
if((value & 7) > 5) {
|
if((value & 7) > 5) {
|
||||||
// display modes above 0-5 are prohibited
|
// display modes above 0-5 are prohibited
|
||||||
DISPCNT = (value & 7);
|
DISPCNT = (value & 7);
|
||||||
|
@ -2626,7 +2777,11 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||||
case 0x7c:
|
case 0x7c:
|
||||||
case 0x80:
|
case 0x80:
|
||||||
case 0x84:
|
case 0x84:
|
||||||
|
lastSR = value & 0xFF;
|
||||||
|
lastSA = address&0xFF;
|
||||||
soundEvent(address&0xFF, (u8)(value & 0xFF));
|
soundEvent(address&0xFF, (u8)(value & 0xFF));
|
||||||
|
lastSR = value >> 8;
|
||||||
|
lastSA = (address&0xFF)+1;
|
||||||
soundEvent((address&0xFF)+1, (u8)(value>>8));
|
soundEvent((address&0xFF)+1, (u8)(value>>8));
|
||||||
break;
|
break;
|
||||||
case 0x82:
|
case 0x82:
|
||||||
|
@ -2643,6 +2798,8 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||||
case 0x9a:
|
case 0x9a:
|
||||||
case 0x9c:
|
case 0x9c:
|
||||||
case 0x9e:
|
case 0x9e:
|
||||||
|
lastSR = value;
|
||||||
|
lastSA = address&0xFF;
|
||||||
soundEvent(address&0xFF, value);
|
soundEvent(address&0xFF, value);
|
||||||
break;
|
break;
|
||||||
case 0xB0:
|
case 0xB0:
|
||||||
|
@ -2822,16 +2979,79 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||||
timerOnOffDelay|=8;
|
timerOnOffDelay|=8;
|
||||||
cpuNextEvent = cpuTotalTicks;
|
cpuNextEvent = cpuTotalTicks;
|
||||||
break;
|
break;
|
||||||
|
case COMM_SIODATA32_L:
|
||||||
|
if(READ16LE(&ioMem[COMM_SIODATA32_L]) != value) {
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
log("SIODATAL(%d) : %04X %04X %04X->%04X %04X %04X %04X %04X (VCOUNT = %d)\n", GetTickCount(), READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), READ16LE(&ioMem[COMM_SIOMULTI0]), value, READ16LE(&ioMem[COMM_SIOMULTI1]), READ16LE(&ioMem[COMM_SIOMULTI2]), READ16LE(&ioMem[COMM_SIOMULTI3]), READ16LE(&ioMem[COMM_SIOMLT_SEND]), VCOUNT );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
UPDATE_REG(COMM_SIODATA32_L, value);
|
||||||
|
break;
|
||||||
|
case COMM_SIODATA32_H:
|
||||||
|
if(READ16LE(&ioMem[COMM_SIODATA32_H]) != value) {
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
log("SIODATAH(%d) : %04X %04X %04X %04X->%04X %04X %04X %04X (VCOUNT = %d)\n", GetTickCount(), READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), READ16LE(&ioMem[COMM_SIOMULTI0]), READ16LE(&ioMem[COMM_SIOMULTI1]), value, READ16LE(&ioMem[COMM_SIOMULTI2]), READ16LE(&ioMem[COMM_SIOMULTI3]), READ16LE(&ioMem[COMM_SIOMLT_SEND]), VCOUNT );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
UPDATE_REG(COMM_SIODATA32_H, value);
|
||||||
|
break;
|
||||||
case COMM_SIOCNT:
|
case COMM_SIOCNT:
|
||||||
|
if(READ16LE(&ioMem[COMM_SIOCNT]) != (/*READ16LE(&ioMem[COMM_SIOCNT]) &*/ value)) {
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
if(value & 0x4000)
|
||||||
|
log("SIOCNT(%08x) : %04X %04X->%04X %04X %04X %04X %04X %04X (VCOUNT = %d)\n", armState ? armNextPC - 4: armNextPC -2, READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), value, READ16LE(&ioMem[COMM_SIOMULTI0]), READ16LE(&ioMem[COMM_SIOMULTI1]), READ16LE(&ioMem[COMM_SIOMULTI2]), READ16LE(&ioMem[COMM_SIOMULTI3]), READ16LE(&ioMem[COMM_SIOMLT_SEND]), VCOUNT );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if( EmuReseted ) { //trying to detect whether the game has exited multiplay mode (ie. game restarted)
|
||||||
|
EmuReseted = false;
|
||||||
|
LinkFirstTime = true;
|
||||||
|
if(lanlink.connected)
|
||||||
|
if(linkid) lc.DiscardData();
|
||||||
|
else ls.DiscardData(1);
|
||||||
|
}
|
||||||
|
//UPDATE_REG(COMM_SIOCNT, value);
|
||||||
|
lanlink.mode = GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]));
|
||||||
|
if(lanlink.mode!=GetSIOMode(READ16LE(&ioMem[COMM_SIOCNT]), READ16LE(&ioMem[COMM_RCNT]))) LinkFirstTime = true;
|
||||||
StartLink(value);
|
StartLink(value);
|
||||||
|
/*switch (GetSIOMode(value, READ16LE(&ioMem[COMM_RCNT]))) {
|
||||||
|
case MULTIPLAYER:
|
||||||
|
if(LinkHandlerActive) {
|
||||||
|
if (value & 0x80) { //AdamN: Start/Busy Bit.7=1 (Active/Transfering)
|
||||||
|
LinkCmdQueue(1,value);
|
||||||
|
c_s.Lock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
//UPDATE_REG(COMM_SIOCNT, value); //AdamN: when using socket handler SIOCNT need to be updated as soon as possible because program might be reading it and ORing it for the next update
|
||||||
|
LinkParam1=value;
|
||||||
|
LinkCommand|=1; //AdamN: StartLink command
|
||||||
|
c_s.Unlock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
} else UPDATE_REG(COMM_SIOCNT, value);
|
||||||
|
} else {
|
||||||
|
LogStrPush("CPUUpdReg");
|
||||||
|
//UPDATE_REG(COMM_SIOCNT, value); //just for testing the effect
|
||||||
|
if (value & 0x80) { //AdamN: Start/Busy Bit.7=1 (Active/Transfering)
|
||||||
|
StartLink(value); //AdamN: using blocking sockets here can cause noticibly delays
|
||||||
|
} else UPDATE_REG(COMM_SIOCNT, value);
|
||||||
|
LogStrPop(9);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NORMAL8:
|
||||||
|
case NORMAL32:
|
||||||
|
case UART:
|
||||||
|
default:
|
||||||
|
UPDATE_REG(COMM_SIOCNT, value);
|
||||||
|
break;
|
||||||
|
} */
|
||||||
/*
|
/*
|
||||||
// old code path for no linking...
|
// old code path for no linking...
|
||||||
{
|
{
|
||||||
if (value & 0x80) {
|
if (value & 0x80) { //Start bit.7
|
||||||
value &= 0xff7f;
|
value &= 0xff7f;
|
||||||
if ((value & 1) && (value & 0x4000)) {
|
if ((value & 1) && (value & 0x4000)) { //IRQ Enable bit.14
|
||||||
UPDATE_REG(COMM_SIODATA8, 0xFF);
|
UPDATE_REG(COMM_SIODATA8, 0xFF);
|
||||||
IF |= 0x80;
|
IF |= 0x80;
|
||||||
UPDATE_REG(0x202, IF);
|
UPDATE_REG(0x202, IF);
|
||||||
|
@ -2843,25 +3063,66 @@ void CPUUpdateRegister(u32 address, u16 value)
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMM_SIODATA8:
|
case COMM_SIODATA8: //AdamN: 8bit(SIODATA8) on Normal/UART(up to 4x8bit with FIFO), 16bit(SIOMLT_SEND) on Multiplayer mode
|
||||||
if (gba_link_enabled)
|
if(READ16LE(&ioMem[COMM_SIOMLT_SEND]) != (/*READ16LE(&ioMem[COMM_SIOMLT_SEND]) &*/ value)) {
|
||||||
LinkSSend(value);
|
#ifdef GBA_LOGGING
|
||||||
UPDATE_REG(COMM_RCNT, value);
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
log("SIODATA(%d) : %04X %04X %04X %04X %04X %04X %04X->%04X (VCOUNT = %d)\n", GetTickCount(), READ16LE(&ioMem[COMM_RCNT]), READ16LE(&ioMem[COMM_SIOCNT]), READ16LE(&ioMem[COMM_SIOMULTI0]), READ16LE(&ioMem[COMM_SIOMULTI1]), READ16LE(&ioMem[COMM_SIOMULTI2]), READ16LE(&ioMem[COMM_SIOMULTI3]), READ16LE(&ioMem[COMM_SIOMLT_SEND]), value, VCOUNT );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
UPDATE_REG(COMM_SIODATA8, value); //COMM_SIOMLT_SEND
|
||||||
|
/*if (gba_link_enabled && lanlink.connected) //AdamN: added active connection checking, don't send any packet if there are no connection
|
||||||
|
LinkSSend(value); //AdamN: Does sending packet really needed in this part?(as transfers are initiated by SIOCNT)
|
||||||
|
UPDATE_REG(COMM_RCNT, value); //AdamN: is this really necessary?? seems to break connection
|
||||||
|
*/
|
||||||
|
/*if(linkid && (READ16LE(&ioMem[COMM_SIOMLT_SEND]) & 0x3f)==0x0f) {
|
||||||
|
lc.WaitForData(-1);
|
||||||
|
LinkUpdate2(0);
|
||||||
|
}*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x130:
|
case 0x130: //AdamN: KEYINPUT
|
||||||
P1 |= (value & 0x3FF);
|
P1 |= (value & 0x3FF);
|
||||||
UPDATE_REG(0x130, P1);
|
UPDATE_REG(0x130, P1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x132:
|
case 0x132: //AdamN: KEYCNT
|
||||||
UPDATE_REG(0x132, value & 0xC3FF);
|
UPDATE_REG(0x132, value & 0xC3FF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMM_RCNT:
|
case COMM_RCNT: //AdamN: often reach here even when no connection yet
|
||||||
StartGPLink(value);
|
/*if(lanlink.connected)
|
||||||
|
if(linkid) {
|
||||||
|
lc.DiscardData(); //AdamN: discarding may cause server to wait for infinity
|
||||||
|
} else {
|
||||||
|
//ls.DiscardData();
|
||||||
|
}*/
|
||||||
|
lanlink.mode = GetSIOMode(READ16LE(&ioMem[COMM_SIOCNT]), value);
|
||||||
|
if(READ16LE(&ioMem[COMM_RCNT]) != (/*READ16LE(&ioMem[COMM_RCNT]) &*/ value)) {
|
||||||
|
#ifdef GBA_LOGGING
|
||||||
|
if(systemVerbose & VERBOSE_SIO) {
|
||||||
|
log("RCNT(%d) : %04X->%04X %04X %04X %04X %04X %04X (VCOUNT = %d)\n", GetTickCount(), READ16LE(&ioMem[COMM_RCNT]), value, READ16LE(&ioMem[COMM_SIOCNT]), READ16LE(&ioMem[COMM_SIOMULTI0]), READ16LE(&ioMem[COMM_SIOMULTI1]), READ16LE(&ioMem[COMM_SIOMULTI2]), READ16LE(&ioMem[COMM_SIOMULTI3]), VCOUNT );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*if(LinkHandlerActive) {
|
||||||
|
LinkCmdQueue(2,value);
|
||||||
|
c_s.Lock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
LinkParam2=value;
|
||||||
|
LinkCommand|=2; //AdamN: StartGPLink command
|
||||||
|
c_s.Unlock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
} else {
|
||||||
|
LogStrPush("CPUUpdReg");*/
|
||||||
|
StartGPLink(value); //AdamN: doesn't need to be put in different thread as it doesn't send/recv data
|
||||||
|
/*LogStrPop(9);
|
||||||
|
}*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/*case COMM_IR:
|
||||||
|
StartIRLink(value); //AdamN: not made yet tho, probably not useful
|
||||||
|
break;*/
|
||||||
|
|
||||||
case COMM_JOYCNT:
|
case COMM_JOYCNT:
|
||||||
{
|
{
|
||||||
u16 cur = READ16LE(&ioMem[COMM_JOYCNT]);
|
u16 cur = READ16LE(&ioMem[COMM_JOYCNT]);
|
||||||
|
@ -3128,6 +3389,8 @@ void CPUInit(const char *biosFileName, bool useBiosFile)
|
||||||
|
|
||||||
void CPUReset()
|
void CPUReset()
|
||||||
{
|
{
|
||||||
|
EmuReseted = true;
|
||||||
|
LinkFirstTime = true;
|
||||||
if(gbaSaveType == 0) {
|
if(gbaSaveType == 0) {
|
||||||
if(eepromInUse)
|
if(eepromInUse)
|
||||||
gbaSaveType = 3;
|
gbaSaveType = 3;
|
||||||
|
@ -3475,21 +3738,27 @@ extern void winlog(const char *, ...);
|
||||||
|
|
||||||
void CPULoop(int ticks)
|
void CPULoop(int ticks)
|
||||||
{
|
{
|
||||||
|
if(EmuCtr>0) {log("Emu inside Emu:%d\n",EmuCtr);return;}
|
||||||
|
|
||||||
int clockTicks;
|
int clockTicks;
|
||||||
int timerOverflow = 0;
|
int timerOverflow = 0;
|
||||||
// variable used by the CPU core
|
// variable used by the CPU core
|
||||||
cpuTotalTicks = 0;
|
cpuTotalTicks = 0;
|
||||||
|
|
||||||
|
cpuBreakLoop = false; //
|
||||||
// shuffle2: what's the purpose?
|
// shuffle2: what's the purpose?
|
||||||
if(gba_link_enabled)
|
/*if(gba_link_enabled && lanlink.connected && lanlink.mode==MULTIPLAYER && frameCount < systemFrameSkip)
|
||||||
cpuNextEvent = 1;
|
//if(linkid)
|
||||||
|
cpuNextEvent = 159; //224; //else; //AdamN: this is to prevent CPU from executing too many opcodes when frame being skipped which cause Linking instability (ie. in-game timeout reached on client)
|
||||||
|
else */
|
||||||
|
cpuNextEvent = CPUUpdateTicks(); //cpuNextEvent = 1; //224 //AdamN: this will cause slowdown?*/
|
||||||
|
bool NewFrame = false;
|
||||||
|
|
||||||
cpuBreakLoop = false;
|
//cpuBreakLoop = false;
|
||||||
cpuNextEvent = CPUUpdateTicks();
|
//cpuNextEvent = CPUUpdateTicks(); //
|
||||||
if(cpuNextEvent > ticks)
|
if(cpuNextEvent > ticks)
|
||||||
cpuNextEvent = ticks;
|
cpuNextEvent = ticks;
|
||||||
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
#ifndef FINAL_VERSION
|
#ifndef FINAL_VERSION
|
||||||
if(systemDebug) {
|
if(systemDebug) {
|
||||||
|
@ -3526,6 +3795,7 @@ void CPULoop(int ticks)
|
||||||
}
|
}
|
||||||
#endif /* FINAL_VERSION */
|
#endif /* FINAL_VERSION */
|
||||||
|
|
||||||
|
if(breakpt && armNextPC==breakaddr) holdState=true; //AdamN: checking for breakpoint
|
||||||
if(!holdState && !SWITicks) {
|
if(!holdState && !SWITicks) {
|
||||||
if(armState) {
|
if(armState) {
|
||||||
if (!armExecute())
|
if (!armExecute())
|
||||||
|
@ -3581,7 +3851,7 @@ void CPULoop(int ticks)
|
||||||
lcdTicks += 224;
|
lcdTicks += 224;
|
||||||
DISPSTAT |= 2;
|
DISPSTAT |= 2;
|
||||||
UPDATE_REG(0x04, DISPSTAT);
|
UPDATE_REG(0x04, DISPSTAT);
|
||||||
if(DISPSTAT & 16) {
|
if(DISPSTAT & 16) { // entering H-Blank
|
||||||
IF |= 2;
|
IF |= 2;
|
||||||
UPDATE_REG(0x202, IF);
|
UPDATE_REG(0x202, IF);
|
||||||
}
|
}
|
||||||
|
@ -3608,12 +3878,15 @@ void CPULoop(int ticks)
|
||||||
DISPSTAT &= 0xFFFD;
|
DISPSTAT &= 0xFFFD;
|
||||||
if(VCOUNT == 160) {
|
if(VCOUNT == 160) {
|
||||||
count++;
|
count++;
|
||||||
|
NewFrame = true;
|
||||||
systemFrame();
|
systemFrame();
|
||||||
|
|
||||||
if((count % 10) == 0) {
|
/*if((count % 10) == 0) {
|
||||||
system10Frames(60);
|
system10Frames(60);
|
||||||
}
|
}*/
|
||||||
if(count == 60) {
|
system1Frames(60, count);
|
||||||
|
|
||||||
|
if(count >= 60) {
|
||||||
u32 time = systemGetClock();
|
u32 time = systemGetClock();
|
||||||
if(time != lastTime) {
|
if(time != lastTime) {
|
||||||
u32 t = 100000/(time - lastTime);
|
u32 t = 100000/(time - lastTime);
|
||||||
|
@ -3623,6 +3896,7 @@ void CPULoop(int ticks)
|
||||||
lastTime = time;
|
lastTime = time;
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 joy = 0;
|
u32 joy = 0;
|
||||||
// update joystick information
|
// update joystick information
|
||||||
if(systemReadJoypads())
|
if(systemReadJoypads())
|
||||||
|
@ -3667,11 +3941,12 @@ void CPULoop(int ticks)
|
||||||
DISPSTAT |= 1;
|
DISPSTAT |= 1;
|
||||||
DISPSTAT &= 0xFFFD;
|
DISPSTAT &= 0xFFFD;
|
||||||
UPDATE_REG(0x04, DISPSTAT);
|
UPDATE_REG(0x04, DISPSTAT);
|
||||||
if(DISPSTAT & 0x0008) {
|
if(DISPSTAT & 0x0008) { //entering V-Blank
|
||||||
IF |= 1;
|
IF |= 1;
|
||||||
UPDATE_REG(0x202, IF);
|
UPDATE_REG(0x202, IF);
|
||||||
}
|
}
|
||||||
CPUCheckDMA(1, 0x0f);
|
CPUCheckDMA(1, 0x0f);
|
||||||
|
|
||||||
if(frameCount >= framesToSkip) {
|
if(frameCount >= framesToSkip) {
|
||||||
systemDrawScreen();
|
systemDrawScreen();
|
||||||
frameCount = 0;
|
frameCount = 0;
|
||||||
|
@ -3786,7 +4061,10 @@ void CPULoop(int ticks)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} //else //AdamN: this seems to fix the instability of linking when frame being skipped, but it causes artifact at the top lines when connection established in game, does cpu executes more opcodes when frameskipped?
|
||||||
|
//frameCount++; //AdamN: shouldn't increase frameCount here, instead do something useless just to delay before calling LinkUpdate to maintain stability
|
||||||
|
//if(lanlink.connected) if(linkid) cpuNextEvent = cpuTotalTicks;/*lc.WaitForData(0); else ls.WaitForData(0);*/
|
||||||
|
|
||||||
// entering H-Blank
|
// entering H-Blank
|
||||||
DISPSTAT |= 2;
|
DISPSTAT |= 2;
|
||||||
UPDATE_REG(0x04, DISPSTAT);
|
UPDATE_REG(0x04, DISPSTAT);
|
||||||
|
@ -3796,6 +4074,7 @@ void CPULoop(int ticks)
|
||||||
IF |= 2;
|
IF |= 2;
|
||||||
UPDATE_REG(0x202, IF);
|
UPDATE_REG(0x202, IF);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3942,8 +4221,21 @@ void CPULoop(int ticks)
|
||||||
if (gba_joybus_enabled)
|
if (gba_joybus_enabled)
|
||||||
JoyBusUpdate(clockTicks);
|
JoyBusUpdate(clockTicks);
|
||||||
|
|
||||||
if (gba_link_enabled)
|
if (gba_link_enabled && (lanlink.connected || !lanlink.active)) { //AdamN: don't update if there are no connection
|
||||||
LinkUpdate(clockTicks);
|
LinkUpdate(clockTicks); //AdamN: when frame being skipped LinkUpdate might not be called(?) thus causing instability
|
||||||
|
NewFrame = false;
|
||||||
|
//if(LinkHandlerActive) {
|
||||||
|
//LinkCmdQueue(8,clockTicks);
|
||||||
|
//c_s.Lock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
//LinkParam8=clockTicks;
|
||||||
|
//LinkCommand|=8; //AdamN: LinkUpdate command
|
||||||
|
//c_s.Unlock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
//} else if(/*(clockTicks & 1)&&*/(lanlink.connected)) { //AdamN: it seems LinkUpdate need to be called every cycle, occasionally doesn't works
|
||||||
|
//LogStrPush("CPULoop");
|
||||||
|
//LinkUpdate2(clockTicks); //AdamN: using blocking sockets here can cause noticibly delays
|
||||||
|
//LogStrPop(7);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
cpuNextEvent = CPUUpdateTicks();
|
cpuNextEvent = CPUUpdateTicks();
|
||||||
|
|
||||||
|
@ -3960,8 +4252,11 @@ void CPULoop(int ticks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// shuffle2: what's the purpose?
|
// shuffle2: what's the purpose?
|
||||||
if(gba_link_enabled)
|
/*if(gba_link_enabled && lanlink.connected)
|
||||||
cpuNextEvent = 1;
|
cpuNextEvent = 1; //AdamN: this will cause great slowdown*/
|
||||||
|
/*if(gba_link_enabled && lanlink.connected && lanlink.mode==MULTIPLAYER && frameCount < systemFrameSkip)
|
||||||
|
//if(linkid)
|
||||||
|
cpuNextEvent = 159; //224;*/ //cpuTotalTicks+224; //AdamN: this is to prevent CPU from executing too many opcodes when frame being skipped which cause Linking instability (ie. in-game timeout reached on client)
|
||||||
|
|
||||||
if(IF && (IME & 1) && armIrqEnable) {
|
if(IF && (IME & 1) && armIrqEnable) {
|
||||||
int res = IF & IE;
|
int res = IF & IE;
|
||||||
|
|
|
@ -66,6 +66,12 @@ extern bool armState;
|
||||||
extern int armMode;
|
extern int armMode;
|
||||||
extern void (*cpuSaveGameFunc)(u32,u8);
|
extern void (*cpuSaveGameFunc)(u32,u8);
|
||||||
|
|
||||||
|
extern int cpuNextEvent;
|
||||||
|
extern int cpuTotalTicks;
|
||||||
|
extern bool holdState;
|
||||||
|
extern bool breakpt;
|
||||||
|
extern u32 breakaddr;
|
||||||
|
|
||||||
#ifdef BKPT_SUPPORT
|
#ifdef BKPT_SUPPORT
|
||||||
extern u8 freezeWorkRAM[0x40000];
|
extern u8 freezeWorkRAM[0x40000];
|
||||||
extern u8 freezeInternalRAM[0x8000];
|
extern u8 freezeInternalRAM[0x8000];
|
||||||
|
|
2940
src/gba/GBALink.cpp
2940
src/gba/GBALink.cpp
File diff suppressed because it is too large
Load Diff
|
@ -4,30 +4,41 @@
|
||||||
#include <SFML/Network.hpp>
|
#include <SFML/Network.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER //#ifdef _WIN32
|
||||||
|
#include "../Win32/WinHelper.h" // AdamN: for CCriticalSection
|
||||||
|
#endif
|
||||||
|
|
||||||
#define LINK_PARENTLOST 0x80
|
#define LINK_PARENTLOST 0x80
|
||||||
#define UNSUPPORTED -1
|
#define UNSUPPORTED -1
|
||||||
#define MULTIPLAYER 0
|
#define MULTIPLAYER 0
|
||||||
#define NORMAL8 1
|
#define NORMAL8 1
|
||||||
#define NORMAL32 2
|
#define NORMAL32 2 //AdamN: wireless use normal32 also
|
||||||
#define UART 3
|
#define UART 3
|
||||||
#define JOYBUS 4
|
#define JOYBUS 4
|
||||||
#define GP 5
|
#define GP 5
|
||||||
|
#define INFRARED 6 //AdamN: Infrared Register at 4000136h
|
||||||
#define RFU_INIT 0
|
#define RFU_INIT 0
|
||||||
#define RFU_COMM 1
|
#define RFU_COMM 1
|
||||||
#define RFU_SEND 2
|
#define RFU_SEND 2
|
||||||
#define RFU_RECV 3
|
#define RFU_RECV 3
|
||||||
|
|
||||||
#define COMM_SIODATA32_L 0x120
|
#define COMM_SIODATA32_L 0x120 //AdamN: Lower 16bit on Normal mode
|
||||||
#define COMM_SIODATA32_H 0x122
|
#define COMM_SIODATA32_H 0x122 //AdamN: Higher 16bit on Normal mode
|
||||||
|
#define COMM_SIOMULTI0 0x120 //AdamN: SIOMULTI0 (16bit) on MultiPlayer mode (Parent/Master)
|
||||||
|
#define COMM_SIOMULTI1 0x122 //AdamN: SIOMULTI1 (16bit) on MultiPlayer mode (Child1/Slave1)
|
||||||
|
#define COMM_SIOMULTI2 0x124 //AdamN: SIOMULTI2 (16bit) on MultiPlayer mode (Child2/Slave2)
|
||||||
|
#define COMM_SIOMULTI3 0x126 //AdamN: SIOMULTI3 (16bit) on MultiPlayer mode (Child3/Slave3)
|
||||||
#define COMM_SIOCNT 0x128
|
#define COMM_SIOCNT 0x128
|
||||||
#define COMM_SIODATA8 0x12a
|
#define COMM_SIODATA8 0x12a //AdamN: 8bit on Normal/UART mode, (up to 4x8bit with FIFO)
|
||||||
#define COMM_RCNT 0x134
|
#define COMM_SIOMLT_SEND 0x12a //AdamN: SIOMLT_SEND (16bit R/W) on MultiPlayer mode (local outgoing)
|
||||||
|
#define COMM_RCNT 0x134 //AdamN: SIO Mode (4bit data) on GeneralPurpose mode
|
||||||
|
#define COMM_IR 0x136 //AdamN: Infrared Register (16bit) 1bit data at a time(LED On/Off)?
|
||||||
#define COMM_JOYCNT 0x140
|
#define COMM_JOYCNT 0x140
|
||||||
#define COMM_JOY_RECV_L 0x150
|
#define COMM_JOY_RECV_L 0x150 //AdamN: Send/Receive 8bit Lower first then 8bit Higher
|
||||||
#define COMM_JOY_RECV_H 0x152
|
#define COMM_JOY_RECV_H 0x152
|
||||||
#define COMM_JOY_TRANS_L 0x154
|
#define COMM_JOY_TRANS_L 0x154 //AdamN: Send/Receive 8bit Lower first then 8bit Higher
|
||||||
#define COMM_JOY_TRANS_H 0x156
|
#define COMM_JOY_TRANS_H 0x156
|
||||||
#define COMM_JOYSTAT 0x158
|
#define COMM_JOYSTAT 0x158 //AdamN: Send/Receive 8bit lower only
|
||||||
|
|
||||||
#define JOYSTAT_RECV 2
|
#define JOYSTAT_RECV 2
|
||||||
#define JOYSTAT_SEND 8
|
#define JOYSTAT_SEND 8
|
||||||
|
@ -53,11 +64,14 @@ typedef struct {
|
||||||
int lastlinktime;
|
int lastlinktime;
|
||||||
u8 numgbas;
|
u8 numgbas;
|
||||||
u8 linkflags;
|
u8 linkflags;
|
||||||
int rfu_q[4];
|
int rfu_q[5];
|
||||||
u8 rfu_request[4];
|
u16 rfu_qid[5];
|
||||||
int rfu_linktime[4];
|
u8 rfu_request[5];
|
||||||
u32 rfu_bdata[4][7];
|
u16 rfu_reqid[5];
|
||||||
u32 rfu_data[4][32];
|
int rfu_linktime[5];
|
||||||
|
u32 rfu_bdata[5][7]; //for 0x16/0x1d/0x1e?
|
||||||
|
u32 rfu_gdata[5]; //for 0x17/0x19?/0x1e?
|
||||||
|
u32 rfu_data[5][32]; //for 0x24-0x26
|
||||||
} LINKDATA;
|
} LINKDATA;
|
||||||
|
|
||||||
class lserver{
|
class lserver{
|
||||||
|
@ -65,56 +79,81 @@ class lserver{
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
timeval wsocktimeout;
|
timeval wsocktimeout;
|
||||||
//timeval udptimeout;
|
//timeval udptimeout;
|
||||||
|
public:
|
||||||
char inbuffer[256], outbuffer[256];
|
char inbuffer[256], outbuffer[256];
|
||||||
int *intinbuffer;
|
int *intinbuffer;
|
||||||
u16 *u16inbuffer;
|
u16 *u16inbuffer;
|
||||||
|
u32 *u32inbuffer;
|
||||||
int *intoutbuffer;
|
int *intoutbuffer;
|
||||||
u16 *u16outbuffer;
|
u16 *u16outbuffer;
|
||||||
|
u32 *u32outbuffer;
|
||||||
|
int insize, outsize;
|
||||||
int counter;
|
int counter;
|
||||||
int done;
|
int done;
|
||||||
public:
|
|
||||||
int howmanytimes;
|
int howmanytimes;
|
||||||
SOCKET tcpsocket[4];
|
SOCKET tcpsocket[5];
|
||||||
SOCKADDR_IN udpaddr[4];
|
SOCKADDR_IN udpaddr[5];
|
||||||
|
DWORD latency[5];
|
||||||
lserver(void);
|
lserver(void);
|
||||||
int Init(void*);
|
int Init(void*);
|
||||||
void Send(void);
|
BOOL Send(void);
|
||||||
void Recv(void);
|
BOOL Recv(void);
|
||||||
|
BOOL WaitForData(int ms);
|
||||||
|
BOOL SendData(int size, int nretry = 0);
|
||||||
|
BOOL SendData(const char *buf, int size, int nretry = 0);
|
||||||
|
BOOL RecvData(int size, int idx, bool peek = false);
|
||||||
|
BOOL IsDataReady(void);
|
||||||
|
int DiscardData(int idx);
|
||||||
};
|
};
|
||||||
|
|
||||||
class lclient{
|
class lclient{
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
timeval wsocktimeout;
|
timeval wsocktimeout;
|
||||||
|
public:
|
||||||
char inbuffer[256], outbuffer[256];
|
char inbuffer[256], outbuffer[256];
|
||||||
int *intinbuffer;
|
int *intinbuffer;
|
||||||
u16 *u16inbuffer;
|
u16 *u16inbuffer;
|
||||||
|
u32 *u32inbuffer;
|
||||||
int *intoutbuffer;
|
int *intoutbuffer;
|
||||||
u16 *u16outbuffer;
|
u16 *u16outbuffer;
|
||||||
int numbytes;
|
u32 *u32outbuffer;
|
||||||
public:
|
int numbytes, insize, outsize;
|
||||||
bool oncesend;
|
bool oncesend;
|
||||||
SOCKADDR_IN serverinfo;
|
SOCKADDR_IN serverinfo;
|
||||||
SOCKET noblock;
|
SOCKET noblock;
|
||||||
int numtransfers;
|
int numtransfers;
|
||||||
lclient(void);
|
lclient(void);
|
||||||
int Init(LPHOSTENT, void*);
|
int Init(LPHOSTENT, void*);
|
||||||
void Send(void);
|
BOOL Send(void);
|
||||||
void Recv(void);
|
BOOL Recv(void);
|
||||||
void CheckConn(void);
|
void CheckConn(void);
|
||||||
|
BOOL SendData(int size, int nretry = 0);
|
||||||
|
BOOL SendData(const char *buf, int size, int nretry = 0);
|
||||||
|
BOOL RecvData(int size, bool peek = false);
|
||||||
|
BOOL WaitForData(int ms);
|
||||||
|
BOOL IsDataReady(void);
|
||||||
|
int DiscardData(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SOCKET tcpsocket;
|
SOCKET tcpsocket;
|
||||||
//SOCKET udpsocket;
|
//SOCKET udpsocket;
|
||||||
|
DWORD latency;
|
||||||
int numgbas;
|
int numgbas;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 server;
|
u8 server;
|
||||||
bool terminate;
|
bool terminate;
|
||||||
bool connected;
|
bool connected;
|
||||||
bool speed;
|
bool speed; //speedhack
|
||||||
bool active;
|
bool active;
|
||||||
|
int mode;
|
||||||
} LANLINKDATA;
|
} LANLINKDATA;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 Command;
|
||||||
|
u16 Param;
|
||||||
|
} LINKCMDPRM;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern bool gba_joybus_enabled;
|
extern bool gba_joybus_enabled;
|
||||||
|
@ -124,24 +163,47 @@ extern sf::IPAddress joybusHostAddr;
|
||||||
extern void JoyBusConnect();
|
extern void JoyBusConnect();
|
||||||
extern void JoyBusShutdown();
|
extern void JoyBusShutdown();
|
||||||
extern void JoyBusUpdate(int ticks);
|
extern void JoyBusUpdate(int ticks);
|
||||||
|
extern inline int GetSIOMode(u16 siocnt, u16 rcnt);
|
||||||
|
|
||||||
extern bool gba_link_enabled;
|
extern bool gba_link_enabled;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
extern void LogStrPush(const char *str);
|
||||||
|
extern void LogStrPop(int len);
|
||||||
|
extern void LinkCmdQueue(u16 Cmd, u16 Prm);
|
||||||
|
extern u8 gbStartLink(u8 b);
|
||||||
|
extern u16 gbLinkUpdate(u8 b);
|
||||||
extern void StartLink(u16);
|
extern void StartLink(u16);
|
||||||
|
extern void StartLink2(u16);
|
||||||
extern void StartGPLink(u16);
|
extern void StartGPLink(u16);
|
||||||
extern void LinkSSend(u16);
|
extern void LinkSSend(u16);
|
||||||
extern void LinkUpdate(int);
|
extern void LinkUpdate(int);
|
||||||
|
extern void LinkUpdate2(int ticks, int FrameCnt);
|
||||||
extern void LinkChildStop();
|
extern void LinkChildStop();
|
||||||
extern void LinkChildSend(u16);
|
extern void LinkChildSend(u16);
|
||||||
extern void CloseLanLink();
|
extern void CloseLink(); //CloseLanLink(); //AdamN: this should be CloseLink isn't?
|
||||||
extern char *MakeInstanceFilename(const char *Input);
|
extern char *MakeInstanceFilename(const char *Input);
|
||||||
extern LANLINKDATA lanlink;
|
extern LANLINKDATA lanlink;
|
||||||
extern int vbaid;
|
extern int vbaid;
|
||||||
extern bool rfu_enabled;
|
extern bool rfu_enabled;
|
||||||
extern int linktimeout;
|
extern int linktimeout;
|
||||||
|
extern u8 gbSIO_SC;
|
||||||
extern lclient lc;
|
extern lclient lc;
|
||||||
|
extern lserver ls;
|
||||||
extern int linkid;
|
extern int linkid;
|
||||||
|
extern bool linkdatarecvd[4];
|
||||||
|
extern bool LinkIsWaiting;
|
||||||
|
extern bool LinkFirstTime;
|
||||||
|
extern bool EmuReseted;
|
||||||
|
extern int EmuCtr;
|
||||||
|
extern WinHelper::CCriticalSection c_s; //AdamN: critical section object to lock shared resource on multithread as CWnd is not thread-safe
|
||||||
|
extern int LinkCommand;
|
||||||
|
extern int LinkParam1;
|
||||||
|
extern int LinkParam2;
|
||||||
|
extern int LinkParam4;
|
||||||
|
extern int LinkParam8;
|
||||||
|
extern bool LinkHandlerActive;
|
||||||
|
//extern CPtrList LinkCmdList;
|
||||||
#else // These are stubbed for now
|
#else // These are stubbed for now
|
||||||
inline void StartLink(u16){}
|
inline void StartLink(u16){}
|
||||||
inline void StartGPLink(u16){}
|
inline void StartGPLink(u16){}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#define VERBOSE_UNDEFINED 256
|
#define VERBOSE_UNDEFINED 256
|
||||||
#define VERBOSE_AGBPRINT 512
|
#define VERBOSE_AGBPRINT 512
|
||||||
#define VERBOSE_SOUNDOUTPUT 1024
|
#define VERBOSE_SOUNDOUTPUT 1024
|
||||||
|
#define VERBOSE_SIO 2048
|
||||||
|
#define VERBOSE_LINK 4096
|
||||||
|
|
||||||
extern reg_pair reg[45];
|
extern reg_pair reg[45];
|
||||||
extern bool ioReadable[0x400];
|
extern bool ioReadable[0x400];
|
||||||
|
|
|
@ -303,7 +303,7 @@ void soundEvent(u32 address, u16 data)
|
||||||
{
|
{
|
||||||
switch ( address )
|
switch ( address )
|
||||||
{
|
{
|
||||||
case SGCNT0_H:
|
case SGCNT0_H: //SOUNDCNT_H
|
||||||
write_SGCNT0_H( data );
|
write_SGCNT0_H( data );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ void soundEvent(u32 address, u16 data)
|
||||||
WRITE16LE( &ioMem[address], data );
|
WRITE16LE( &ioMem[address], data );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x88:
|
case 0x88: //SOUNDBIAS
|
||||||
data &= 0xC3FF;
|
data &= 0xC3FF;
|
||||||
WRITE16LE( &ioMem[address], data );
|
WRITE16LE( &ioMem[address], data );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -856,7 +856,7 @@ void BIOS_RegisterRamReset(u32 flags)
|
||||||
// no need to trace here. this is only called directly from GBA.cpp
|
// no need to trace here. this is only called directly from GBA.cpp
|
||||||
// to emulate bios initialization
|
// to emulate bios initialization
|
||||||
|
|
||||||
CPUUpdateRegister(0x0, 0x80);
|
CPUUpdateRegister(0x0, 0x80); //DISPCNT
|
||||||
|
|
||||||
if(flags) {
|
if(flags) {
|
||||||
if(flags & 0x01) {
|
if(flags & 0x01) {
|
||||||
|
@ -894,35 +894,35 @@ void BIOS_RegisterRamReset(u32 flags)
|
||||||
for(i = 0; i < 0x18; i++)
|
for(i = 0; i < 0x18; i++)
|
||||||
CPUUpdateRegister(0xb0+i*2, 0);
|
CPUUpdateRegister(0xb0+i*2, 0);
|
||||||
|
|
||||||
CPUUpdateRegister(0x130, 0);
|
CPUUpdateRegister(0x130, 0); //KEYINPUT
|
||||||
CPUUpdateRegister(0x20, 0x100);
|
CPUUpdateRegister(0x20, 0x100); //BG2PA
|
||||||
CPUUpdateRegister(0x30, 0x100);
|
CPUUpdateRegister(0x30, 0x100); //BG3PA
|
||||||
CPUUpdateRegister(0x26, 0x100);
|
CPUUpdateRegister(0x26, 0x100); //BG2PD
|
||||||
CPUUpdateRegister(0x36, 0x100);
|
CPUUpdateRegister(0x36, 0x100); //BG3PD
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags & 0x20) {
|
if(flags & 0x20) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
CPUUpdateRegister(0x110+i*2, 0);
|
CPUUpdateRegister(0x110+i*2, 0); //Unused Registers after Timer Register?
|
||||||
CPUUpdateRegister(0x134, 0x8000);
|
CPUUpdateRegister(0x134, 0x8000); //COMM_RCNT for GP/JOYBUS?
|
||||||
for(i = 0; i < 7; i++)
|
for(i = 0; i < 7; i++)
|
||||||
CPUUpdateRegister(0x140+i*2, 0);
|
CPUUpdateRegister(0x140+i*2, 0); //Unused Registers after COMM_JOYCNT?
|
||||||
}
|
}
|
||||||
|
|
||||||
if(flags & 0x40) {
|
if(flags & 0x40) {
|
||||||
int i;
|
int i;
|
||||||
CPUWriteByte(0x4000084, 0);
|
CPUWriteByte(0x4000084, 0); //SOUNDCNT_X, Is this realy needed as below it's rewritten right?
|
||||||
CPUWriteByte(0x4000084, 0x80);
|
CPUWriteByte(0x4000084, 0x80); //SOUNDCNT_X, Rewritten above?
|
||||||
CPUWriteMemory(0x4000080, 0x880e0000);
|
CPUWriteMemory(0x4000080, 0x880e0000); //SOUNDCNT_L
|
||||||
CPUUpdateRegister(0x88, CPUReadHalfWord(0x4000088)&0x3ff);
|
CPUUpdateRegister(0x88, CPUReadHalfWord(0x4000088)&0x3ff); //SOUNDBIAS
|
||||||
CPUWriteByte(0x4000070, 0x70);
|
CPUWriteByte(0x4000070, 0x70); //SOUND3CNT_L
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
CPUUpdateRegister(0x90+i*2, 0);
|
CPUUpdateRegister(0x90+i*2, 0);
|
||||||
CPUWriteByte(0x4000070, 0);
|
CPUWriteByte(0x4000070, 0); //SOUND3CNT_L, Rewritten again?
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
CPUUpdateRegister(0x90+i*2, 0);
|
CPUUpdateRegister(0x90+i*2, 0);
|
||||||
CPUWriteByte(0x4000084, 0);
|
CPUWriteByte(0x4000084, 0); //SOUNDCNT_X, Another Rewriten??
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
void reset(); // stop and reset the secondary sound buffer
|
void reset(); // stop and reset the secondary sound buffer
|
||||||
void resume(); // resume the secondary sound buffer
|
void resume(); // resume the secondary sound buffer
|
||||||
void write(u16 * finalWave, int length); // write the emulated sound to the secondary sound buffer
|
void write(u16 * finalWave, int length); // write the emulated sound to the secondary sound buffer
|
||||||
|
// Configuration Changes
|
||||||
|
void setThrottle( unsigned short throttle );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,6 +193,8 @@ bool DirectSound::init(long sampleRate)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setThrottle(theApp.throttle); //AdamN: setting sound pitch to current throttle
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +244,7 @@ void DirectSound::write(u16 * finalWave, int length)
|
||||||
LPVOID lpvPtr2;
|
LPVOID lpvPtr2;
|
||||||
DWORD dwBytes2 = 0;
|
DWORD dwBytes2 = 0;
|
||||||
|
|
||||||
if( !speedup && synchronize && !theApp.throttle ) {
|
if( !speedup && synchronize /*&& !theApp.throttle*/ ) {
|
||||||
hr = dsbSecondary->GetStatus(&status);
|
hr = dsbSecondary->GetStatus(&status);
|
||||||
if( status & DSBSTATUS_PLAYING ) {
|
if( status & DSBSTATUS_PLAYING ) {
|
||||||
if( !soundPaused ) {
|
if( !soundPaused ) {
|
||||||
|
@ -310,6 +314,18 @@ void DirectSound::write(u16 * finalWave, int length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DirectSound::setThrottle( unsigned short throttle ) //AdamN: doesn't works quite right yet
|
||||||
|
{
|
||||||
|
if(!pDirectSound) return;
|
||||||
|
if( dsbSecondary == NULL ) return;
|
||||||
|
|
||||||
|
if( throttle == 0 ) throttle = 100;
|
||||||
|
//HRESULT hr = dsbPrimary->SetFrequency( (DWORD)(soundGetSampleRate() * throttle / 100.0f) ); //AdamN: may not be valid for primary buffer, also need to check CAPS whether frequency is supported or not
|
||||||
|
//ASSERT( hr == S_OK );
|
||||||
|
HRESULT hr = dsbSecondary->SetFrequency( (DWORD)(soundGetSampleRate() * throttle / 100.0f) ); //AdamN: may need to use IDirectMusicSegment8::SetLength to adjust the inverval for looping to prevent silence when pitch is higher than normal pitch or restarted/relooped when pitch is lower than normal before it finished the whole stream
|
||||||
|
ASSERT( hr == S_OK );
|
||||||
|
}
|
||||||
|
|
||||||
SoundDriver *newDirectSound()
|
SoundDriver *newDirectSound()
|
||||||
{
|
{
|
||||||
return new DirectSound();
|
return new DirectSound();
|
||||||
|
|
|
@ -33,10 +33,15 @@ Disassemble::Disassemble(CWnd* pParent /*=NULL*/)
|
||||||
m_t = FALSE;
|
m_t = FALSE;
|
||||||
m_v = FALSE;
|
m_v = FALSE;
|
||||||
m_z = FALSE;
|
m_z = FALSE;
|
||||||
|
m_breakpt = FALSE;
|
||||||
|
m_autostep = FALSE;
|
||||||
mode = -1;
|
mode = -1;
|
||||||
//}}AFX_DATA_INIT
|
//}}AFX_DATA_INIT
|
||||||
mode = 0;
|
mode = 0;
|
||||||
address = 0;
|
address = 0;
|
||||||
|
//breakaddr = 0xffffffff;
|
||||||
|
//breakpt = false;
|
||||||
|
autostep = false;
|
||||||
autoUpdate = false;
|
autoUpdate = false;
|
||||||
count = 1;
|
count = 1;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +61,9 @@ void Disassemble::DoDataExchange(CDataExchange* pDX)
|
||||||
DDX_Check(pDX, IDC_V, m_v);
|
DDX_Check(pDX, IDC_V, m_v);
|
||||||
DDX_Check(pDX, IDC_Z, m_z);
|
DDX_Check(pDX, IDC_Z, m_z);
|
||||||
DDX_Radio(pDX, IDC_AUTOMATIC, mode);
|
DDX_Radio(pDX, IDC_AUTOMATIC, mode);
|
||||||
|
DDX_Check(pDX, IDC_BREAK_AT, m_breakpt);
|
||||||
|
DDX_Control(pDX, IDC_ADDRESS2, m_address2);
|
||||||
|
DDX_Check(pDX, IDC_AUTO_STEP, m_autostep);
|
||||||
//}}AFX_DATA_MAP
|
//}}AFX_DATA_MAP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +81,8 @@ BEGIN_MESSAGE_MAP(Disassemble, CDialog)
|
||||||
ON_BN_CLICKED(IDC_THUMB, OnThumb)
|
ON_BN_CLICKED(IDC_THUMB, OnThumb)
|
||||||
ON_WM_VSCROLL()
|
ON_WM_VSCROLL()
|
||||||
//}}AFX_MSG_MAP
|
//}}AFX_MSG_MAP
|
||||||
|
ON_BN_CLICKED(IDC_BREAK_AT, &Disassemble::OnBnClickedBreakAt)
|
||||||
|
ON_BN_CLICKED(IDC_STEPINTO, &Disassemble::OnBnClickedStepinto)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -338,3 +348,38 @@ void Disassemble::PostNcDestroy()
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Disassemble::OnBnClickedBreakAt()
|
||||||
|
{
|
||||||
|
// TODO: Add your control notification handler code here
|
||||||
|
CString buffer;
|
||||||
|
m_address2.GetWindowText(buffer);
|
||||||
|
sscanf(buffer, "%x", &breakaddr);
|
||||||
|
//if (mode==1)
|
||||||
|
breakaddr&=0xfffffffc;
|
||||||
|
//else if (mode==2)
|
||||||
|
// breakaddr&=0xfffffffe;
|
||||||
|
m_breakpt = !m_breakpt;
|
||||||
|
breakpt = (bool)m_breakpt;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Disassemble::OnBnClickedStepinto()
|
||||||
|
{
|
||||||
|
// TODO: Add your control notification handler code here
|
||||||
|
if(rom != NULL)
|
||||||
|
{
|
||||||
|
if(armState)
|
||||||
|
breakaddr = breakaddr + 4;
|
||||||
|
else
|
||||||
|
breakaddr = breakaddr + 2;
|
||||||
|
char buffer[20];
|
||||||
|
sprintf(buffer, _T("%08x"), breakaddr);
|
||||||
|
m_address2.SetWindowText(buffer);
|
||||||
|
cpuNextEvent = 1; //cpuTotalTicks;
|
||||||
|
holdState = false;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,13 +22,17 @@ class Disassemble : public ResizeDlg, IUpdateListener
|
||||||
void refresh();
|
void refresh();
|
||||||
int count;
|
int count;
|
||||||
bool autoUpdate;
|
bool autoUpdate;
|
||||||
|
//bool breakpt;
|
||||||
|
bool autostep;
|
||||||
u32 address;
|
u32 address;
|
||||||
|
//u32 breakaddr;
|
||||||
Disassemble(CWnd* pParent = NULL); // standard constructor
|
Disassemble(CWnd* pParent = NULL); // standard constructor
|
||||||
|
|
||||||
// Dialog Data
|
// Dialog Data
|
||||||
//{{AFX_DATA(Disassemble)
|
//{{AFX_DATA(Disassemble)
|
||||||
enum { IDD = IDD_DISASSEMBLE };
|
enum { IDD = IDD_DISASSEMBLE };
|
||||||
CEdit m_address;
|
CEdit m_address;
|
||||||
|
CEdit m_address2;
|
||||||
CListBox m_list;
|
CListBox m_list;
|
||||||
BOOL m_c;
|
BOOL m_c;
|
||||||
BOOL m_f;
|
BOOL m_f;
|
||||||
|
@ -37,6 +41,8 @@ class Disassemble : public ResizeDlg, IUpdateListener
|
||||||
BOOL m_t;
|
BOOL m_t;
|
||||||
BOOL m_v;
|
BOOL m_v;
|
||||||
BOOL m_z;
|
BOOL m_z;
|
||||||
|
BOOL m_breakpt;
|
||||||
|
BOOL m_autostep;
|
||||||
int mode;
|
int mode;
|
||||||
//}}AFX_DATA
|
//}}AFX_DATA
|
||||||
|
|
||||||
|
@ -67,6 +73,9 @@ class Disassemble : public ResizeDlg, IUpdateListener
|
||||||
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||||
//}}AFX_MSG
|
//}}AFX_MSG
|
||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
|
public:
|
||||||
|
afx_msg void OnBnClickedBreakAt();
|
||||||
|
afx_msg void OnBnClickedStepinto();
|
||||||
};
|
};
|
||||||
|
|
||||||
//{{AFX_INSERT_LOCATION}}
|
//{{AFX_INSERT_LOCATION}}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
//#include "afxctl.h"
|
||||||
#include "vba.h"
|
#include "vba.h"
|
||||||
#include "LinkOptions.h"
|
#include "LinkOptions.h"
|
||||||
#include "../gba/GBALink.h"
|
#include "../gba/GBALink.h"
|
||||||
|
|
||||||
|
/*#ifdef _MSC_VER //#ifdef _WIN32
|
||||||
|
#include "WinHelper.h" // AdamN: MFC MultiThreading
|
||||||
|
#endif*/
|
||||||
|
|
||||||
extern lserver ls;
|
extern lserver ls;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -49,7 +54,7 @@ void LinkOptions::DoDataExchange(CDataExchange* pDX)
|
||||||
|
|
||||||
BOOL LinkOptions::OnInitDialog(){
|
BOOL LinkOptions::OnInitDialog(){
|
||||||
TCITEM tabitem;
|
TCITEM tabitem;
|
||||||
char tabtext[3][8] = {"General", "Server", "Client"};
|
char tabtext[3][8] = {_T("General"), _T("Server"), _T("Client")};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
@ -145,6 +150,11 @@ void LinkServer::DoDataExchange(CDataExchange* pDX)
|
||||||
{
|
{
|
||||||
CDialog::DoDataExchange(pDX);
|
CDialog::DoDataExchange(pDX);
|
||||||
//{{AFX_DATA_MAP(LinkServer)
|
//{{AFX_DATA_MAP(LinkServer)
|
||||||
|
BOOL ok = (theApp.cartridgeType != IMAGE_GB);
|
||||||
|
GetDlgItem(IDC_LINK3P)->EnableWindow(ok);
|
||||||
|
GetDlgItem(IDC_LINK4P)->EnableWindow(ok);
|
||||||
|
GetDlgItem(IDC_LINK5P)->EnableWindow(rfu_enabled && ok);
|
||||||
|
|
||||||
DDX_Radio(pDX, IDC_LINK2P, m_numplayers);
|
DDX_Radio(pDX, IDC_LINK2P, m_numplayers);
|
||||||
DDX_Radio(pDX, IDC_LINKTCP, m_prottype);
|
DDX_Radio(pDX, IDC_LINKTCP, m_prottype);
|
||||||
DDX_Check(pDX, IDC_SSPEED, m_speed);
|
DDX_Check(pDX, IDC_SSPEED, m_speed);
|
||||||
|
@ -195,7 +205,7 @@ BOOL LinkServer::OnInitDialog()
|
||||||
{
|
{
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
|
||||||
m_numplayers = lanlink.numgbas;
|
m_numplayers = max(lanlink.numgbas-1,0);
|
||||||
m_prottype = lanlink.type;
|
m_prottype = lanlink.type;
|
||||||
m_speed = lanlink.speed;
|
m_speed = lanlink.speed;
|
||||||
|
|
||||||
|
@ -455,14 +465,14 @@ void LinkOptions::OnOk()
|
||||||
void LinkGeneral::OnRadio1()
|
void LinkGeneral::OnRadio1()
|
||||||
{
|
{
|
||||||
m_type = 0;
|
m_type = 0;
|
||||||
lanlink.active = 0;
|
lanlink.active = 0; //Single Computer
|
||||||
GetParent()->Invalidate();
|
GetParent()->Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkGeneral::OnRadio2()
|
void LinkGeneral::OnRadio2()
|
||||||
{
|
{
|
||||||
m_type = 1;
|
m_type = 1;
|
||||||
lanlink.active = 1;
|
lanlink.active = 1; //Networks
|
||||||
GetParent()->Invalidate();
|
GetParent()->Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +483,7 @@ BOOL LinkGeneral::OnInitDialog(){
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
|
||||||
m_timeout.LimitText(5);
|
m_timeout.LimitText(5);
|
||||||
sprintf(timeout, "%d", linktimeout);
|
sprintf(timeout, _T("%d"), linktimeout);
|
||||||
m_timeout.SetWindowText(timeout);
|
m_timeout.SetWindowText(timeout);
|
||||||
|
|
||||||
m_type = lanlink.active;
|
m_type = lanlink.active;
|
||||||
|
@ -504,8 +514,8 @@ void LinkServer::OnServerStart()
|
||||||
|
|
||||||
if((errorcode=ls.Init(&dlg))!=0){
|
if((errorcode=ls.Init(&dlg))!=0){
|
||||||
char message[50];
|
char message[50];
|
||||||
sprintf(message, "Error %d occured.\nPlease try again.", errorcode);
|
sprintf(message, _T("Error %d occured.\nPlease try again."), errorcode);
|
||||||
MessageBox(message, "Error", MB_OK);
|
MessageBox(message, _T("Error"), MB_OK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,6 +530,7 @@ BOOL LinkClient::OnInitDialog()
|
||||||
|
|
||||||
m_prottype = lanlink.type;
|
m_prottype = lanlink.type;
|
||||||
m_hacks = lanlink.speed;
|
m_hacks = lanlink.speed;
|
||||||
|
m_serverip.SetWindowText(_T("localhost"));
|
||||||
|
|
||||||
UpdateData(FALSE);
|
UpdateData(FALSE);
|
||||||
|
|
||||||
|
@ -541,9 +552,10 @@ void LinkClient::OnLinkConnect()
|
||||||
m_serverip.GetWindowText(ipaddress, 30);
|
m_serverip.GetWindowText(ipaddress, 30);
|
||||||
|
|
||||||
if((errorcode=lc.Init(gethostbyname(ipaddress), &dlg))!=0){
|
if((errorcode=lc.Init(gethostbyname(ipaddress), &dlg))!=0){
|
||||||
|
|
||||||
char message[50];
|
char message[50];
|
||||||
sprintf(message, "Error %d occured.\nPlease try again.", errorcode);
|
sprintf(message, _T("Error %d occured.\nPlease try again."), errorcode);
|
||||||
MessageBox(message, "Error", MB_OK);
|
MessageBox(message, _T("Error"), MB_OK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dlg.DoModal();
|
dlg.DoModal();
|
||||||
|
@ -557,7 +569,7 @@ void LinkOptions::GetAllData(LinkGeneral *src)
|
||||||
src->UpdateData(true);
|
src->UpdateData(true);
|
||||||
|
|
||||||
src->m_timeout.GetWindowText(timeout, 5);
|
src->m_timeout.GetWindowText(timeout, 5);
|
||||||
sscanf(timeout, "%d", &linktimeout);
|
sscanf(timeout, _T("%d"), &linktimeout);
|
||||||
|
|
||||||
if(src->m_type==0){
|
if(src->m_type==0){
|
||||||
lanlink.speed = 0;
|
lanlink.speed = 0;
|
||||||
|
@ -593,6 +605,7 @@ void ServerWait::DoDataExchange(CDataExchange* pDX)
|
||||||
//}}AFX_DATA_MAP
|
//}}AFX_DATA_MAP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(ServerWait, CDialog)
|
BEGIN_MESSAGE_MAP(ServerWait, CDialog)
|
||||||
//{{AFX_MSG_MAP(ServerWait)
|
//{{AFX_MSG_MAP(ServerWait)
|
||||||
ON_BN_CLICKED(ID_CANCEL, OnCancel)
|
ON_BN_CLICKED(ID_CANCEL, OnCancel)
|
||||||
|
@ -604,7 +617,9 @@ END_MESSAGE_MAP()
|
||||||
|
|
||||||
void ServerWait::OnCancel()
|
void ServerWait::OnCancel()
|
||||||
{
|
{
|
||||||
lanlink.terminate = true;
|
c_s.Lock(); //AdamN: Locking resource to prevent deadlock
|
||||||
|
lanlink.terminate = true; //AdamN: accessing this might not be thread-safe w/o locking
|
||||||
|
c_s.Unlock(); //AdamN: Unlock it after use
|
||||||
CDialog::OnCancel();
|
CDialog::OnCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ Logging::Logging(CWnd* pParent /*=NULL*/)
|
||||||
m_dma3 = FALSE;
|
m_dma3 = FALSE;
|
||||||
m_agbprint = FALSE;
|
m_agbprint = FALSE;
|
||||||
m_undefined = FALSE;
|
m_undefined = FALSE;
|
||||||
|
m_sio = FALSE;
|
||||||
//}}AFX_DATA_INIT
|
//}}AFX_DATA_INIT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +53,8 @@ void Logging::DoDataExchange(CDataExchange* pDX)
|
||||||
DDX_Check(pDX, IDC_VERBOSE_AGBPRINT, m_agbprint);
|
DDX_Check(pDX, IDC_VERBOSE_AGBPRINT, m_agbprint);
|
||||||
DDX_Check(pDX, IDC_VERBOSE_UNDEFINED, m_undefined);
|
DDX_Check(pDX, IDC_VERBOSE_UNDEFINED, m_undefined);
|
||||||
DDX_Check(pDX, IDC_VERBOSE_SOUNDOUTPUT, m_sound_output);
|
DDX_Check(pDX, IDC_VERBOSE_SOUNDOUTPUT, m_sound_output);
|
||||||
|
DDX_Check(pDX, IDC_VERBOSE_SIO, m_sio);
|
||||||
|
DDX_Check(pDX, IDC_VERBOSE_LINK, m_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,10 +72,13 @@ BEGIN_MESSAGE_MAP(Logging, CDialog)
|
||||||
ON_BN_CLICKED(IDC_VERBOSE_UNALIGNED_ACCESS, OnVerboseUnalignedAccess)
|
ON_BN_CLICKED(IDC_VERBOSE_UNALIGNED_ACCESS, OnVerboseUnalignedAccess)
|
||||||
ON_BN_CLICKED(IDC_VERBOSE_UNDEFINED, OnVerboseUndefined)
|
ON_BN_CLICKED(IDC_VERBOSE_UNDEFINED, OnVerboseUndefined)
|
||||||
ON_BN_CLICKED(IDC_VERBOSE_SOUNDOUTPUT, OnVerboseSoundoutput)
|
ON_BN_CLICKED(IDC_VERBOSE_SOUNDOUTPUT, OnVerboseSoundoutput)
|
||||||
|
ON_BN_CLICKED(IDC_VERBOSE_SIO, OnVerboseSIO)
|
||||||
ON_BN_CLICKED(IDC_SAVE, OnSave)
|
ON_BN_CLICKED(IDC_SAVE, OnSave)
|
||||||
ON_EN_ERRSPACE(IDC_LOG, OnErrspaceLog)
|
ON_EN_ERRSPACE(IDC_LOG, OnErrspaceLog)
|
||||||
ON_EN_MAXTEXT(IDC_LOG, OnMaxtextLog)
|
ON_EN_MAXTEXT(IDC_LOG, OnMaxtextLog)
|
||||||
ON_WM_CLOSE()
|
ON_WM_CLOSE()
|
||||||
|
// ON_BN_CLICKED(IDC_VERBOSE_LINK, &Logging::OnBnClickedVerboseLink)
|
||||||
|
ON_BN_CLICKED(IDC_VERBOSE_LINK, &Logging::OnVerboseLink)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,6 +153,16 @@ void Logging::OnVerboseSoundoutput()
|
||||||
systemVerbose ^= VERBOSE_SOUNDOUTPUT;
|
systemVerbose ^= VERBOSE_SOUNDOUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Logging::OnVerboseSIO()
|
||||||
|
{
|
||||||
|
systemVerbose ^= VERBOSE_SIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logging::OnVerboseLink()
|
||||||
|
{
|
||||||
|
systemVerbose ^= VERBOSE_LINK;
|
||||||
|
}
|
||||||
|
|
||||||
void Logging::OnSave()
|
void Logging::OnSave()
|
||||||
{
|
{
|
||||||
int len = m_log.GetWindowTextLength();
|
int len = m_log.GetWindowTextLength();
|
||||||
|
@ -213,6 +229,8 @@ BOOL Logging::OnInitDialog()
|
||||||
m_undefined = (systemVerbose & VERBOSE_UNDEFINED) != 0;
|
m_undefined = (systemVerbose & VERBOSE_UNDEFINED) != 0;
|
||||||
m_agbprint = (systemVerbose & VERBOSE_AGBPRINT) != 0;
|
m_agbprint = (systemVerbose & VERBOSE_AGBPRINT) != 0;
|
||||||
m_sound_output = (systemVerbose & VERBOSE_SOUNDOUTPUT) != 0;
|
m_sound_output = (systemVerbose & VERBOSE_SOUNDOUTPUT) != 0;
|
||||||
|
m_sio = (systemVerbose & VERBOSE_SIO) != 0;
|
||||||
|
m_link = (systemVerbose & VERBOSE_LINK) != 0;
|
||||||
UpdateData(FALSE);
|
UpdateData(FALSE);
|
||||||
|
|
||||||
m_log.LimitText(-1);
|
m_log.LimitText(-1);
|
||||||
|
@ -293,3 +311,7 @@ void toolsClearLog()
|
||||||
Logging::instance->clearLog();
|
Logging::instance->clearLog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
BOOL m_agbprint;
|
BOOL m_agbprint;
|
||||||
BOOL m_undefined;
|
BOOL m_undefined;
|
||||||
BOOL m_sound_output;
|
BOOL m_sound_output;
|
||||||
|
BOOL m_sio;
|
||||||
|
BOOL m_link;
|
||||||
|
|
||||||
// Overrides
|
// Overrides
|
||||||
protected:
|
protected:
|
||||||
|
@ -47,6 +49,8 @@ protected:
|
||||||
afx_msg void OnVerboseUnalignedAccess();
|
afx_msg void OnVerboseUnalignedAccess();
|
||||||
afx_msg void OnVerboseUndefined();
|
afx_msg void OnVerboseUndefined();
|
||||||
afx_msg void OnVerboseSoundoutput();
|
afx_msg void OnVerboseSoundoutput();
|
||||||
|
afx_msg void OnVerboseSIO();
|
||||||
|
afx_msg void OnVerboseLink();
|
||||||
afx_msg void OnSave();
|
afx_msg void OnSave();
|
||||||
afx_msg void OnClose();
|
afx_msg void OnClose();
|
||||||
afx_msg void OnErrspaceLog();
|
afx_msg void OnErrspaceLog();
|
||||||
|
|
|
@ -40,7 +40,12 @@
|
||||||
void MainWnd::OnOptionsFrameskipThrottleNothrottle()
|
void MainWnd::OnOptionsFrameskipThrottleNothrottle()
|
||||||
{
|
{
|
||||||
theApp.updateThrottle( 0 ); // disable
|
theApp.updateThrottle( 0 ); // disable
|
||||||
theApp.autoFrameSkip = false;
|
/*if(theApp.autoFrameSkip) {
|
||||||
|
frameSkip = 0;
|
||||||
|
gbFrameSkip = 0;
|
||||||
|
systemFrameSkip = 0;
|
||||||
|
}
|
||||||
|
theApp.autoFrameSkip = false;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
|
||||||
|
@ -52,7 +57,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsFrameskipThrottle25()
|
void MainWnd::OnOptionsFrameskipThrottle25()
|
||||||
{
|
{
|
||||||
theApp.updateThrottle( 25 );
|
theApp.updateThrottle( 25 );
|
||||||
theApp.autoFrameSkip = false;
|
//theApp.autoFrameSkip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
|
||||||
|
@ -64,7 +69,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsFrameskipThrottle50()
|
void MainWnd::OnOptionsFrameskipThrottle50()
|
||||||
{
|
{
|
||||||
theApp.updateThrottle( 50 );
|
theApp.updateThrottle( 50 );
|
||||||
theApp.autoFrameSkip = false;
|
//theApp.autoFrameSkip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
|
||||||
|
@ -76,7 +81,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsFrameskipThrottle100()
|
void MainWnd::OnOptionsFrameskipThrottle100()
|
||||||
{
|
{
|
||||||
theApp.updateThrottle( 100 );
|
theApp.updateThrottle( 100 );
|
||||||
theApp.autoFrameSkip = false;
|
//theApp.autoFrameSkip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
|
||||||
|
@ -88,7 +93,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsFrameskipThrottle150()
|
void MainWnd::OnOptionsFrameskipThrottle150()
|
||||||
{
|
{
|
||||||
theApp.updateThrottle( 150 );
|
theApp.updateThrottle( 150 );
|
||||||
theApp.autoFrameSkip = false;
|
//theApp.autoFrameSkip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
|
||||||
|
@ -100,7 +105,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsFrameskipThrottle200()
|
void MainWnd::OnOptionsFrameskipThrottle200()
|
||||||
{
|
{
|
||||||
theApp.updateThrottle( 200 );
|
theApp.updateThrottle( 200 );
|
||||||
theApp.autoFrameSkip = false;
|
//theApp.autoFrameSkip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI)
|
||||||
|
@ -116,7 +121,7 @@ void MainWnd::OnOptionsFrameskipThrottleOther()
|
||||||
|
|
||||||
if( v ) {
|
if( v ) {
|
||||||
theApp.updateThrottle( v );
|
theApp.updateThrottle( v );
|
||||||
theApp.autoFrameSkip = false;
|
//theApp.autoFrameSkip = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,12 +142,16 @@ void MainWnd::OnOptionsFrameskipAutomatic()
|
||||||
theApp.autoFrameSkip = !theApp.autoFrameSkip;
|
theApp.autoFrameSkip = !theApp.autoFrameSkip;
|
||||||
if(!theApp.autoFrameSkip && emulating)
|
if(!theApp.autoFrameSkip && emulating)
|
||||||
theApp.updateFrameSkip();
|
theApp.updateFrameSkip();
|
||||||
else
|
else if(theApp.autoFrameSkip)
|
||||||
{
|
{
|
||||||
theApp.throttle = false;
|
//theApp.throttle = false;
|
||||||
frameSkip = 0;
|
frameSkip = 9;
|
||||||
|
gbFrameSkip = 9;
|
||||||
systemFrameSkip = 0;
|
systemFrameSkip = 0;
|
||||||
}
|
}
|
||||||
|
//frameSkip = 0;
|
||||||
|
//gbFrameSkip = 0;
|
||||||
|
//systemFrameSkip = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsFrameskipAutomatic(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsFrameskipAutomatic(CCmdUI* pCmdUI)
|
||||||
|
@ -152,6 +161,7 @@ void MainWnd::OnUpdateOptionsFrameskipAutomatic(CCmdUI* pCmdUI)
|
||||||
|
|
||||||
BOOL MainWnd::OnOptionsFrameskip(UINT nID)
|
BOOL MainWnd::OnOptionsFrameskip(UINT nID)
|
||||||
{
|
{
|
||||||
|
//theApp.autoFrameSkip = false;
|
||||||
switch(nID) {
|
switch(nID) {
|
||||||
case ID_OPTIONS_VIDEO_FRAMESKIP_0:
|
case ID_OPTIONS_VIDEO_FRAMESKIP_0:
|
||||||
case ID_OPTIONS_VIDEO_FRAMESKIP_1:
|
case ID_OPTIONS_VIDEO_FRAMESKIP_1:
|
||||||
|
@ -166,7 +176,7 @@ BOOL MainWnd::OnOptionsFrameskip(UINT nID)
|
||||||
}
|
}
|
||||||
if(emulating)
|
if(emulating)
|
||||||
theApp.updateFrameSkip();
|
theApp.updateFrameSkip();
|
||||||
theApp.updateThrottle( 0 );
|
//theApp.updateThrottle( 0 );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
case ID_OPTIONS_VIDEO_FRAMESKIP_6:
|
case ID_OPTIONS_VIDEO_FRAMESKIP_6:
|
||||||
|
@ -180,7 +190,7 @@ BOOL MainWnd::OnOptionsFrameskip(UINT nID)
|
||||||
}
|
}
|
||||||
if(emulating)
|
if(emulating)
|
||||||
theApp.updateFrameSkip();
|
theApp.updateFrameSkip();
|
||||||
theApp.updateThrottle( 0 );
|
//theApp.updateThrottle( 0 );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -585,8 +595,13 @@ void MainWnd::OnUpdateOptionsEmulatorDisablestatusmessages(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsEmulatorSynchronize()
|
void MainWnd::OnOptionsEmulatorSynchronize()
|
||||||
{
|
{
|
||||||
synchronize = !synchronize;
|
synchronize = !synchronize;
|
||||||
if (synchronize)
|
if (synchronize) {
|
||||||
theApp.throttle = false;
|
//theApp.throttle = false;
|
||||||
|
//theApp.autoFrameSkip = false;
|
||||||
|
frameSkip = 0;
|
||||||
|
gbFrameSkip = 0;
|
||||||
|
systemFrameSkip = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsEmulatorSynchronize(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsEmulatorSynchronize(CCmdUI* pCmdUI)
|
||||||
|
@ -1023,6 +1038,8 @@ void MainWnd::OnUpdateOptionsGameboyBorder(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsGameboyPrinter()
|
void MainWnd::OnOptionsGameboyPrinter()
|
||||||
{
|
{
|
||||||
theApp.winGbPrinterEnabled = !theApp.winGbPrinterEnabled;
|
theApp.winGbPrinterEnabled = !theApp.winGbPrinterEnabled;
|
||||||
|
if(gba_link_enabled)
|
||||||
|
gbSerialFunction = gbStartLink; else
|
||||||
if(theApp.winGbPrinterEnabled)
|
if(theApp.winGbPrinterEnabled)
|
||||||
gbSerialFunction = gbPrinterSend;
|
gbSerialFunction = gbPrinterSend;
|
||||||
else
|
else
|
||||||
|
@ -1560,7 +1577,7 @@ void MainWnd::OnOptionsLinkRFU()
|
||||||
if(rfu_enabled) rfu_enabled = false;
|
if(rfu_enabled) rfu_enabled = false;
|
||||||
else {
|
else {
|
||||||
rfu_enabled = true;
|
rfu_enabled = true;
|
||||||
MessageBox("Please note this is the first version\nof RFU emulation code and it's not 100% bug free.\nAlso only 2 players single computer are supported at this time.", "Warning", MB_OK);
|
//MessageBox("Please note this is the first version\nof RFU emulation code and it's not 100% bug free.\nAlso only 2 players single computer are supported at this time.", "Warning", MB_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1572,6 +1589,12 @@ void MainWnd::OnUpdateOptionsLinkEnable(CCmdUI* pCmdUI)
|
||||||
void MainWnd::OnOptionsLinkEnable()
|
void MainWnd::OnOptionsLinkEnable()
|
||||||
{
|
{
|
||||||
gba_link_enabled = !gba_link_enabled;
|
gba_link_enabled = !gba_link_enabled;
|
||||||
|
if(gba_link_enabled)
|
||||||
|
gbSerialFunction = gbStartLink; else
|
||||||
|
if(theApp.winGbPrinterEnabled)
|
||||||
|
gbSerialFunction = gbPrinterSend;
|
||||||
|
else
|
||||||
|
gbSerialFunction = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWnd::OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI)
|
void MainWnd::OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI)
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
void reset(); // stop and reset the secondary sound buffer
|
void reset(); // stop and reset the secondary sound buffer
|
||||||
void resume(); // play/resume the secondary sound buffer
|
void resume(); // play/resume the secondary sound buffer
|
||||||
void write(u16 * finalWave, int length); // write the emulated sound to a sound buffer
|
void write(u16 * finalWave, int length); // write the emulated sound to a sound buffer
|
||||||
|
void setThrottle( unsigned short throttle ); //pitch
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OPENALFNTABLE ALFunction;
|
OPENALFNTABLE ALFunction;
|
||||||
|
@ -181,6 +182,8 @@ bool OpenAL::init(long sampleRate)
|
||||||
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
|
setThrottle(theApp.throttle); //setting pitch to current throttle
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +284,7 @@ void OpenAL::write(u16 * finalWave, int length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !speedup && synchronize && !theApp.throttle ) {
|
if( !speedup && synchronize /*&& !theApp.throttle*/ ) {
|
||||||
// wait until at least one buffer has finished
|
// wait until at least one buffer has finished
|
||||||
while( nBuffersProcessed == 0 ) {
|
while( nBuffersProcessed == 0 ) {
|
||||||
winlog( " waiting...\n" );
|
winlog( " waiting...\n" );
|
||||||
|
@ -320,6 +323,20 @@ void OpenAL::write(u16 * finalWave, int length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenAL::setThrottle( unsigned short throttle )
|
||||||
|
{
|
||||||
|
if( !initialized ) return;
|
||||||
|
winlog( "OpenAL::setThrottle\n" );
|
||||||
|
|
||||||
|
debugState();
|
||||||
|
|
||||||
|
if( throttle == 0 ) throttle = 100;
|
||||||
|
ALFunction.alSourcef(source, AL_PITCH, (float)throttle / 100.0f );
|
||||||
|
ASSERT_SUCCESS;
|
||||||
|
|
||||||
|
debugState(); //AdamN: is this needed?
|
||||||
|
}
|
||||||
|
|
||||||
SoundDriver *newOpenAL()
|
SoundDriver *newOpenAL()
|
||||||
{
|
{
|
||||||
winlog( "newOpenAL\n" );
|
winlog( "newOpenAL\n" );
|
||||||
|
|
|
@ -59,8 +59,8 @@ void Throttle::OnOk()
|
||||||
{
|
{
|
||||||
UpdateData();
|
UpdateData();
|
||||||
|
|
||||||
if(m_throttle < 5 || m_throttle > 1000)
|
if(m_throttle < 5 || m_throttle > 2000)
|
||||||
systemMessage(IDS_INVALID_THROTTLE_VALUE, "Invalid throttle value. Please enter a number between 5 and 1000");
|
systemMessage(IDS_INVALID_THROTTLE_VALUE, "Invalid throttle value. Please enter a number between 5 and 2000");
|
||||||
else
|
else
|
||||||
EndDialog(m_throttle);
|
EndDialog(m_throttle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,9 @@ void winOutput(const char *, u32);
|
||||||
void (*dbgSignal)(int,int) = winSignal;
|
void (*dbgSignal)(int,int) = winSignal;
|
||||||
void (*dbgOutput)(const char *, u32) = winOutput;
|
void (*dbgOutput)(const char *, u32) = winOutput;
|
||||||
|
|
||||||
|
int lastSA = 0;
|
||||||
|
int lastSR = 0;
|
||||||
|
|
||||||
#ifdef MMX
|
#ifdef MMX
|
||||||
extern "C" bool cpu_mmx;
|
extern "C" bool cpu_mmx;
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,7 +159,7 @@ extern "C" bool cpu_mmx;
|
||||||
namespace Sm60FPS
|
namespace Sm60FPS
|
||||||
{
|
{
|
||||||
float K_fCpuSpeed = 100.0f; // was 98.0f before, but why?
|
float K_fCpuSpeed = 100.0f; // was 98.0f before, but why?
|
||||||
float K_fTargetFps = 60.0f * K_fCpuSpeed / 100;
|
float K_fTargetFps = 60.0f * K_fCpuSpeed / 100.0f;
|
||||||
float K_fDT = 1000.0f / K_fTargetFps;
|
float K_fDT = 1000.0f / K_fTargetFps;
|
||||||
|
|
||||||
u32 dwTimeElapse;
|
u32 dwTimeElapse;
|
||||||
|
@ -167,6 +170,7 @@ namespace Sm60FPS
|
||||||
float fCurFPS;
|
float fCurFPS;
|
||||||
bool bLastSkip;
|
bool bLastSkip;
|
||||||
int nCurSpeed;
|
int nCurSpeed;
|
||||||
|
float nPrvSpeed;
|
||||||
int bSaveMoreCPU;
|
int bSaveMoreCPU;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -336,8 +340,21 @@ VBA::VBA()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CString DataHex(const char *buf, int len) {
|
||||||
|
CString dat = _T("");
|
||||||
|
if(buf!=NULL && len>0) {
|
||||||
|
for(int i=0; i<len; i++) {
|
||||||
|
dat.AppendFormat(_T("%02X "), (byte)buf[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
VBA::~VBA()
|
VBA::~VBA()
|
||||||
{
|
{
|
||||||
|
c_s.Lock();
|
||||||
|
AppTerminated = true;
|
||||||
|
c_s.Unlock();
|
||||||
rpiCleanup();
|
rpiCleanup();
|
||||||
InterframeCleanup();
|
InterframeCleanup();
|
||||||
|
|
||||||
|
@ -352,6 +369,8 @@ VBA::~VBA()
|
||||||
|
|
||||||
JoyBusShutdown();
|
JoyBusShutdown();
|
||||||
|
|
||||||
|
CloseLink(); //AdamN: closing connections gracefully
|
||||||
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
if(moviePlaying) {
|
if(moviePlaying) {
|
||||||
|
@ -422,6 +441,8 @@ BOOL VBA::InitInstance()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//SetProcessAffinityMask(GetCurrentProcess(), 1); //AdamN: using only 1 CPU for all threads in this process for testing if there were bug caused by deadlock
|
||||||
|
|
||||||
SetRegistryKey(_T("VBA"));
|
SetRegistryKey(_T("VBA"));
|
||||||
|
|
||||||
remoteSetProtocol(0);
|
remoteSetProtocol(0);
|
||||||
|
@ -447,6 +468,7 @@ BOOL VBA::InitInstance()
|
||||||
|
|
||||||
if(!InitLink())
|
if(!InitLink())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
lanlink.mode = NORMAL8;
|
||||||
|
|
||||||
bool force = false;
|
bool force = false;
|
||||||
|
|
||||||
|
@ -839,18 +861,21 @@ void VBA::updateFilter()
|
||||||
|
|
||||||
void VBA::updateThrottle( unsigned short throttle )
|
void VBA::updateThrottle( unsigned short throttle )
|
||||||
{
|
{
|
||||||
|
//if(throttle>100 && synchronize) throttle = 100; //max speed when audio sync enabled is 100%
|
||||||
|
|
||||||
this->throttle = throttle;
|
this->throttle = throttle;
|
||||||
|
|
||||||
if( throttle ) {
|
if( throttle ) {
|
||||||
Sm60FPS::K_fCpuSpeed = (float)throttle;
|
Sm60FPS::K_fCpuSpeed = (float)throttle;
|
||||||
Sm60FPS::K_fTargetFps = 60.0f * Sm60FPS::K_fCpuSpeed / 100;
|
Sm60FPS::K_fTargetFps = 60.0f * Sm60FPS::K_fCpuSpeed / 100;
|
||||||
Sm60FPS::K_fDT = 1000.0f / Sm60FPS::K_fTargetFps;
|
Sm60FPS::K_fDT = 1000.0f / Sm60FPS::K_fTargetFps;
|
||||||
autoFrameSkip = false;
|
/*autoFrameSkip = true;
|
||||||
frameSkip = 0;
|
frameSkip = 0;
|
||||||
systemFrameSkip = 0;
|
gbFrameSkip = 0;
|
||||||
|
systemFrameSkip = 0;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
soundSetThrottle(throttle);
|
soundSetThrottle(throttle); //AdamN: only XAudio2 that have this feature? (added for OpenAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1065,14 +1090,13 @@ void systemFrame()
|
||||||
|
|
||||||
void system10Frames(int rate)
|
void system10Frames(int rate)
|
||||||
{
|
{
|
||||||
|
|
||||||
if( theApp.autoFrameSkip )
|
if( theApp.autoFrameSkip )
|
||||||
{
|
{
|
||||||
u32 time = systemGetClock();
|
u32 time = systemGetClock();
|
||||||
u32 diff = time - theApp.autoFrameSkipLastTime;
|
u32 diff = time - theApp.autoFrameSkipLastTime;
|
||||||
theApp.autoFrameSkipLastTime = time;
|
|
||||||
if( diff ) {
|
if( diff ) {
|
||||||
// countermeasure against div/0 when debugging
|
// countermeasure against div/0 when debugging
|
||||||
|
theApp.autoFrameSkipLastTime = time;
|
||||||
Sm60FPS::nCurSpeed = (1000000/rate)/diff;
|
Sm60FPS::nCurSpeed = (1000000/rate)/diff;
|
||||||
} else {
|
} else {
|
||||||
Sm60FPS::nCurSpeed = 100;
|
Sm60FPS::nCurSpeed = 100;
|
||||||
|
@ -1112,6 +1136,96 @@ void system10Frames(int rate)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void system1Frames(int rate, int count) //AdamN: update skippedframes faster to make sure it didn't cause too many frames or too little frames being skipped
|
||||||
|
{
|
||||||
|
|
||||||
|
if( theApp.autoFrameSkip ) //AdamN: CurSpeed might need to be updated regardless of autoframeskip for throttle to works properly w/o autoframeskip
|
||||||
|
{
|
||||||
|
theApp.autoFrameSkipCount++;
|
||||||
|
u32 time = systemGetClock();
|
||||||
|
u32 diff = time - theApp.autoFrameSkipLastTime;
|
||||||
|
if( diff) {
|
||||||
|
// countermeasure against div/0 when debugging
|
||||||
|
int tm = (diff/theApp.autoFrameSkipCount);
|
||||||
|
float cspd = (100000.0f/rate/*60.0f*/)/tm; //calc current speed smoothly (frame 1-10,2-11,3-12,so on)
|
||||||
|
Sm60FPS::nCurSpeed = (int)cspd; //(500000/rate)/diff;
|
||||||
|
if(theApp.autoFrameSkipCount >= 10) { //60
|
||||||
|
theApp.autoFrameSkipCount--; //= 0; //to maintain 10 frames per update
|
||||||
|
theApp.autoFrameSkipLastTime += tm ; //theApp.autoFrameSkipLastTime2;
|
||||||
|
//theApp.autoFrameSkipLastTime2 += tm; //rough prediction of nextframe's time
|
||||||
|
}/* else if(theApp.autoFrameSkipCount == 2)
|
||||||
|
theApp.autoFrameSkipLastTime2 = time;*/
|
||||||
|
//if(theApp.autoFrameSkip)
|
||||||
|
{
|
||||||
|
float tgtspd = Sm60FPS::K_fCpuSpeed;
|
||||||
|
int maxfs = gbFrameSkip;
|
||||||
|
if(theApp.cartridgeType == IMAGE_GBA) maxfs = frameSkip;
|
||||||
|
//if(speedup && (count % 10)==0) theApp.updateThrottle(Sm60FPS::nCurSpeed); //update throttle on turbo, may slows down things
|
||||||
|
//if(synchronize && tgtspd>100.0f) float tgtspd = 100.0f; //max speed when audio sync enabled is 100%, this is to prevent skippedframe piling up since CurSpeed never goes beyond 100
|
||||||
|
if((systemFrameSkip < maxfs) && (Sm60FPS::nCurSpeed < tgtspd*0.94f/**0.89f *0.845f*/)) { //*0.7f
|
||||||
|
/*if(maxfs==9) //special feature for auto-frameskip-cap=9
|
||||||
|
if(Sm60FPS::nCurSpeed <= 1.01f*Sm60FPS::nPrvSpeed && systemFrameSkip>3) { //if frameskipping no longer effective, don't skip more
|
||||||
|
systemFrameSkip--;
|
||||||
|
//Sm60FPS::nPrvSpeed = 0.0f; //0.99f*Sm60FPS::nPrvSpeed;
|
||||||
|
} else
|
||||||
|
Sm60FPS::nPrvSpeed = (float)Sm60FPS::nCurSpeed;*/
|
||||||
|
//frameSkip += 1;
|
||||||
|
//gbFrameSkip += 1;
|
||||||
|
systemFrameSkip += 1; //frames to skip for the next n frames
|
||||||
|
} else
|
||||||
|
if((systemFrameSkip > 0) && (Sm60FPS::nCurSpeed > tgtspd/**1.02f*//**1.1f *1.4f*/)) { //*1.07f
|
||||||
|
//frameSkip -= 1;
|
||||||
|
//gbFrameSkip -= 1;
|
||||||
|
systemFrameSkip -= 1; //frames to skip for the next n frames
|
||||||
|
}
|
||||||
|
//Sm60FPS::nPrvSpeed = Sm60FPS::nCurSpeed;
|
||||||
|
}
|
||||||
|
//theApp.autoFrameSkipCount = 0;
|
||||||
|
} else {
|
||||||
|
/*if(theApp.autoFrameSkipCount == 2)
|
||||||
|
theApp.autoFrameSkipLastTime2 = time;*/
|
||||||
|
if(!Sm60FPS::nCurSpeed)
|
||||||
|
Sm60FPS::nCurSpeed = (int)Sm60FPS::K_fCpuSpeed; //100;
|
||||||
|
//frameSkip = 0;
|
||||||
|
//gbFrameSkip = 0;
|
||||||
|
//systemFrameSkip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((count % 10)!=0) return;
|
||||||
|
|
||||||
|
if(theApp.rewindMemory) {
|
||||||
|
if(++theApp.rewindCounter >= (theApp.rewindTimer)) {
|
||||||
|
theApp.rewindSaveNeeded = true;
|
||||||
|
theApp.rewindCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(systemSaveUpdateCounter) {
|
||||||
|
if(--systemSaveUpdateCounter <= SYSTEM_SAVE_NOT_UPDATED) {
|
||||||
|
((MainWnd *)theApp.m_pMainWnd)->writeBatteryFile();
|
||||||
|
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
theApp.wasPaused = false;
|
||||||
|
|
||||||
|
// Old autoframeskip crap... might be useful later. autoframeskip Ifdef above might be useless as well now
|
||||||
|
// theApp.autoFrameSkipLastTime = time;
|
||||||
|
|
||||||
|
#ifdef LOG_PERFORMANCE
|
||||||
|
if( systemSpeedCounter >= PERFORMANCE_INTERVAL ) {
|
||||||
|
// log performance every PERFORMANCE_INTERVAL frames
|
||||||
|
float a = 0.0f;
|
||||||
|
for( unsigned short i = 0 ; i < PERFORMANCE_INTERVAL ; i++ ) {
|
||||||
|
a += (float)systemSpeedTable[i];
|
||||||
|
}
|
||||||
|
a /= (float)PERFORMANCE_INTERVAL;
|
||||||
|
log( _T("Speed: %f\n"), a );
|
||||||
|
systemSpeedCounter = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void systemScreenMessage(const char *msg)
|
void systemScreenMessage(const char *msg)
|
||||||
{
|
{
|
||||||
theApp.screenMessage = true;
|
theApp.screenMessage = true;
|
||||||
|
@ -1163,7 +1277,7 @@ SoundDriver * systemSoundInit()
|
||||||
|
|
||||||
if( drv ) {
|
if( drv ) {
|
||||||
if (theApp.throttle)
|
if (theApp.throttle)
|
||||||
drv->setThrottle( theApp.throttle );
|
drv->setThrottle( theApp.throttle ); //AdamN: XAudio2 seems the only one who has this feature?
|
||||||
}
|
}
|
||||||
|
|
||||||
return drv;
|
return drv;
|
||||||
|
@ -1251,10 +1365,13 @@ BOOL VBA::OnIdle(LONG lCount)
|
||||||
if(debugger)
|
if(debugger)
|
||||||
return TRUE; // continue loop
|
return TRUE; // continue loop
|
||||||
return !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);
|
return !::PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE);
|
||||||
} else if(emulating && active && !paused) {
|
} else if(emulating && (gba_link_enabled || active) && !paused) {
|
||||||
for(int i = 0; i < 2; i++) {
|
for(int i = 0; i < 2; i++) {
|
||||||
emulator.emuMain(emulator.emuCount);
|
emulator.emuMain(emulator.emuCount); //emuMain=CPULoop,emuCount=250000
|
||||||
if(lanlink.connected&&linkid&&lc.numtransfers==0) lc.CheckConn();
|
if(/*gba_link_enabled &&*/ lanlink.connected && linkid && lc.numtransfers==0 && (theApp.cartridgeType == IMAGE_GBA) && !rfu_enabled) {
|
||||||
|
if(/*(i & 1) &&*/ !LinkHandlerActive)
|
||||||
|
lc.CheckConn(); //AdamN: This is Needed for Client/Slave to works properly, but does it need to be called twice in the FOR loop?
|
||||||
|
}
|
||||||
|
|
||||||
if(rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState) {
|
if(rewindSaveNeeded && rewindMemory && emulator.emuWriteMemState) {
|
||||||
rewindCount++;
|
rewindCount++;
|
||||||
|
@ -1622,6 +1739,8 @@ void VBA::loadSettings()
|
||||||
|
|
||||||
rfu_enabled = regQueryDwordValue("RFU", false) ? true : false;
|
rfu_enabled = regQueryDwordValue("RFU", false) ? true : false;
|
||||||
gba_link_enabled = regQueryDwordValue("linkEnabled", false) ? true : false;
|
gba_link_enabled = regQueryDwordValue("linkEnabled", false) ? true : false;
|
||||||
|
if(gba_link_enabled)
|
||||||
|
gbSerialFunction = gbStartLink;
|
||||||
gba_joybus_enabled = regQueryDwordValue("joybusEnabled", false) ? true : false;
|
gba_joybus_enabled = regQueryDwordValue("joybusEnabled", false) ? true : false;
|
||||||
buffer = regQueryStringValue("joybusHostAddr", "");
|
buffer = regQueryStringValue("joybusHostAddr", "");
|
||||||
|
|
||||||
|
@ -2620,11 +2739,11 @@ void Sm60FPS_Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Sm60FPS_CanSkipFrame()
|
bool Sm60FPS_CanSkipFrame() //AdamN: autoframeskipping here doesn't seems to give much effect, more like only giving up to 1 frame skipped(per 10 frames) instead of up to 9 frames
|
||||||
{
|
{
|
||||||
if( theApp.autoFrameSkip ) {
|
/*if( theApp.autoFrameSkip )*/ { //AdamN: this is the reason why throttle doesn't works properly w/o autoframeskip
|
||||||
if( Sm60FPS::nFrameCnt == 0 ) {
|
if( Sm60FPS::nFrameCnt == 0 ) {
|
||||||
Sm60FPS::nFrameCnt = 0;
|
//Sm60FPS::nFrameCnt = 0; //AdamN: is this really necessary?
|
||||||
Sm60FPS::dwTimeElapse = 0;
|
Sm60FPS::dwTimeElapse = 0;
|
||||||
Sm60FPS::dwTime0 = GetTickCount();
|
Sm60FPS::dwTime0 = GetTickCount();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2634,14 +2753,18 @@ bool Sm60FPS_CanSkipFrame()
|
||||||
|
|
||||||
if( Sm60FPS::nCurSpeed > Sm60FPS::K_fCpuSpeed ) {
|
if( Sm60FPS::nCurSpeed > Sm60FPS::K_fCpuSpeed ) {
|
||||||
Sm60FPS::fWantFPS += 1;
|
Sm60FPS::fWantFPS += 1;
|
||||||
if( Sm60FPS::fWantFPS > Sm60FPS::K_fTargetFps ){
|
//frameSkip = 0;
|
||||||
Sm60FPS::fWantFPS = Sm60FPS::K_fTargetFps;
|
//systemFrameSkip = 0;
|
||||||
|
if( Sm60FPS::fWantFPS > Sm60FPS::K_fTargetFps/**(systemFrameSkip+1)*/ ){
|
||||||
|
Sm60FPS::fWantFPS = Sm60FPS::K_fTargetFps/**(systemFrameSkip+1)*/;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if( Sm60FPS::nCurSpeed < (Sm60FPS::K_fCpuSpeed - 5) ) {
|
if( Sm60FPS::nCurSpeed < (Sm60FPS::K_fCpuSpeed/**0.94f*/ /*- 5*/) ) {
|
||||||
Sm60FPS::fWantFPS -= 1;
|
Sm60FPS::fWantFPS -= 1;
|
||||||
if( Sm60FPS::fWantFPS < 30.f ) {
|
//frameSkip += 1;
|
||||||
Sm60FPS::fWantFPS = 30.f;
|
//systemFrameSkip += 1;
|
||||||
|
if( Sm60FPS::fWantFPS < 6.f/*30.f*/ ) {
|
||||||
|
Sm60FPS::fWantFPS = 6.f/*30.f*/;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2649,12 +2772,15 @@ bool Sm60FPS_CanSkipFrame()
|
||||||
Sm60FPS::dwTime1 = GetTickCount();
|
Sm60FPS::dwTime1 = GetTickCount();
|
||||||
Sm60FPS::dwTimeElapse += (Sm60FPS::dwTime1 - Sm60FPS::dwTime0);
|
Sm60FPS::dwTimeElapse += (Sm60FPS::dwTime1 - Sm60FPS::dwTime0);
|
||||||
Sm60FPS::dwTime0 = Sm60FPS::dwTime1;
|
Sm60FPS::dwTime0 = Sm60FPS::dwTime1;
|
||||||
|
|
||||||
if( !Sm60FPS::bLastSkip &&
|
if( !Sm60FPS::bLastSkip &&
|
||||||
( (Sm60FPS::fWantFPS < Sm60FPS::K_fTargetFps) || Sm60FPS::bSaveMoreCPU) ) {
|
( (Sm60FPS::fWantFPS < Sm60FPS::K_fTargetFps/**(systemFrameSkip+1)*/) || Sm60FPS::bSaveMoreCPU) ) {
|
||||||
Sm60FPS::fCurFPS = (float)Sm60FPS::nFrameCnt * 1000 / Sm60FPS::dwTimeElapse;
|
Sm60FPS::fCurFPS = (float)Sm60FPS::nFrameCnt * 1000 / Sm60FPS::dwTimeElapse;
|
||||||
if( (Sm60FPS::fCurFPS < Sm60FPS::K_fTargetFps) || Sm60FPS::bSaveMoreCPU ) {
|
if( (Sm60FPS::fCurFPS < Sm60FPS::K_fTargetFps/**(systemFrameSkip+1)*/) || Sm60FPS::bSaveMoreCPU ) {
|
||||||
Sm60FPS::bLastSkip = true;
|
Sm60FPS::bLastSkip = true;
|
||||||
Sm60FPS::nFrameCnt++;
|
Sm60FPS::nFrameCnt++;
|
||||||
|
//frameSkip += 1;
|
||||||
|
//systemFrameSkip += 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2662,6 +2788,8 @@ bool Sm60FPS_CanSkipFrame()
|
||||||
}
|
}
|
||||||
Sm60FPS::bLastSkip = false;
|
Sm60FPS::bLastSkip = false;
|
||||||
Sm60FPS::nFrameCnt++;
|
Sm60FPS::nFrameCnt++;
|
||||||
|
//frameSkip = 0;
|
||||||
|
//systemFrameSkip = 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2669,9 +2797,11 @@ bool Sm60FPS_CanSkipFrame()
|
||||||
|
|
||||||
void Sm60FPS_Sleep()
|
void Sm60FPS_Sleep()
|
||||||
{
|
{
|
||||||
if( theApp.autoFrameSkip ) {
|
if(!speedup) /*if( theApp.autoFrameSkip )*/ { //AdamN: this is the reason why throttle doesn't works properly w/o autoframeskip
|
||||||
u32 dwTimePass = Sm60FPS::dwTimeElapse + (GetTickCount() - Sm60FPS::dwTime0);
|
u32 dwTimePass = Sm60FPS::dwTimeElapse + (GetTickCount() - Sm60FPS::dwTime0);
|
||||||
u32 dwTimeShould = (u32)(Sm60FPS::nFrameCnt * Sm60FPS::K_fDT);
|
float kfdt = Sm60FPS::K_fDT;
|
||||||
|
if(!theApp.autoFrameSkip) kfdt*=(systemFrameSkip+1);
|
||||||
|
u32 dwTimeShould = (u32)(Sm60FPS::nFrameCnt * kfdt);
|
||||||
if( dwTimeShould > dwTimePass ) {
|
if( dwTimeShould > dwTimePass ) {
|
||||||
Sleep(dwTimeShould - dwTimePass);
|
Sleep(dwTimeShould - dwTimePass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,8 @@ class VBA : public CWinApp
|
||||||
bool tripleBuffering;
|
bool tripleBuffering;
|
||||||
unsigned short throttle;
|
unsigned short throttle;
|
||||||
u32 autoFrameSkipLastTime;
|
u32 autoFrameSkipLastTime;
|
||||||
|
u32 autoFrameSkipLastTime2;
|
||||||
|
int autoFrameSkipCount;
|
||||||
bool autoFrameSkip;
|
bool autoFrameSkip;
|
||||||
bool vsync;
|
bool vsync;
|
||||||
bool changingVideoSize;
|
bool changingVideoSize;
|
||||||
|
@ -255,6 +257,27 @@ class VBA : public CWinApp
|
||||||
extern VBA theApp;
|
extern VBA theApp;
|
||||||
extern int emulating;
|
extern int emulating;
|
||||||
|
|
||||||
|
extern bool AppTerminated; //AdamN: to mark Application is exiting for other threads to check
|
||||||
|
extern CString DataHex(const char *buf, int len); //AdamN: buffer to hex string
|
||||||
|
|
||||||
|
namespace Sm60FPS
|
||||||
|
{
|
||||||
|
extern float K_fCpuSpeed; // was 98.0f before, but why?
|
||||||
|
extern float K_fTargetFps;
|
||||||
|
extern float K_fDT;
|
||||||
|
|
||||||
|
extern u32 dwTimeElapse;
|
||||||
|
extern u32 dwTime0;
|
||||||
|
extern u32 dwTime1;
|
||||||
|
extern u32 nFrameCnt;
|
||||||
|
extern float fWantFPS;
|
||||||
|
extern float fCurFPS;
|
||||||
|
extern bool bLastSkip;
|
||||||
|
extern int nCurSpeed;
|
||||||
|
extern float nPrvSpeed;
|
||||||
|
extern int bSaveMoreCPU;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef MMX
|
#ifdef MMX
|
||||||
extern "C" bool cpu_mmx;
|
extern "C" bool cpu_mmx;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -132,13 +132,14 @@ BEGIN
|
||||||
CONTROL "Network",IDC_LINK_LAN,"Button",BS_AUTORADIOBUTTON,17,43,70,16
|
CONTROL "Network",IDC_LINK_LAN,"Button",BS_AUTORADIOBUTTON,17,43,70,16
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_LINKTAB2 DIALOG 0, 0, 210, 113
|
IDD_LINKTAB2 DIALOGEX 0, 0, 210, 113
|
||||||
STYLE DS_SETFONT | WS_CHILD
|
STYLE DS_SETFONT | WS_CHILD
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
CONTROL "2",IDC_LINK2P,"Button",BS_AUTORADIOBUTTON | WS_GROUP,46,16,21,13
|
CONTROL "2",IDC_LINK2P,"Button",BS_AUTORADIOBUTTON | WS_GROUP,33,17,21,13
|
||||||
CONTROL "3",IDC_LINK3P,"Button",BS_AUTORADIOBUTTON,94,16,21,13
|
CONTROL "3",IDC_LINK3P,"Button",BS_AUTORADIOBUTTON,73,17,21,13
|
||||||
CONTROL "4",IDC_LINK4P,"Button",BS_AUTORADIOBUTTON,142,16,21,13
|
CONTROL "4",IDC_LINK4P,"Button",BS_AUTORADIOBUTTON,115,17,21,13
|
||||||
|
CONTROL "5",IDC_LINK5P,"Button",BS_AUTORADIOBUTTON,156,17,21,13
|
||||||
CONTROL "TCP/IP",IDC_LINKTCP,"Button",BS_AUTORADIOBUTTON | WS_GROUP,54,47,42,14
|
CONTROL "TCP/IP",IDC_LINKTCP,"Button",BS_AUTORADIOBUTTON | WS_GROUP,54,47,42,14
|
||||||
CONTROL "UDP",IDC_LINKUDP,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,121,47,33,14
|
CONTROL "UDP",IDC_LINKUDP,"Button",BS_AUTORADIOBUTTON | WS_DISABLED,121,47,33,14
|
||||||
PUSHBUTTON "Start!",IDC_SERVERSTART,79,89,50,17
|
PUSHBUTTON "Start!",IDC_SERVERSTART,79,89,50,17
|
||||||
|
@ -162,17 +163,17 @@ BEGIN
|
||||||
CONTROL "On (fast)",IDC_SPEEDON,"Button",BS_AUTORADIOBUTTON,128,63,48,12
|
CONTROL "On (fast)",IDC_SPEEDON,"Button",BS_AUTORADIOBUTTON,128,63,48,12
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_SERVERWAIT DIALOG 0, 0, 186, 90
|
IDD_SERVERWAIT DIALOGEX 0, 0, 186, 90
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Waiting for players"
|
CAPTION "Waiting for players"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,63,69,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,63,69,50,14
|
||||||
CONTROL "Progress1",IDC_SERVERWAIT,"msctls_progress32",WS_BORDER,33,50,120,13
|
CONTROL "Progress1",IDC_SERVERWAIT,"msctls_progress32",WS_BORDER,33,50,120,13
|
||||||
LTEXT "",IDC_STATIC1,7,7,154,8
|
LTEXT "",IDC_STATIC1,7,7,178,8,SS_ENDELLIPSIS
|
||||||
LTEXT "",IDC_STATIC2,7,17,105,8
|
LTEXT "",IDC_STATIC2,7,17,175,8
|
||||||
LTEXT "",IDC_STATIC3,7,25,105,8
|
LTEXT "",IDC_STATIC3,7,25,175,8
|
||||||
LTEXT "",IDC_STATIC4,7,33,105,8
|
LTEXT "",IDC_STATIC4,7,33,175,8
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_OPENDLG DIALOG 36, 24, 202, 117
|
IDD_OPENDLG DIALOG 36, 24, 202, 117
|
||||||
|
@ -740,10 +741,10 @@ BEGIN
|
||||||
GROUPBOX "Sprite",IDC_STATIC,8,67,154,30
|
GROUPBOX "Sprite",IDC_STATIC,8,67,154,30
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_DISASSEMBLE DIALOG 0, 0, 402, 225
|
IDD_DISASSEMBLE DIALOGEX 0, 0, 402, 250
|
||||||
STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||||
CAPTION "Disassemble"
|
CAPTION "Disassemble"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
CONTROL "Automatic",IDC_AUTOMATIC,"Button",BS_AUTORADIOBUTTON | WS_GROUP,7,9,47,10
|
CONTROL "Automatic",IDC_AUTOMATIC,"Button",BS_AUTORADIOBUTTON | WS_GROUP,7,9,47,10
|
||||||
CONTROL "ARM",IDC_ARM,"Button",BS_AUTORADIOBUTTON,62,9,32,10
|
CONTROL "ARM",IDC_ARM,"Button",BS_AUTORADIOBUTTON,62,9,32,10
|
||||||
|
@ -800,6 +801,10 @@ BEGIN
|
||||||
LTEXT "",IDC_MODE,376,176,20,8,SS_NOPREFIX
|
LTEXT "",IDC_MODE,376,176,20,8,SS_NOPREFIX
|
||||||
SCROLLBAR IDC_VSCROLL,283,25,10,161,SBS_VERT
|
SCROLLBAR IDC_VSCROLL,283,25,10,161,SBS_VERT
|
||||||
PUSHBUTTON "Goto R15",IDC_GOPC,7,204,50,14
|
PUSHBUTTON "Goto R15",IDC_GOPC,7,204,50,14
|
||||||
|
CONTROL "Break at",IDC_BREAK_AT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,225,41,10
|
||||||
|
EDITTEXT IDC_ADDRESS2,53,222,65,14,ES_UPPERCASE | ES_AUTOHSCROLL | WS_GROUP
|
||||||
|
PUSHBUTTON "Step Into",IDC_STEPINTO,124,222,50,14
|
||||||
|
CONTROL "Auto Step",IDC_AUTO_STEP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,179,225,47,10
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_GDB_PORT DIALOG 0, 0, 186, 51
|
IDD_GDB_PORT DIALOG 0, 0, 186, 51
|
||||||
|
@ -823,13 +828,12 @@ BEGIN
|
||||||
LTEXT "",IDC_PORT,143,7,36,8,SS_NOPREFIX
|
LTEXT "",IDC_PORT,143,7,36,8,SS_NOPREFIX
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_LOGGING DIALOGEX 0, 0, 382, 220
|
IDD_LOGGING DIALOGEX 0, 0, 382, 257
|
||||||
STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||||
EXSTYLE WS_EX_TOOLWINDOW
|
EXSTYLE WS_EX_TOOLWINDOW
|
||||||
CAPTION "Logging"
|
CAPTION "Logging"
|
||||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
CONTROL "SWI",IDC_VERBOSE_SWI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,18,90,12
|
|
||||||
CONTROL "Unaligned memory",IDC_VERBOSE_UNALIGNED_ACCESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,36,90,12
|
CONTROL "Unaligned memory",IDC_VERBOSE_UNALIGNED_ACCESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,36,90,12
|
||||||
CONTROL "Illegal write",IDC_VERBOSE_ILLEGAL_WRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,54,90,12
|
CONTROL "Illegal write",IDC_VERBOSE_ILLEGAL_WRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,54,90,12
|
||||||
CONTROL "Illegal read",IDC_VERBOSE_ILLEGAL_READ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,90,12
|
CONTROL "Illegal read",IDC_VERBOSE_ILLEGAL_READ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,90,12
|
||||||
|
@ -839,12 +843,15 @@ BEGIN
|
||||||
CONTROL "DMA 3",IDC_VERBOSE_DMA3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,144,90,12
|
CONTROL "DMA 3",IDC_VERBOSE_DMA3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,144,90,12
|
||||||
CONTROL "Undefined instruction",IDC_VERBOSE_UNDEFINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,162,90,12
|
CONTROL "Undefined instruction",IDC_VERBOSE_UNDEFINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,162,90,12
|
||||||
CONTROL "AGBPrint",IDC_VERBOSE_AGBPRINT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,180,90,12
|
CONTROL "AGBPrint",IDC_VERBOSE_AGBPRINT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,180,90,12
|
||||||
EDITTEXT IDC_LOG,114,6,258,192,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
|
EDITTEXT IDC_LOG,114,6,258,226,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL
|
||||||
PUSHBUTTON "Save...",IDC_SAVE,114,204,48,12
|
PUSHBUTTON "Save...",IDC_SAVE,113,238,48,12
|
||||||
PUSHBUTTON "Clear",IDC_CLEAR,168,204,48,12
|
PUSHBUTTON "Clear",IDC_CLEAR,171,238,48,12
|
||||||
DEFPUSHBUTTON "OK",ID_OK,324,204,48,12
|
DEFPUSHBUTTON "OK",ID_OK,327,238,48,12
|
||||||
GROUPBOX "Verbose",IDC_STATIC,6,6,102,210
|
GROUPBOX "Verbose",IDC_STATIC,6,7,102,243
|
||||||
CONTROL "Sound output",IDC_VERBOSE_SOUNDOUTPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,198,90,12
|
CONTROL "Sound output",IDC_VERBOSE_SOUNDOUTPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,198,90,12
|
||||||
|
CONTROL "SIO",IDC_VERBOSE_SIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,216,90,12
|
||||||
|
CONTROL "Link",IDC_VERBOSE_LINK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,233,90,12
|
||||||
|
CONTROL "SWI",IDC_VERBOSE_SWI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,19,90,12
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_EXPORT_SPS DIALOGEX 0, 0, 248, 148
|
IDD_EXPORT_SPS DIALOGEX 0, 0, 248, 148
|
||||||
|
@ -1238,6 +1245,14 @@ BEGIN
|
||||||
BOTTOMMARGIN, 107
|
BOTTOMMARGIN, 107
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_LINKTAB2, DIALOG
|
||||||
|
BEGIN
|
||||||
|
END
|
||||||
|
|
||||||
|
IDD_SERVERWAIT, DIALOG
|
||||||
|
BEGIN
|
||||||
|
END
|
||||||
|
|
||||||
IDD_OPENDLG, DIALOG
|
IDD_OPENDLG, DIALOG
|
||||||
BEGIN
|
BEGIN
|
||||||
RIGHTMARGIN, 165
|
RIGHTMARGIN, 165
|
||||||
|
@ -1424,7 +1439,7 @@ BEGIN
|
||||||
LEFTMARGIN, 7
|
LEFTMARGIN, 7
|
||||||
RIGHTMARGIN, 396
|
RIGHTMARGIN, 396
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 218
|
BOTTOMMARGIN, 243
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_GDB_PORT, DIALOG
|
IDD_GDB_PORT, DIALOG
|
||||||
|
@ -1448,7 +1463,7 @@ BEGIN
|
||||||
LEFTMARGIN, 7
|
LEFTMARGIN, 7
|
||||||
RIGHTMARGIN, 375
|
RIGHTMARGIN, 375
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 213
|
BOTTOMMARGIN, 250
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_EXPORT_SPS, DIALOG
|
IDD_EXPORT_SPS, DIALOG
|
||||||
|
@ -2225,13 +2240,21 @@ BEGIN
|
||||||
IDS_LOADED_CHEATS "Loaded cheats"
|
IDS_LOADED_CHEATS "Loaded cheats"
|
||||||
IDS_ERROR_DISP_COLOR "Unsupported display setting for color depth: %d bits. \nWindows desktop must be in either 16-bit, 24-bit or 32-bit mode for this program to work in window mode."
|
IDS_ERROR_DISP_COLOR "Unsupported display setting for color depth: %d bits. \nWindows desktop must be in either 16-bit, 24-bit or 32-bit mode for this program to work in window mode."
|
||||||
IDS_ADD_GSA_CODE "Add GameSharkAdvance code"
|
IDS_ADD_GSA_CODE "Add GameSharkAdvance code"
|
||||||
IDS_FILTER_GSVSPS "GS & PAC Snapshots (*.SPS;*.XPS)_*.SPS;*.XPS_GameShark SP Snapshots (*.GSV)_*.gsv__"
|
|
||||||
IDS_FILTER_SPS "Gameshark Snapshot_*.SPS__"
|
IDS_FILTER_SPS "Gameshark Snapshot_*.SPS__"
|
||||||
IDS_SELECT_SNAPSHOT_FILE "Select snapshot file"
|
IDS_SELECT_SNAPSHOT_FILE "Select snapshot file"
|
||||||
IDS_FILTER_SAV "Battery file_*.SAV_Flash save_*.DAT__"
|
IDS_FILTER_SAV "Battery file_*.SAV_Flash save_*.DAT__"
|
||||||
IDS_SELECT_BATTERY_FILE "Select battery file"
|
IDS_SELECT_BATTERY_FILE "Select battery file"
|
||||||
END
|
END
|
||||||
|
|
||||||
|
STRINGTABLE
|
||||||
|
BEGIN
|
||||||
|
IDS_INVALID_INTERVAL_VALUE
|
||||||
|
"Invalid rewind interval value. Please enter a number between 0 and 600 seconds."
|
||||||
|
IDS_REGISTRY "VisualBoyAdvance no longer uses the registry to store its settings. Your previous settings have been exported into the file: %s"
|
||||||
|
IDS_MOVIE_PLAY "Playing a movie will load a save state which may erase your previous battery saves. Please be sure to have a saved state if you don't want to loose any previous data."
|
||||||
|
IDS_FILTER_GSVSPS "GS & PAC Snapshots (*.SPS;*.XPS)_*.SPS;*.XPS_GameShark SP Snapshots (*.GSV)_*.gsv__"
|
||||||
|
END
|
||||||
|
|
||||||
STRINGTABLE
|
STRINGTABLE
|
||||||
BEGIN
|
BEGIN
|
||||||
IDS_UNSUPPORTED_CHEAT_LIST_TYPE "Unsupported cheat list type %d"
|
IDS_UNSUPPORTED_CHEAT_LIST_TYPE "Unsupported cheat list type %d"
|
||||||
|
@ -2292,14 +2315,6 @@ BEGIN
|
||||||
IDS_END_OF_MOVIE "end of movie"
|
IDS_END_OF_MOVIE "end of movie"
|
||||||
END
|
END
|
||||||
|
|
||||||
STRINGTABLE
|
|
||||||
BEGIN
|
|
||||||
IDS_INVALID_INTERVAL_VALUE
|
|
||||||
"Invalid rewind interval value. Please enter a number between 0 and 600 seconds."
|
|
||||||
IDS_REGISTRY "VisualBoyAdvance no longer uses the registry to store its settings. Your previous settings have been exported into the file: %s"
|
|
||||||
IDS_MOVIE_PLAY "Playing a movie will load a save state which may erase your previous battery saves. Please be sure to have a saved state if you don't want to loose any previous data."
|
|
||||||
END
|
|
||||||
|
|
||||||
STRINGTABLE
|
STRINGTABLE
|
||||||
BEGIN
|
BEGIN
|
||||||
IDS_OAL_NODEVICE "There are no sound devices present on this system."
|
IDS_OAL_NODEVICE "There are no sound devices present on this system."
|
||||||
|
|
|
@ -278,6 +278,8 @@ bool XAudio2_Output::init(long sampleRate)
|
||||||
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
|
setThrottle(theApp.throttle); //AdamN: setting sound pitch to current throttle
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ void XAudio2_Output::write(u16 * finalWave, int length)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// the maximum number of buffers is currently queued
|
// the maximum number of buffers is currently queued
|
||||||
if( synchronize && !speedup && !theApp.throttle ) {
|
if( synchronize && !speedup /*&& !theApp.throttle*/ ) {
|
||||||
// wait for one buffer to finish playing
|
// wait for one buffer to finish playing
|
||||||
WaitForSingleObject( notify.hBufferEndEvent, INFINITE );
|
WaitForSingleObject( notify.hBufferEndEvent, INFINITE );
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -150,6 +150,7 @@
|
||||||
#define IDC_C_FLAG 1020
|
#define IDC_C_FLAG 1020
|
||||||
#define IDC_CONTINUE 1020
|
#define IDC_CONTINUE 1020
|
||||||
#define IDC_SAVE_DIR 1020
|
#define IDC_SAVE_DIR 1020
|
||||||
|
#define IDC_STEPINTO 1020
|
||||||
#define IDC_V_FLAG 1021
|
#define IDC_V_FLAG 1021
|
||||||
#define IDC_CAPTURE_DIR 1021
|
#define IDC_CAPTURE_DIR 1021
|
||||||
#define IDC_CHEAT_LIST 1021
|
#define IDC_CHEAT_LIST 1021
|
||||||
|
@ -215,6 +216,7 @@
|
||||||
#define IDS_VALUE_CANNOT_BE_EMPTY 1042
|
#define IDS_VALUE_CANNOT_BE_EMPTY 1042
|
||||||
#define IDS_ERROR_ON_STARTDOC 1043
|
#define IDS_ERROR_ON_STARTDOC 1043
|
||||||
#define IDC_R 1043
|
#define IDC_R 1043
|
||||||
|
#define IDC_ADDRESS2 1043
|
||||||
#define IDS_ERROR_ON_STARTPAGE 1044
|
#define IDS_ERROR_ON_STARTPAGE 1044
|
||||||
#define IDC_G 1044
|
#define IDC_G 1044
|
||||||
#define IDS_ERROR_PRINTING_ON_STRETCH 1045
|
#define IDS_ERROR_PRINTING_ON_STRETCH 1045
|
||||||
|
@ -459,6 +461,8 @@
|
||||||
#define IDC_ARM 1200
|
#define IDC_ARM 1200
|
||||||
#define IDC_THUMB 1201
|
#define IDC_THUMB 1201
|
||||||
#define IDC_AUTO_UPDATE 1204
|
#define IDC_AUTO_UPDATE 1204
|
||||||
|
#define IDC_BREAK_AT 1205
|
||||||
|
#define IDC_AUTO_STEP 1206
|
||||||
#define IDC_N 1210
|
#define IDC_N 1210
|
||||||
#define IDC_Z 1211
|
#define IDC_Z 1211
|
||||||
#define IDC_C 1212
|
#define IDC_C 1212
|
||||||
|
@ -491,6 +495,8 @@
|
||||||
#define IDC_VERBOSE_SOUNDOUTPUT 1235
|
#define IDC_VERBOSE_SOUNDOUTPUT 1235
|
||||||
#define IDC_NOTES 1236
|
#define IDC_NOTES 1236
|
||||||
#define IDC_CURRENT_ADDRESS_LABEL 1236
|
#define IDC_CURRENT_ADDRESS_LABEL 1236
|
||||||
|
#define IDC_VERBOSE_SIO 1236
|
||||||
|
#define IDC_VERBOSE_LINK 1237
|
||||||
#define IDC_LOAD 1238
|
#define IDC_LOAD 1238
|
||||||
#define IDC_SIZE_CONTROL 1240
|
#define IDC_SIZE_CONTROL 1240
|
||||||
#define IDC_MODES 1240
|
#define IDC_MODES 1240
|
||||||
|
@ -841,6 +847,7 @@
|
||||||
#define IDC_LINK3P 40325
|
#define IDC_LINK3P 40325
|
||||||
#define IDC_LINK4P 40326
|
#define IDC_LINK4P 40326
|
||||||
#define IDC_CLINKUDP 40327
|
#define IDC_CLINKUDP 40327
|
||||||
|
#define IDC_LINK5P 40327
|
||||||
#define IDC_SPEEDON 40328
|
#define IDC_SPEEDON 40328
|
||||||
#define ID_OPTIONS_EMULATOR_REMOVEINTROSGBA 40331
|
#define ID_OPTIONS_EMULATOR_REMOVEINTROSGBA 40331
|
||||||
#define ID_Menu 40332
|
#define ID_Menu 40332
|
||||||
|
|
Loading…
Reference in New Issue