fix handling of matrix stack busy flag (the fifo seems to track whether whether a matrix operation is pending and set flag if so; if a non-matrix command jams in a busy geometry engine then backed-up matrix command will cause the flag to get set). fixed wild west, which polls this flag to see when it is safe to read the matrix stack cursor while the geometry engine is jammed. our understanding of the gfx fifo behaviour is still incomplete..
This commit is contained in:
parent
c73a7cb883
commit
236e4b3374
|
@ -1,6 +1,6 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
/* Copyright 2006 yopyop
|
||||
Copyright 2007 shash
|
||||
Copyright 2007-2010 DeSmuME team
|
||||
Copyright 2007-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -169,6 +169,7 @@ void GFX_PIPEclear()
|
|||
gxPIPE.head = 0;
|
||||
gxPIPE.tail = 0;
|
||||
gxPIPE.size = 0;
|
||||
gxFIFO.matrix_stack_op_size = 0;
|
||||
}
|
||||
|
||||
void GFX_FIFOclear()
|
||||
|
@ -176,6 +177,7 @@ void GFX_FIFOclear()
|
|||
gxFIFO.head = 0;
|
||||
gxFIFO.tail = 0;
|
||||
gxFIFO.size = 0;
|
||||
gxFIFO.matrix_stack_op_size = 0;
|
||||
}
|
||||
|
||||
static void GXF_FIFO_handleEvents()
|
||||
|
@ -189,6 +191,9 @@ static void GXF_FIFO_handleEvents()
|
|||
bool emptychange = MMU_new.gxstat.fifo_empty ^ empty;
|
||||
MMU_new.gxstat.fifo_empty = empty;
|
||||
|
||||
|
||||
MMU_new.gxstat.sb = gxFIFO.matrix_stack_op_size != 0;
|
||||
|
||||
if(emptychange||lowchange) NDS_Reschedule();
|
||||
}
|
||||
|
||||
|
@ -220,6 +225,12 @@ void GFX_FIFOsend(u8 cmd, u32 param)
|
|||
gxFIFO.size++;
|
||||
if (gxFIFO.tail > HACK_GXIFO_SIZE-1) gxFIFO.tail = 0;
|
||||
|
||||
//if a matrix op is entering the pipeline, do accounting for it
|
||||
//(this is tested by wild west, which will jam a few ops in the fifo and then wait for the matrix stack to be
|
||||
//un-busy so it can read back the current matrix stack position)
|
||||
if((cmd & 0xF0) == 0x10)
|
||||
gxFIFO.matrix_stack_op_size++;
|
||||
|
||||
if(gxFIFO.size>=HACK_GXIFO_SIZE) {
|
||||
printf("--FIFO FULL-- : %d\n",gxFIFO.size);
|
||||
}
|
||||
|
@ -245,6 +256,14 @@ BOOL GFX_PIPErecv(u8 *cmd, u32 *param)
|
|||
*cmd = gxFIFO.cmd[gxFIFO.head];
|
||||
*param = gxFIFO.param[gxFIFO.head];
|
||||
|
||||
//see the associated increment in another function
|
||||
if((*cmd & 0xF0) == 0x10)
|
||||
{
|
||||
gxFIFO.matrix_stack_op_size--;
|
||||
if(gxFIFO.matrix_stack_op_size>0x10000000)
|
||||
printf("bad news disaster in matrix_stack_op_size\n");
|
||||
}
|
||||
|
||||
gxFIFO.head++;
|
||||
gxFIFO.size--;
|
||||
if (gxFIFO.head > HACK_GXIFO_SIZE-1) gxFIFO.head = 0;
|
||||
|
|
|
@ -1,25 +1,20 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
/*
|
||||
Copyright 2006 yopyop
|
||||
Copyright 2007 shash
|
||||
Copyright 2007-2009 DeSmuME team
|
||||
Copyright 2007-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -59,6 +54,7 @@ typedef struct
|
|||
u32 head; // start position
|
||||
u32 tail; // tail
|
||||
u32 size; // size FIFO buffer
|
||||
u32 matrix_stack_op_size; //number of matrix stack items in the fifo (stack is busy when this is nonzero)
|
||||
} GFX_FIFO;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -1636,7 +1636,9 @@ u32 TGXSTAT::read32()
|
|||
|
||||
// stack position always equal zero. possible timings is wrong
|
||||
// using in "The Wild West"
|
||||
ret |= ((_hack_getMatrixStackLevel(0) << 13) | (_hack_getMatrixStackLevel(1) << 8)); //matrix stack levels //no proof that these are needed yet
|
||||
int proj_level = _hack_getMatrixStackLevel(0);
|
||||
int mv_level = _hack_getMatrixStackLevel(1);
|
||||
ret |= ((proj_level << 13) | (mv_level << 8)); //matrix stack levels //no proof that these are needed yet
|
||||
|
||||
ret |= sb<<14; //stack busy
|
||||
ret |= se<<15;
|
||||
|
@ -1650,9 +1652,12 @@ u32 TGXSTAT::read32()
|
|||
//if fifo is nonempty, we're busy
|
||||
if(gxFIFO.size!=0) ret |= BIT(27);
|
||||
|
||||
//printf("[%d] %d %d %d\n",currFrameCounter,se,sb,gxFIFO.size!=0);
|
||||
|
||||
|
||||
ret |= ((gxfifo_irq & 0x3) << 30); //user's irq flags
|
||||
|
||||
//printf("vc=%03d Returning gxstat read: %08X\n",nds.VCount,ret);
|
||||
//printf("vc=%03d Returning gxstat read: %08X (isSwapBuffers=%d)\n",nds.VCount,ret,isSwapBuffers);
|
||||
|
||||
//ret = (2 << 8);
|
||||
//INFO("gxSTAT 0x%08X (proj %i, pos %i)\n", ret, _hack_getMatrixStackLevel(1), _hack_getMatrixStackLevel(2));
|
||||
|
|
|
@ -1776,7 +1776,7 @@ FORCEINLINE void arm9log()
|
|||
INFO("Disassembler is stopped\n");
|
||||
}*/
|
||||
#else
|
||||
printf("%05d:%03d %12lld 9:%08X %08X %-30s\nR00:%08X R01:%08X R02:%08X R03:%08X R04:%08X R05:%08X R06:%08X R07:%08X R08:%08X R09:%08X R10:%08X R11:%08X R12:%08X R13:%08X R14:%08X R15:%08X\n",
|
||||
printf("%05d:%03d %12lld 9:%08X %08X %-30s R00:%08X R01:%08X R02:%08X R03:%08X R04:%08X R05:%08X R06:%08X R07:%08X R08:%08X R09:%08X R10:%08X R11:%08X R12:%08X R13:%08X R14:%08X R15:%08X\n",
|
||||
currFrameCounter, nds.VCount, nds_timer,
|
||||
NDS_ARM9.instruct_adr,NDS_ARM9.instruction, dasmbuf,
|
||||
NDS_ARM9.R[0], NDS_ARM9.R[1], NDS_ARM9.R[2], NDS_ARM9.R[3], NDS_ARM9.R[4], NDS_ARM9.R[5], NDS_ARM9.R[6], NDS_ARM9.R[7],
|
||||
|
@ -1889,7 +1889,6 @@ static /*donotinline*/ std::pair<s32,s32> armInnerLoop(
|
|||
|
||||
timer = minarmtime<doarm9,doarm7>(arm9,arm7);
|
||||
nds_timer = nds_timer_base + timer;
|
||||
if (nds_timer >= MMU.gfx3dCycles) MMU_new.gxstat.sb = 0; // clear stack busy flag
|
||||
}
|
||||
|
||||
return std::make_pair(arm9, arm7);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2010 DeSmuME team
|
||||
Copyright (C) 2008-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
|
@ -3023,6 +3024,7 @@ TEMPLATE static u32 FASTCALL OP_MSR_CPSR(const u32 i)
|
|||
}
|
||||
cpu->CPSR.val = ((cpu->CPSR.val & (~mask)) | (operand & mask));
|
||||
if (BIT16(i)) armcpu_switchMode(cpu, cpu->CPSR.bits.mode);
|
||||
cpu->changeCPSR();
|
||||
#else
|
||||
if(cpu->CPSR.bits.mode!=USR)
|
||||
{
|
||||
|
@ -3070,6 +3072,7 @@ TEMPLATE static u32 FASTCALL OP_MSR_SPSR(const u32 i)
|
|||
mask = byte_mask & (v4_USER_MASK | v4_PRIV_MASK | v4_STATE_MASK);
|
||||
}
|
||||
cpu->SPSR.val = ((cpu->SPSR.val & (~mask)) | (operand & mask));
|
||||
cpu->changeCPSR();
|
||||
#else
|
||||
if(cpu->CPSR.bits.mode!=USR)
|
||||
{
|
||||
|
@ -3084,6 +3087,7 @@ TEMPLATE static u32 FASTCALL OP_MSR_SPSR(const u32 i)
|
|||
}
|
||||
if(BIT19(i))
|
||||
cpu->SPSR.val = (cpu->SPSR.val & 0x00FFFFFF) | (operand & 0xFF000000);
|
||||
cpu->changeCPSR();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
|
@ -3126,6 +3130,7 @@ TEMPLATE static u32 FASTCALL OP_MSR_CPSR_IMM_VAL(const u32 i)
|
|||
}
|
||||
cpu->CPSR.val = ((cpu->CPSR.val & (~mask)) | (operand & mask));
|
||||
if (BIT16(i)) armcpu_switchMode(cpu, cpu->CPSR.bits.mode);
|
||||
cpu->changeCPSR();
|
||||
#else
|
||||
if(cpu->CPSR.bits.mode!=USR)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2010 DeSmuME team
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2011 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -851,8 +852,6 @@ static void gfx3d_glPushMatrix()
|
|||
|
||||
if(mymode==2)
|
||||
MatrixStackPushMatrix (&mtxStack[1], mtxCurrent[1]);
|
||||
|
||||
MMU_new.gxstat.sb = 1; // set busy
|
||||
}
|
||||
|
||||
static void gfx3d_glPopMatrix(s32 i)
|
||||
|
@ -874,8 +873,6 @@ static void gfx3d_glPopMatrix(s32 i)
|
|||
|
||||
if (mymode == 2)
|
||||
MatrixStackPopMatrix(mtxCurrent[1], &mtxStack[1], i);
|
||||
|
||||
MMU_new.gxstat.sb = 1; // set busy
|
||||
}
|
||||
|
||||
static void gfx3d_glStoreMatrix(u32 v)
|
||||
|
@ -888,7 +885,9 @@ static void gfx3d_glStoreMatrix(u32 v)
|
|||
if(mymode==0 || mymode==3)
|
||||
v = 0;
|
||||
|
||||
if (v >= 31) return;
|
||||
v &= 31;
|
||||
//this behaviour is unverified. gbatek suggests that it may be meaningful somehow.
|
||||
if(v==31) return;
|
||||
|
||||
MatrixStackLoadMatrix (&mtxStack[mymode], v, mtxCurrent[mymode]);
|
||||
|
||||
|
@ -908,7 +907,14 @@ static void gfx3d_glRestoreMatrix(u32 v)
|
|||
if(mymode==0 || mymode==3)
|
||||
v = 0;
|
||||
|
||||
if (v >= 31) return;
|
||||
v &= 31;
|
||||
|
||||
//this seems to do something irrational if v==31, as far as we know.
|
||||
//lets arbitrarily choose to use entry -
|
||||
if(v==31) {
|
||||
v = 0;
|
||||
printf("gfx3d_glRestoreMatrix is using -1. why would anyone do this? please report!\n");
|
||||
}
|
||||
|
||||
MatrixCopy (mtxCurrent[mymode], MatrixStackGetPos(&mtxStack[mymode], v));
|
||||
|
||||
|
@ -916,9 +922,6 @@ static void gfx3d_glRestoreMatrix(u32 v)
|
|||
|
||||
if (mymode == 2)
|
||||
MatrixCopy (mtxCurrent[1], MatrixStackGetPos(&mtxStack[1], v));
|
||||
|
||||
//printf("restore: matrix %d to: \n",mymode); MatrixPrint(mtxCurrent[1]);
|
||||
|
||||
}
|
||||
|
||||
static void gfx3d_glLoadIdentity()
|
||||
|
@ -1672,7 +1675,7 @@ s32 gfx3d_GetClipMatrix (unsigned int index)
|
|||
{
|
||||
s32 val = MatrixGetMultipliedIndex (index, mtxCurrent[0], mtxCurrent[1]);
|
||||
|
||||
//val *= (1<<12);
|
||||
//printf("reading clip matrix: %d\n",index);
|
||||
|
||||
return (s32)val;
|
||||
}
|
||||
|
@ -1827,7 +1830,6 @@ static void gfx3d_execute(u8 cmd, u32 param)
|
|||
log3D(cmd, param);
|
||||
#endif
|
||||
|
||||
MMU_new.gxstat.sb = 0; // clear stack busy flag
|
||||
switch (cmd)
|
||||
{
|
||||
case 0x10: // MTX_MODE - Set Matrix Mode (W)
|
||||
|
@ -2002,6 +2004,8 @@ void gfx3d_glFlush(u32 v)
|
|||
|
||||
isSwapBuffers = TRUE;
|
||||
|
||||
//printf("%05d:%03d:%12lld: FLUSH\n",currFrameCounter, nds.VCount, nds_timer);
|
||||
|
||||
//well, the game wanted us to flush.
|
||||
//it may be badly timed. lets just flush it.
|
||||
#ifdef FLUSHMODE_HACK
|
||||
|
@ -2173,6 +2177,8 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
|
|||
|
||||
void gfx3d_sendCommandToFIFO(u32 val)
|
||||
{
|
||||
//printf("gxFIFO: send val=0x%08X, size=%03i (fifo)\n", val, gxFIFO.size);
|
||||
|
||||
gxf_hardware.receive(val);
|
||||
}
|
||||
|
||||
|
@ -2338,6 +2344,7 @@ SFORMAT SF_GFX3D[]={
|
|||
{ "GFHE", 4, 1, &gxFIFO.head},
|
||||
{ "GFTA", 4, 1, &gxFIFO.tail},
|
||||
{ "GFSZ", 4, 1, &gxFIFO.size},
|
||||
{ "GFMS", 4, 1, &gxFIFO.matrix_stack_op_size},
|
||||
{ "GFCM", 1, HACK_GXIFO_SIZE, &gxFIFO.cmd[0]},
|
||||
{ "GFPM", 4, HACK_GXIFO_SIZE, &gxFIFO.param[0]},
|
||||
{ "GPHE", 1, 1, &gxPIPE.head},
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
/*
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2007-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -274,7 +272,13 @@ static void MatrixStackSetStackPosition (MatrixStack *stack, int pos)
|
|||
|
||||
if((stack->position < 0) || (stack->position > stack->size))
|
||||
MMU_new.gxstat.se = 1;
|
||||
stack->position &= stack->size;
|
||||
|
||||
//this behaviour is unverified, but its more logical than the old code which would wrap around and turn negative
|
||||
//it may still be right to wrap around, but we have no proof right now one way or another
|
||||
if(stack->position < 0)
|
||||
stack->position = 0;
|
||||
if(stack->position > stack->size)
|
||||
stack->position = stack->size;
|
||||
}
|
||||
|
||||
void MatrixStackPushMatrix (MatrixStack *stack, const s32 *ptr)
|
||||
|
|
|
@ -1,25 +1,20 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008-2010 DeSmuME team
|
||||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2008 shash
|
||||
Copyright (C) 2008-2011 DeSmuME team
|
||||
|
||||
Code added on 18/08/2006 by shash
|
||||
- Missing missaligned addresses correction
|
||||
(reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments)
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
This file is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
along with the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// THUMB core TODO:
|
||||
|
@ -1042,6 +1037,7 @@ TEMPLATE static u32 FASTCALL OP_SWI_THUMB(const u32 i)
|
|||
cpu->SPSR = tmp; /* save old CPSR as new SPSR */
|
||||
cpu->CPSR.bits.T = 0; /* handle as ARM32 code */
|
||||
cpu->CPSR.bits.I = 1;
|
||||
cpu->changeCPSR();
|
||||
cpu->R[15] = cpu->intVector + 0x08;
|
||||
cpu->next_instruction = cpu->R[15];
|
||||
return 3;
|
||||
|
|
Loading…
Reference in New Issue