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:
Shawn Hoffman 2009-11-07 17:56:01 +00:00
parent 5579a9169d
commit 42cd2838a3
6 changed files with 89 additions and 97 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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);