📄 fxemu.cpp
字号:
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 + -