Implemented accurate BP and accurate Watermark, this should eventually retire FAKE_Watchdog.
AbortFrame is not implemented yet. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5699 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
6c164cd161
commit
673b9ac179
|
@ -86,7 +86,7 @@ int et_UpdateInterrupts;
|
||||||
|
|
||||||
void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate)
|
void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate)
|
||||||
{
|
{
|
||||||
UpdateInterrupts((userdata) ? true : false);
|
UpdateInterrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for 1002 verts, breakpoint there, see why next draw is flushed
|
// look for 1002 verts, breakpoint there, see why next draw is flushed
|
||||||
|
@ -98,9 +98,6 @@ UCPStatusReg m_CPStatusReg;
|
||||||
UCPCtrlReg m_CPCtrlReg;
|
UCPCtrlReg m_CPCtrlReg;
|
||||||
UCPClearReg m_CPClearReg;
|
UCPClearReg m_CPClearReg;
|
||||||
|
|
||||||
int m_tempHWM, m_tempLWM;
|
|
||||||
int m_tempBP;
|
|
||||||
|
|
||||||
int m_bboxleft;
|
int m_bboxleft;
|
||||||
int m_bboxtop;
|
int m_bboxtop;
|
||||||
int m_bboxright;
|
int m_bboxright;
|
||||||
|
@ -123,12 +120,9 @@ void FifoCriticalLeave()
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(m_tempHWM);
|
|
||||||
p.Do(m_tempLWM);
|
|
||||||
p.Do(m_tempBP);
|
|
||||||
p.Do(m_CPStatusReg);
|
p.Do(m_CPStatusReg);
|
||||||
p.Do(m_CPCtrlReg);
|
p.Do(m_CPCtrlReg);
|
||||||
//p.Do(m_CPClearReg);
|
p.Do(m_CPClearReg);
|
||||||
p.Do(m_bboxleft);
|
p.Do(m_bboxleft);
|
||||||
p.Do(m_bboxtop);
|
p.Do(m_bboxtop);
|
||||||
p.Do(m_bboxright);
|
p.Do(m_bboxright);
|
||||||
|
@ -148,7 +142,7 @@ inline u16 ReadHigh (u32 _reg) {return (u16)(_reg >> 16);}
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
m_CPStatusReg.Hex = 0;
|
m_CPStatusReg.Hex = 0;
|
||||||
m_CPStatusReg.CommandIdle = 1; // Seems not used
|
m_CPStatusReg.CommandIdle = 1;
|
||||||
m_CPStatusReg.ReadIdle = 1;
|
m_CPStatusReg.ReadIdle = 1;
|
||||||
|
|
||||||
m_CPCtrlReg.Hex = 0;
|
m_CPCtrlReg.Hex = 0;
|
||||||
|
@ -165,7 +159,7 @@ void Init()
|
||||||
memset(&fifo,0,sizeof(fifo));
|
memset(&fifo,0,sizeof(fifo));
|
||||||
fifo.CPCmdIdle = 1 ;
|
fifo.CPCmdIdle = 1 ;
|
||||||
fifo.CPReadIdle = 1;
|
fifo.CPReadIdle = 1;
|
||||||
fifo.bFF_Breakpoint = 1;
|
fifo.bFF_Breakpoint = 0;
|
||||||
|
|
||||||
s_fifoIdleEvent.Init();
|
s_fifoIdleEvent.Init();
|
||||||
|
|
||||||
|
@ -183,10 +177,10 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
switch (_Address & 0xFFF)
|
switch (_Address & 0xFFF)
|
||||||
{
|
{
|
||||||
case STATUS_REGISTER:
|
case STATUS_REGISTER:
|
||||||
//TODO?: if really needed
|
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint && fifo.bFF_BPInt;
|
||||||
//m_CPStatusReg.CommandIdle = fifo.CPCmdIdle;
|
m_CPStatusReg.ReadIdle = fifo.bFF_Breakpoint || !fifo.CPReadWriteDistance || !fifo.bFF_GPReadEnable;
|
||||||
//m_CPStatusReg.CommandIdle = fifo.CPReadIdle;
|
m_CPStatusReg.CommandIdle = fifo.CPCmdIdle;
|
||||||
// uncomment: change a bit the behaviour MP1. Not very useful though
|
m_CPStatusReg.UnderflowLoWatermark = fifo.CPReadIdle;
|
||||||
|
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
//m_CPStatusReg.ReadIdle = 1;
|
//m_CPStatusReg.ReadIdle = 1;
|
||||||
|
@ -201,14 +195,13 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
);
|
);
|
||||||
|
|
||||||
_rReturnValue = m_CPStatusReg.Hex;
|
_rReturnValue = m_CPStatusReg.Hex;
|
||||||
// Clear on read
|
|
||||||
UpdateInterrupts(false);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return;
|
case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return;
|
||||||
case CLEAR_REGISTER:
|
case CLEAR_REGISTER:
|
||||||
_rReturnValue = m_CPClearReg.Hex;
|
_rReturnValue = m_CPClearReg.Hex;
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "(r) clear: 0x%04x", _rReturnValue);
|
PanicAlert("CommandProcessor:: CPU reads from CLEAR_REGISTER!");
|
||||||
|
ERROR_LOG(COMMANDPROCESSOR, "(r) clear: 0x%04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FIFO_TOKEN_REGISTER: _rReturnValue = m_tokenReg; return;
|
case FIFO_TOKEN_REGISTER: _rReturnValue = m_tokenReg; return;
|
||||||
|
@ -228,17 +221,15 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
|
|
||||||
// TODO: cases cleanup
|
// TODO: cases cleanup
|
||||||
case FIFO_RW_DISTANCE_LO:
|
case FIFO_RW_DISTANCE_LO:
|
||||||
|
_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
// But even if you return the true value, most games just don't care
|
//_rReturnValue = 0;
|
||||||
//_rReturnValue = ReadLow (fifo.CPReadWriteDistance);
|
|
||||||
_rReturnValue = 0;
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_RW_DISTANCE_HI:
|
case FIFO_RW_DISTANCE_HI:
|
||||||
|
_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
// But even if you return the true value, most games just don't care
|
//_rReturnValue = 0;
|
||||||
//_rReturnValue = ReadHigh(fifo.CPReadWriteDistance);
|
|
||||||
_rReturnValue = 0;
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -252,17 +243,15 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case FIFO_READ_POINTER_LO:
|
case FIFO_READ_POINTER_LO:
|
||||||
|
_rReturnValue = ReadLow (fifo.CPReadPointer);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
// But even if you return the true value, most games just don't care
|
//_rReturnValue = ReadLow (fifo.CPWritePointer);
|
||||||
//_rReturnValue = ReadLow (fifo.CPReadPointer);
|
|
||||||
_rReturnValue = ReadLow (fifo.CPWritePointer);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_LO : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_LO : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
case FIFO_READ_POINTER_HI:
|
case FIFO_READ_POINTER_HI:
|
||||||
|
_rReturnValue = ReadHigh(fifo.CPReadPointer);
|
||||||
// hack: CPU will always believe fifo is empty and on idle
|
// hack: CPU will always believe fifo is empty and on idle
|
||||||
// But even if you return the true value, most games just don't care
|
//_rReturnValue = ReadHigh(fifo.CPWritePointer);
|
||||||
//_rReturnValue = ReadHigh(fifo.CPReadPointer);
|
|
||||||
_rReturnValue = ReadHigh(fifo.CPWritePointer);
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_HI : %04x", _rReturnValue);
|
DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_HI : %04x", _rReturnValue);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -348,12 +337,8 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
|
|
||||||
void Write16(const u16 _Value, const u32 _Address)
|
void Write16(const u16 _Value, const u32 _Address)
|
||||||
{
|
{
|
||||||
bool bUpdate = false;
|
|
||||||
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
|
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
|
||||||
|
|
||||||
//Spin until queue is empty - it WILL become empty because this is the only thread
|
|
||||||
//that submits data
|
|
||||||
|
|
||||||
if (g_VideoInitialize.bOnThread)
|
if (g_VideoInitialize.bOnThread)
|
||||||
{
|
{
|
||||||
// Force complete fifo flush if we attempt to set/reset the fifo (API GXSetGPFifo or equivalent)
|
// Force complete fifo flush if we attempt to set/reset the fifo (API GXSetGPFifo or equivalent)
|
||||||
|
@ -369,23 +354,22 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
// - spin until fifo is empty
|
// - spin until fifo is empty
|
||||||
// - else
|
// - else
|
||||||
// - normal write16
|
// - normal write16
|
||||||
|
|
||||||
if (((_Address&0xFFF) == CTRL_REGISTER) && (_Value == 0)) // API hack
|
if (((_Address&0xFFF) == CTRL_REGISTER) && (_Value == 0)) // API hack
|
||||||
{
|
{
|
||||||
// weird MP1 redo that right after linking fifo with GP... hmmm
|
// weird MP1 redo that right after linking fifo with GP... hmmm
|
||||||
/*_dbg_assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance == 0,
|
//_dbg_assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance == 0,
|
||||||
"WTF! Something went wrong with GP/PPC the sync! -> CPReadWriteDistance: 0x%08X\n"
|
// "WTF! Something went wrong with GP/PPC the sync! -> CPReadWriteDistance: 0x%08X\n"
|
||||||
" - The fifo is not empty but we are going to lock it anyway.\n"
|
// " - The fifo is not empty but we are going to lock it anyway.\n"
|
||||||
" - \"Normaly\", this is due to fifo-hang-so-lets-attempt-recovery.\n"
|
// " - \"Normaly\", this is due to fifo-hang-so-lets-attempt-recovery.\n"
|
||||||
" - The bad news is dolphin don't support special recovery features like GXfifo's metric yet.\n"
|
// " - The bad news is dolphin don't support special recovery features like GXfifo's metric yet.\n"
|
||||||
" - The good news is, the time you read that message, the fifo should be empty now :p\n"
|
// " - The good news is, the time you read that message, the fifo should be empty now :p\n"
|
||||||
" - Anyway, fifo flush will be forced if you press OK and dolphin might continue to work...\n"
|
// " - Anyway, fifo flush will be forced if you press OK and dolphin might continue to work...\n"
|
||||||
" - We aren't betting on that :)", fifo.CPReadWriteDistance);
|
// " - We aren't betting on that :)", fifo.CPReadWriteDistance);
|
||||||
*/
|
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "*********************** GXSetGPFifo very soon? ***********************");
|
DEBUG_LOG(COMMANDPROCESSOR, "*********************** GXSetGPFifo very soon? ***********************");
|
||||||
// (mb2) We don't sleep here since it could be a perf issue for super monkey ball (yup only this game IIRC)
|
// (mb2) We don't sleep here since it could be a perf issue for super monkey ball (yup only this game IIRC)
|
||||||
// Touching that game is a no-go so I don't want to take the risk :p
|
// Touching that game is a no-go so I don't want to take the risk :p
|
||||||
while (fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
||||||
{
|
{
|
||||||
s_fifoIdleEvent.Wait();
|
s_fifoIdleEvent.Wait();
|
||||||
}
|
}
|
||||||
|
@ -407,40 +391,37 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
UCPCtrlReg tmpCtrl(_Value);
|
UCPCtrlReg tmpCtrl(_Value);
|
||||||
m_CPCtrlReg.Hex = tmpCtrl.Hex;
|
m_CPCtrlReg.Hex = tmpCtrl.Hex;
|
||||||
|
|
||||||
Common::AtomicStore(fifo.bFF_GPLinkEnable, tmpCtrl.GPLinkEnable);
|
if (!tmpCtrl.BPEnable)
|
||||||
Common::AtomicStore(fifo.bFF_GPReadEnable, tmpCtrl.GPReadEnable);
|
Common::AtomicStore(fifo.bFF_Breakpoint, false);
|
||||||
Common::AtomicStore(fifo.bFF_BPEnable, tmpCtrl.BPEnable);
|
|
||||||
|
|
||||||
if (tmpCtrl.BPInit && tmpCtrl.BPEnable && tmpCtrl.GPReadEnable)
|
fifo.bFF_BPInt = tmpCtrl.BPInt;
|
||||||
{
|
fifo.bFF_BPEnable = tmpCtrl.BPEnable;
|
||||||
// Clear old BP and initiate new BP
|
fifo.bFF_GPReadEnable = tmpCtrl.GPReadEnable;
|
||||||
Common::AtomicStore(fifo.bFF_Breakpoint, 0);
|
|
||||||
|
|
||||||
// The following is a hack of Synchronized Breakpoint for dual core mode
|
UpdateInterrupts();
|
||||||
// Some games only waits a finite N cycles for FIFO interrupts, then hangs up on time out
|
|
||||||
// e.g. Metriod Prime 2
|
|
||||||
if (g_VideoInitialize.bOnThread && g_ActiveConfig.bFIFOBPhack)
|
|
||||||
UpdateInterrupts(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value);
|
INFO_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | LINK %s | BP %s || Init %s | OvF %s | UndF %s"
|
DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | BP %s | Int %s | OvF %s | UndF %s | LINK %s"
|
||||||
, fifo.bFF_GPReadEnable ? "ON" : "OFF"
|
, fifo.bFF_GPReadEnable ? "ON" : "OFF"
|
||||||
, fifo.bFF_GPLinkEnable ? "ON" : "OFF"
|
|
||||||
, fifo.bFF_BPEnable ? "ON" : "OFF"
|
, fifo.bFF_BPEnable ? "ON" : "OFF"
|
||||||
, m_CPCtrlReg.BPInit ? "ON" : "OFF"
|
, fifo.bFF_BPInt ? "ON" : "OFF"
|
||||||
, m_CPCtrlReg.FifoOverflowIntEnable ? "ON" : "OFF"
|
, m_CPCtrlReg.FifoOverflowIntEnable ? "ON" : "OFF"
|
||||||
, m_CPCtrlReg.FifoUnderflowIntEnable ? "ON" : "OFF"
|
, m_CPCtrlReg.FifoUnderflowIntEnable ? "ON" : "OFF"
|
||||||
|
, m_CPCtrlReg.GPLinkEnable ? "ON" : "OFF"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLEAR_REGISTER:
|
case CLEAR_REGISTER:
|
||||||
// We don't care since we don't implement Watermark
|
{
|
||||||
//m_CPClearReg.Hex = 0;
|
UCPClearReg tmpCtrl(_Value);
|
||||||
//m_CPStatusReg.OverflowHiWatermark = 0;
|
if (tmpCtrl.ClearFifoOverflow)
|
||||||
//m_CPStatusReg.UnderflowHiWatermark = 0;
|
m_CPStatusReg.OverflowHiWatermark = false;
|
||||||
|
if (tmpCtrl.ClearFifoUnderflow)
|
||||||
|
Common::AtomicStore(fifo.CPReadIdle, false);
|
||||||
|
UpdateInterrupts();
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x", _Value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERF_SELECT:
|
case PERF_SELECT:
|
||||||
|
@ -455,46 +436,38 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIFO_BASE_LO:
|
case FIFO_BASE_LO:
|
||||||
bUpdate = true;
|
|
||||||
WriteLow ((u32 &)fifo.CPBase, _Value & 0xFFE0);
|
WriteLow ((u32 &)fifo.CPBase, _Value & 0xFFE0);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_LO : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_LO : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
case FIFO_BASE_HI:
|
case FIFO_BASE_HI:
|
||||||
bUpdate = true;
|
|
||||||
WriteHigh((u32 &)fifo.CPBase, _Value);
|
WriteHigh((u32 &)fifo.CPBase, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_HI : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_HI : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIFO_END_LO:
|
case FIFO_END_LO:
|
||||||
bUpdate = true;
|
|
||||||
// Somtimes this value is not aligned with 32B, e.g. New Super Mario Bros. Wii
|
// Somtimes this value is not aligned with 32B, e.g. New Super Mario Bros. Wii
|
||||||
WriteLow ((u32 &)fifo.CPEnd, _Value & 0xFFE0);
|
WriteLow ((u32 &)fifo.CPEnd, _Value & 0xFFE0);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_LO : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_LO : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
case FIFO_END_HI:
|
case FIFO_END_HI:
|
||||||
bUpdate = true;
|
|
||||||
WriteHigh((u32 &)fifo.CPEnd, _Value);
|
WriteHigh((u32 &)fifo.CPEnd, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_HI : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_HI : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIFO_WRITE_POINTER_LO:
|
case FIFO_WRITE_POINTER_LO:
|
||||||
bUpdate = true;
|
|
||||||
WriteLow ((u32 &)fifo.CPWritePointer, _Value & 0xFFE0);
|
WriteLow ((u32 &)fifo.CPWritePointer, _Value & 0xFFE0);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_LO : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_LO : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
case FIFO_WRITE_POINTER_HI:
|
case FIFO_WRITE_POINTER_HI:
|
||||||
bUpdate = true;
|
|
||||||
WriteHigh((u32 &)fifo.CPWritePointer, _Value);
|
WriteHigh((u32 &)fifo.CPWritePointer, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_HI : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_HI : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIFO_READ_POINTER_LO:
|
case FIFO_READ_POINTER_LO:
|
||||||
bUpdate = true;
|
|
||||||
WriteLow ((u32 &)fifo.CPReadPointer, _Value & 0xFFE0);
|
WriteLow ((u32 &)fifo.CPReadPointer, _Value & 0xFFE0);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_LO : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_LO : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
case FIFO_READ_POINTER_HI:
|
case FIFO_READ_POINTER_HI:
|
||||||
bUpdate = true;
|
|
||||||
WriteHigh((u32 &)fifo.CPReadPointer, _Value);
|
WriteHigh((u32 &)fifo.CPReadPointer, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_HI : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_HI : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
|
@ -531,11 +504,11 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
// When we fall here CPReadWriteDistance should be always null and the game should always want to overwrite it by 0.
|
// When we fall here CPReadWriteDistance should be always null and the game should always want to overwrite it by 0.
|
||||||
// So, we can skip it.
|
// So, we can skip it.
|
||||||
case FIFO_RW_DISTANCE_HI:
|
case FIFO_RW_DISTANCE_HI:
|
||||||
//WriteHigh((u32 &)fifo.CPReadWriteDistance, _Value);
|
WriteHigh((u32 &)fifo.CPReadWriteDistance, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_HI : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_HI : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
case FIFO_RW_DISTANCE_LO:
|
case FIFO_RW_DISTANCE_LO:
|
||||||
//WriteLow((u32 &)fifo.CPReadWriteDistance, _Value);
|
WriteLow((u32 &)fifo.CPReadWriteDistance, _Value);
|
||||||
DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_LO : %04x", _Value);
|
DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_LO : %04x", _Value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -543,12 +516,8 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
WARN_LOG(COMMANDPROCESSOR, "(w16) unknown CP reg write %04x @ %08x", _Value, _Address);
|
WARN_LOG(COMMANDPROCESSOR, "(w16) unknown CP reg write %04x @ %08x", _Value, _Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bUpdate || !g_VideoInitialize.bOnThread) // TOCHECK(mb2): check again if thread safe?
|
if (!g_VideoInitialize.bOnThread)
|
||||||
{
|
CatchUpGPU();
|
||||||
if (g_VideoInitialize.bOnThread) FifoCriticalEnter(); // This may not be necessary, just for safety
|
|
||||||
UpdateFifoRegister();
|
|
||||||
if (g_VideoInitialize.bOnThread) FifoCriticalLeave();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Read32(u32& _rReturnValue, const u32 _Address)
|
void Read32(u32& _rReturnValue, const u32 _Address)
|
||||||
|
@ -577,7 +546,7 @@ bool AllowIdleSkipping()
|
||||||
// if not then lock CPUThread until GP finish a frame.
|
// if not then lock CPUThread until GP finish a frame.
|
||||||
void WaitForFrameFinish()
|
void WaitForFrameFinish()
|
||||||
{
|
{
|
||||||
while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
||||||
{
|
{
|
||||||
s_fifoIdleEvent.Wait();
|
s_fifoIdleEvent.Wait();
|
||||||
}
|
}
|
||||||
|
@ -588,7 +557,7 @@ void WaitForFrameFinish()
|
||||||
void STACKALIGN GatherPipeBursted()
|
void STACKALIGN GatherPipeBursted()
|
||||||
{
|
{
|
||||||
// if we aren't linked, we don't care about gather pipe data
|
// if we aren't linked, we don't care about gather pipe data
|
||||||
if (!fifo.bFF_GPLinkEnable)
|
if (!m_CPCtrlReg.GPLinkEnable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (g_VideoInitialize.bOnThread)
|
if (g_VideoInitialize.bOnThread)
|
||||||
|
@ -601,6 +570,13 @@ void STACKALIGN GatherPipeBursted()
|
||||||
|
|
||||||
Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE);
|
Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE);
|
||||||
|
|
||||||
|
if (fifo.CPReadWriteDistance >= fifo.CPHiWatermark)
|
||||||
|
{
|
||||||
|
m_CPStatusReg.OverflowHiWatermark = true;
|
||||||
|
if (m_CPCtrlReg.FifoOverflowIntEnable)
|
||||||
|
UpdateInterrupts();
|
||||||
|
}
|
||||||
|
/*
|
||||||
// High watermark overflow handling (hacked way)
|
// High watermark overflow handling (hacked way)
|
||||||
if (fifo.CPReadWriteDistance > fifo.CPHiWatermark)
|
if (fifo.CPReadWriteDistance > fifo.CPHiWatermark)
|
||||||
{
|
{
|
||||||
|
@ -627,6 +603,7 @@ void STACKALIGN GatherPipeBursted()
|
||||||
s_fifoIdleEvent.Wait();
|
s_fifoIdleEvent.Wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// check if we are in sync
|
// check if we are in sync
|
||||||
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == *(g_VideoInitialize.Fifo_CPUWritePointer), "FIFOs linked but out of sync");
|
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == *(g_VideoInitialize.Fifo_CPUWritePointer), "FIFOs linked but out of sync");
|
||||||
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == *(g_VideoInitialize.Fifo_CPUBase), "FIFOs linked but out of sync");
|
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == *(g_VideoInitialize.Fifo_CPUBase), "FIFOs linked but out of sync");
|
||||||
|
@ -643,40 +620,30 @@ void STACKALIGN GatherPipeBursted()
|
||||||
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == *(g_VideoInitialize.Fifo_CPUBase), "FIFOs linked but out of sync");
|
_assert_msg_(COMMANDPROCESSOR, fifo.CPBase == *(g_VideoInitialize.Fifo_CPUBase), "FIFOs linked but out of sync");
|
||||||
_assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == *(g_VideoInitialize.Fifo_CPUEnd), "FIFOs linked but out of sync");
|
_assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == *(g_VideoInitialize.Fifo_CPUEnd), "FIFOs linked but out of sync");
|
||||||
|
|
||||||
UpdateFifoRegister();
|
fifo.CPReadWriteDistance += GATHER_PIPE_SIZE;
|
||||||
|
|
||||||
|
CatchUpGPU();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only used in single core mode
|
// This is only used in single core mode
|
||||||
void CatchUpGPU()
|
void CatchUpGPU()
|
||||||
{
|
|
||||||
// check if we are able to run this buffer
|
|
||||||
if (fifo.bFF_GPReadEnable && !(fifo.bFF_BPEnable && fifo.bFF_Breakpoint))
|
|
||||||
{
|
{
|
||||||
// HyperIris: Memory_GetPtr is an expensive call, call it less, run faster
|
// HyperIris: Memory_GetPtr is an expensive call, call it less, run faster
|
||||||
u8 *ptr = Memory_GetPtr(fifo.CPReadPointer);
|
u8 *ptr = Memory_GetPtr(fifo.CPReadPointer);
|
||||||
|
|
||||||
// Sometimes we have already exceeded the BP even before it is set
|
// check if we are able to run this buffer
|
||||||
// so careful check is required
|
while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
|
||||||
while (fifo.CPReadWriteDistance || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint))
|
|
||||||
{
|
{
|
||||||
// check if we are on a breakpoint
|
// check if we are on a breakpoint
|
||||||
if (fifo.bFF_BPEnable)
|
if (fifo.bFF_BPEnable && fifo.CPReadPointer == fifo.CPBreakpoint)
|
||||||
{
|
|
||||||
if (
|
|
||||||
(fifo.CPReadPointer == fifo.CPBreakpoint) ||
|
|
||||||
//(fifo.CPReadPointer <= fifo.CPBreakpoint && fifo.CPReadPointer + 32 > fifo.CPBreakpoint) ||
|
|
||||||
(fifo.CPReadPointer <= fifo.CPWritePointer && fifo.CPWritePointer < fifo.CPBreakpoint) ||
|
|
||||||
(fifo.CPReadPointer <= fifo.CPWritePointer && fifo.CPReadPointer > fifo.CPBreakpoint) ||
|
|
||||||
(fifo.CPReadPointer > fifo.CPBreakpoint && fifo.CPBreakpoint > fifo.CPWritePointer)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//_assert_msg_(POWERPC,0,"BP: %08x",fifo.CPBreakpoint);
|
//_assert_msg_(POWERPC,0,"BP: %08x",fifo.CPBreakpoint);
|
||||||
fifo.bFF_Breakpoint = 1;
|
fifo.bFF_Breakpoint = 1;
|
||||||
UpdateInterrupts(true);
|
if (fifo.bFF_BPInt)
|
||||||
|
UpdateInterrupts();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// read the data and send it to the VideoPlugin
|
// read the data and send it to the VideoPlugin
|
||||||
// We are going to do FP math on the main thread so have to save the current state
|
// We are going to do FP math on the main thread so have to save the current state
|
||||||
|
@ -685,7 +652,6 @@ void CatchUpGPU()
|
||||||
Fifo_SendFifoData(ptr,32);
|
Fifo_SendFifoData(ptr,32);
|
||||||
LoadSSEState();
|
LoadSSEState();
|
||||||
|
|
||||||
fifo.CPReadWriteDistance -= 32;
|
|
||||||
// increase the ReadPtr
|
// increase the ReadPtr
|
||||||
if (fifo.CPReadPointer + 32 >= fifo.CPEnd)
|
if (fifo.CPReadPointer + 32 >= fifo.CPEnd)
|
||||||
{
|
{
|
||||||
|
@ -699,54 +665,29 @@ void CatchUpGPU()
|
||||||
fifo.CPReadPointer += 32;
|
fifo.CPReadPointer += 32;
|
||||||
ptr += 32;
|
ptr += 32;
|
||||||
}
|
}
|
||||||
}
|
fifo.CPReadWriteDistance -= 32;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// __________________________________________________________________________________________________
|
if (fifo.CPReadWriteDistance >= fifo.CPHiWatermark)
|
||||||
// !!! Temporary (I hope): re-used in DC mode
|
|
||||||
// UpdateFifoRegister
|
|
||||||
// It's no problem if the gfx falls behind a little bit. Better make sure to stop the cpu thread
|
|
||||||
// when the distance is way huge, though.
|
|
||||||
// So:
|
|
||||||
// CPU thread
|
|
||||||
/// 0. Write data (done before entering this)
|
|
||||||
// 1. Compute distance
|
|
||||||
// 2. If distance > threshold, sleep and goto 1
|
|
||||||
// GPU thread
|
|
||||||
// 1. Compute distance
|
|
||||||
// 2. If distance < threshold, sleep and goto 1 (or wait for trigger?)
|
|
||||||
// 3. Read and use a bit of data, goto 1
|
|
||||||
void UpdateFifoRegister()
|
|
||||||
{
|
{
|
||||||
// update the distance
|
m_CPStatusReg.OverflowHiWatermark = true;
|
||||||
int wp = fifo.CPWritePointer;
|
if (m_CPCtrlReg.FifoOverflowIntEnable)
|
||||||
int rp = fifo.CPReadPointer;
|
UpdateInterrupts();
|
||||||
int dist;
|
}
|
||||||
if (wp >= rp)
|
|
||||||
dist = wp - rp;
|
|
||||||
else
|
|
||||||
dist = (wp - fifo.CPBase) + ((fifo.CPEnd + GATHER_PIPE_SIZE) - rp);
|
|
||||||
|
|
||||||
Common::AtomicStore(fifo.CPReadWriteDistance, dist);
|
|
||||||
|
|
||||||
if (!g_VideoInitialize.bOnThread)
|
|
||||||
CatchUpGPU();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInterrupts(bool active)
|
void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
INFO_LOG(COMMANDPROCESSOR, "Fifo Breakpoint Interrupt: %s", (active)? "Asserted" : "Deasserted");
|
bool active = (fifo.bFF_BPInt && fifo.bFF_Breakpoint)
|
||||||
m_CPStatusReg.Breakpoint = active;
|
|| (m_CPCtrlReg.FifoUnderflowIntEnable && fifo.CPReadIdle)
|
||||||
|
|| (m_CPCtrlReg.FifoOverflowIntEnable && m_CPStatusReg.OverflowHiWatermark);
|
||||||
|
INFO_LOG(COMMANDPROCESSOR, "Fifo Interrupt: %s", (active)? "Asserted" : "Deasserted");
|
||||||
g_VideoInitialize.pSetInterrupt(INT_CAUSE_CP, active);
|
g_VideoInitialize.pSetInterrupt(INT_CAUSE_CP, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInterruptsFromVideoPlugin(bool active)
|
void UpdateInterruptsFromVideoPlugin()
|
||||||
{
|
{
|
||||||
if (g_ActiveConfig.bFIFOBPhack)
|
g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0);
|
||||||
return;
|
|
||||||
else
|
|
||||||
g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, active);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFifoIdleFromVideoPlugin()
|
void SetFifoIdleFromVideoPlugin()
|
||||||
|
|
|
@ -110,7 +110,7 @@ union UCPCtrlReg
|
||||||
unsigned FifoOverflowIntEnable : 1;
|
unsigned FifoOverflowIntEnable : 1;
|
||||||
unsigned FifoUnderflowIntEnable : 1;
|
unsigned FifoUnderflowIntEnable : 1;
|
||||||
unsigned GPLinkEnable : 1;
|
unsigned GPLinkEnable : 1;
|
||||||
unsigned BPInit : 1;
|
unsigned BPInt : 1;
|
||||||
unsigned : 10;
|
unsigned : 10;
|
||||||
};
|
};
|
||||||
u16 Hex;
|
u16 Hex;
|
||||||
|
@ -148,8 +148,8 @@ void Write32(const u32 _Data, const u32 _Address);
|
||||||
void CatchUpGPU();
|
void CatchUpGPU();
|
||||||
void GatherPipeBursted();
|
void GatherPipeBursted();
|
||||||
void UpdateFifoRegister();
|
void UpdateFifoRegister();
|
||||||
void UpdateInterrupts(bool active);
|
void UpdateInterrupts();
|
||||||
void UpdateInterruptsFromVideoPlugin(bool active);
|
void UpdateInterruptsFromVideoPlugin();
|
||||||
void SetFifoIdleFromVideoPlugin();
|
void SetFifoIdleFromVideoPlugin();
|
||||||
|
|
||||||
bool AllowIdleSkipping();
|
bool AllowIdleSkipping();
|
||||||
|
|
|
@ -148,38 +148,31 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||||
VideoFifo_CheckSwapRequest();
|
VideoFifo_CheckSwapRequest();
|
||||||
|
|
||||||
// check if we are able to run this buffer
|
// check if we are able to run this buffer
|
||||||
while (_fifo.bFF_GPReadEnable && ((!_fifo.bFF_BPEnable && _fifo.CPReadWriteDistance) || (_fifo.bFF_BPEnable && !_fifo.bFF_Breakpoint)))
|
while (_fifo.bFF_GPReadEnable && _fifo.CPReadWriteDistance && (!_fifo.bFF_BPEnable || (_fifo.bFF_BPEnable && !_fifo.bFF_Breakpoint)))
|
||||||
{
|
{
|
||||||
if (!fifoStateRun)
|
if (!fifoStateRun)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
_fifo.CPCmdIdle = false;
|
||||||
CommandProcessor::FifoCriticalEnter();
|
CommandProcessor::FifoCriticalEnter();
|
||||||
|
|
||||||
// Create pointer to video data and send it to the VideoPlugin
|
// Create pointer to video data and send it to the VideoPlugin
|
||||||
u32 readPtr = _fifo.CPReadPointer;
|
u32 readPtr = _fifo.CPReadPointer;
|
||||||
u8 *uData = video_initialize.pGetMemoryPointer(readPtr);
|
u8 *uData = video_initialize.pGetMemoryPointer(readPtr);
|
||||||
// NOTICE_LOG(BOOT, "readPtr: %08x uData %08x", readPtr, uData);
|
// DEBUG_LOG(BOOT, "readPtr: %08x uData %08x", readPtr, uData);
|
||||||
|
|
||||||
// If we are in BP mode we only send 32B chunks to Video plugin for BP checking
|
// If we are in BP mode we only send 32B chunks to Video plugin for BP checking
|
||||||
if (_fifo.bFF_BPEnable)
|
if (_fifo.bFF_BPEnable)
|
||||||
{
|
{
|
||||||
// Sometimes we have already exceeded the BP even before it is set
|
if (readPtr == _fifo.CPBreakpoint)
|
||||||
// so careful check is required
|
|
||||||
if (
|
|
||||||
(readPtr == _fifo.CPBreakpoint) ||
|
|
||||||
//(readPtr <= _fifo.CPBreakpoint && readPtr + 32 > _fifo.CPBreakpoint) ||
|
|
||||||
(readPtr <= _fifo.CPWritePointer && _fifo.CPWritePointer < _fifo.CPBreakpoint) ||
|
|
||||||
(readPtr <= _fifo.CPWritePointer && readPtr > _fifo.CPBreakpoint) ||
|
|
||||||
(readPtr > _fifo.CPBreakpoint && _fifo.CPBreakpoint > _fifo.CPWritePointer)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Common::AtomicStore(_fifo.bFF_Breakpoint, 1);
|
Common::AtomicStore(_fifo.bFF_Breakpoint, 1);
|
||||||
CommandProcessor::UpdateInterruptsFromVideoPlugin(true);
|
if (_fifo.bFF_BPInt)
|
||||||
|
CommandProcessor::UpdateInterruptsFromVideoPlugin();
|
||||||
CommandProcessor::FifoCriticalLeave();
|
CommandProcessor::FifoCriticalLeave();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
distToSend = 32;
|
|
||||||
|
|
||||||
|
distToSend = 32;
|
||||||
if (readPtr + 32 >= _fifo.CPEnd)
|
if (readPtr + 32 >= _fifo.CPEnd)
|
||||||
readPtr = _fifo.CPBase;
|
readPtr = _fifo.CPBase;
|
||||||
else
|
else
|
||||||
|
@ -191,7 +184,6 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||||
distToSend = _fifo.CPReadWriteDistance;
|
distToSend = _fifo.CPReadWriteDistance;
|
||||||
// send 1024B chunk max length to have better control over PeekMessages' period
|
// send 1024B chunk max length to have better control over PeekMessages' period
|
||||||
distToSend = distToSend > 1024 ? 1024 : distToSend;
|
distToSend = distToSend > 1024 ? 1024 : distToSend;
|
||||||
// add 32 bytes because the cp end points to the start of the last 32 byte chunk
|
|
||||||
if (readPtr + distToSend >= _fifo.CPEnd)
|
if (readPtr + distToSend >= _fifo.CPEnd)
|
||||||
{
|
{
|
||||||
distToSend = _fifo.CPEnd - readPtr;
|
distToSend = _fifo.CPEnd - readPtr;
|
||||||
|
@ -215,6 +207,13 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
VideoFifo_CheckSwapRequest();
|
VideoFifo_CheckSwapRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_fifo.CPReadIdle && _fifo.CPReadWriteDistance <= _fifo.CPLoWatermark)
|
||||||
|
{
|
||||||
|
Common::AtomicStore(_fifo.CPReadIdle, true);
|
||||||
|
CommandProcessor::UpdateInterruptsFromVideoPlugin();
|
||||||
|
}
|
||||||
|
_fifo.CPCmdIdle = true;
|
||||||
CommandProcessor::SetFifoIdleFromVideoPlugin();
|
CommandProcessor::SetFifoIdleFromVideoPlugin();
|
||||||
if (EmuRunning)
|
if (EmuRunning)
|
||||||
Common::YieldCPU();
|
Common::YieldCPU();
|
||||||
|
|
|
@ -189,11 +189,11 @@ bool FifoCommandRunnable()
|
||||||
"CPBreakpoint: 0x%08x\n"
|
"CPBreakpoint: 0x%08x\n"
|
||||||
"bFF_GPReadEnable: %s\n"
|
"bFF_GPReadEnable: %s\n"
|
||||||
"bFF_BPEnable: %s\n"
|
"bFF_BPEnable: %s\n"
|
||||||
"bFF_GPLinkEnable: %s\n"
|
"bFF_BPInt: %s\n"
|
||||||
"bFF_Breakpoint: %s\n"
|
"bFF_Breakpoint: %s\n"
|
||||||
,cmd_byte, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance
|
,cmd_byte, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance
|
||||||
,fifo.CPWritePointer, fifo.CPReadPointer, fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false"
|
,fifo.CPWritePointer, fifo.CPReadPointer, fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false"
|
||||||
,fifo.bFF_BPEnable ? "true" : "false" ,fifo.bFF_GPLinkEnable ? "true" : "false"
|
,fifo.bFF_BPEnable ? "true" : "false" ,fifo.bFF_BPInt ? "true" : "false"
|
||||||
,fifo.bFF_Breakpoint ? "true" : "false");
|
,fifo.bFF_Breakpoint ? "true" : "false");
|
||||||
|
|
||||||
g_VideoInitialize.pSysMessage(szTmp);
|
g_VideoInitialize.pSysMessage(szTmp);
|
||||||
|
|
|
@ -58,7 +58,7 @@ typedef struct
|
||||||
|
|
||||||
volatile u32 bFF_GPReadEnable;
|
volatile u32 bFF_GPReadEnable;
|
||||||
volatile u32 bFF_BPEnable;
|
volatile u32 bFF_BPEnable;
|
||||||
volatile u32 bFF_GPLinkEnable;
|
volatile u32 bFF_BPInt;
|
||||||
volatile u32 bFF_Breakpoint;
|
volatile u32 bFF_Breakpoint;
|
||||||
|
|
||||||
volatile u32 CPCmdIdle;
|
volatile u32 CPCmdIdle;
|
||||||
|
|
Loading…
Reference in New Issue