aboutsummaryrefslogtreecommitdiff
path: root/source/fxemu.c
diff options
context:
space:
mode:
authoraliaspider2014-10-30 00:23:30 +0100
committeraliaspider2014-10-30 00:23:30 +0100
commit804169dd621a3ad3eec1a32ce30350de667fee80 (patch)
tree5bce839a3652f6725d50639cccd3f589ee901515 /source/fxemu.c
parent5382d193371c8db303d056b87b8ffd51316bf2e0 (diff)
downloadsnes9x2005-804169dd621a3ad3eec1a32ce30350de667fee80.tar.gz
snes9x2005-804169dd621a3ad3eec1a32ce30350de667fee80.tar.bz2
snes9x2005-804169dd621a3ad3eec1a32ce30350de667fee80.zip
apply a facelift
Diffstat (limited to 'source/fxemu.c')
-rw-r--r--source/fxemu.c1022
1 files changed, 513 insertions, 509 deletions
diff --git a/source/fxemu.c b/source/fxemu.c
index 8dd7a15..b0ec6c7 100644
--- a/source/fxemu.c
+++ b/source/fxemu.c
@@ -1,6 +1,6 @@
/*******************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
-
+
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and
Jerremy Koot (jkoot@snes9x.com)
@@ -43,46 +43,46 @@
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive and John Weidman
-
+
S-RTC C emulator code
(c) Copyright 2001 John Weidman
-
+
ST010 C++ emulator code
(c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora
- Super FX x86 assembler emulator code
- (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
+ Super FX x86 assembler emulator code
+ (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault
- Super FX C emulator code
+ Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman
SH assembler code partly based on x86 assembler code
- (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+ (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
+
-
Specific ports contains the works of other authors. See headers in
individual files.
-
+
Snes9x homepage: http://www.snes9x.com
-
+
Permission to use, copy, modify and distribute Snes9x in both binary and
source form, for non-commercial purposes, is hereby granted without fee,
providing that this license information and copyright notice appear with
all copies and any derived work.
-
+
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software.
-
+
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes
charging money for Snes9x or software derived from Snes9x.
-
+
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
-
+
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
*******************************************************************************/
@@ -95,632 +95,636 @@
/* The FxChip Emulator's internal variables */
struct FxRegs_s GSU = FxRegs_s_null;
-uint32 (**fx_ppfFunctionTable)(uint32) = 0;
+uint32(**fx_ppfFunctionTable)(uint32) = 0;
void (**fx_ppfPlotTable)() = 0;
void (**fx_ppfOpcodeTable)() = 0;
#if 0
void fx_setCache()
{
- uint32 c;
- GSU.bCacheActive = TRUE;
- GSU.pvRegisters[0x3e] &= 0xf0;
- c = (uint32)GSU.pvRegisters[0x3e];
- c |= ((uint32)GSU.pvRegisters[0x3f])<<8;
- if(c == GSU.vCacheBaseReg)
- return;
- GSU.vCacheBaseReg = c;
- GSU.vCacheFlags = 0;
- if(c < (0x10000-512))
- {
- uint8 const* t = &ROM(c);
- memcpy(GSU.pvCache,t,512);
- }
- else
- {
- uint8 const* t1;
- uint8 const* t2;
- uint32 i = 0x10000 - c;
- t1 = &ROM(c);
- t2 = &ROM(0);
- memcpy(GSU.pvCache,t1,i);
- memcpy(&GSU.pvCache[i],t2,512-i);
- }
+ uint32 c;
+ GSU.bCacheActive = TRUE;
+ GSU.pvRegisters[0x3e] &= 0xf0;
+ c = (uint32)GSU.pvRegisters[0x3e];
+ c |= ((uint32)GSU.pvRegisters[0x3f]) << 8;
+ if (c == GSU.vCacheBaseReg)
+ return;
+ GSU.vCacheBaseReg = c;
+ GSU.vCacheFlags = 0;
+ if (c < (0x10000 - 512))
+ {
+ uint8 const* t = &ROM(c);
+ memcpy(GSU.pvCache, t, 512);
+ }
+ else
+ {
+ uint8 const* t1;
+ uint8 const* t2;
+ uint32 i = 0x10000 - c;
+ t1 = &ROM(c);
+ t2 = &ROM(0);
+ memcpy(GSU.pvCache, t1, i);
+ memcpy(&GSU.pvCache[i], t2, 512 - i);
+ }
}
#endif
void FxCacheWriteAccess(uint16 vAddress)
{
#if 0
- if(!GSU.bCacheActive)
- {
- uint8 v = GSU.pvCache[GSU.pvCache[vAddress&0x1ff];
- fx_setCache();
- GSU.pvCache[GSU.pvCache[vAddress&0x1ff] = v;
- }
+ if (!GSU.bCacheActive)
+ {
+ uint8 v = GSU.pvCache[GSU.pvCache[vAddress & 0x1ff];
+ fx_setCache();
+ GSU.pvCache[GSU.pvCache[vAddress & 0x1ff] = v;
+ }
#endif
- if((vAddress & 0x00f) == 0x00f)
- GSU.vCacheFlags |= 1 << ((vAddress&0x1f0) >> 4);
+ if ((vAddress & 0x00f) == 0x00f)
+ GSU.vCacheFlags |= 1 << ((vAddress & 0x1f0) >> 4);
}
-void FxFlushCache()
+ void FxFlushCache()
{
- GSU.vCacheFlags = 0;
- GSU.vCacheBaseReg = 0;
- GSU.bCacheActive = FALSE;
-// GSU.vPipe = 0x1;
+ GSU.vCacheFlags = 0;
+ GSU.vCacheBaseReg = 0;
+ GSU.bCacheActive = FALSE;
+ // GSU.vPipe = 0x1;
}
static void fx_backupCache()
{
#if 0
- uint32 i;
- uint32 v = GSU.vCacheFlags;
- uint32 c = USEX16(GSU.vCacheBaseReg);
- if(v)
- for(i=0; i<32; i++)
- {
- if(v&1)
- {
- if(c < (0x10000-16))
- {
- uint8 * t = &GSU.pvPrgBank[c];
- memcpy(&GSU.avCacheBackup[i<<4],t,16);
- memcpy(t,&GSU.pvCache[i<<4],16);
- }
- else
- {
- uint8 * t1;
- uint8 * t2;
- uint32 a = 0x10000 - c;
- t1 = &GSU.pvPrgBank[c];
- t2 = &GSU.pvPrgBank[0];
- memcpy(&GSU.avCacheBackup[i<<4],t1,a);
- memcpy(t1,&GSU.pvCache[i<<4],a);
- memcpy(&GSU.avCacheBackup[(i<<4)+a],t2,16-a);
- memcpy(t2,&GSU.pvCache[(i<<4)+a],16-a);
- }
- }
- c = USEX16(c+16);
- v >>= 1;
- }
+ uint32 i;
+ uint32 v = GSU.vCacheFlags;
+ uint32 c = USEX16(GSU.vCacheBaseReg);
+ if (v)
+ for (i = 0; i < 32; i++)
+ {
+ if (v & 1)
+ {
+ if (c < (0x10000 - 16))
+ {
+ uint8* t = &GSU.pvPrgBank[c];
+ memcpy(&GSU.avCacheBackup[i << 4], t, 16);
+ memcpy(t, &GSU.pvCache[i << 4], 16);
+ }
+ else
+ {
+ uint8* t1;
+ uint8* t2;
+ uint32 a = 0x10000 - c;
+ t1 = &GSU.pvPrgBank[c];
+ t2 = &GSU.pvPrgBank[0];
+ memcpy(&GSU.avCacheBackup[i << 4], t1, a);
+ memcpy(t1, &GSU.pvCache[i << 4], a);
+ memcpy(&GSU.avCacheBackup[(i << 4) + a], t2, 16 - a);
+ memcpy(t2, &GSU.pvCache[(i << 4) + a], 16 - a);
+ }
+ }
+ c = USEX16(c + 16);
+ v >>= 1;
+ }
#endif
}
static void fx_restoreCache()
{
#if 0
- uint32 i;
- uint32 v = GSU.vCacheFlags;
- uint32 c = USEX16(GSU.vCacheBaseReg);
- if(v)
- for(i=0; i<32; i++)
- {
- if(v&1)
- {
- if(c < (0x10000-16))
- {
- uint8 * t = &GSU.pvPrgBank[c];
- memcpy(t,&GSU.avCacheBackup[i<<4],16);
- memcpy(&GSU.pvCache[i<<4],t,16);
- }
- else
- {
- uint8 * t1;
- uint8 * t2;
- uint32 a = 0x10000 - c;
- t1 = &GSU.pvPrgBank[c];
- t2 = &GSU.pvPrgBank[0];
- memcpy(t1,&GSU.avCacheBackup[i<<4],a);
- memcpy(&GSU.pvCache[i<<4],t1,a);
- memcpy(t2,&GSU.avCacheBackup[(i<<4)+a],16-a);
- memcpy(&GSU.pvCache[(i<<4)+a],t2,16-a);
- }
- }
- c = USEX16(c+16);
- v >>= 1;
- }
+ uint32 i;
+ uint32 v = GSU.vCacheFlags;
+ uint32 c = USEX16(GSU.vCacheBaseReg);
+ if (v)
+ for (i = 0; i < 32; i++)
+ {
+ if (v & 1)
+ {
+ if (c < (0x10000 - 16))
+ {
+ uint8* t = &GSU.pvPrgBank[c];
+ memcpy(t, &GSU.avCacheBackup[i << 4], 16);
+ memcpy(&GSU.pvCache[i << 4], t, 16);
+ }
+ else
+ {
+ uint8* t1;
+ uint8* t2;
+ uint32 a = 0x10000 - c;
+ t1 = &GSU.pvPrgBank[c];
+ t2 = &GSU.pvPrgBank[0];
+ memcpy(t1, &GSU.avCacheBackup[i << 4], a);
+ memcpy(&GSU.pvCache[i << 4], t1, a);
+ memcpy(t2, &GSU.avCacheBackup[(i << 4) + a], 16 - a);
+ memcpy(&GSU.pvCache[(i << 4) + a], t2, 16 - a);
+ }
+ }
+ c = USEX16(c + 16);
+ v >>= 1;
+ }
#endif
}
void fx_flushCache()
{
- fx_restoreCache();
- GSU.vCacheFlags = 0;
- GSU.bCacheActive = FALSE;
+ fx_restoreCache();
+ GSU.vCacheFlags = 0;
+ GSU.bCacheActive = FALSE;
}
void fx_updateRamBank(uint8 Byte)
{
- // Update BankReg and Bank pointer
- GSU.vRamBankReg = (uint32)Byte & (FX_RAM_BANKS-1);
- GSU.pvRamBank = GSU.apvRamBank[Byte & 0x3];
+ // Update BankReg and Bank pointer
+ GSU.vRamBankReg = (uint32)Byte & (FX_RAM_BANKS - 1);
+ GSU.pvRamBank = GSU.apvRamBank[Byte & 0x3];
}
static void fx_readRegisterSpace()
{
- int i;
- uint8 *p;
- static uint32 avHeight[] = { 128, 160, 192, 256 };
- static uint32 avMult[] = { 16, 32, 32, 64 };
-
- GSU.vErrorCode = 0;
-
- /* Update R0-R15 */
- p = GSU.pvRegisters;
- for(i=0; i<16; i++)
- {
- GSU.avReg[i] = *p++;
- GSU.avReg[i] += ((uint32)(*p++)) << 8;
- }
-
- /* Update other registers */
- p = GSU.pvRegisters;
- GSU.vStatusReg = (uint32)p[GSU_SFR];
- GSU.vStatusReg |= ((uint32)p[GSU_SFR+1]) << 8;
- GSU.vPrgBankReg = (uint32)p[GSU_PBR];
- GSU.vRomBankReg = (uint32)p[GSU_ROMBR];
- GSU.vRamBankReg = ((uint32)p[GSU_RAMBR]) & (FX_RAM_BANKS-1);
- GSU.vCacheBaseReg = (uint32)p[GSU_CBR];
- GSU.vCacheBaseReg |= ((uint32)p[GSU_CBR+1]) << 8;
-
- /* Update status register variables */
- GSU.vZero = !(GSU.vStatusReg & FLG_Z);
- GSU.vSign = (GSU.vStatusReg & FLG_S) << 12;
- GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16;
- GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2;
-
- /* Set bank pointers */
- GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3];
- GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg];
- GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg];
-
- /* Set screen pointers */
- GSU.pvScreenBase = &GSU.pvRam[ USEX8(p[GSU_SCBR]) << 10 ];
- i = (int)(!!(p[GSU_SCMR] & 0x04));
- i |= ((int)(!!(p[GSU_SCMR] & 0x20))) << 1;
- GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[i];
- GSU.vMode = p[GSU_SCMR] & 0x03;
+ int i;
+ uint8* p;
+ static uint32 avHeight[] = { 128, 160, 192, 256 };
+ static uint32 avMult[] = { 16, 32, 32, 64 };
+
+ GSU.vErrorCode = 0;
+
+ /* Update R0-R15 */
+ p = GSU.pvRegisters;
+ for (i = 0; i < 16; i++)
+ {
+ GSU.avReg[i] = *p++;
+ GSU.avReg[i] += ((uint32)(*p++)) << 8;
+ }
+
+ /* Update other registers */
+ p = GSU.pvRegisters;
+ GSU.vStatusReg = (uint32)p[GSU_SFR];
+ GSU.vStatusReg |= ((uint32)p[GSU_SFR + 1]) << 8;
+ GSU.vPrgBankReg = (uint32)p[GSU_PBR];
+ GSU.vRomBankReg = (uint32)p[GSU_ROMBR];
+ GSU.vRamBankReg = ((uint32)p[GSU_RAMBR]) & (FX_RAM_BANKS - 1);
+ GSU.vCacheBaseReg = (uint32)p[GSU_CBR];
+ GSU.vCacheBaseReg |= ((uint32)p[GSU_CBR + 1]) << 8;
+
+ /* Update status register variables */
+ GSU.vZero = !(GSU.vStatusReg & FLG_Z);
+ GSU.vSign = (GSU.vStatusReg & FLG_S) << 12;
+ GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16;
+ GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2;
+
+ /* Set bank pointers */
+ GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3];
+ GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg];
+ GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg];
+
+ /* Set screen pointers */
+ GSU.pvScreenBase = &GSU.pvRam[ USEX8(p[GSU_SCBR]) << 10 ];
+ i = (int)(!!(p[GSU_SCMR] & 0x04));
+ i |= ((int)(!!(p[GSU_SCMR] & 0x20))) << 1;
+ GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[i];
+ GSU.vMode = p[GSU_SCMR] & 0x03;
#if 0
- if(GSU.vMode == 2)
- error illegal color depth GSU.vMode;
+ if (GSU.vMode == 2)
+ error illegal color depth GSU.vMode;
#endif
- if(i == 3)
- GSU.vScreenSize = (256/8) * (256/8) * 32;
- else
- GSU.vScreenSize = (GSU.vScreenHeight/8) * (256/8) * avMult[GSU.vMode];
- if (GSU.vPlotOptionReg & 0x10)
- {
- /* OBJ Mode (for drawing into sprites) */
- GSU.vScreenHeight = 256;
- }
+ if (i == 3)
+ GSU.vScreenSize = (256 / 8) * (256 / 8) * 32;
+ else
+ GSU.vScreenSize = (GSU.vScreenHeight / 8) * (256 / 8) * avMult[GSU.vMode];
+ if (GSU.vPlotOptionReg & 0x10)
+ {
+ /* OBJ Mode (for drawing into sprites) */
+ GSU.vScreenHeight = 256;
+ }
#if 0
- if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
- error illegal address for screen base register
+ if (GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
+ error illegal address for screen base register
#else
- if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
- GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize;
+ if (GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536))
+ GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize;
#endif
- GSU.pfPlot = fx_apfPlotTable[GSU.vMode];
- GSU.pfRpix = fx_apfPlotTable[GSU.vMode + 5];
+ 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_ppfOpcodeTable[0x04c] = GSU.pfPlot;
+ fx_ppfOpcodeTable[0x14c] = GSU.pfRpix;
+ fx_ppfOpcodeTable[0x24c] = GSU.pfPlot;
+ fx_ppfOpcodeTable[0x34c] = GSU.pfRpix;
- fx_computeScreenPointers ();
+ fx_computeScreenPointers();
- fx_backupCache();
+ fx_backupCache();
}
void fx_dirtySCBR()
{
- GSU.vSCBRDirty = TRUE;
+ GSU.vSCBRDirty = TRUE;
}
-void fx_computeScreenPointers ()
+void fx_computeScreenPointers()
{
- if (GSU.vMode != GSU.vPrevMode ||
- GSU.vPrevScreenHeight != GSU.vScreenHeight ||
- GSU.vSCBRDirty)
- {
- int i;
-
- GSU.vSCBRDirty = FALSE;
-
- /* Make a list of pointers to the start of each screen column */
- switch (GSU.vScreenHeight)
- {
- case 128:
- switch (GSU.vMode)
- {
- case 0:
- for (i = 0; i < 32; i++)
- {
- GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
- GSU.x[i] = i << 8;
- }
- break;
- case 1:
- for (i = 0; i < 32; i++)
- {
- GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
- GSU.x[i] = i << 9;
- }
- break;
- case 2:
- case 3:
- for (i = 0; i < 32; i++)
- {
- GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
- GSU.x[i] = i << 10;
- }
- break;
- }
- break;
- case 160:
- switch (GSU.vMode)
- {
- case 0:
- for (i = 0; i < 32; i++)
- {
- GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
- GSU.x[i] = (i << 8) + (i << 6);
- }
- break;
- case 1:
- for (i = 0; i < 32; i++)
- {
- GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
- GSU.x[i] = (i << 9) + (i << 7);
- }
- break;
- case 2:
- case 3:
- for (i = 0; i < 32; i++)
- {
- GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
- GSU.x[i] = (i << 10) + (i << 8);
- }
- break;
- }
- break;
- case 192:
- switch (GSU.vMode)
- {
- case 0:
- for (i = 0; i < 32; i++)
- {
- 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;
- }
+ if (GSU.vMode != GSU.vPrevMode ||
+ GSU.vPrevScreenHeight != GSU.vScreenHeight ||
+ GSU.vSCBRDirty)
+ {
+ int i;
+
+ GSU.vSCBRDirty = FALSE;
+
+ /* Make a list of pointers to the start of each screen column */
+ switch (GSU.vScreenHeight)
+ {
+ case 128:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
+ GSU.x[i] = i << 8;
+ }
+ break;
+ case 1:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
+ GSU.x[i] = i << 9;
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
+ GSU.x[i] = i << 10;
+ }
+ break;
+ }
+ break;
+ case 160:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4);
+ GSU.x[i] = (i << 8) + (i << 6);
+ }
+ break;
+ case 1:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5);
+ GSU.x[i] = (i << 9) + (i << 7);
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 32; i++)
+ {
+ GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6);
+ GSU.x[i] = (i << 10) + (i << 8);
+ }
+ break;
+ }
+ break;
+ case 192:
+ switch (GSU.vMode)
+ {
+ case 0:
+ for (i = 0; i < 32; i++)
+ {
+ 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();
+ 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)
+void FxReset(struct FxInit_s* psFxInfo)
{
- int i;
- static uint32 (**appfFunction[])(uint32) = {
- &fx_apfFunctionTable[0],
+ 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],
+ &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();
+ &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;
+ /* 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;
+ uint32 vCount;
- /* Read registers and initialize GSU session */
- fx_readRegisterSpace();
+ /* Read registers and initialize GSU session */
+ fx_readRegisterSpace();
- /* Check if the start address is valid */
- if(!fx_checkStartAddress())
- {
- CF(G);
- fx_writeRegisterSpace();
+ /* 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;
+ GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;
+ return FX_ERROR_ILLEGAL_ADDRESS;
#else
- return 0;
+ return 0;
#endif
- }
+ }
- /* Execute GSU session */
- CF(IRQ);
+ /* 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);
+ 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();
+ /* Store GSU registers */
+ fx_writeRegisterSpace();
- /* Check for error code */
- if(GSU.vErrorCode)
- return GSU.vErrorCode;
- else
- return vCount;
+ /* 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);
+ GSU.bBreakPoint = TRUE;
+ GSU.vBreakPoint = USEX16(vAddress);
}
void FxBreakPointClear()
{
- GSU.bBreakPoint = FALSE;
+ GSU.bBreakPoint = FALSE;
}
/* Step by step execution */
int FxStepOver(uint32 nInstructions)
{
- uint32 vCount;
- fx_readRegisterSpace();
+ uint32 vCount;
+ fx_readRegisterSpace();
- /* Check if the start address is valid */
- if(!fx_checkStartAddress())
- {
- CF(G);
+ /* 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;
+ GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15;
+ return FX_ERROR_ILLEGAL_ADDRESS;
#else
- return 0;
+ 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;
+ }
+
+ 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;
+ return GSU.vErrorCode;
}
int FxGetIllegalAddress()
{
- return GSU.vIllegalAddress;
+ return GSU.vIllegalAddress;
}
/* Access to internal registers */
uint32 FxGetColorRegister()
{
- return GSU.vColorReg & 0xff;
+ return GSU.vColorReg & 0xff;
}
uint32 FxGetPlotOptionRegister()
{
- return GSU.vPlotOptionReg & 0x1f;
+ return GSU.vPlotOptionReg & 0x1f;
}
uint32 FxGetSourceRegisterIndex()
{
- return GSU.pvSreg - GSU.avReg;
+ return GSU.pvSreg - GSU.avReg;
}
uint32 FxGetDestinationRegisterIndex()
{
- return GSU.pvDreg - GSU.avReg;
+ return GSU.pvDreg - GSU.avReg;
}
uint8 FxPipe()
{
- return GSU.vPipe;
+ return GSU.vPipe;
}