mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-27 15:35:27 +00:00
jit bcctrx and misc code cleanup. NES games launched from animal crossing work, but have major video problems...
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4504 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
5579a9169d
commit
42cd2838a3
@ -251,9 +251,7 @@ union bba_descr {
|
||||
u32 word;
|
||||
};
|
||||
bool CEXIETHERNET::cbwriteDescriptor(u32 size) {
|
||||
//if(size < 0x3C) {//60
|
||||
#define ETHERNET_HEADER_SIZE 0xE
|
||||
if(size < ETHERNET_HEADER_SIZE)
|
||||
if(size < SIZEOF_ETH_HEADER)
|
||||
{
|
||||
DEBUGPRINT("Packet too small: %i bytes\n", size);
|
||||
return false;
|
||||
|
@ -15,7 +15,6 @@
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <assert.h>
|
||||
#include "StringUtil.h"
|
||||
#include "../Memmap.h"
|
||||
// GROSS CODE ALERT: headers need to be included in the following order
|
||||
@ -226,8 +225,7 @@ bool CEXIETHERNET::activate()
|
||||
if ( !(info[0] > TAP_WIN32_MIN_MAJOR
|
||||
|| (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)) )
|
||||
{
|
||||
#define PACKAGE_NAME "Dolphin"
|
||||
DEBUGPRINT("ERROR: This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
|
||||
DEBUGPRINT("ERROR: This version of Dolphin requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your Dolphin distribution, a reboot is probably required at this point to get Windows to see the new driver.",
|
||||
TAP_WIN32_MIN_MAJOR,
|
||||
TAP_WIN32_MIN_MINOR);
|
||||
return false;
|
||||
@ -279,7 +277,7 @@ bool CEXIETHERNET::CheckRecieved()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||
bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||
{
|
||||
if (!isActivated())
|
||||
activate();
|
||||
@ -297,7 +295,7 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||
DWORD res = GetLastError();
|
||||
DEBUGPRINT("Failed to send packet with error 0x%X", res);
|
||||
}
|
||||
if (numBytesWrit != size)
|
||||
if (numBytesWrit != size)
|
||||
{
|
||||
DEBUGPRINT("BBA sendPacket %i only got %i bytes sent!", size, numBytesWrit);
|
||||
return false;
|
||||
@ -307,7 +305,7 @@ bool CEXIETHERNET::sendPacket(u8 *etherpckt, int size)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEXIETHERNET::handleRecvdPacket()
|
||||
bool CEXIETHERNET::handleRecvdPacket()
|
||||
{
|
||||
int rbwpp = (int)(mCbw.p_write() + CB_OFFSET); // read buffer write page pointer
|
||||
u32 available_bytes_in_cb;
|
||||
@ -322,7 +320,7 @@ bool CEXIETHERNET::handleRecvdPacket()
|
||||
//DUMPWORD(mRBRPP);
|
||||
//DUMPWORD(available_bytes_in_cb);
|
||||
|
||||
assert(available_bytes_in_cb <= CB_SIZE);
|
||||
_dbg_assert_(SP1, available_bytes_in_cb <= CB_SIZE);
|
||||
if (available_bytes_in_cb != CB_SIZE)//< mRecvBufferLength + SIZEOF_RECV_DESCRIPTOR)
|
||||
return true;
|
||||
cbwriteDescriptor(mRecvBufferLength);
|
||||
@ -440,9 +438,7 @@ union bba_descr
|
||||
|
||||
bool CEXIETHERNET::cbwriteDescriptor(u32 size)
|
||||
{
|
||||
//if(size < 0x3C) {//60
|
||||
#define ETHERNET_HEADER_SIZE 0xE
|
||||
if (size < ETHERNET_HEADER_SIZE)
|
||||
if (size < SIZEOF_ETH_HEADER)
|
||||
{
|
||||
DEBUGPRINT("Packet too small: %i bytes", size);
|
||||
return false;
|
||||
@ -453,7 +449,7 @@ bool CEXIETHERNET::cbwriteDescriptor(u32 size)
|
||||
|
||||
//We should probably not implement wraparound here,
|
||||
//since neither tmbinc, riptool.dol, or libogc does...
|
||||
if (mCbw.p_write() + SIZEOF_RECV_DESCRIPTOR >= CB_SIZE)
|
||||
if (mCbw.p_write() + SIZEOF_RECV_DESCRIPTOR >= CB_SIZE)
|
||||
{
|
||||
DEBUGPRINT("The descriptor won't fit");
|
||||
return false;
|
||||
@ -469,11 +465,11 @@ bool CEXIETHERNET::cbwriteDescriptor(u32 size)
|
||||
descr.packet_len = size;
|
||||
descr.status = 0;
|
||||
u32 npp;
|
||||
if (mCbw.p_write() + size < CB_SIZE)
|
||||
if (mCbw.p_write() + size < CB_SIZE)
|
||||
{
|
||||
npp = (u32)(mCbw.p_write() + size + CB_OFFSET);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
npp = (u32)(mCbw.p_write() + size + CB_OFFSET - CB_SIZE);
|
||||
}
|
||||
@ -493,4 +489,4 @@ bool CEXIETHERNET::cbwriteDescriptor(u32 size)
|
||||
mCbw.write(&descr.word, SIZEOF_RECV_DESCRIPTOR);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +116,13 @@ private:
|
||||
// TODO: convert into unions
|
||||
enum
|
||||
{
|
||||
BBA_RECV_SIZE = 0x800,
|
||||
BBA_MEM_SIZE = 0x1000,
|
||||
BBA_RECV_SIZE = 0x800,
|
||||
BBA_MEM_SIZE = 0x1000,
|
||||
|
||||
CB_OFFSET = 0x100,
|
||||
CB_SIZE = (BBA_MEM_SIZE - CB_OFFSET),
|
||||
SIZEOF_RECV_DESCRIPTOR = 4,
|
||||
SIZEOF_ETH_HEADER = 0xe,
|
||||
SIZEOF_RECV_DESCRIPTOR = 4,
|
||||
|
||||
EXI_DEVTYPE_ETHER = 0x04020200,
|
||||
|
||||
|
@ -589,7 +589,10 @@ enum EQuantizeType
|
||||
// branches
|
||||
enum
|
||||
{
|
||||
BO_DONT_DECREMENT_FLAG = 0x4,
|
||||
BO_BRANCH_IF_CTR_0 = 2, // 3
|
||||
BO_DONT_DECREMENT_FLAG = 4, // 2
|
||||
BO_BRANCH_IF_TRUE = 8, // 1
|
||||
BO_DONT_CHECK_CONDITION = 16, // 0
|
||||
};
|
||||
|
||||
// Special purpose register indices
|
||||
|
@ -63,39 +63,38 @@ void bcx(UGeckoInstruction _inst)
|
||||
NPC = SignExt16(_inst.BD << 2);
|
||||
else
|
||||
NPC = PC + SignExt16(_inst.BD << 2);
|
||||
}
|
||||
}
|
||||
m_EndBlock = true;
|
||||
}
|
||||
|
||||
void bcctrx(UGeckoInstruction _inst)
|
||||
{
|
||||
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||
CTR--;
|
||||
_dbg_assert_msg_(POWERPC, _inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!");
|
||||
|
||||
int condition = ((_inst.BO>>4) | (GetCRBit(_inst.BI) == ((_inst.BO>>3) & 1))) & 1;
|
||||
int condition = ((_inst.BO_2>>4) | (GetCRBit(_inst.BI_2) == ((_inst.BO_2>>3) & 1))) & 1;
|
||||
|
||||
if (condition)
|
||||
{
|
||||
if (_inst.LK)
|
||||
LR = PC + 4;
|
||||
NPC = CTR & (~3);
|
||||
if (_inst.LK_3)
|
||||
LR = PC + 4;
|
||||
}
|
||||
m_EndBlock = true;
|
||||
}
|
||||
|
||||
void bclrx(UGeckoInstruction _inst)
|
||||
{
|
||||
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||
if ((_inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
|
||||
CTR--;
|
||||
|
||||
int counter = ((_inst.BO >> 2) | ((CTR != 0) ^ (_inst.BO >> 1)))&1;
|
||||
int condition = ((_inst.BO >> 4) | (GetCRBit(_inst.BI) == ((_inst.BO >> 3) & 1))) & 1;
|
||||
int counter = ((_inst.BO_2 >> 2) | ((CTR != 0) ^ (_inst.BO_2 >> 1))) & 1;
|
||||
int condition = ((_inst.BO_2 >> 4) | (GetCRBit(_inst.BI_2) == ((_inst.BO_2 >> 3) & 1))) & 1;
|
||||
|
||||
if (counter & condition)
|
||||
{
|
||||
NPC = LR & (~3);
|
||||
if (_inst.LK)
|
||||
LR = PC+4;
|
||||
NPC = LR & (~3);
|
||||
if (_inst.LK_3)
|
||||
LR = PC + 4;
|
||||
}
|
||||
m_EndBlock = true;
|
||||
}
|
||||
|
@ -42,10 +42,8 @@ using namespace Gen;
|
||||
|
||||
void Jit64::sc(UGeckoInstruction inst)
|
||||
{
|
||||
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITBranchOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
|
||||
INSTRUCTION_START;
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Branch)
|
||||
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
@ -54,10 +52,8 @@ void Jit64::sc(UGeckoInstruction inst)
|
||||
|
||||
void Jit64::rfi(UGeckoInstruction inst)
|
||||
{
|
||||
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITBranchOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
|
||||
INSTRUCTION_START;
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Branch)
|
||||
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
@ -79,10 +75,8 @@ void Jit64::rfi(UGeckoInstruction inst)
|
||||
|
||||
void Jit64::bx(UGeckoInstruction inst)
|
||||
{
|
||||
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITBranchOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
|
||||
INSTRUCTION_START;
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Branch)
|
||||
|
||||
if (inst.LK)
|
||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
||||
@ -121,10 +115,8 @@ void Jit64::bx(UGeckoInstruction inst)
|
||||
// variants of this instruction.
|
||||
void Jit64::bcx(UGeckoInstruction inst)
|
||||
{
|
||||
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITBranchOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
|
||||
INSTRUCTION_START;
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Branch)
|
||||
|
||||
// USES_CR
|
||||
_assert_msg_(DYNA_REC, js.isLastInstruction, "bcx not last instruction of block");
|
||||
@ -138,13 +130,13 @@ void Jit64::bcx(UGeckoInstruction inst)
|
||||
//const bool only_condition_check = (inst.BO & 4) ? true : false;
|
||||
//if (only_condition_check && only_counter_check)
|
||||
// PanicAlert("Bizarre bcx encountered. Likely bad or corrupt code.");
|
||||
bool doFullTest = (inst.BO & 16) == 0 && (inst.BO & 4) == 0;
|
||||
bool doFullTest = ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) && ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0);
|
||||
bool ctrDecremented = false;
|
||||
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit
|
||||
{
|
||||
TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
|
||||
if (inst.BO & 8) // Conditional branch
|
||||
if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch
|
||||
branch = CC_NZ;
|
||||
else
|
||||
branch = CC_Z;
|
||||
@ -158,13 +150,13 @@ void Jit64::bcx(UGeckoInstruction inst)
|
||||
MOV(32, R(EAX), Imm32(1));
|
||||
}
|
||||
|
||||
if ((inst.BO & 4) == 0) // Decrement and test CTR
|
||||
if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR
|
||||
{
|
||||
// Decrement CTR
|
||||
SUB(32, M(&CTR), Imm8(1));
|
||||
ctrDecremented = true;
|
||||
// Test whether to branch if CTR is zero or not
|
||||
if (inst.BO & 2)
|
||||
if (inst.BO & BO_BRANCH_IF_CTR_0)
|
||||
branch = CC_Z;
|
||||
else
|
||||
branch = CC_NZ;
|
||||
@ -217,56 +209,58 @@ void Jit64::bcx(UGeckoInstruction inst)
|
||||
|
||||
void Jit64::bcctrx(UGeckoInstruction inst)
|
||||
{
|
||||
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITBranchOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
|
||||
INSTRUCTION_START;
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Branch)
|
||||
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
|
||||
// bool fastway = true;
|
||||
// bcctrx doesn't decrement and/or test CTR
|
||||
_dbg_assert_msg_(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!");
|
||||
|
||||
if ((inst.BO & 16) == 0)
|
||||
if (inst.BO_2 & BO_DONT_CHECK_CONDITION)
|
||||
{
|
||||
// Rare condition usually used by NES Emulators
|
||||
// TODO: JIT does not support this
|
||||
ERROR_LOG(DYNA_REC, "Bizarro bcctrx %08x, not supported.", inst.hex);
|
||||
//_assert_msg_(DYNA_REC, 0, "Bizarro bcctrx");
|
||||
/*
|
||||
fastway = false;
|
||||
MOV(32, M(&PC), Imm32(js.compilerPC+4));
|
||||
MOV(32, R(EAX), M(&CR));
|
||||
XOR(32, R(ECX), R(ECX));
|
||||
AND(32, R(EAX), Imm32(0x80000000 >> inst.BI));
|
||||
// BO_2 == 1z1zz -> b always
|
||||
|
||||
CCFlags branch;
|
||||
if(inst.BO & 8)
|
||||
branch = CC_NZ;
|
||||
else
|
||||
branch = CC_Z;
|
||||
*/
|
||||
// TODO(ector): Why is this commented out?
|
||||
//SETcc(branch, R(ECX));
|
||||
// check for EBX
|
||||
//TEST(32, R(ECX), R(ECX));
|
||||
//linkEnd = J_CC(branch);
|
||||
//NPC = CTR & 0xfffffffc;
|
||||
MOV(32, R(EAX), M(&CTR));
|
||||
if (inst.LK_3)
|
||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||
WriteExitDestInEAX(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rare condition seen in (just some versions of?) Nintendo's NES Emulator
|
||||
|
||||
// BO_2 == 001zy -> b if false
|
||||
// BO_2 == 011zy -> b if true
|
||||
|
||||
// Ripped from bclrx
|
||||
TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
|
||||
Gen::CCFlags branch;
|
||||
if (inst.BO_2 & BO_BRANCH_IF_TRUE)
|
||||
branch = CC_Z;
|
||||
else
|
||||
branch = CC_NZ;
|
||||
MOV(32, R(EAX), Imm32(js.compilerPC + 4));
|
||||
FixupBranch b = J_CC(branch, false);
|
||||
MOV(32, R(EAX), M(&CTR));
|
||||
MOV(32, M(&PC), R(EAX));
|
||||
if (inst.LK_3)
|
||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||
// Would really like to continue the block here, but it ends. TODO.
|
||||
SetJumpTarget(b);
|
||||
WriteExitDestInEAX(0);
|
||||
return;
|
||||
}
|
||||
// NPC = CTR & 0xfffffffc;
|
||||
MOV(32, R(EAX), M(&CTR));
|
||||
if (inst.LK)
|
||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||
WriteExitDestInEAX(0);
|
||||
}
|
||||
|
||||
|
||||
void Jit64::bclrx(UGeckoInstruction inst)
|
||||
{
|
||||
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITBranchOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
|
||||
INSTRUCTION_START;
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(Branch)
|
||||
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
@ -281,13 +275,14 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||
#endif
|
||||
MOV(32, R(EAX), M(&LR));
|
||||
MOV(32, M(&PC), R(EAX));
|
||||
if (inst.LK)
|
||||
if (inst.LK_3)
|
||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||
WriteExitDestInEAX(0);
|
||||
return;
|
||||
} else if ((inst.BO & 4) == 0) {
|
||||
// Decrement CTR?? in bclrx?? this goes to fallback.
|
||||
} else if ((inst.BO & 16) == 0) {
|
||||
} else if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) {
|
||||
// Decrement CTR. Not mutually exclusive...
|
||||
// Will fall back to int, but we should be able to do it here, sometime
|
||||
} else if ((inst.BO_2 & BO_DONT_CHECK_CONDITION) == 0) {
|
||||
// Test a CR bit. Not too hard.
|
||||
// beqlr- 4d820020
|
||||
// blelr- 4c810020
|
||||
@ -296,7 +291,7 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||
// etc...
|
||||
TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3)));
|
||||
Gen::CCFlags branch;
|
||||
if (inst.BO & 8)
|
||||
if (inst.BO_2 & BO_BRANCH_IF_TRUE)
|
||||
branch = CC_Z;
|
||||
else
|
||||
branch = CC_NZ;
|
||||
@ -304,7 +299,7 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||
FixupBranch b = J_CC(branch, false);
|
||||
MOV(32, R(EAX), M(&LR));
|
||||
MOV(32, M(&PC), R(EAX));
|
||||
if (inst.LK)
|
||||
if (inst.LK_3)
|
||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||
// Would really like to continue the block here, but it ends. TODO.
|
||||
SetJumpTarget(b);
|
||||
|
Loading…
x
Reference in New Issue
Block a user