From 3777d1fcf4232cde426f46b7ee5c374fd949b1b0 Mon Sep 17 00:00:00 2001 From: João Silva Date: Sun, 12 Feb 2017 01:52:03 +0000 Subject: Type fixes. Fixes from snes9x 1.50. Minor changes and optimizations. --- source/fxemu.c | 68 +++++++--------------------------------------------------- 1 file changed, 8 insertions(+), 60 deletions(-) (limited to 'source/fxemu.c') diff --git a/source/fxemu.c b/source/fxemu.c index 5b3aba3..a92e3df 100644 --- a/source/fxemu.c +++ b/source/fxemu.c @@ -9,10 +9,6 @@ /* The FxChip Emulator's internal variables */ struct FxRegs_s GSU; // This will be initialized when loading a ROM -uint32_t(**fx_ppfFunctionTable)(uint32_t) = 0; -void (**fx_ppfPlotTable)() = 0; -void (**fx_ppfOpcodeTable)() = 0; - void FxCacheWriteAccess(uint16_t vAddress) { if ((vAddress & 0x00f) == 0x00f) @@ -99,10 +95,10 @@ static void fx_readRegisterSpace() GSU.pfPlot = fx_apfPlotTable[GSU.vMode]; GSU.pfRpix = fx_apfPlotTable[GSU.vMode + 5]; - fx_ppfOpcodeTable[0x04c] = GSU.pfPlot; - fx_ppfOpcodeTable[0x14c] = GSU.pfRpix; - fx_ppfOpcodeTable[0x24c] = GSU.pfPlot; - fx_ppfOpcodeTable[0x34c] = GSU.pfRpix; + fx_apfOpcodeTable[0x04c] = GSU.pfPlot; + fx_apfOpcodeTable[0x14c] = GSU.pfRpix; + fx_apfOpcodeTable[0x24c] = GSU.pfPlot; + fx_apfOpcodeTable[0x34c] = GSU.pfRpix; fx_computeScreenPointers(); } @@ -277,27 +273,8 @@ static void fx_writeRegisterSpace() /* Reset the FxChip */ void FxReset(struct FxInit_s* psFxInfo) { - int32_t i; - static uint32_t(**appfFunction[])(uint32_t) = - { - &fx_apfFunctionTable[0] - }; - static void (**appfPlot[])() = - { - &fx_apfPlotTable[0] - }; - static void (**appfOpcode[])() = - { - &fx_apfOpcodeTable[0] - }; - - /* 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_t*)&GSU, 0, sizeof(struct FxRegs_s)); + memset((uint8_t*) &GSU, 0, sizeof(struct FxRegs_s)); /* Set default registers */ GSU.pvSreg = GSU.pvDreg = &R0; @@ -322,6 +299,7 @@ void FxReset(struct FxInit_s* psFxInfo) GSU.pvRegisters[0x3b] = 0; /* Make ROM bank table */ + int32_t i; for (i = 0; i < 256; i++) { uint32_t b = i & 0x7f; @@ -360,13 +338,10 @@ void FxReset(struct FxInit_s* psFxInfo) static bool fx_checkStartAddress() { /* Check if we start inside the cache */ - if (GSU.bCacheActive && R15 >= GSU.vCacheBaseReg - && R15 < (GSU.vCacheBaseReg + 512)) + 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) @@ -402,7 +377,7 @@ int32_t FxEmulate(uint32_t nInstructions) /* Execute GSU session */ CF(IRQ); - vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN](nInstructions); + vCount = fx_run(nInstructions); /* Store GSU registers */ fx_writeRegisterSpace(); @@ -414,33 +389,6 @@ int32_t FxEmulate(uint32_t nInstructions) return vCount; } -/* Step by step execution */ -int32_t FxStepOver(uint32_t nInstructions) -{ - uint32_t vCount; - fx_readRegisterSpace(); - - /* Check if the start address is valid */ - if (!fx_checkStartAddress()) - { - CF(G); - return 0; - } - - 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 */ int32_t FxGetErrorCode() { -- cgit v1.2.3 From fb2517282da2fdfc26e58207bbb8e0a8bca35be2 Mon Sep 17 00:00:00 2001 From: João Silva Date: Sun, 12 Feb 2017 14:46:44 +0000 Subject: Minor SuperFX optimization. Fixed broken graphics caused by All-Stars SMW speedhack. --- source/fxemu.c | 93 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 38 deletions(-) (limited to 'source/fxemu.c') diff --git a/source/fxemu.c b/source/fxemu.c index a92e3df..d9c5082 100644 --- a/source/fxemu.c +++ b/source/fxemu.c @@ -32,23 +32,30 @@ void fx_flushCache() void fx_updateRamBank(uint8_t Byte) { // Update BankReg and Bank pointer - GSU.vRamBankReg = (uint32_t)Byte & (FX_RAM_BANKS - 1); + GSU.vRamBankReg = (uint32_t) Byte & (FX_RAM_BANKS - 1); GSU.pvRamBank = GSU.apvRamBank[Byte & 0x3]; } +static void fx_readRegisterSpaceForCheck() +{ + R15 = GSU.pvRegisters[30]; + R15 |= ((uint32_t) GSU.pvRegisters[31]) << 8; + GSU.vStatusReg = (uint32_t) GSU.pvRegisters[GSU_SFR]; + GSU.vStatusReg |= ((uint32_t) GSU.pvRegisters[GSU_SFR + 1]) << 8; + GSU.vPrgBankReg = (uint32_t) GSU.pvRegisters[GSU_PBR]; +} -static void fx_readRegisterSpace() +static void fx_readRegisterSpaceForUse() { - int32_t i; - uint8_t* p; static uint32_t avHeight[] = { 128, 160, 192, 256 }; static uint32_t avMult[] = { 16, 32, 32, 64 }; + int32_t i; + uint8_t* p = GSU.pvRegisters; GSU.vErrorCode = 0; - /* Update R0-R15 */ - p = GSU.pvRegisters; - for (i = 0; i < 16; i++) + /* Update R0 - R14 */ + for (i = 0; i < 15; i++) { GSU.avReg[i] = *p++; GSU.avReg[i] += ((uint32_t)(*p++)) << 8; @@ -56,9 +63,6 @@ static void fx_readRegisterSpace() /* Update other registers */ p = GSU.pvRegisters; - GSU.vStatusReg = (uint32_t)p[GSU_SFR]; - GSU.vStatusReg |= ((uint32_t)p[GSU_SFR + 1]) << 8; - GSU.vPrgBankReg = (uint32_t)p[GSU_PBR]; GSU.vRomBankReg = (uint32_t)p[GSU_ROMBR]; GSU.vRamBankReg = ((uint32_t)p[GSU_RAMBR]) & (FX_RAM_BANKS - 1); GSU.vCacheBaseReg = (uint32_t)p[GSU_CBR]; @@ -208,16 +212,14 @@ void fx_computeScreenPointers() case 0: for (i = 0; i < 32; i++) { - GSU.apvScreen[i] = GSU.pvScreenBase + - ((i & 0x10) << 9) + ((i & 0xf) << 8); + 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.apvScreen[i] = GSU.pvScreenBase + ((i & 0x10) << 10) + ((i & 0xf) << 9); GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5); } break; @@ -225,8 +227,7 @@ void fx_computeScreenPointers() case 3: for (i = 0; i < 32; i++) { - GSU.apvScreen[i] = GSU.pvScreenBase + - ((i & 0x10) << 11) + ((i & 0xf) << 10); + GSU.apvScreen[i] = GSU.pvScreenBase + ((i & 0x10) << 11) + ((i & 0xf) << 10); GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6); } break; @@ -238,32 +239,44 @@ void fx_computeScreenPointers() } } -static void fx_writeRegisterSpace() +static void fx_writeRegisterSpaceAfterCheck() { - int32_t i; - uint8_t* p; + GSU.pvRegisters[30] = (uint8_t) R15; + GSU.pvRegisters[31] = (uint8_t) (R15 >> 8); + GSU.pvRegisters[GSU_SFR] = (uint8_t) GSU.vStatusReg; + GSU.pvRegisters[GSU_SFR + 1] = (uint8_t) (GSU.vStatusReg >> 8); + GSU.pvRegisters[GSU_PBR] = (uint8_t) GSU.vPrgBankReg; +} - p = GSU.pvRegisters; - for (i = 0; i < 16; i++) +static void fx_writeRegisterSpaceAfterUse() +{ + int32_t i; + uint8_t* p = GSU.pvRegisters; + for (i = 0; i < 15; i++) { *p++ = (uint8_t)GSU.avReg[i]; *p++ = (uint8_t)(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); + 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_t)GSU.vStatusReg; - p[GSU_SFR + 1] = (uint8_t)(GSU.vStatusReg >> 8); - p[GSU_PBR] = (uint8_t)GSU.vPrgBankReg; p[GSU_ROMBR] = (uint8_t)GSU.vRomBankReg; p[GSU_RAMBR] = (uint8_t)GSU.vRamBankReg; p[GSU_CBR] = (uint8_t)GSU.vCacheBaseReg; @@ -305,12 +318,12 @@ void FxReset(struct FxInit_s* psFxInfo) uint32_t b = i & 0x7f; if (b >= 0x40) { - if (GSU.nRomBanks > 1) + if (GSU.nRomBanks > 2) b %= GSU.nRomBanks; else b &= 1; - GSU.apvRomBank[i] = &GSU.pvRom[ b << 16 ]; + GSU.apvRomBank[i] = &GSU.pvRom[b << 16]; } else { @@ -332,7 +345,8 @@ void FxReset(struct FxInit_s* psFxInfo) /* Set pointer to GSU cache */ GSU.pvCache = &GSU.pvRegisters[0x100]; - fx_readRegisterSpace(); + fx_readRegisterSpaceForCheck(); + fx_readRegisterSpaceForUse(); } static bool fx_checkStartAddress() @@ -364,23 +378,26 @@ int32_t FxEmulate(uint32_t nInstructions) uint32_t vCount; /* Read registers and initialize GSU session */ - fx_readRegisterSpace(); + fx_readRegisterSpaceForCheck(); /* Check if the start address is valid */ if (!fx_checkStartAddress()) { CF(G); - fx_writeRegisterSpace(); + fx_writeRegisterSpaceAfterCheck(); return 0; } + fx_readRegisterSpaceForUse(); + /* Execute GSU session */ CF(IRQ); vCount = fx_run(nInstructions); /* Store GSU registers */ - fx_writeRegisterSpace(); + fx_writeRegisterSpaceAfterCheck(); + fx_writeRegisterSpaceAfterUse(); /* Check for error code */ if (GSU.vErrorCode) -- cgit v1.2.3