Merge remote-tracking branch 'remotes/origin/master' into audio_interp
# Conflicts: # src/frontend/qt_sdl/main.cpp
This commit is contained in:
commit
561c607521
|
@ -67,6 +67,13 @@ endif()
|
||||||
|
|
||||||
if (ENABLE_JIT)
|
if (ENABLE_JIT)
|
||||||
add_definitions(-DJIT_ENABLED)
|
add_definitions(-DJIT_ENABLED)
|
||||||
|
|
||||||
|
option(ENABLE_JIT_PROFILING "Enable JIT profiling with VTune" OFF)
|
||||||
|
|
||||||
|
if (ENABLE_JIT_PROFILING)
|
||||||
|
include(cmake/FindVTune.cmake)
|
||||||
|
add_definitions(-DJIT_PROFILING_ENABLED)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL Release)
|
if (CMAKE_BUILD_TYPE STREQUAL Release)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
find_path(VTUNE_PATH "")
|
||||||
|
|
||||||
|
include_directories("${VTUNE_PATH}/include")
|
||||||
|
link_directories("${VTUNE_PATH}/lib64")
|
|
@ -43,9 +43,6 @@
|
||||||
#include "Wifi.h"
|
#include "Wifi.h"
|
||||||
#include "NDSCart.h"
|
#include "NDSCart.h"
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(__aarch64__)
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ARMJIT_x64/ARMJIT_Offsets.h"
|
#include "ARMJIT_x64/ARMJIT_Offsets.h"
|
||||||
static_assert(offsetof(ARM, CPSR) == ARM_CPSR_offset, "");
|
static_assert(offsetof(ARM, CPSR) == ARM_CPSR_offset, "");
|
||||||
|
@ -320,9 +317,7 @@ void Init()
|
||||||
|
|
||||||
void DeInit()
|
void DeInit()
|
||||||
{
|
{
|
||||||
#if defined(__APPLE__) && defined(__aarch64__)
|
JitEnableWrite();
|
||||||
pthread_jit_write_protect_np(false);
|
|
||||||
#endif
|
|
||||||
ResetBlockCache();
|
ResetBlockCache();
|
||||||
ARMJIT_Memory::DeInit();
|
ARMJIT_Memory::DeInit();
|
||||||
|
|
||||||
|
@ -331,9 +326,7 @@ void DeInit()
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
#if defined(__APPLE__) && defined(__aarch64__)
|
JitEnableWrite();
|
||||||
pthread_jit_write_protect_np(false);
|
|
||||||
#endif
|
|
||||||
ResetBlockCache();
|
ResetBlockCache();
|
||||||
|
|
||||||
ARMJIT_Memory::Reset();
|
ARMJIT_Memory::Reset();
|
||||||
|
@ -918,13 +911,10 @@ void CompileBlock(ARM* cpu)
|
||||||
block->StartAddrLocal = localAddr;
|
block->StartAddrLocal = localAddr;
|
||||||
|
|
||||||
FloodFillSetFlags(instrs, i - 1, 0xF);
|
FloodFillSetFlags(instrs, i - 1, 0xF);
|
||||||
#if defined(__APPLE__) && defined(__aarch64__)
|
|
||||||
pthread_jit_write_protect_np(false);
|
JitEnableWrite();
|
||||||
#endif
|
|
||||||
block->EntryPoint = JITCompiler->CompileBlock(cpu, thumb, instrs, i, hasMemoryInstr);
|
block->EntryPoint = JITCompiler->CompileBlock(cpu, thumb, instrs, i, hasMemoryInstr);
|
||||||
#if defined(__APPLE__) && defined(__aarch64__)
|
JitEnableExecute();
|
||||||
pthread_jit_write_protect_np(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JIT_DEBUGPRINT("block start %p\n", block->EntryPoint);
|
JIT_DEBUGPRINT("block start %p\n", block->EntryPoint);
|
||||||
}
|
}
|
||||||
|
@ -1168,4 +1158,20 @@ void ResetBlockCache()
|
||||||
JITCompiler->Reset();
|
JITCompiler->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitEnableWrite()
|
||||||
|
{
|
||||||
|
#if defined(__APPLE__) && defined(__aarch64__)
|
||||||
|
if (__builtin_available(macOS 11.0, *))
|
||||||
|
pthread_jit_write_protect_np(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitEnableExecute()
|
||||||
|
{
|
||||||
|
#if defined(__APPLE__) && defined(__aarch64__)
|
||||||
|
if (__builtin_available(macOS 11.0, *))
|
||||||
|
pthread_jit_write_protect_np(true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
#include "ARM.h"
|
#include "ARM.h"
|
||||||
#include "ARM_InstrInfo.h"
|
#include "ARM_InstrInfo.h"
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__aarch64__)
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ARMJIT
|
namespace ARMJIT
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -48,6 +52,8 @@ void ResetBlockCache();
|
||||||
JitBlockEntry LookUpBlock(u32 num, u64* entries, u32 offset, u32 addr);
|
JitBlockEntry LookUpBlock(u32 num, u64* entries, u32 offset, u32 addr);
|
||||||
bool SetupExecutableRegion(u32 num, u32 blockAddr, u64*& entry, u32& start, u32& size);
|
bool SetupExecutableRegion(u32 num, u32 blockAddr, u64*& entry, u32& start, u32& size);
|
||||||
|
|
||||||
|
void JitEnableWrite();
|
||||||
|
void JitEnableExecute();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void ARM_Dispatch(ARM* cpu, ARMJIT::JitBlockEntry entry);
|
extern "C" void ARM_Dispatch(ARM* cpu, ARMJIT::JitBlockEntry entry);
|
||||||
|
|
|
@ -33,10 +33,6 @@ extern char __start__;
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace Arm64Gen;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
extern "C" void ARM_Ret();
|
extern "C" void ARM_Ret();
|
||||||
|
@ -266,7 +262,7 @@ Compiler::Compiler()
|
||||||
u64 alignedSize = (((u64)JitMem + sizeof(JitMem)) & ~(pageSize - 1)) - (u64)pageAligned;
|
u64 alignedSize = (((u64)JitMem + sizeof(JitMem)) & ~(pageSize - 1)) - (u64)pageAligned;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
pageAligned = (u8*)mmap(NULL, 1024*1024*16, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT,-1, 0);
|
pageAligned = (u8*)mmap(NULL, 1024*1024*16, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT,-1, 0);
|
||||||
pthread_jit_write_protect_np(false);
|
JitEnableWrite();
|
||||||
#else
|
#else
|
||||||
mprotect(pageAligned, alignedSize, PROT_EXEC | PROT_READ | PROT_WRITE);
|
mprotect(pageAligned, alignedSize, PROT_EXEC | PROT_READ | PROT_WRITE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -685,6 +681,7 @@ void Compiler::Comp_BranchSpecialBehaviour(bool taken)
|
||||||
{
|
{
|
||||||
RegCache.PrepareExit();
|
RegCache.PrepareExit();
|
||||||
|
|
||||||
|
if (ConstantCycles)
|
||||||
ADD(RCycles, RCycles, ConstantCycles);
|
ADD(RCycles, RCycles, ConstantCycles);
|
||||||
QuickTailCall(X0, ARM_Ret);
|
QuickTailCall(X0, ARM_Ret);
|
||||||
}
|
}
|
||||||
|
@ -836,6 +833,7 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
||||||
|
|
||||||
RegCache.Flush();
|
RegCache.Flush();
|
||||||
|
|
||||||
|
if (ConstantCycles)
|
||||||
ADD(RCycles, RCycles, ConstantCycles);
|
ADD(RCycles, RCycles, ConstantCycles);
|
||||||
QuickTailCall(X0, ARM_Ret);
|
QuickTailCall(X0, ARM_Ret);
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ public:
|
||||||
void T_Comp_BL_LONG_2();
|
void T_Comp_BL_LONG_2();
|
||||||
void T_Comp_BL_Merged();
|
void T_Comp_BL_Merged();
|
||||||
|
|
||||||
s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode);
|
s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode, bool skipLoadingRn);
|
||||||
|
|
||||||
void Comp_Mul_Mla(bool S, bool mla, Arm64Gen::ARM64Reg rd, Arm64Gen::ARM64Reg rm, Arm64Gen::ARM64Reg rs, Arm64Gen::ARM64Reg rn);
|
void Comp_Mul_Mla(bool S, bool mla, Arm64Gen::ARM64Reg rd, Arm64Gen::ARM64Reg rm, Arm64Gen::ARM64Reg rs, Arm64Gen::ARM64Reg rn);
|
||||||
|
|
||||||
|
|
|
@ -465,7 +465,7 @@ void Compiler::T_Comp_MemSPRel()
|
||||||
Comp_MemAccess(CurInstr.T_Reg(8), 13, Op2(offset), 32, load ? 0 : memop_Store);
|
Comp_MemAccess(CurInstr.T_Reg(8), 13, Op2(offset), 32, load ? 0 : memop_Store);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode)
|
s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode, bool skipLoadingRn)
|
||||||
{
|
{
|
||||||
IrregularCycles = true;
|
IrregularCycles = true;
|
||||||
|
|
||||||
|
@ -474,7 +474,8 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
if (regsCount == 0)
|
if (regsCount == 0)
|
||||||
return 0; // actually not the right behaviour TODO: fix me
|
return 0; // actually not the right behaviour TODO: fix me
|
||||||
|
|
||||||
if (regsCount == 1 && !usermode && RegCache.LoadedRegs & (1 << *regs.begin()))
|
int firstReg = *regs.begin();
|
||||||
|
if (regsCount == 1 && !usermode && RegCache.LoadedRegs & (1 << firstReg) && !(firstReg == rn && skipLoadingRn))
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (store)
|
if (store)
|
||||||
|
@ -483,7 +484,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
flags |= memop_SubtractOffset;
|
flags |= memop_SubtractOffset;
|
||||||
Op2 offset = preinc ? Op2(4) : Op2(0);
|
Op2 offset = preinc ? Op2(4) : Op2(0);
|
||||||
|
|
||||||
Comp_MemAccess(*regs.begin(), rn, offset, 32, flags);
|
Comp_MemAccess(firstReg, rn, offset, 32, flags);
|
||||||
|
|
||||||
return decrement ? -4 : 4;
|
return decrement ? -4 : 4;
|
||||||
}
|
}
|
||||||
|
@ -539,12 +540,16 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
loadStoreOffsets[i++] = GetCodeOffset();
|
loadStoreOffsets[i++] = GetCodeOffset();
|
||||||
|
|
||||||
if (store)
|
if (store)
|
||||||
|
{
|
||||||
STR(INDEX_UNSIGNED, first, X1, offset);
|
STR(INDEX_UNSIGNED, first, X1, offset);
|
||||||
else
|
}
|
||||||
|
else if (!(reg == rn && skipLoadingRn))
|
||||||
|
{
|
||||||
LDR(INDEX_UNSIGNED, first, X1, offset);
|
LDR(INDEX_UNSIGNED, first, X1, offset);
|
||||||
|
|
||||||
if (!(RegCache.LoadedRegs & (1 << reg)) && !store)
|
if (!(RegCache.LoadedRegs & (1 << reg)))
|
||||||
SaveReg(reg, first);
|
SaveReg(reg, first);
|
||||||
|
}
|
||||||
|
|
||||||
offset += 4;
|
offset += 4;
|
||||||
}
|
}
|
||||||
|
@ -558,13 +563,23 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
|
|
||||||
ARM64Reg first = W3, second = W4;
|
ARM64Reg first = W3, second = W4;
|
||||||
if (RegCache.LoadedRegs & (1 << reg))
|
if (RegCache.LoadedRegs & (1 << reg))
|
||||||
|
{
|
||||||
|
if (!(reg == rn && skipLoadingRn))
|
||||||
first = MapReg(reg);
|
first = MapReg(reg);
|
||||||
|
}
|
||||||
else if (store)
|
else if (store)
|
||||||
|
{
|
||||||
LoadReg(reg, first);
|
LoadReg(reg, first);
|
||||||
|
}
|
||||||
if (RegCache.LoadedRegs & (1 << nextReg))
|
if (RegCache.LoadedRegs & (1 << nextReg))
|
||||||
|
{
|
||||||
|
if (!(nextReg == rn && skipLoadingRn))
|
||||||
second = MapReg(nextReg);
|
second = MapReg(nextReg);
|
||||||
|
}
|
||||||
else if (store)
|
else if (store)
|
||||||
|
{
|
||||||
LoadReg(nextReg, second);
|
LoadReg(nextReg, second);
|
||||||
|
}
|
||||||
|
|
||||||
loadStoreOffsets[i++] = GetCodeOffset();
|
loadStoreOffsets[i++] = GetCodeOffset();
|
||||||
if (store)
|
if (store)
|
||||||
|
@ -705,6 +720,8 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
LDR(INDEX_UNSIGNED, W3, SP, i * 8);
|
LDR(INDEX_UNSIGNED, W3, SP, i * 8);
|
||||||
MOVI2R(W1, reg - 8);
|
MOVI2R(W1, reg - 8);
|
||||||
BL(WriteBanked);
|
BL(WriteBanked);
|
||||||
|
if (!(reg == rn && skipLoadingRn))
|
||||||
|
{
|
||||||
FixupBranch alreadyWritten = CBNZ(W4);
|
FixupBranch alreadyWritten = CBNZ(W4);
|
||||||
if (RegCache.LoadedRegs & (1 << reg))
|
if (RegCache.LoadedRegs & (1 << reg))
|
||||||
MOV(MapReg(reg), W3);
|
MOV(MapReg(reg), W3);
|
||||||
|
@ -712,13 +729,14 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
SaveReg(reg, W3);
|
SaveReg(reg, W3);
|
||||||
SetJumpTarget(alreadyWritten);
|
SetJumpTarget(alreadyWritten);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!usermode && nextReg != regs.end())
|
else if (!usermode && nextReg != regs.end())
|
||||||
{
|
{
|
||||||
ARM64Reg first = W3, second = W4;
|
ARM64Reg first = W3, second = W4;
|
||||||
|
|
||||||
if (RegCache.LoadedRegs & (1 << reg))
|
if (RegCache.LoadedRegs & (1 << reg) && !(reg == rn && skipLoadingRn))
|
||||||
first = MapReg(reg);
|
first = MapReg(reg);
|
||||||
if (RegCache.LoadedRegs & (1 << *nextReg))
|
if (RegCache.LoadedRegs & (1 << *nextReg) && !(*nextReg == rn && skipLoadingRn))
|
||||||
second = MapReg(*nextReg);
|
second = MapReg(*nextReg);
|
||||||
|
|
||||||
LDP(INDEX_SIGNED, EncodeRegTo64(first), EncodeRegTo64(second), SP, i * 8);
|
LDP(INDEX_SIGNED, EncodeRegTo64(first), EncodeRegTo64(second), SP, i * 8);
|
||||||
|
@ -732,10 +750,13 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else if (RegCache.LoadedRegs & (1 << reg))
|
else if (RegCache.LoadedRegs & (1 << reg))
|
||||||
|
{
|
||||||
|
if (!(reg == rn && skipLoadingRn))
|
||||||
{
|
{
|
||||||
ARM64Reg mapped = MapReg(reg);
|
ARM64Reg mapped = MapReg(reg);
|
||||||
LDR(INDEX_UNSIGNED, mapped, SP, i * 8);
|
LDR(INDEX_UNSIGNED, mapped, SP, i * 8);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LDR(INDEX_UNSIGNED, W3, SP, i * 8);
|
LDR(INDEX_UNSIGNED, W3, SP, i * 8);
|
||||||
|
@ -778,13 +799,13 @@ void Compiler::A_Comp_LDM_STM()
|
||||||
|
|
||||||
ARM64Reg rn = MapReg(CurInstr.A_Reg(16));
|
ARM64Reg rn = MapReg(CurInstr.A_Reg(16));
|
||||||
|
|
||||||
s32 offset = Comp_MemAccessBlock(CurInstr.A_Reg(16), regs, !load, pre, !add, usermode);
|
|
||||||
|
|
||||||
if (load && writeback && regs[CurInstr.A_Reg(16)])
|
if (load && writeback && regs[CurInstr.A_Reg(16)])
|
||||||
writeback = Num == 0
|
writeback = Num == 0
|
||||||
? (!(regs & ~BitSet16(1 << CurInstr.A_Reg(16)))) || (regs & ~BitSet16((2 << CurInstr.A_Reg(16)) - 1))
|
&& (!(regs & ~BitSet16(1 << CurInstr.A_Reg(16)))) || (regs & ~BitSet16((2 << CurInstr.A_Reg(16)) - 1));
|
||||||
: false;
|
|
||||||
if (writeback)
|
s32 offset = Comp_MemAccessBlock(CurInstr.A_Reg(16), regs, !load, pre, !add, usermode, load && writeback);
|
||||||
|
|
||||||
|
if (writeback && offset)
|
||||||
{
|
{
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
ADD(rn, rn, offset);
|
ADD(rn, rn, offset);
|
||||||
|
@ -806,12 +827,15 @@ void Compiler::T_Comp_PUSH_POP()
|
||||||
}
|
}
|
||||||
|
|
||||||
ARM64Reg sp = MapReg(13);
|
ARM64Reg sp = MapReg(13);
|
||||||
s32 offset = Comp_MemAccessBlock(13, regs, !load, !load, !load, false);
|
s32 offset = Comp_MemAccessBlock(13, regs, !load, !load, !load, false, false);
|
||||||
|
|
||||||
|
if (offset)
|
||||||
|
{
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
ADD(sp, sp, offset);
|
ADD(sp, sp, offset);
|
||||||
else
|
else
|
||||||
SUB(sp, sp, -offset);
|
SUB(sp, sp, -offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::T_Comp_LDMIA_STMIA()
|
void Compiler::T_Comp_LDMIA_STMIA()
|
||||||
|
@ -821,9 +845,11 @@ void Compiler::T_Comp_LDMIA_STMIA()
|
||||||
bool load = CurInstr.Instr & (1 << 11);
|
bool load = CurInstr.Instr & (1 << 11);
|
||||||
u32 regsCount = regs.Count();
|
u32 regsCount = regs.Count();
|
||||||
|
|
||||||
s32 offset = Comp_MemAccessBlock(CurInstr.T_Reg(8), regs, !load, false, false, false);
|
bool writeback = !load || !regs[CurInstr.T_Reg(8)];
|
||||||
|
|
||||||
if (!load || !regs[CurInstr.T_Reg(8)])
|
s32 offset = Comp_MemAccessBlock(CurInstr.T_Reg(8), regs, !load, false, false, false, load && writeback);
|
||||||
|
|
||||||
|
if (writeback && offset)
|
||||||
{
|
{
|
||||||
if (offset > 0)
|
if (offset > 0)
|
||||||
ADD(rb, rb, offset);
|
ADD(rb, rb, offset);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "../Config.h"
|
#include "../Config.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "../dolphin/CommonFuncs.h"
|
#include "../dolphin/CommonFuncs.h"
|
||||||
|
|
||||||
|
@ -298,6 +299,10 @@ Compiler::Compiler()
|
||||||
SetJumpTarget(und);
|
SetJumpTarget(und);
|
||||||
MOV(32, R(RSCRATCH3), MComplex(RCPU, RSCRATCH2, SCALE_4, offsetof(ARM, R_UND)));
|
MOV(32, R(RSCRATCH3), MComplex(RCPU, RSCRATCH2, SCALE_4, offsetof(ARM, R_UND)));
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
CreateMethod("ReadBanked", ReadBanked);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// RSCRATCH mode
|
// RSCRATCH mode
|
||||||
|
@ -341,6 +346,10 @@ Compiler::Compiler()
|
||||||
MOV(32, MComplex(RCPU, RSCRATCH2, SCALE_4, offsetof(ARM, R_UND)), R(RSCRATCH3));
|
MOV(32, MComplex(RCPU, RSCRATCH2, SCALE_4, offsetof(ARM, R_UND)), R(RSCRATCH3));
|
||||||
CLC();
|
CLC();
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
CreateMethod("WriteBanked", WriteBanked);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int consoleType = 0; consoleType < 2; consoleType++)
|
for (int consoleType = 0; consoleType < 2; consoleType++)
|
||||||
|
@ -401,6 +410,10 @@ Compiler::Compiler()
|
||||||
ABI_PopRegistersAndAdjustStack(CallerSavedPushRegs, 8);
|
ABI_PopRegistersAndAdjustStack(CallerSavedPushRegs, 8);
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
CreateMethod("FastMemStorePatch%d_%d_%d", PatchedStoreFuncs[consoleType][num][size][reg], num, size, reg);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int signextend = 0; signextend < 2; signextend++)
|
for (int signextend = 0; signextend < 2; signextend++)
|
||||||
{
|
{
|
||||||
PatchedLoadFuncs[consoleType][num][size][signextend][reg] = GetWritableCodePtr();
|
PatchedLoadFuncs[consoleType][num][size][signextend][reg] = GetWritableCodePtr();
|
||||||
|
@ -439,6 +452,10 @@ Compiler::Compiler()
|
||||||
else
|
else
|
||||||
MOVZX(32, 8 << size, rdMapped, R(RSCRATCH));
|
MOVZX(32, 8 << size, rdMapped, R(RSCRATCH));
|
||||||
RET();
|
RET();
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
CreateMethod("FastMemLoadPatch%d_%d_%d_%d", PatchedLoadFuncs[consoleType][num][size][signextend][reg], num, size, reg, signextend);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -663,11 +680,34 @@ void Compiler::Comp_SpecialBranchBehaviour(bool taken)
|
||||||
{
|
{
|
||||||
RegCache.PrepareExit();
|
RegCache.PrepareExit();
|
||||||
|
|
||||||
|
if (ConstantCycles)
|
||||||
ADD(32, MDisp(RCPU, offsetof(ARM, Cycles)), Imm32(ConstantCycles));
|
ADD(32, MDisp(RCPU, offsetof(ARM, Cycles)), Imm32(ConstantCycles));
|
||||||
JMP((u8*)&ARM_Ret, true);
|
JMP((u8*)&ARM_Ret, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
void Compiler::CreateMethod(const char* namefmt, void* start, ...)
|
||||||
|
{
|
||||||
|
if (iJIT_IsProfilingActive())
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, start);
|
||||||
|
char name[64];
|
||||||
|
vsprintf(name, namefmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
iJIT_Method_Load method = {0};
|
||||||
|
method.method_id = iJIT_GetNewMethodID();
|
||||||
|
method.method_name = name;
|
||||||
|
method.method_load_address = start;
|
||||||
|
method.method_size = GetWritableCodePtr() - (u8*)start;
|
||||||
|
|
||||||
|
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[], int instrsCount, bool hasMemoryInstr)
|
JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[], int instrsCount, bool hasMemoryInstr)
|
||||||
{
|
{
|
||||||
if (NearSize - (GetCodePtr() - NearStart) < 1024 * 32) // guess...
|
if (NearSize - (GetCodePtr() - NearStart) < 1024 * 32) // guess...
|
||||||
|
@ -802,9 +842,14 @@ JitBlockEntry Compiler::CompileBlock(ARM* cpu, bool thumb, FetchedInstr instrs[]
|
||||||
|
|
||||||
RegCache.Flush();
|
RegCache.Flush();
|
||||||
|
|
||||||
|
if (ConstantCycles)
|
||||||
ADD(32, MDisp(RCPU, offsetof(ARM, Cycles)), Imm32(ConstantCycles));
|
ADD(32, MDisp(RCPU, offsetof(ARM, Cycles)), Imm32(ConstantCycles));
|
||||||
JMP((u8*)ARM_Ret, true);
|
JMP((u8*)ARM_Ret, true);
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
CreateMethod("JIT_Block_%d_%d_%08X", (void*)res, Num, Thumb, instrs[0].Addr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*FILE* codeout = fopen("codeout", "a");
|
/*FILE* codeout = fopen("codeout", "a");
|
||||||
fprintf(codeout, "beginning block argargarg__ %x!!!", instrs[0].Addr);
|
fprintf(codeout, "beginning block argargarg__ %x!!!", instrs[0].Addr);
|
||||||
fwrite((u8*)res, GetWritableCodePtr() - (u8*)res, 1, codeout);
|
fwrite((u8*)res, GetWritableCodePtr() - (u8*)res, 1, codeout);
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
#include "../ARMJIT_Internal.h"
|
#include "../ARMJIT_Internal.h"
|
||||||
#include "../ARMJIT_RegisterCache.h"
|
#include "../ARMJIT_RegisterCache.h"
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
#include <jitprofiling.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace ARMJIT
|
namespace ARMJIT
|
||||||
|
@ -163,7 +167,7 @@ public:
|
||||||
memop_SubtractOffset = 1 << 4
|
memop_SubtractOffset = 1 << 4
|
||||||
};
|
};
|
||||||
void Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flags);
|
void Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flags);
|
||||||
s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode);
|
s32 Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode, bool skipLoadingRn);
|
||||||
bool Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr);
|
bool Comp_MemLoadLiteral(int size, bool signExtend, int rd, u32 addr);
|
||||||
|
|
||||||
void Comp_ArithTriOp(void (Compiler::*op)(int, const Gen::OpArg&, const Gen::OpArg&),
|
void Comp_ArithTriOp(void (Compiler::*op)(int, const Gen::OpArg&, const Gen::OpArg&),
|
||||||
|
@ -230,6 +234,10 @@ public:
|
||||||
|
|
||||||
u8* RewriteMemAccess(u8* pc);
|
u8* RewriteMemAccess(u8* pc);
|
||||||
|
|
||||||
|
#ifdef JIT_PROFILING_ENABLED
|
||||||
|
void CreateMethod(const char* namefmt, void* start, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
u8* FarCode;
|
u8* FarCode;
|
||||||
u8* NearCode;
|
u8* NearCode;
|
||||||
u32 FarSize;
|
u32 FarSize;
|
||||||
|
|
|
@ -399,14 +399,15 @@ void Compiler::Comp_MemAccess(int rd, int rn, const Op2& op2, int size, int flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode)
|
s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc, bool decrement, bool usermode, bool skipLoadingRn)
|
||||||
{
|
{
|
||||||
int regsCount = regs.Count();
|
int regsCount = regs.Count();
|
||||||
|
|
||||||
if (regsCount == 0)
|
if (regsCount == 0)
|
||||||
return 0; // actually not the right behaviour TODO: fix me
|
return 0; // actually not the right behaviour TODO: fix me
|
||||||
|
|
||||||
if (regsCount == 1 && !usermode && RegCache.LoadedRegs & (1 << *regs.begin()))
|
int firstReg = *regs.begin();
|
||||||
|
if (regsCount == 1 && !usermode && RegCache.LoadedRegs & (1 << firstReg) && !(firstReg == rn && skipLoadingRn))
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (store)
|
if (store)
|
||||||
|
@ -415,7 +416,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
flags |= memop_SubtractOffset;
|
flags |= memop_SubtractOffset;
|
||||||
Op2 offset = preinc ? Op2(4) : Op2(0);
|
Op2 offset = preinc ? Op2(4) : Op2(0);
|
||||||
|
|
||||||
Comp_MemAccess(*regs.begin(), rn, offset, 32, flags);
|
Comp_MemAccess(firstReg, rn, offset, 32, flags);
|
||||||
|
|
||||||
return decrement ? -4 : 4;
|
return decrement ? -4 : 4;
|
||||||
}
|
}
|
||||||
|
@ -482,7 +483,10 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
{
|
{
|
||||||
if (RegCache.LoadedRegs & (1 << reg))
|
if (RegCache.LoadedRegs & (1 << reg))
|
||||||
{
|
{
|
||||||
|
if (!(reg == rn && skipLoadingRn))
|
||||||
MOV(32, MapReg(reg), mem);
|
MOV(32, MapReg(reg), mem);
|
||||||
|
else
|
||||||
|
MOV(32, R(RSCRATCH), mem); // just touch the memory
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -548,6 +552,8 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
MOV(32, R(RSCRATCH2), Imm32(reg - 8));
|
MOV(32, R(RSCRATCH2), Imm32(reg - 8));
|
||||||
POP(RSCRATCH3);
|
POP(RSCRATCH3);
|
||||||
CALL(WriteBanked);
|
CALL(WriteBanked);
|
||||||
|
if (!(reg == rn && skipLoadingRn))
|
||||||
|
{
|
||||||
FixupBranch sucessfulWritten = J_CC(CC_NC);
|
FixupBranch sucessfulWritten = J_CC(CC_NC);
|
||||||
if (RegCache.LoadedRegs & (1 << reg))
|
if (RegCache.LoadedRegs & (1 << reg))
|
||||||
MOV(32, R(RegCache.Mapping[reg]), R(RSCRATCH3));
|
MOV(32, R(RegCache.Mapping[reg]), R(RSCRATCH3));
|
||||||
|
@ -555,6 +561,7 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
SaveReg(reg, RSCRATCH3);
|
SaveReg(reg, RSCRATCH3);
|
||||||
SetJumpTarget(sucessfulWritten);
|
SetJumpTarget(sucessfulWritten);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (!(RegCache.LoadedRegs & (1 << reg)))
|
else if (!(RegCache.LoadedRegs & (1 << reg)))
|
||||||
{
|
{
|
||||||
assert(reg != 15);
|
assert(reg != 15);
|
||||||
|
@ -562,6 +569,10 @@ s32 Compiler::Comp_MemAccessBlock(int rn, BitSet16 regs, bool store, bool preinc
|
||||||
POP(RSCRATCH);
|
POP(RSCRATCH);
|
||||||
SaveReg(reg, RSCRATCH);
|
SaveReg(reg, RSCRATCH);
|
||||||
}
|
}
|
||||||
|
else if (reg == rn && skipLoadingRn)
|
||||||
|
{
|
||||||
|
ADD(64, R(RSP), Imm8(8));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
POP(MapReg(reg).GetSimpleReg());
|
POP(MapReg(reg).GetSimpleReg());
|
||||||
|
@ -748,14 +759,14 @@ void Compiler::A_Comp_LDM_STM()
|
||||||
|
|
||||||
OpArg rn = MapReg(CurInstr.A_Reg(16));
|
OpArg rn = MapReg(CurInstr.A_Reg(16));
|
||||||
|
|
||||||
s32 offset = Comp_MemAccessBlock(CurInstr.A_Reg(16), regs, !load, pre, !add, usermode);
|
|
||||||
|
|
||||||
if (load && writeback && regs[CurInstr.A_Reg(16)])
|
if (load && writeback && regs[CurInstr.A_Reg(16)])
|
||||||
writeback = Num == 0
|
writeback = Num == 0
|
||||||
? (!(regs & ~BitSet16(1 << CurInstr.A_Reg(16)))) || (regs & ~BitSet16((2 << CurInstr.A_Reg(16)) - 1))
|
&& (!(regs & ~BitSet16(1 << CurInstr.A_Reg(16)))) || (regs & ~BitSet16((2 << CurInstr.A_Reg(16)) - 1));
|
||||||
: false;
|
|
||||||
if (writeback)
|
s32 offset = Comp_MemAccessBlock(CurInstr.A_Reg(16), regs, !load, pre, !add, usermode, load && writeback);
|
||||||
ADD(32, rn, offset >= INT8_MIN && offset < INT8_MAX ? Imm8(offset) : Imm32(offset));
|
|
||||||
|
if (writeback && offset)
|
||||||
|
ADD(32, rn, Imm32(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::T_Comp_MemImm()
|
void Compiler::T_Comp_MemImm()
|
||||||
|
@ -825,8 +836,9 @@ void Compiler::T_Comp_PUSH_POP()
|
||||||
}
|
}
|
||||||
|
|
||||||
OpArg sp = MapReg(13);
|
OpArg sp = MapReg(13);
|
||||||
s32 offset = Comp_MemAccessBlock(13, regs, !load, !load, !load, false);
|
s32 offset = Comp_MemAccessBlock(13, regs, !load, !load, !load, false, false);
|
||||||
|
|
||||||
|
if (offset)
|
||||||
ADD(32, sp, Imm8(offset)); // offset will be always be in range since PUSH accesses 9 regs max
|
ADD(32, sp, Imm8(offset)); // offset will be always be in range since PUSH accesses 9 regs max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,9 +848,11 @@ void Compiler::T_Comp_LDMIA_STMIA()
|
||||||
OpArg rb = MapReg(CurInstr.T_Reg(8));
|
OpArg rb = MapReg(CurInstr.T_Reg(8));
|
||||||
bool load = CurInstr.Instr & (1 << 11);
|
bool load = CurInstr.Instr & (1 << 11);
|
||||||
|
|
||||||
s32 offset = Comp_MemAccessBlock(CurInstr.T_Reg(8), regs, !load, false, false, false);
|
bool writeback = !load || !regs[CurInstr.T_Reg(8)];
|
||||||
|
|
||||||
if (!load || !regs[CurInstr.T_Reg(8)])
|
s32 offset = Comp_MemAccessBlock(CurInstr.T_Reg(8), regs, !load, false, false, false, load && writeback);
|
||||||
|
|
||||||
|
if (writeback && offset)
|
||||||
ADD(32, rb, Imm8(offset));
|
ADD(32, rb, Imm8(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,3 +124,7 @@ else()
|
||||||
target_link_libraries(core rt)
|
target_link_libraries(core rt)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_JIT_PROFILING)
|
||||||
|
target_link_libraries(core jitprofiling)
|
||||||
|
endif()
|
641
src/DSi.cpp
641
src/DSi.cpp
File diff suppressed because it is too large
Load Diff
|
@ -60,6 +60,7 @@ bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
void SetupDirectBoot();
|
||||||
void SoftReset();
|
void SoftReset();
|
||||||
|
|
||||||
bool LoadBIOS();
|
bool LoadBIOS();
|
||||||
|
|
10
src/NDS.cpp
10
src/NDS.cpp
|
@ -164,7 +164,6 @@ bool Running;
|
||||||
|
|
||||||
bool RunningGame;
|
bool RunningGame;
|
||||||
|
|
||||||
|
|
||||||
void DivDone(u32 param);
|
void DivDone(u32 param);
|
||||||
void SqrtDone(u32 param);
|
void SqrtDone(u32 param);
|
||||||
void RunTimer(u32 tid, s32 cycles);
|
void RunTimer(u32 tid, s32 cycles);
|
||||||
|
@ -342,8 +341,13 @@ void SetupDirectBoot()
|
||||||
{
|
{
|
||||||
if (ConsoleType == 1)
|
if (ConsoleType == 1)
|
||||||
{
|
{
|
||||||
printf("!! DIRECT BOOT NOT SUPPORTED IN DSI MODE\n");
|
// With the BIOS select in SCFG_BIOS and the initialization od
|
||||||
return;
|
// SCFG_BIOS depending on the Header->UnitType, we can now boot
|
||||||
|
// directly in the roms.
|
||||||
|
// There are some more SCFG Settings that change depending on
|
||||||
|
// the unit type, so this is experimental
|
||||||
|
printf("!! DIRECT BOOT NOT STABLE IN DSI MODE\n");
|
||||||
|
DSi::SetupDirectBoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 bootparams[8];
|
u32 bootparams[8];
|
||||||
|
|
|
@ -106,6 +106,8 @@ u32 micExtBufferWritePos;
|
||||||
u32 micWavLength;
|
u32 micWavLength;
|
||||||
s16* micWavBuffer;
|
s16* micWavBuffer;
|
||||||
|
|
||||||
|
void micCallback(void* data, Uint8* stream, int len);
|
||||||
|
|
||||||
|
|
||||||
void audioCallback(void* data, Uint8* stream, int len)
|
void audioCallback(void* data, Uint8* stream, int len)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +145,40 @@ void audioCallback(void* data, Uint8* stream, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void micOpen()
|
||||||
|
{
|
||||||
|
if (Config::MicInputType != 1)
|
||||||
|
{
|
||||||
|
micDevice = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_AudioSpec whatIwant, whatIget;
|
||||||
|
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
|
||||||
|
whatIwant.freq = 44100;
|
||||||
|
whatIwant.format = AUDIO_S16LSB;
|
||||||
|
whatIwant.channels = 1;
|
||||||
|
whatIwant.samples = 1024;
|
||||||
|
whatIwant.callback = micCallback;
|
||||||
|
micDevice = SDL_OpenAudioDevice(NULL, 1, &whatIwant, &whatIget, 0);
|
||||||
|
if (!micDevice)
|
||||||
|
{
|
||||||
|
printf("Mic init failed: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_PauseAudioDevice(micDevice, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void micClose()
|
||||||
|
{
|
||||||
|
if (micDevice)
|
||||||
|
SDL_CloseAudioDevice(micDevice);
|
||||||
|
|
||||||
|
micDevice = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void micLoadWav(const char* name)
|
void micLoadWav(const char* name)
|
||||||
{
|
{
|
||||||
SDL_AudioSpec format;
|
SDL_AudioSpec format;
|
||||||
|
@ -625,7 +661,7 @@ void EmuThread::emuRun()
|
||||||
// checkme
|
// checkme
|
||||||
emit windowEmuStart();
|
emit windowEmuStart();
|
||||||
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0);
|
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0);
|
||||||
if (micDevice) SDL_PauseAudioDevice(micDevice, 0);
|
micOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::emuPause()
|
void EmuThread::emuPause()
|
||||||
|
@ -638,7 +674,7 @@ void EmuThread::emuPause()
|
||||||
while (EmuStatus != 2);
|
while (EmuStatus != 2);
|
||||||
|
|
||||||
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1);
|
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1);
|
||||||
if (micDevice) SDL_PauseAudioDevice(micDevice, 1);
|
micClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::emuUnpause()
|
void EmuThread::emuUnpause()
|
||||||
|
@ -651,7 +687,7 @@ void EmuThread::emuUnpause()
|
||||||
EmuRunning = PrevEmuStatus;
|
EmuRunning = PrevEmuStatus;
|
||||||
|
|
||||||
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0);
|
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0);
|
||||||
if (micDevice) SDL_PauseAudioDevice(micDevice, 0);
|
micOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::emuStop()
|
void EmuThread::emuStop()
|
||||||
|
@ -660,7 +696,7 @@ void EmuThread::emuStop()
|
||||||
EmuPause = 0;
|
EmuPause = 0;
|
||||||
|
|
||||||
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1);
|
if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1);
|
||||||
if (micDevice) SDL_PauseAudioDevice(micDevice, 1);
|
micClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuThread::emuFrameStep()
|
void EmuThread::emuFrameStep()
|
||||||
|
@ -2401,6 +2437,8 @@ void MainWindow::onUpdateAudioSettings()
|
||||||
|
|
||||||
void MainWindow::onAudioSettingsFinished(int res)
|
void MainWindow::onAudioSettingsFinished(int res)
|
||||||
{
|
{
|
||||||
|
micClose();
|
||||||
|
|
||||||
SPU::SetInterpolation(Config::AudioInterp);
|
SPU::SetInterpolation(Config::AudioInterp);
|
||||||
|
|
||||||
if (Config::MicInputType == 3)
|
if (Config::MicInputType == 3)
|
||||||
|
@ -2418,6 +2456,8 @@ void MainWindow::onAudioSettingsFinished(int res)
|
||||||
else
|
else
|
||||||
Frontend::Mic_SetExternalBuffer(NULL, 0);
|
Frontend::Mic_SetExternalBuffer(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
micOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onOpenWifiSettings()
|
void MainWindow::onOpenWifiSettings()
|
||||||
|
@ -2762,21 +2802,7 @@ int main(int argc, char** argv)
|
||||||
SDL_PauseAudioDevice(audioDevice, 1);
|
SDL_PauseAudioDevice(audioDevice, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
|
micDevice = 0;
|
||||||
whatIwant.freq = 44100;
|
|
||||||
whatIwant.format = AUDIO_S16LSB;
|
|
||||||
whatIwant.channels = 1;
|
|
||||||
whatIwant.samples = 1024;
|
|
||||||
whatIwant.callback = micCallback;
|
|
||||||
micDevice = SDL_OpenAudioDevice(NULL, 1, &whatIwant, &whatIget, 0);
|
|
||||||
if (!micDevice)
|
|
||||||
{
|
|
||||||
printf("Mic init failed: %s\n", SDL_GetError());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SDL_PauseAudioDevice(micDevice, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
memset(micExtBuffer, 0, sizeof(micExtBuffer));
|
memset(micExtBuffer, 0, sizeof(micExtBuffer));
|
||||||
|
@ -2847,7 +2873,7 @@ int main(int argc, char** argv)
|
||||||
Frontend::DeInit_ROM();
|
Frontend::DeInit_ROM();
|
||||||
|
|
||||||
if (audioDevice) SDL_CloseAudioDevice(audioDevice);
|
if (audioDevice) SDL_CloseAudioDevice(audioDevice);
|
||||||
if (micDevice) SDL_CloseAudioDevice(micDevice);
|
micClose();
|
||||||
|
|
||||||
SDL_DestroyCond(audioSync);
|
SDL_DestroyCond(audioSync);
|
||||||
SDL_DestroyMutex(audioSyncLock);
|
SDL_DestroyMutex(audioSyncLock);
|
||||||
|
|
Loading…
Reference in New Issue