⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fxemu.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			    GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);			    GSU.x[i] = (i << 8) + (i << 7);			}			break;		    case 1:			for (i = 0; i < 32; i++)			{			    GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);			    GSU.x[i] = (i << 9) + (i << 8);			}			break;		    case 2:		    case 3:			for (i = 0; i < 32; i++)			{			    GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);			    GSU.x[i] = (i << 10) + (i << 9);			}			break;		}		break;	    case 256:		switch (GSU.vMode)		{		    case 0:			for (i = 0; i < 32; i++)			{			    GSU.apvScreen[i] = GSU.pvScreenBase + 				((i & 0x10) << 9) + ((i & 0xf) << 8);			    GSU.x[i] = ((i & 0x10) << 8) + ((i & 0xf) << 4);			}			break;		    case 1:			for (i = 0; i < 32; i++)			{			    GSU.apvScreen[i] = GSU.pvScreenBase + 				((i & 0x10) << 10) + ((i & 0xf) << 9);			    GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5);			}			break;		    case 2:		    case 3:			for (i = 0; i < 32; i++)			{			    GSU.apvScreen[i] = GSU.pvScreenBase + 				((i & 0x10) << 11) + ((i & 0xf) << 10);			    GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6);			}			break;		}		break;	}	GSU.vPrevMode = GSU.vMode;	GSU.vPrevScreenHeight = GSU.vScreenHeight;    }}static void fx_writeRegisterSpace(){    int i;    uint8 *p;        p = GSU.pvRegisters;    for(i=0; i<16; i++)    {	*p++ = (uint8)GSU.avReg[i];	*p++ = (uint8)(GSU.avReg[i] >> 8);    }    /* Update status register */    if( USEX16(GSU.vZero) == 0 ) SF(Z);    else CF(Z);    if( GSU.vSign & 0x8000 ) SF(S);    else CF(S);    if(GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000) SF(OV);    else CF(OV);    if(GSU.vCarry) SF(CY);    else CF(CY);        p = GSU.pvRegisters;    p[GSU_SFR] = (uint8)GSU.vStatusReg;    p[GSU_SFR+1] = (uint8)(GSU.vStatusReg>>8);    p[GSU_PBR] = (uint8)GSU.vPrgBankReg;    p[GSU_ROMBR] = (uint8)GSU.vRomBankReg;    p[GSU_RAMBR] = (uint8)GSU.vRamBankReg;    p[GSU_CBR] = (uint8)GSU.vCacheBaseReg;    p[GSU_CBR+1] = (uint8)(GSU.vCacheBaseReg>>8);        fx_restoreCache();}/* Reset the FxChip */void FxReset(struct FxInit_s *psFxInfo){    int i;    static uint32 (**appfFunction[])(uint32) = {	&fx_apfFunctionTable[0],#if 0	&fx_a_apfFunctionTable[0],	&fx_r_apfFunctionTable[0],	&fx_ar_apfFunctionTable[0],#endif	    };    static void (**appfPlot[])() = {	&fx_apfPlotTable[0],#if 0	&fx_a_apfPlotTable[0],	&fx_r_apfPlotTable[0],	&fx_ar_apfPlotTable[0],#endif	    };    static void (**appfOpcode[])() = {	&fx_apfOpcodeTable[0],#if 0		&fx_a_apfOpcodeTable[0],	&fx_r_apfOpcodeTable[0],	&fx_ar_apfOpcodeTable[0],#endif	    };    /* Get function pointers for the current emulation mode */    fx_ppfFunctionTable = appfFunction[psFxInfo->vFlags & 0x3];    fx_ppfPlotTable = appfPlot[psFxInfo->vFlags & 0x3];    fx_ppfOpcodeTable = appfOpcode[psFxInfo->vFlags & 0x3];        /* Clear all internal variables */    memset((uint8*)&GSU,0,sizeof(struct FxRegs_s));    /* Set default registers */    GSU.pvSreg = GSU.pvDreg = &R0;    /* Set RAM and ROM pointers */    GSU.pvRegisters = psFxInfo->pvRegisters;    GSU.nRamBanks = psFxInfo->nRamBanks;    GSU.pvRam = psFxInfo->pvRam;    GSU.nRomBanks = psFxInfo->nRomBanks;    GSU.pvRom = psFxInfo->pvRom;    GSU.vPrevScreenHeight = ~0;    GSU.vPrevMode = ~0;    /* The GSU can't access more than 2mb (16mbits) */    if(GSU.nRomBanks > 0x20)	GSU.nRomBanks = 0x20;        /* Clear FxChip register space */    memset(GSU.pvRegisters,0,0x300);    /* Set FxChip version Number */    GSU.pvRegisters[0x3b] = 0;    /* Make ROM bank table */    for(i=0; i<256; i++)    {	uint32 b = i & 0x7f;	if (b >= 0x40)	{	    if (GSU.nRomBanks > 1)		b %= GSU.nRomBanks;	    else		b &= 1;	    GSU.apvRomBank[i] = &GSU.pvRom[ b << 16 ];	}	else	{	    b %= GSU.nRomBanks * 2;	    GSU.apvRomBank[i] = &GSU.pvRom[ (b << 16) + 0x200000];	}    }    /* Make RAM bank table */    for(i=0; i<4; i++)    {	GSU.apvRamBank[i] = &GSU.pvRam[(i % GSU.nRamBanks) << 16];	GSU.apvRomBank[0x70 + i] = GSU.apvRamBank[i];    }        /* Start with a nop in the pipe */    GSU.vPipe = 0x01;    /* Set pointer to GSU cache */    GSU.pvCache = &GSU.pvRegisters[0x100];    fx_readRegisterSpace();}static uint8 fx_checkStartAddress(){    /* Check if we start inside the cache */    if(GSU.bCacheActive && R15 >= GSU.vCacheBaseReg && R15 < (GSU.vCacheBaseReg+512))	return TRUE;       /*  Check if we're in an unused area */    if(GSU.vPrgBankReg < 0x40 && R15 < 0x8000)	return FALSE;    if(GSU.vPrgBankReg >= 0x60 && GSU.vPrgBankReg <= 0x6f)	return FALSE;    if(GSU.vPrgBankReg >= 0x74)	return FALSE;    /* Check if we're in RAM and the RAN flag is not set */    if(GSU.vPrgBankReg >= 0x70 && GSU.vPrgBankReg <= 0x73 && !(SCMR&(1<<3)) )	return FALSE;    /* If not, we're in ROM, so check if the RON flag is set */    if(!(SCMR&(1<<4)))	return FALSE;        return TRUE;}/* Execute until the next stop instruction */int FxEmulate(uint32 nInstructions){    uint32 vCount;    /* Read registers and initialize GSU session */    fx_readRegisterSpace();    /* Check if the start address is valid */    if(!fx_checkStartAddress())    {	CF(G);	fx_writeRegisterSpace();#if 0	GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;	return FX_ERROR_ILLEGAL_ADDRESS;#else	return 0;#endif    }    /* Execute GSU session */    CF(IRQ);    if(GSU.bBreakPoint)	vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN_TO_BREAKPOINT](nInstructions);    else	vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN](nInstructions);    /* Store GSU registers */    fx_writeRegisterSpace();    /* Check for error code */    if(GSU.vErrorCode)	return GSU.vErrorCode;    else	return vCount;}/* Breakpoints */void FxBreakPointSet(uint32 vAddress){    GSU.bBreakPoint = TRUE;    GSU.vBreakPoint = USEX16(vAddress);}void FxBreakPointClear(){    GSU.bBreakPoint = FALSE;}/* Step by step execution */int FxStepOver(uint32 nInstructions){    uint32 vCount;    fx_readRegisterSpace();    /* Check if the start address is valid */    if(!fx_checkStartAddress())    {	CF(G);#if 0	GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;	return FX_ERROR_ILLEGAL_ADDRESS;#else	return 0;#endif    }        if( PIPE >= 0xf0 )	GSU.vStepPoint = USEX16(R15+3);    else if( (PIPE >= 0x05 && PIPE <= 0x0f) || (PIPE >= 0xa0 && PIPE <= 0xaf) )	GSU.vStepPoint = USEX16(R15+2);    else	GSU.vStepPoint = USEX16(R15+1);    vCount = fx_ppfFunctionTable[FX_FUNCTION_STEP_OVER](nInstructions);    fx_writeRegisterSpace();    if(GSU.vErrorCode)	return GSU.vErrorCode;    else	return vCount;}/* Errors */int FxGetErrorCode(){    return GSU.vErrorCode;}int FxGetIllegalAddress(){    return GSU.vIllegalAddress;}/* Access to internal registers */uint32 FxGetColorRegister(){    return GSU.vColorReg & 0xff;}uint32 FxGetPlotOptionRegister(){    return GSU.vPlotOptionReg & 0x1f;}uint32 FxGetSourceRegisterIndex(){    return GSU.pvSreg - GSU.avReg;}uint32 FxGetDestinationRegisterIndex(){    return GSU.pvDreg - GSU.avReg;}uint8 FxPipe(){    return GSU.vPipe;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -