mirror of
https://github.com/libretro/fixGB.git
synced 2024-11-23 09:09:40 +00:00
-improved audio output and small audio emulation fixes and improvements
-added support for one of the multicarts I own because why not -various small updates regarding the libretro hook, including better handling of rom switching and saving
This commit is contained in:
parent
0004be631e
commit
251e12cf98
176
apu.c
176
apu.c
@ -53,10 +53,10 @@ static uint8_t p1LengthCtr, p2LengthCtr, noiseLengthCtr;
|
||||
static uint8_t wavLinearCtr;
|
||||
static uint16_t wavLengthCtr;
|
||||
static uint8_t wavVolShift;
|
||||
static uint16_t modeCurCtr = 0;
|
||||
static uint16_t modeCurCtr;
|
||||
static uint8_t modePos;
|
||||
static uint16_t p1freqCtr, p2freqCtr, wavFreqCtr, noiseFreqCtr;
|
||||
static uint8_t p1Cycle, p2Cycle, wavCycle;
|
||||
static uint8_t modePos = 0;
|
||||
static bool p1haltloop, p2haltloop, wavhaltloop, noisehaltloop;
|
||||
static bool p1dacenable, p2dacenable, wavdacenable, noisedacenable;
|
||||
static bool p1enable, p2enable, wavenable, noiseenable;
|
||||
@ -118,16 +118,16 @@ void apuInitBufs()
|
||||
apuFrequency = 262144;
|
||||
double dt = 1.0/((double)apuFrequency);
|
||||
|
||||
//LP at 22kHz
|
||||
double rc = 1.0/(M_2_PI * 22000.0);
|
||||
//LP at 20kHz
|
||||
double rc = 1.0/(M_2_PI * 20000.0);
|
||||
#if AUDIO_FLOAT
|
||||
lpVal = dt / (rc + dt);
|
||||
#else
|
||||
//convert to 32bit int for calcs later
|
||||
lpVal = (int32_t)((dt / (rc + dt))*32768.0);
|
||||
#endif
|
||||
//HP at 40Hz
|
||||
rc = 1.0/(M_2_PI * 40.0);
|
||||
//HP at 20Hz for GB/GBA (150Hz for GBC)
|
||||
rc = 1.0/(M_2_PI * 20.0);
|
||||
#if AUDIO_FLOAT
|
||||
hpVal = rc / (rc + dt);
|
||||
#else
|
||||
@ -154,6 +154,16 @@ void apuDeinitBufs()
|
||||
apuOutBuf = NULL;
|
||||
}
|
||||
|
||||
#if AUDIO_FLOAT
|
||||
static float lastHPOutLeft, lastHPOutRight, lastLPOutLeft, lastLPOutRight;
|
||||
#else
|
||||
static int32_t lastHPOutLeft, lastHPOutRight, lastLPOutLeft, lastLPOutRight;
|
||||
#endif
|
||||
//used externally
|
||||
uint8_t curP1Out, curP2Out, curWavOut, curNoiseOut;
|
||||
|
||||
extern bool emuSkipVsync, emuSkipFrame;
|
||||
|
||||
extern bool gbCgbMode;
|
||||
extern bool gbCgbBootrom;
|
||||
void apuInit()
|
||||
@ -166,8 +176,11 @@ void apuInit()
|
||||
memset(apuOutBuf, 0, apuBufSizeBytes);
|
||||
curBufPos = 0;
|
||||
|
||||
modeCurCtr = 0;
|
||||
modePos = 0;
|
||||
|
||||
freq1 = 0; freq2 = 0; wavFreq = 0; noiseFreq = 0;
|
||||
noiseShiftReg = 1;
|
||||
noiseShiftReg = 0;
|
||||
p1LengthCtr = 0; p2LengthCtr = 0;
|
||||
noiseLengthCtr = 0; wavLengthCtr = 0;
|
||||
wavLinearCtr = 0;
|
||||
@ -197,18 +210,10 @@ void apuInit()
|
||||
APU_IO_Reg[0x24] = 0x77;
|
||||
APU_IO_Reg[0x25] = 0xF3;
|
||||
}
|
||||
}
|
||||
|
||||
#if AUDIO_FLOAT
|
||||
static float lastHPOutLeft = 0, lastHPOutRight = 0, lastLPOutLeft = 0, lastLPOutRight = 0;
|
||||
#else
|
||||
static int32_t lastHPOutLeft = 0, lastHPOutRight = 0, lastLPOutLeft = 0, lastLPOutRight = 0;
|
||||
#endif
|
||||
static uint8_t lastP1OutLeft = 0, lastP2OutLeft = 0, lastWavOutLeft = 0, lastNoiseOutLeft = 0;
|
||||
static uint8_t lastP1OutRight = 0, lastP2OutRight = 0, lastWavOutRight = 0, lastNoiseOutRight = 0;
|
||||
extern bool emuSkipVsync, emuSkipFrame;
|
||||
//used externally
|
||||
uint8_t curP1Out = 0, curP2Out = 0, curWavOut = 0, curNoiseOut = 0;
|
||||
lastHPOutLeft = 0, lastHPOutRight = 0, lastLPOutLeft = 0, lastLPOutRight = 0;
|
||||
curP1Out = 0, curP2Out = 0, curWavOut = 0, curNoiseOut = 0;
|
||||
}
|
||||
|
||||
bool apuCycle()
|
||||
{
|
||||
@ -238,108 +243,100 @@ bool apuCycle()
|
||||
#endif
|
||||
curBufPos = 0;
|
||||
}
|
||||
uint8_t p1OutLeft = lastP1OutLeft, p2OutLeft = lastP2OutLeft,
|
||||
wavOutLeft = lastWavOutLeft, noiseOutLeft = lastNoiseOutLeft;
|
||||
uint8_t p1OutRight = lastP1OutRight, p2OutRight = lastP2OutRight,
|
||||
wavOutRight = lastWavOutRight, noiseOutRight = lastNoiseOutRight;
|
||||
uint8_t apuMasterVolLeft = ((APU_IO_Reg[0x24]>>4)&7), apuMasterVolRight = (APU_IO_Reg[0x24]&7);
|
||||
int8_t p1Out = 0, p2Out = 0, noiseOut = 0, wavOut = 0;
|
||||
int8_t p1OutLeft = 0, p2OutLeft = 0,
|
||||
wavOutLeft = 0, noiseOutLeft = 0;
|
||||
int8_t p1OutRight = 0, p2OutRight = 0,
|
||||
wavOutRight = 0, noiseOutRight = 0;
|
||||
int8_t apuMasterVolLeft = ((APU_IO_Reg[0x24]>>4)&7), apuMasterVolRight = (APU_IO_Reg[0x24]&7);
|
||||
if(p1enable && p1dacenable)
|
||||
{
|
||||
if(p1seq[p1Cycle] && freq1 > 0 && freq1 < 0x7FF)
|
||||
{
|
||||
if(p1seq[p1Cycle])
|
||||
curP1Out = p1Env.curVol;
|
||||
if(APU_IO_Reg[0x25] & P1_ENABLE_LEFT)
|
||||
lastP1OutLeft = p1OutLeft = curP1Out;
|
||||
if(APU_IO_Reg[0x25] & P1_ENABLE_RIGHT)
|
||||
lastP1OutRight = p1OutRight = curP1Out;
|
||||
}
|
||||
else
|
||||
{
|
||||
curP1Out = 0;
|
||||
if(APU_IO_Reg[0x25] & P1_ENABLE_LEFT)
|
||||
p1OutLeft = 0;
|
||||
if(APU_IO_Reg[0x25] & P1_ENABLE_RIGHT)
|
||||
p1OutRight = 0;
|
||||
//actually audible output
|
||||
if(freq1 > 0 && freq1 < 0x7FF)
|
||||
{
|
||||
//GB/GBC Behavior
|
||||
//p1Out = (curP1Out<<1)-15;
|
||||
//GBA Behavior
|
||||
p1Out = (curP1Out<<1)-p1Env.curVol;
|
||||
}
|
||||
}
|
||||
else
|
||||
curP1Out = 0;
|
||||
if(APU_IO_Reg[0x25] & P1_ENABLE_LEFT)
|
||||
p1OutLeft = p1Out;
|
||||
if(APU_IO_Reg[0x25] & P1_ENABLE_RIGHT)
|
||||
p1OutRight = p1Out;
|
||||
if(p2enable && p2dacenable)
|
||||
{
|
||||
if(p2seq[p2Cycle] && freq2 > 0 && freq2 < 0x7FF)
|
||||
{
|
||||
if(p2seq[p2Cycle])
|
||||
curP2Out = p2Env.curVol;
|
||||
if(APU_IO_Reg[0x25] & P2_ENABLE_LEFT)
|
||||
lastP2OutLeft = p2OutLeft = curP2Out;
|
||||
if(APU_IO_Reg[0x25] & P2_ENABLE_RIGHT)
|
||||
lastP2OutRight = p2OutRight = curP2Out;
|
||||
}
|
||||
else
|
||||
{
|
||||
curP2Out = 0;
|
||||
if(APU_IO_Reg[0x25] & P2_ENABLE_LEFT)
|
||||
p2OutLeft = 0;
|
||||
if(APU_IO_Reg[0x25] & P2_ENABLE_RIGHT)
|
||||
p2OutRight = 0;
|
||||
//actually audible output
|
||||
if(freq2 > 0 && freq2 < 0x7FF)
|
||||
{
|
||||
//GB/GBC Behavior
|
||||
//p2Out = (curP2Out<<1)-15;
|
||||
//GBA Behavior
|
||||
p2Out = (curP2Out<<1)-p2Env.curVol;
|
||||
}
|
||||
}
|
||||
else
|
||||
curP2Out = 0;
|
||||
if(APU_IO_Reg[0x25] & P2_ENABLE_LEFT)
|
||||
p2OutLeft = p2Out;
|
||||
if(APU_IO_Reg[0x25] & P2_ENABLE_RIGHT)
|
||||
p2OutRight = p2Out;
|
||||
if(wavenable && wavdacenable)
|
||||
{
|
||||
uint8_t v = APU_IO_Reg[0x30+(wavCycle>>1)];
|
||||
curWavOut = APU_IO_Reg[0x30+(wavCycle>>1)];
|
||||
if((wavCycle&1)==0)
|
||||
v >>= 4;
|
||||
curWavOut >>= 4;
|
||||
else
|
||||
v &= 0xF;
|
||||
v>>=wavVolShift;
|
||||
if(v && ((wavFreq > 0 && wavFreq < 0x7FF) || wavEqual))
|
||||
{
|
||||
curWavOut = v;
|
||||
if(APU_IO_Reg[0x25] & WAV_ENABLE_LEFT)
|
||||
lastWavOutLeft = wavOutLeft = curWavOut;
|
||||
if(APU_IO_Reg[0x25] & WAV_ENABLE_RIGHT)
|
||||
lastWavOutRight = wavOutRight = curWavOut;
|
||||
}
|
||||
else
|
||||
{
|
||||
curWavOut = 0;
|
||||
if(APU_IO_Reg[0x25] & WAV_ENABLE_LEFT)
|
||||
wavOutLeft = 0;
|
||||
if(APU_IO_Reg[0x25] & WAV_ENABLE_RIGHT)
|
||||
wavOutRight = 0;
|
||||
}
|
||||
curWavOut &= 0xF;
|
||||
curWavOut >>= wavVolShift;
|
||||
//actually audible output
|
||||
if((wavFreq > 0 && wavFreq < 0x7FF) || wavEqual)
|
||||
wavOut = (curWavOut<<1)-15;
|
||||
}
|
||||
else
|
||||
curWavOut = 0;
|
||||
if(APU_IO_Reg[0x25] & WAV_ENABLE_LEFT)
|
||||
wavOutLeft = wavOut;
|
||||
if(APU_IO_Reg[0x25] & WAV_ENABLE_RIGHT)
|
||||
wavOutRight = wavOut;
|
||||
if(noiseenable && noisedacenable)
|
||||
{
|
||||
if((noiseShiftReg&1) == 0 && noiseFreq > 0)
|
||||
{
|
||||
if((noiseShiftReg&1) == 0)
|
||||
curNoiseOut = noiseEnv.curVol;
|
||||
if(APU_IO_Reg[0x25] & NOISE_ENABLE_LEFT)
|
||||
lastNoiseOutLeft = noiseOutLeft = curNoiseOut;
|
||||
if(APU_IO_Reg[0x25] & NOISE_ENABLE_RIGHT)
|
||||
lastNoiseOutRight = noiseOutRight = curNoiseOut;
|
||||
}
|
||||
else
|
||||
{
|
||||
curNoiseOut = 0;
|
||||
if(APU_IO_Reg[0x25] & NOISE_ENABLE_LEFT)
|
||||
noiseOutLeft = 0;
|
||||
if(APU_IO_Reg[0x25] & NOISE_ENABLE_RIGHT)
|
||||
noiseOutRight = 0;
|
||||
//actually audible output
|
||||
if(noiseFreq > 0)
|
||||
{
|
||||
//GB/GBC Behavior
|
||||
//noiseOut = (curNoiseOut<<1)-15;
|
||||
//GBA Behavior
|
||||
noiseOut = (curNoiseOut<<1)-noiseEnv.curVol;
|
||||
}
|
||||
}
|
||||
else
|
||||
curNoiseOut = 0;
|
||||
if(APU_IO_Reg[0x25] & NOISE_ENABLE_LEFT)
|
||||
noiseOutLeft = noiseOut;
|
||||
if(APU_IO_Reg[0x25] & NOISE_ENABLE_RIGHT)
|
||||
noiseOutRight = noiseOut;
|
||||
#if AUDIO_FLOAT
|
||||
//gen output Left
|
||||
float curInLeft = ((float)(p1OutLeft + p2OutLeft + wavOutLeft + noiseOutLeft))*volLevel[apuMasterVolLeft]/32.f;
|
||||
float curInLeft = ((float)(p1OutLeft + p2OutLeft + wavOutLeft + noiseOutLeft))*volLevel[apuMasterVolLeft]/85.333333f;
|
||||
float curLPOutLeft = lastLPOutLeft+(lpVal*(curInLeft-lastLPOutLeft));
|
||||
float curHPOutLeft = hpVal*(lastHPOutLeft+lastLPOutLeft-curLPOutLeft);
|
||||
//gen output Right
|
||||
float curInRight = ((float)(p1OutRight + p2OutRight + wavOutRight + noiseOutRight))*volLevel[apuMasterVolRight]/32.f;
|
||||
float curInRight = ((float)(p1OutRight + p2OutRight + wavOutRight + noiseOutRight))*volLevel[apuMasterVolRight]/85.333333f;
|
||||
float curLPOutRight = lastLPOutRight+(lpVal*(curInRight-lastLPOutRight));
|
||||
float curHPOutRight = hpVal*(lastHPOutRight+lastLPOutRight-curLPOutRight);
|
||||
//set output Left
|
||||
@ -355,7 +352,7 @@ bool apuCycle()
|
||||
#else
|
||||
int32_t curIn, curOut;
|
||||
//gen output Left
|
||||
curIn = ((p1OutLeft + p2OutLeft + wavOutLeft + noiseOutLeft))*(apuMasterVolLeft+1)<<7;
|
||||
curIn = (p1OutLeft + p2OutLeft + wavOutLeft + noiseOutLeft)*(apuMasterVolLeft+1)*48;
|
||||
curOut = lastLPOutLeft+((lpVal*(curIn-lastLPOutLeft))>>15); //Set Left Lowpass Output
|
||||
curIn = (lastHPOutLeft+lastLPOutLeft-curOut); //Set Left Highpass Input
|
||||
curIn += (curIn>>31)&1; //Add Sign Bit for proper Downshift later
|
||||
@ -365,7 +362,7 @@ bool apuCycle()
|
||||
//Save Clipped Left Highpass Output
|
||||
apuOutBuf[curBufPos++] = ((soundEnabled)?((curOut > 32767)?(32767):((curOut < -32768)?(-32768):curOut)):0);
|
||||
//gen output Right
|
||||
curIn = ((p1OutRight + p2OutRight + wavOutRight + noiseOutRight))*(apuMasterVolRight+1)<<7;
|
||||
curIn = (p1OutRight + p2OutRight + wavOutRight + noiseOutRight)*(apuMasterVolRight+1)*48;
|
||||
curOut = lastLPOutRight+((lpVal*(curIn-lastLPOutRight))>>15); //Set Right Lowpass Output
|
||||
curIn = (lastHPOutRight+lastLPOutRight-curOut); //Set Right Highpass Input
|
||||
curIn += (curIn>>31)&1; //Add Sign Bit for proper Downshift later
|
||||
@ -567,10 +564,9 @@ void apuClockTimers()
|
||||
if(noiseFreqCtr == 0)
|
||||
{
|
||||
noiseFreqCtr = noiseFreq;
|
||||
uint8_t cmpBit = noiseMode1 ? (noiseShiftReg>>6)&1 : (noiseShiftReg>>1)&1;
|
||||
uint8_t cmpRes = (noiseShiftReg&1)^cmpBit;
|
||||
uint8_t cmpRes = (noiseShiftReg&1)^((noiseShiftReg>>1)&1);
|
||||
noiseShiftReg >>= 1;
|
||||
noiseShiftReg |= cmpRes<<14;
|
||||
noiseShiftReg |= cmpRes << (noiseMode1 ? 6 : 14);
|
||||
}
|
||||
if(noiseFreqCtr)
|
||||
noiseFreqCtr--;
|
||||
@ -657,8 +653,6 @@ void apuSetReg8(uint16_t addr, uint8_t val)
|
||||
p1Env.curVol++;
|
||||
p1Env.curVol &= 0xF;
|
||||
}
|
||||
else //Normal behaviour
|
||||
p1Env.curVol = p1Env.vol;
|
||||
p1dacenable = (p1Env.modeadd || p1Env.vol);
|
||||
if(!p1dacenable)
|
||||
p1enable = false;
|
||||
@ -731,8 +725,6 @@ void apuSetReg8(uint16_t addr, uint8_t val)
|
||||
p2Env.curVol++;
|
||||
p2Env.curVol &= 0xF;
|
||||
}
|
||||
else //Normal behaviour
|
||||
p2Env.curVol = p2Env.vol;
|
||||
p2dacenable = (p2Env.modeadd || p2Env.vol);
|
||||
if(!p2dacenable)
|
||||
p2enable = false;
|
||||
@ -855,8 +847,6 @@ void apuSetReg8(uint16_t addr, uint8_t val)
|
||||
noiseEnv.curVol++;
|
||||
noiseEnv.curVol &= 0xF;
|
||||
}
|
||||
else //Normal behaviour
|
||||
noiseEnv.curVol = noiseEnv.vol;
|
||||
noisedacenable = (noiseEnv.modeadd || noiseEnv.vol);
|
||||
if(!noisedacenable)
|
||||
noiseenable = false;
|
||||
@ -900,6 +890,8 @@ void apuSetReg8(uint16_t addr, uint8_t val)
|
||||
noiseEnv.curVol = noiseEnv.vol;
|
||||
//period 0 is actually period 8!
|
||||
noiseEnv.divider = (noiseEnv.period-1)&7;
|
||||
//trigger sets all shift reg bits
|
||||
noiseShiftReg = 0x7FFF;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
297
cpu.c
297
cpu.c
@ -28,15 +28,14 @@ extern uint16_t gbsSP;
|
||||
extern uint8_t cpuTimer;
|
||||
extern bool gbCgbMode;
|
||||
extern bool gbCgbBootrom;
|
||||
|
||||
//used externally
|
||||
bool cpuDoStopSwitch = false;
|
||||
bool cpuCgbSpeed = false;
|
||||
//initalized elsewhere
|
||||
uint8_t cpuAddSpeed = 1;
|
||||
void cpuSetupActionArr();
|
||||
bool cpu_oam_dma = false;
|
||||
bool cpu_oam_dma_running = false;
|
||||
uint16_t cpu_oam_dma_addr = 0;
|
||||
bool cpuCgbSpeed = false;
|
||||
//used externally
|
||||
bool cpuDoStopSwitch;
|
||||
bool cpu_oam_dma;
|
||||
bool cpu_oam_dma_running;
|
||||
uint16_t cpu_oam_dma_addr;
|
||||
|
||||
static uint16_t sp, pc, cpuTmp16;
|
||||
static uint8_t a,b,c,d,e,f,h,l,cpuTmp;
|
||||
@ -47,6 +46,18 @@ static bool gbsInitRet, gbsPlayRet;
|
||||
static uint8_t sub_in_val;
|
||||
static bool irqEnable;
|
||||
static bool cpuHaltLoop,cpuStopLoop,cpuHaltBug,cpuPrevInAny;
|
||||
|
||||
static uint8_t curInstr;
|
||||
|
||||
static bool cpu_oam_dma_started;
|
||||
static uint8_t cpu_oam_dma_pos;
|
||||
bool cpuDmaHalt;
|
||||
|
||||
static void cpuSetupActionArr();
|
||||
static const uint8_t *cpu_action_arr;
|
||||
static uint8_t cpu_arr_pos;
|
||||
static inline void cpuSetNopArr();
|
||||
|
||||
void cpuInit()
|
||||
{
|
||||
sub_in_val=0,cpuTmp=0,cpuTmp16=0;
|
||||
@ -70,8 +81,8 @@ void cpuInit()
|
||||
cpuHaltLoop = false;
|
||||
cpuStopLoop = false;
|
||||
cpuHaltBug = false;
|
||||
cpuCgbSpeed = false;
|
||||
cpuPrevInAny = false;
|
||||
cpuDoStopSwitch = false;
|
||||
cpu_oam_dma = false;
|
||||
cpu_oam_dma_running = false;
|
||||
cpu_oam_dma_addr = 0;
|
||||
@ -79,15 +90,22 @@ void cpuInit()
|
||||
//gbs stuff
|
||||
gbsInitRet = false; //for first init
|
||||
gbsPlayRet = true; //for first play call
|
||||
|
||||
curInstr = 0;
|
||||
cpu_oam_dma_started = false;
|
||||
cpu_oam_dma_pos = 0;
|
||||
cpuDmaHalt = false;
|
||||
|
||||
cpuSetNopArr();
|
||||
}
|
||||
|
||||
static void setAImmRegStats()
|
||||
static inline void setAImmRegStats()
|
||||
{
|
||||
f &= ~(P_FLAG_C|P_FLAG_H|P_FLAG_N|P_FLAG_Z);
|
||||
if(a == 0) f |= P_FLAG_Z;
|
||||
}
|
||||
|
||||
void cpuAdd16(uint16_t x)
|
||||
static inline void cpuAdd16(uint16_t x)
|
||||
{
|
||||
uint32_t r1,r2;
|
||||
r1=((h<<8)|l)+(x);
|
||||
@ -103,7 +121,7 @@ void cpuAdd16(uint16_t x)
|
||||
f = tf;
|
||||
}
|
||||
|
||||
uint16_t cpuAddSp16(uint8_t add)
|
||||
static inline int16_t cpuAddSp16(uint8_t add)
|
||||
{
|
||||
int32_t n = (int8_t)add;
|
||||
uint32_t r1,r2,r3;
|
||||
@ -123,7 +141,7 @@ uint16_t cpuAddSp16(uint8_t add)
|
||||
return (uint16_t)r1;
|
||||
}
|
||||
|
||||
void setAddSubCmpFlags(uint16_t r1, uint16_t r2)
|
||||
static inline void setAddSubCmpFlags(uint16_t r1, uint16_t r2)
|
||||
{
|
||||
if(((uint8_t)r2)==0)
|
||||
f |= P_FLAG_Z;
|
||||
@ -141,7 +159,7 @@ void setAddSubCmpFlags(uint16_t r1, uint16_t r2)
|
||||
f &= ~P_FLAG_H;
|
||||
}
|
||||
|
||||
uint8_t cpuDoAdd8(uint8_t x, uint8_t y)
|
||||
static inline uint8_t cpuDoAdd8(uint8_t x, uint8_t y)
|
||||
{
|
||||
uint16_t r1,r2;
|
||||
r1=(uint16_t)((x&0xF)+(y&0xF));
|
||||
@ -154,12 +172,12 @@ uint8_t cpuDoAdd8(uint8_t x, uint8_t y)
|
||||
return (uint8_t)r2;
|
||||
}
|
||||
|
||||
void cpuAdd8(uint8_t *reg)
|
||||
static void cpuAdd8(uint8_t *reg)
|
||||
{
|
||||
a = cpuDoAdd8(a,*reg);
|
||||
}
|
||||
|
||||
uint8_t cpuDoSub8(uint8_t x, uint8_t y)
|
||||
static inline uint8_t cpuDoSub8(uint8_t x, uint8_t y)
|
||||
{
|
||||
uint16_t r1,r2;
|
||||
r1=(uint16_t)((x&0xF)-(y&0xF));
|
||||
@ -172,17 +190,17 @@ uint8_t cpuDoSub8(uint8_t x, uint8_t y)
|
||||
return (uint8_t)r2;
|
||||
}
|
||||
|
||||
void cpuSub8(uint8_t *reg)
|
||||
static void cpuSub8(uint8_t *reg)
|
||||
{
|
||||
a = cpuDoSub8(a,*reg);
|
||||
}
|
||||
|
||||
void cpuCmp8(uint8_t *reg)
|
||||
static void cpuCmp8(uint8_t *reg)
|
||||
{
|
||||
cpuDoSub8(a,*reg);
|
||||
}
|
||||
|
||||
void cpuSbc8(uint8_t *reg)
|
||||
static void cpuSbc8(uint8_t *reg)
|
||||
{
|
||||
uint16_t r1,r2;
|
||||
uint8_t x = *reg;
|
||||
@ -196,7 +214,7 @@ void cpuSbc8(uint8_t *reg)
|
||||
f |= P_FLAG_N;
|
||||
}
|
||||
|
||||
void cpuAdc8(uint8_t *reg)
|
||||
static void cpuAdc8(uint8_t *reg)
|
||||
{
|
||||
uint16_t r1,r2;
|
||||
uint8_t x = *reg;
|
||||
@ -582,7 +600,7 @@ static void cpuDec(uint8_t *reg)
|
||||
f|=tf;
|
||||
}
|
||||
|
||||
void cpuDAA(uint8_t *reg)
|
||||
static void cpuDAA(uint8_t *reg)
|
||||
{
|
||||
int16_t in = *reg;
|
||||
|
||||
@ -744,130 +762,132 @@ enum {
|
||||
};
|
||||
|
||||
/* arrays for multiple similar instructions */
|
||||
static uint8_t cpu_imm_arr[1] = { CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_a_arr[1] = { CPU_A_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_b_arr[1] = { CPU_B_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_c_arr[1] = { CPU_C_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_d_arr[1] = { CPU_D_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_e_arr[1] = { CPU_E_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_h_arr[1] = { CPU_H_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_l_arr[1] = { CPU_L_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_bc_arr[2] = { CPU_TMP_READ8_BC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_de_arr[2] = { CPU_TMP_READ8_DE, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_hl_arr[2] = { CPU_TMP_READ8_HL, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_pc_arr[2] = { CPU_TMP_READ8_PC_INC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_hl_inc_arr[2] = { CPU_TMP_READ8_HL_INC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_hl_dec_arr[2] = { CPU_TMP_READ8_HL_DEC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_delay_arr[2] = { CPU_DELAY_CYCLE, CPU_ACTION_GET_INSTRUCTION };
|
||||
static uint8_t cpu_imm_hl_st_arr[3] = { CPU_TMP_READ8_HL, CPU_ACTION_WRITE8_HL, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_arr[1] = { CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_a_arr[1] = { CPU_A_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_b_arr[1] = { CPU_B_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_c_arr[1] = { CPU_C_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_d_arr[1] = { CPU_D_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_e_arr[1] = { CPU_E_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_h_arr[1] = { CPU_H_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_l_arr[1] = { CPU_L_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_bc_arr[2] = { CPU_TMP_READ8_BC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_de_arr[2] = { CPU_TMP_READ8_DE, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_hl_arr[2] = { CPU_TMP_READ8_HL, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_pc_arr[2] = { CPU_TMP_READ8_PC_INC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_hl_inc_arr[2] = { CPU_TMP_READ8_HL_INC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_hl_dec_arr[2] = { CPU_TMP_READ8_HL_DEC, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_delay_arr[2] = { CPU_DELAY_CYCLE, CPU_ACTION_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_imm_hl_st_arr[3] = { CPU_TMP_READ8_HL, CPU_ACTION_WRITE8_HL, CPU_GET_INSTRUCTION };
|
||||
|
||||
/* arrays for single special instructions */
|
||||
static uint8_t cpu_nop_arr[1] = { CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_sub_arr[1] = { CPU_GET_SUBINSTRUCTION };
|
||||
static uint8_t cpu_hljmp_arr[1] = { CPU_PC_FROM_HL_GET_INSTRUCTION };
|
||||
static uint8_t cpu_sp_from_hl_arr[2] = { CPU_SP_FROM_HL, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_absjmp_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_PCL_FROM_TMP_PCH_READ8_PC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_absjmpnz_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPNZ_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_absjmpnc_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPNC_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_absjmpz_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPZ_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_absjmpc_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPC_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_nop_arr[1] = { CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_sub_arr[1] = { CPU_GET_SUBINSTRUCTION };
|
||||
static const uint8_t cpu_hljmp_arr[1] = { CPU_PC_FROM_HL_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_sp_from_hl_arr[2] = { CPU_SP_FROM_HL, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_absjmp_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_PCL_FROM_TMP_PCH_READ8_PC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_absjmpnz_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPNZ_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_absjmpnc_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPNC_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_absjmpz_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPZ_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_absjmpc_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_JPC_CHK, CPU_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_abscall_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_abscallnz_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CNZ_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_abscallnc_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CNC_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_abscallz_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CZ_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_abscallc_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CC_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_abscall_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_abscallnz_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CNZ_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_abscallnc_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CNC_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_abscallz_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CZ_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_abscallc_arr[6] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC_CC_CHK, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_T16, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_ret_arr[4] = { CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_reti_arr[4] = { CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_EI_GET_INSTRUCTION };
|
||||
static uint8_t cpu_retnz_arr[5] = { CPU_RET_NZ_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_retnc_arr[5] = { CPU_RET_NC_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_retz_arr[5] = { CPU_RET_Z_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_retc_arr[5] = { CPU_RET_C_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ret_arr[4] = { CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_reti_arr[4] = { CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_EI_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_retnz_arr[5] = { CPU_RET_NZ_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_retnc_arr[5] = { CPU_RET_NC_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_retz_arr[5] = { CPU_RET_Z_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_retc_arr[5] = { CPU_RET_C_CHK, CPU_TMP_READ8_SP_INC, CPU_PCL_FROM_TMP_PCH_READ8_SP_INC, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_rst00_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_00, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst08_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_08, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst10_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_10, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst18_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_18, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst20_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_20, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst28_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_28, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst30_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_30, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst38_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_38, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst40_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_40, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst48_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_48, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst50_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_50, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst58_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_58, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_rst60_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_60, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst00_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_00, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst08_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_08, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst10_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_10, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst18_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_18, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst20_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_20, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst28_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_28, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst30_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_30, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst38_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_38, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst40_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_40, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst48_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_48, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst50_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_50, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst58_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_58, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_rst60_arr[5] = { CPU_DELAY_CYCLE, CPU_DELAY_CYCLE, CPU_SP_WRITE8_PCH_DEC, CPU_SP_WRITE8_PCL_DEC_PC_FROM_60, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_push_bc_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_B_DEC, CPU_SP_WRITE8_C_DEC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_push_de_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_D_DEC, CPU_SP_WRITE8_E_DEC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_push_hl_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_H_DEC, CPU_SP_WRITE8_L_DEC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_push_af_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_A_DEC, CPU_SP_WRITE8_F_DEC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_push_bc_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_B_DEC, CPU_SP_WRITE8_C_DEC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_push_de_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_D_DEC, CPU_SP_WRITE8_E_DEC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_push_hl_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_H_DEC, CPU_SP_WRITE8_L_DEC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_push_af_arr[4] = { CPU_DELAY_CYCLE, CPU_SP_WRITE8_A_DEC, CPU_SP_WRITE8_F_DEC, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_pop_bc_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_C_FROM_TMP_B_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_pop_de_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_E_FROM_TMP_D_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_pop_hl_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_L_FROM_TMP_H_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_pop_af_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_F_FROM_TMP_A_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_pop_bc_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_C_FROM_TMP_B_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_pop_de_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_E_FROM_TMP_D_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_pop_hl_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_L_FROM_TMP_H_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_pop_af_arr[3] = { CPU_TMP_READ8_SP_INC, CPU_F_FROM_TMP_A_READ8_SP_INC, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_ld_a_arr[2] = { CPU_A_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_b_arr[2] = { CPU_B_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_c_arr[2] = { CPU_C_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_d_arr[2] = { CPU_D_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_e_arr[2] = { CPU_E_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_h_arr[2] = { CPU_H_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_l_arr[2] = { CPU_L_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_a_arr[2] = { CPU_A_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_b_arr[2] = { CPU_B_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_c_arr[2] = { CPU_C_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_d_arr[2] = { CPU_D_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_e_arr[2] = { CPU_E_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_h_arr[2] = { CPU_H_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_l_arr[2] = { CPU_L_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_ldhc_a_arr[2] = { CPU_C_READHIGH_A, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ldhc_a_arr[2] = { CPU_C_READHIGH_A, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_ldh_a_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_TMP_READHIGH_A, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ldh_a_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_TMP_READHIGH_A, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_ld_bc_arr[3] = { CPU_C_READ8_PC_INC, CPU_B_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_de_arr[3] = { CPU_E_READ8_PC_INC, CPU_D_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_hl_arr[3] = { CPU_L_READ8_PC_INC, CPU_H_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_sp_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_SPL_FROM_TMP_SPH_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_bc_arr[3] = { CPU_C_READ8_PC_INC, CPU_B_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_de_arr[3] = { CPU_E_READ8_PC_INC, CPU_D_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_hl_arr[3] = { CPU_L_READ8_PC_INC, CPU_H_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_sp_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_SPL_FROM_TMP_SPH_READ8_PC_INC, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_ld16_a_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_A_READ8_TMP16, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld16_a_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_A_READ8_TMP16, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_st_a_arr[2] = { CPU_A_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_st_b_arr[2] = { CPU_B_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_st_c_arr[2] = { CPU_C_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_st_d_arr[2] = { CPU_D_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_st_e_arr[2] = { CPU_E_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_st_h_arr[2] = { CPU_H_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_st_l_arr[2] = { CPU_L_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_a_arr[2] = { CPU_A_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_b_arr[2] = { CPU_B_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_c_arr[2] = { CPU_C_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_d_arr[2] = { CPU_D_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_e_arr[2] = { CPU_E_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_h_arr[2] = { CPU_H_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_l_arr[2] = { CPU_L_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_st_imm_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st_imm_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_sthc_a_arr[2] = { CPU_C_WRITEHIGH_A, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_sth_a_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_TMP_WRITEHIGH_A, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_sthc_a_arr[2] = { CPU_C_WRITEHIGH_A, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_sth_a_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_TMP_WRITEHIGH_A, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_st16_a_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_A_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st16_a_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_A_ACTION_WRITE, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_st16_sp_arr[5] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_TMP16_WRITE8_SPL_INC, CPU_TMP16_WRITE8_SPH, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_st16_sp_arr[5] = { CPU_TMP_READ8_PC_INC, CPU_T16L_FROM_TMP_T16H_READ8_PC_INC, CPU_TMP16_WRITE8_SPL_INC, CPU_TMP16_WRITE8_SPH, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_jr_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_jrnz_arr[3] = { CPU_TMP_READ8_PC_INC_JRNZ_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_jrz_arr[3] = { CPU_TMP_READ8_PC_INC_JRZ_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_jrnc_arr[3] = { CPU_TMP_READ8_PC_INC_JRNC_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_jrc_arr[3] = { CPU_TMP_READ8_PC_INC_JRC_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_jr_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_jrnz_arr[3] = { CPU_TMP_READ8_PC_INC_JRNZ_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_jrz_arr[3] = { CPU_TMP_READ8_PC_INC_JRZ_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_jrnc_arr[3] = { CPU_TMP_READ8_PC_INC_JRNC_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_jrc_arr[3] = { CPU_TMP_READ8_PC_INC_JRC_CHK, CPU_TMP_ADD_PC, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_di_arr[1] = { CPU_DI_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ei_arr[1] = { CPU_GET_INSTRUCTION_EI };
|
||||
static uint8_t cpu_scf_arr[1] = { CPU_SCF_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ccf_arr[1] = { CPU_CCF_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_di_arr[1] = { CPU_DI_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ei_arr[1] = { CPU_GET_INSTRUCTION_EI };
|
||||
static const uint8_t cpu_scf_arr[1] = { CPU_SCF_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ccf_arr[1] = { CPU_CCF_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_add_bc_arr[2] = { CPU_BC_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_add_de_arr[2] = { CPU_DE_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_add_hl_arr[2] = { CPU_HL_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_add_sp_arr[2] = { CPU_SP_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_ld_hl_add_sp_imm_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_HL_ADD_SPECIAL, CPU_GET_INSTRUCTION };
|
||||
static uint8_t cpu_add_sp_imm_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_SP_ADD_SPECIAL, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_add_bc_arr[2] = { CPU_BC_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_add_de_arr[2] = { CPU_DE_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_add_hl_arr[2] = { CPU_HL_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_add_sp_arr[2] = { CPU_SP_ACTION_ADD, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_ld_hl_add_sp_imm_arr[3] = { CPU_TMP_READ8_PC_INC, CPU_HL_ADD_SPECIAL, CPU_GET_INSTRUCTION };
|
||||
static const uint8_t cpu_add_sp_imm_arr[4] = { CPU_TMP_READ8_PC_INC, CPU_SP_ADD_SPECIAL, CPU_DELAY_CYCLE, CPU_GET_INSTRUCTION };
|
||||
|
||||
static uint8_t cpu_start_arr[1] = { CPU_GET_INSTRUCTION };
|
||||
static uint8_t *cpu_action_arr = cpu_start_arr;
|
||||
static uint8_t cpu_arr_pos = 0;
|
||||
static inline void cpuSetNopArr()
|
||||
{
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
}
|
||||
|
||||
static uint8_t *cpu_instr_arr[256] = {
|
||||
static const uint8_t *cpu_instr_arr[256] = {
|
||||
cpu_nop_arr, cpu_ld_bc_arr, cpu_st_a_arr, cpu_imm_delay_arr, //0x00-0x03
|
||||
cpu_imm_b_arr, cpu_imm_b_arr, cpu_ld_b_arr, cpu_imm_a_arr, //0x04-0x07
|
||||
cpu_st16_sp_arr, cpu_add_bc_arr, cpu_imm_bc_arr, cpu_imm_delay_arr, //0x08-0x0B
|
||||
@ -953,7 +973,7 @@ typedef void (*cpu_action_t)(uint8_t*);
|
||||
static cpu_action_t cpu_actions_arr[256];
|
||||
static cpu_action_t cpu_action_func;
|
||||
|
||||
void cpuSetupActionArr()
|
||||
static void cpuSetupActionArr()
|
||||
{
|
||||
cpu_actions_arr[0x00] = cpuNoAction; cpu_actions_arr[0x01] = cpuNoAction; cpu_actions_arr[0x02] = cpuSTbc; cpu_actions_arr[0x03] = cpuBcInc;
|
||||
cpu_actions_arr[0x04] = cpuInc; cpu_actions_arr[0x05] = cpuDec; cpu_actions_arr[0x06] = cpuNoAction; cpu_actions_arr[0x07] = cpuRLCA;
|
||||
@ -1085,7 +1105,7 @@ bool cpuHandleIrqUpdates()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static uint8_t curInstr;
|
||||
|
||||
void cpuGetInstruction()
|
||||
{
|
||||
if(cpuHandleIrqUpdates())
|
||||
@ -1102,8 +1122,7 @@ void cpuGetInstruction()
|
||||
//if(!gbsInitRet)
|
||||
// printf("Init return\n");
|
||||
gbsInitRet = true; //allow play call
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
cpuSetNopArr();
|
||||
return;
|
||||
} //play return
|
||||
else if(pc == 0x8765)
|
||||
@ -1111,15 +1130,13 @@ void cpuGetInstruction()
|
||||
//if(!gbsPlayRet)
|
||||
// printf("Play return\n");
|
||||
gbsPlayRet = true; //allow next play call
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
cpuSetNopArr();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(cpuHaltLoop)
|
||||
{
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
cpuSetNopArr();
|
||||
//happens when IME=0
|
||||
if(!irqEnable && memGetCurIrqList())
|
||||
cpuHaltLoop = false;
|
||||
@ -1132,19 +1149,18 @@ void cpuGetInstruction()
|
||||
if(cpuInAny && !cpuPrevInAny)
|
||||
cpuStopLoop = false;
|
||||
cpuPrevInAny = cpuInAny;
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
cpuSetNopArr();
|
||||
return;
|
||||
}
|
||||
curInstr = memGet8(pc);
|
||||
cpu_action_arr = cpu_instr_arr[curInstr];
|
||||
cpu_arr_pos = 0;
|
||||
if(cpu_action_arr == NULL)
|
||||
{
|
||||
printf("CPU Error: Unsupported Instruction at %04x:%02x!\n", pc-1,curInstr);
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpuSetNopArr();
|
||||
cpuSetStopLoop();
|
||||
}
|
||||
cpu_arr_pos = 0;
|
||||
cpu_action_func = cpu_actions_arr[curInstr];
|
||||
|
||||
//if(pc==0xABC || pc == 0xAC1 || pc == 0x5E0E || pc == 0x5E0F)
|
||||
@ -1154,8 +1170,6 @@ void cpuGetInstruction()
|
||||
cpuHaltBug = false;
|
||||
}
|
||||
|
||||
static bool cpu_oam_dma_started = false;
|
||||
static uint8_t cpu_oam_dma_pos = 0;
|
||||
static void cpuHandleOAMDMA()
|
||||
{
|
||||
if(cpu_oam_dma)
|
||||
@ -1184,7 +1198,6 @@ static void cpuHandleOAMDMA()
|
||||
}
|
||||
|
||||
/* Main CPU Interpreter */
|
||||
bool cpuDmaHalt = false;
|
||||
|
||||
void cpuCycle()
|
||||
{
|
||||
@ -1233,7 +1246,7 @@ void cpuCycle()
|
||||
break;
|
||||
default: //should never happen
|
||||
printf("CPU Error: Unknown sub %02x\n", sub_instr);
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpuSetNopArr();
|
||||
cpuSetStopLoop();
|
||||
break;
|
||||
}
|
||||
@ -1703,8 +1716,7 @@ void cpuPlayGBS()
|
||||
a = 0, b = 0, c = 0, d = 0, e = 0;//, h = 0, l = 0;
|
||||
//jump to play
|
||||
pc = gbsPlayAddr;
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
cpuSetNopArr();
|
||||
//printf("Playback Start at %04x\n", pc);
|
||||
}
|
||||
extern uint8_t gbsTMA, gbsTAC;
|
||||
@ -1731,7 +1743,6 @@ void cpuLoadGBS(uint8_t song)
|
||||
a = song;
|
||||
pc = gbsInitAddr;
|
||||
//start getting instructions
|
||||
cpu_action_arr = cpu_nop_arr;
|
||||
cpu_arr_pos = 0;
|
||||
cpuSetNopArr();
|
||||
//printf("Init Start at %04x\n", pc);
|
||||
}
|
||||
|
@ -32,10 +32,6 @@ extern uint32_t textureImage[0x5A00];
|
||||
extern volatile bool emuRenderFrame;
|
||||
extern const char *VERSION_STRING;
|
||||
|
||||
void memLoadSave()
|
||||
{
|
||||
|
||||
}
|
||||
void memSaveGame()
|
||||
{
|
||||
|
||||
@ -196,12 +192,17 @@ unsigned retro_get_region()
|
||||
return RETRO_REGION_NTSC;
|
||||
}
|
||||
|
||||
extern bool emuSaveEnabled;
|
||||
extern char emuSaveName[1024];
|
||||
extern size_t extTotalSize;
|
||||
void *retro_get_memory_data(unsigned id)
|
||||
{
|
||||
switch(id & RETRO_MEMORY_MASK)
|
||||
{
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
return Ext_Mem;
|
||||
if(emuSaveName[0] && emuSaveEnabled && extTotalSize)
|
||||
return Ext_Mem;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -211,7 +212,9 @@ size_t retro_get_memory_size(unsigned id)
|
||||
switch(id & RETRO_MEMORY_MASK)
|
||||
{
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
return sizeof(Ext_Mem);
|
||||
if(emuSaveName[0] && emuSaveEnabled && extTotalSize)
|
||||
return extTotalSize;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
151
main.c
151
main.c
@ -32,7 +32,7 @@
|
||||
#define DEBUG_KEY 0
|
||||
#define DEBUG_LOAD_INFO 1
|
||||
|
||||
const char *VERSION_STRING = "fixGB Alpha v0.8.1";
|
||||
const char *VERSION_STRING = "fixGB Alpha v0.8.2";
|
||||
static char window_title[256];
|
||||
static char window_title_pause[256];
|
||||
|
||||
@ -49,7 +49,7 @@ enum {
|
||||
static void gbEmuFileOpen(const char *name);
|
||||
static bool gbEmuFileRead();
|
||||
static void gbEmuFileClose();
|
||||
|
||||
static void gbEmuResetRegs();
|
||||
static void gbEmuDisplayFrame(void);
|
||||
void gbEmuMainLoop(void);
|
||||
void gbEmuDeinit(void);
|
||||
@ -59,30 +59,41 @@ static void gbEmuHandleKeyUp(unsigned char key, int x, int y);
|
||||
static void gbEmuHandleSpecialDown(int key, int x, int y);
|
||||
static void gbEmuHandleSpecialUp(int key, int x, int y);
|
||||
|
||||
static int emuFileType = FTYPE_UNK;
|
||||
volatile bool emuRenderFrame;
|
||||
|
||||
static int emuFileType;
|
||||
static char emuFileName[1024];
|
||||
uint8_t *emuGBROM = NULL;
|
||||
uint32_t emuGBROMsize = 0;
|
||||
uint32_t emuGBROMsize;
|
||||
char emuSaveName[1024];
|
||||
bool emuSaveEnabled;
|
||||
//used externally
|
||||
uint32_t textureImage[0x5A00];
|
||||
bool gbPause = false;
|
||||
bool gbEmuGBSPlayback = false;
|
||||
bool gbsTimerMode = false;
|
||||
uint16_t gbsLoadAddr = 0;
|
||||
uint16_t gbsInitAddr = 0;
|
||||
uint16_t gbsPlayAddr = 0;
|
||||
uint32_t gbsRomSize = 0;
|
||||
uint16_t gbsSP = 0;
|
||||
uint8_t gbsTracksTotal = 0, gbsTMA = 0, gbsTAC = 0;
|
||||
uint8_t cpuTimer = 3;
|
||||
bool gbCgbGame = false;
|
||||
bool gbCgbMode = false;
|
||||
bool gbCgbBootrom = false;
|
||||
bool gbAllowInvVRAM = false;
|
||||
bool gbPause;
|
||||
bool gbEmuGBSPlayback;
|
||||
bool gbsTimerMode;
|
||||
uint16_t gbsLoadAddr;
|
||||
uint16_t gbsInitAddr;
|
||||
uint16_t gbsPlayAddr;
|
||||
uint32_t gbsRomSize;
|
||||
uint16_t gbsSP;
|
||||
uint8_t gbsTracksTotal, gbsTMA, gbsTAC;
|
||||
uint8_t cpuTimer;
|
||||
bool gbCgbGame;
|
||||
bool gbCgbMode;
|
||||
bool gbCgbBootrom;
|
||||
bool gbAllowInvVRAM;
|
||||
bool gbIsMulticart;
|
||||
|
||||
static bool inPause = false;
|
||||
static bool inResize = false;
|
||||
static bool inPause;
|
||||
static bool inResize;
|
||||
|
||||
//used externally
|
||||
bool emuSkipVsync;
|
||||
bool emuSkipFrame;
|
||||
|
||||
static uint8_t mainClock;
|
||||
static uint8_t memClock;
|
||||
|
||||
#if WINDOWS_BUILD
|
||||
#include <windows.h>
|
||||
@ -104,15 +115,28 @@ static DWORD emuMainTotalElapsed = 0;
|
||||
#define VISIBLE_DOTS 160
|
||||
#define VISIBLE_LINES 144
|
||||
|
||||
static uint32_t linesToDraw = VISIBLE_LINES;
|
||||
static uint32_t linesToDraw;
|
||||
static const uint32_t visibleImg = VISIBLE_DOTS*VISIBLE_LINES*4;
|
||||
static uint8_t scaleFactor = 3;
|
||||
static uint8_t scaleFactor;
|
||||
#ifndef __LIBRETRO__
|
||||
static uint32_t mainLoopRuns;
|
||||
static uint16_t mainLoopPos;
|
||||
#endif
|
||||
|
||||
static FILE *gbEmuFilePointer = NULL;
|
||||
#if ZIPSUPPORT
|
||||
static bool gbEmuFileIsZip;
|
||||
static uint8_t *gbEmuZipBuf = NULL;
|
||||
static uint32_t gbEmuZipLen;
|
||||
static unzFile gbEmuZipObj;
|
||||
static unz_file_info gbEmuZipObjInfo;
|
||||
#endif
|
||||
|
||||
//from input.c
|
||||
extern uint8_t inValReads[8];
|
||||
//from mbc.c
|
||||
extern bool rtcUsed;
|
||||
extern size_t extTotalSize;
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
int gbEmuLoadGame(const char* filename)
|
||||
@ -124,11 +148,7 @@ int main(int argc, char** argv)
|
||||
{
|
||||
#endif
|
||||
puts(VERSION_STRING);
|
||||
strcpy(window_title, VERSION_STRING);
|
||||
memset(textureImage,0,visibleImg);
|
||||
emuFileType = FTYPE_UNK;
|
||||
memset(emuFileName,0,1024);
|
||||
memset(emuSaveName,0,1024);
|
||||
gbEmuResetRegs();
|
||||
if(argc >= 2)
|
||||
gbEmuFileOpen(argv[1]);
|
||||
if(emuFileType == FTYPE_GB || emuFileType == FTYPE_GBC)
|
||||
@ -170,6 +190,8 @@ int main(int argc, char** argv)
|
||||
gbCgbGame = (emuGBROM[0x143] == 0x80 || emuGBROM[0x143] == 0xC0);
|
||||
gbCgbMode = (gbCgbGame || gbCgbBootrom);
|
||||
printf("Main: CGB Regs are %sallowed\n", gbCgbMode?"":"dis");
|
||||
//Quick multicart check
|
||||
gbIsMulticart = (emuGBROMsize == 0x200000 && strcmp((char*)(emuGBROM+0x134), "QBILLION") == 0);
|
||||
if(!memInit(true,false))
|
||||
{
|
||||
free(emuGBROM);
|
||||
@ -317,14 +339,59 @@ int main(int argc, char** argv)
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static FILE *gbEmuFilePointer = NULL;
|
||||
static void gbEmuResetRegs()
|
||||
{
|
||||
strcpy(window_title, VERSION_STRING);
|
||||
|
||||
emuRenderFrame = false;
|
||||
linesToDraw = VISIBLE_LINES;
|
||||
scaleFactor = 3;
|
||||
|
||||
memset(textureImage,0,visibleImg);
|
||||
emuFileType = FTYPE_UNK;
|
||||
memset(emuFileName,0,1024);
|
||||
memset(emuSaveName,0,1024);
|
||||
emuSaveEnabled = false;
|
||||
if(emuGBROM)
|
||||
free(emuGBROM);
|
||||
emuGBROM = NULL;
|
||||
emuGBROMsize = 0;
|
||||
|
||||
gbPause = false;
|
||||
gbEmuGBSPlayback = false;
|
||||
gbsTimerMode = false;
|
||||
gbsLoadAddr = 0, gbsInitAddr = 0;
|
||||
gbsPlayAddr = 0, gbsRomSize = 0;
|
||||
gbsSP = 0;
|
||||
gbsTracksTotal = 0, gbsTMA = 0, gbsTAC = 0;
|
||||
cpuTimer = 3;
|
||||
gbCgbGame = false;
|
||||
gbCgbMode = false;
|
||||
gbCgbBootrom = false;
|
||||
gbAllowInvVRAM = false;
|
||||
gbIsMulticart = false;
|
||||
|
||||
inPause = false;
|
||||
inResize = false;
|
||||
|
||||
emuSkipVsync = false;
|
||||
emuSkipFrame = false;
|
||||
|
||||
mainClock = 0;
|
||||
memClock = 0;
|
||||
|
||||
if(gbEmuFilePointer)
|
||||
fclose(gbEmuFilePointer);
|
||||
gbEmuFilePointer = NULL;
|
||||
#if ZIPSUPPORT
|
||||
static bool gbEmuFileIsZip = false;
|
||||
static uint8_t *gbEmuZipBuf = NULL;
|
||||
static uint32_t gbEmuZipLen = 0;
|
||||
static unzFile gbEmuZipObj;
|
||||
static unz_file_info gbEmuZipObjInfo;
|
||||
gbEmuFileIsZip = false;
|
||||
if(gbEmuZipBuf)
|
||||
free(gbEmuZipBuf);
|
||||
gbEmuZipBuf = NULL;
|
||||
gbEmuZipLen = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int gbEmuGetFileType(const char *name)
|
||||
{
|
||||
int nLen = strlen(name);
|
||||
@ -487,8 +554,6 @@ static void gbEmuFileClose()
|
||||
gbEmuFilePointer = NULL;
|
||||
}
|
||||
|
||||
volatile bool emuRenderFrame = false;
|
||||
|
||||
void gbEmuDeinit(void)
|
||||
{
|
||||
//printf("\n");
|
||||
@ -498,17 +563,19 @@ void gbEmuDeinit(void)
|
||||
if(emuGBROM != NULL)
|
||||
free(emuGBROM);
|
||||
emuGBROM = NULL;
|
||||
#ifndef __LIBRETRO__
|
||||
memSaveGame();
|
||||
#endif
|
||||
emuFileType = FTYPE_UNK;
|
||||
memset(emuFileName,0,1024);
|
||||
memset(emuSaveName,0,1024);
|
||||
extTotalSize = 0;
|
||||
rtcUsed = false;
|
||||
memDeinit();
|
||||
gbIsMulticart = false;
|
||||
//printf("Bye!\n");
|
||||
}
|
||||
|
||||
//used externally
|
||||
bool emuSkipVsync = false;
|
||||
bool emuSkipFrame = false;
|
||||
|
||||
static uint8_t mainClock = 0;
|
||||
static uint8_t memClock = 0;
|
||||
|
||||
void gbEmuMainLoop(void)
|
||||
{
|
||||
//do one scanline loop
|
||||
|
98
mbc.c
98
mbc.c
@ -14,26 +14,37 @@
|
||||
#include "mbc.h"
|
||||
|
||||
uint8_t Ext_Mem[0x20000];
|
||||
static bool RamIOAllowed = false;
|
||||
set8FuncT mbcSet8;
|
||||
set8FuncT mbcSetRAM8;
|
||||
get8FuncT mbcGetRAM8;
|
||||
|
||||
static uint8_t rtcReg = 0;
|
||||
uint16_t cBank = 1;
|
||||
uint16_t extBank = 0;
|
||||
uint16_t bankMask = 0;
|
||||
uint16_t extMask = 0;
|
||||
uint16_t extAddrMask = 0;
|
||||
size_t extTotalSize = 0;
|
||||
//multicart regs
|
||||
uint16_t tBank0;
|
||||
uint16_t tBank1;
|
||||
uint16_t oBank;
|
||||
uint16_t iBank;
|
||||
uint16_t oBankAnd;
|
||||
uint16_t iBankAnd;
|
||||
uint8_t mcState;
|
||||
bool mcLocked;
|
||||
|
||||
bool extMemEnabled = false;
|
||||
bool bankUsed = false;
|
||||
bool extSelect = false;
|
||||
bool rtcUsed = false;
|
||||
bool rtcEnabled = false;
|
||||
//normal regs
|
||||
uint8_t rtcReg;
|
||||
uint16_t cBank;
|
||||
uint16_t extBank;
|
||||
uint16_t bankMask;
|
||||
uint16_t extMask;
|
||||
uint16_t extAddrMask;
|
||||
size_t extTotalSize;
|
||||
|
||||
static uint8_t lastRTCval = 0;
|
||||
bool RamIOAllowed;
|
||||
bool extMemEnabled;
|
||||
bool bankUsed;
|
||||
bool extSelect;
|
||||
bool rtcUsed;
|
||||
bool rtcEnabled;
|
||||
|
||||
uint8_t lastRTCval;
|
||||
|
||||
//used in for example VBA
|
||||
static struct RTCSave_t {
|
||||
@ -52,6 +63,7 @@ static struct RTCSave_t {
|
||||
|
||||
static void noSet8(uint16_t addr, uint8_t val);
|
||||
static void mbc1Set8(uint16_t addr, uint8_t val);
|
||||
static void mbc1mcSet8(uint16_t addr, uint8_t val);
|
||||
static void mbc2Set8(uint16_t addr, uint8_t val);
|
||||
static void mbc3Set8(uint16_t addr, uint8_t val);
|
||||
static void mbc5Set8(uint16_t addr, uint8_t val);
|
||||
@ -69,9 +81,12 @@ static void mbc2SetExtRAM8(uint16_t addr, uint8_t val);
|
||||
static uint8_t mbcGetNoExtRAM8(uint16_t addr);
|
||||
static void mbcSetNoExtRAM8(uint16_t addr, uint8_t val);
|
||||
|
||||
extern bool gbIsMulticart;
|
||||
void mbcInit(uint8_t type)
|
||||
{
|
||||
if(type == MBC_TYPE_1)
|
||||
if(gbIsMulticart)
|
||||
mbcSet8 = mbc1mcSet8;
|
||||
else if(type == MBC_TYPE_1)
|
||||
mbcSet8 = mbc1Set8;
|
||||
else if(type == MBC_TYPE_2)
|
||||
mbcSet8 = mbc2Set8;
|
||||
@ -127,6 +142,30 @@ void mbcInit(uint8_t type)
|
||||
mbcExtRAMInit(type);
|
||||
}
|
||||
|
||||
void mbcResetRegs()
|
||||
{
|
||||
//multicart regs
|
||||
tBank0 = 0, tBank1 = 1;
|
||||
oBank = 0, iBank = 1;
|
||||
oBankAnd = 0x20, iBankAnd = 0x3F;
|
||||
mcState = 0, mcLocked = false;
|
||||
//normal regs
|
||||
rtcReg = 0;
|
||||
cBank = 1;
|
||||
bankMask = 1;
|
||||
extBank = 0;
|
||||
extMask = 0;
|
||||
extAddrMask = 0;
|
||||
extTotalSize = 0;
|
||||
RamIOAllowed = false;
|
||||
extMemEnabled = false;
|
||||
bankUsed = false;
|
||||
extSelect = false;
|
||||
rtcUsed = false;
|
||||
rtcEnabled = false;
|
||||
lastRTCval = 0;
|
||||
}
|
||||
|
||||
static void noSet8(uint16_t addr, uint8_t val)
|
||||
{
|
||||
(void)addr;
|
||||
@ -176,6 +215,35 @@ static void mbc1Set8(uint16_t addr, uint8_t val)
|
||||
extSelect = !!val;
|
||||
}
|
||||
|
||||
static void mbc1mcSet8(uint16_t addr, uint8_t val)
|
||||
{
|
||||
if(addr >= 0x2000 && addr < 0x4000)
|
||||
{
|
||||
iBank = val&0x3F;
|
||||
if(iBank == 0)
|
||||
iBank |= 1;
|
||||
tBank1 = ((oBank&oBankAnd)<<1)+(iBank&iBankAnd);
|
||||
}
|
||||
else if(addr >= 0x6000 && addr < 0x8000 && !mcLocked)
|
||||
{
|
||||
if(mcState == 0)
|
||||
{
|
||||
oBank = val&0x3F;
|
||||
tBank0 = ((oBank&oBankAnd)<<1);
|
||||
tBank1 = ((oBank&oBankAnd)<<1)+(iBank&iBankAnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
iBankAnd=(~(val<<1))&0x3F;
|
||||
oBankAnd=0x20|(val&0x1F);
|
||||
tBank0 = ((oBank&oBankAnd)<<1);
|
||||
tBank1 = ((oBank&oBankAnd)<<1)+(iBank&iBankAnd);
|
||||
mcLocked = !!(val&0x20);
|
||||
}
|
||||
mcState^=1;
|
||||
}
|
||||
}
|
||||
|
||||
static void mbc2Set8(uint16_t addr, uint8_t val)
|
||||
{
|
||||
if(addr < 0x2000 && ((addr&0x100) == 0))
|
||||
|
1
mbc.h
1
mbc.h
@ -20,6 +20,7 @@ enum {
|
||||
};
|
||||
|
||||
void mbcInit(uint8_t type);
|
||||
void mbcResetRegs();
|
||||
size_t mbcRTCSize();
|
||||
void mbcRTCInit();
|
||||
void mbcRTCLoad(FILE *f);
|
||||
|
61
mem.c
61
mem.c
@ -35,6 +35,7 @@ static uint8_t timerReg;
|
||||
static uint8_t timerRegVal;
|
||||
static uint8_t timerResetVal;
|
||||
static uint16_t timerRegBit;
|
||||
static bool timerPrevTicked;
|
||||
static uint8_t sioTimerRegClock;
|
||||
static uint8_t sioTimerRegTimer;
|
||||
static uint8_t sioBitsTransfered;
|
||||
@ -48,15 +49,26 @@ static bool cgbDmaHBlankMode;
|
||||
static bool cgbBootromEnabled = false;
|
||||
static bool timerRegEnable = false;
|
||||
static bool sioTimerRegEnable = false;
|
||||
static bool emuSaveEnabled = false;
|
||||
|
||||
//from main.c
|
||||
extern bool gbCgbGame;
|
||||
extern bool gbCgbMode;
|
||||
extern bool gbCgbBootrom;
|
||||
extern uint8_t *emuGBROM;
|
||||
extern bool gbIsMulticart;
|
||||
|
||||
//from mbc.c
|
||||
//multicart regs
|
||||
extern uint16_t tBank0;
|
||||
extern uint16_t tBank1;
|
||||
extern uint16_t oBank;
|
||||
extern uint16_t iBank;
|
||||
extern uint16_t oBankAnd;
|
||||
extern uint16_t iBankAnd;
|
||||
extern uint8_t mcState;
|
||||
extern bool mcLocked;
|
||||
//normal regs
|
||||
extern uint8_t rtcReg;
|
||||
extern uint16_t cBank;
|
||||
extern uint16_t extBank;
|
||||
extern uint16_t bankMask;
|
||||
@ -72,16 +84,21 @@ extern bool cpuDoStopSwitch;
|
||||
extern uint8_t ppuCgbBank;
|
||||
|
||||
//from mbc.c
|
||||
extern bool RamIOAllowed;
|
||||
extern bool extMemEnabled;
|
||||
extern bool bankUsed;
|
||||
extern bool extSelect;
|
||||
extern bool rtcUsed;
|
||||
extern bool rtcEnabled;
|
||||
extern uint8_t lastRTCval;
|
||||
|
||||
static get8FuncT memGet8ptr[0x10000];
|
||||
static set8FuncT memSet8ptr[0x10000];
|
||||
static uint8_t memCGBBootrom[0x900];
|
||||
static uint8_t memGetROMBank8(uint16_t addr);
|
||||
static uint8_t memGetROMNoBank8(uint16_t addr);
|
||||
static uint8_t memGetROM0Multicart8(uint16_t addr);
|
||||
static uint8_t memGetROM1Multicart8(uint16_t addr);
|
||||
static uint8_t memGetBootROMNoBank8(uint16_t addr);
|
||||
static uint8_t memGetRAMBank8(uint16_t addr);
|
||||
static uint8_t memGetRAMNoBank8(uint16_t addr);
|
||||
@ -213,24 +230,17 @@ static void memSetExtVal()
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t curGBS = 0;
|
||||
static uint8_t curGBS;
|
||||
extern uint8_t gbsTracksTotal;
|
||||
extern uint32_t gbsRomSize;
|
||||
bool memInit(bool romcheck, bool gbs)
|
||||
{
|
||||
if(romcheck)
|
||||
{
|
||||
cBank = 1;
|
||||
bankMask = 1;
|
||||
extBank = 0;
|
||||
extMask = 0;
|
||||
extAddrMask = 0;
|
||||
extTotalSize = 0;
|
||||
bankUsed = false;
|
||||
extMemEnabled = false;
|
||||
rtcUsed = false;
|
||||
mbcResetRegs();
|
||||
if(gbs)
|
||||
{
|
||||
curGBS = 0;
|
||||
bankUsed = true;
|
||||
//Get ROM Size multiple
|
||||
if(gbsRomSize <= 0x8000)
|
||||
@ -422,6 +432,7 @@ bool memInit(bool romcheck, bool gbs)
|
||||
timerRegVal = 0;
|
||||
timerResetVal = 0;
|
||||
timerRegBit = (1<<9); //Freq 0
|
||||
timerPrevTicked = false;
|
||||
sioTimerRegClock = 1;
|
||||
sioTimerRegTimer = 32;
|
||||
sioBitsTransfered = 0;
|
||||
@ -438,6 +449,11 @@ bool memInit(bool romcheck, bool gbs)
|
||||
return true;
|
||||
}
|
||||
|
||||
void memDeinit()
|
||||
{
|
||||
cgbBootromEnabled = false;
|
||||
}
|
||||
|
||||
void memInitGetSetPointers()
|
||||
{
|
||||
//init memGet8 and memSet8 arrays
|
||||
@ -446,12 +462,12 @@ void memInitGetSetPointers()
|
||||
{
|
||||
if(addr < 0x4000) //0x0000 - 0x3FFF = Cartridge ROM
|
||||
{
|
||||
memGet8ptr[addr] = cgbBootromEnabled?memGetBootROMNoBank8:memGetROMNoBank8;
|
||||
memGet8ptr[addr] = cgbBootromEnabled?memGetBootROMNoBank8:(gbIsMulticart?memGetROM0Multicart8:memGetROMNoBank8);
|
||||
memSet8ptr[addr] = mbcSet8;
|
||||
}
|
||||
else if(addr < 0x8000) //0x4000 - 0x7FFF = Cartridge ROM (possibly banked)
|
||||
{
|
||||
memGet8ptr[addr] = bankUsed?memGetROMBank8:memGetROMNoBank8;
|
||||
memGet8ptr[addr] = gbIsMulticart?memGetROM1Multicart8:(bankUsed?memGetROMBank8:memGetROMNoBank8);
|
||||
memSet8ptr[addr] = mbcSet8;
|
||||
}
|
||||
else if(addr < 0xA000) //0x8000 - 0x9FFF = PPU VRAM
|
||||
@ -459,7 +475,7 @@ void memInitGetSetPointers()
|
||||
memGet8ptr[addr] = gbCgbMode?ppuGetVRAMBank8:ppuGetVRAMNoBank8;
|
||||
memSet8ptr[addr] = gbCgbMode?ppuSetVRAMBank8:ppuSetVRAMNoBank8;
|
||||
}
|
||||
else if(addr < 0xC000) //0xA000 - 0xBFFF = Cardridge RAM
|
||||
else if(addr < 0xC000) //0xA000 - 0xBFFF = Cartridge RAM
|
||||
{
|
||||
memGet8ptr[addr] = mbcGetRAM8;
|
||||
memSet8ptr[addr] = mbcSetRAM8;
|
||||
@ -627,6 +643,16 @@ static uint8_t memGetROMNoBank8(uint16_t addr)
|
||||
return emuGBROM[addr&0x7FFF];
|
||||
}
|
||||
|
||||
static uint8_t memGetROM0Multicart8(uint16_t addr)
|
||||
{
|
||||
return emuGBROM[(tBank0<<14)|(addr&0x3FFF)];
|
||||
}
|
||||
|
||||
static uint8_t memGetROM1Multicart8(uint16_t addr)
|
||||
{
|
||||
return emuGBROM[(tBank1<<14)|(addr&0x3FFF)];
|
||||
}
|
||||
|
||||
static uint8_t memGetBootROMNoBank8(uint16_t addr)
|
||||
{
|
||||
if(addr < 0x100 || (addr >= 0x200 && addr < 0x900))
|
||||
@ -871,14 +897,14 @@ void memDumpMainMem()
|
||||
ppuDumpMem();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __LIBRETRO__
|
||||
extern bool emuSaveEnabled;
|
||||
extern char emuSaveName[1024];
|
||||
void memLoadSave()
|
||||
{
|
||||
if(emuSaveName[0] && (extTotalSize || rtcUsed))
|
||||
{
|
||||
emuSaveEnabled = true;
|
||||
#ifndef __LIBRETRO__
|
||||
FILE *save = fopen(emuSaveName, "rb");
|
||||
if(save)
|
||||
{
|
||||
@ -895,9 +921,11 @@ void memLoadSave()
|
||||
printf("Mem: Done reading %s\n", emuSaveName);
|
||||
fclose(save);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __LIBRETRO__
|
||||
void memSaveGame()
|
||||
{
|
||||
if(emuSaveName[0] && ((emuSaveEnabled && extTotalSize) || rtcUsed))
|
||||
@ -919,7 +947,6 @@ void memSaveGame()
|
||||
extern bool gbEmuGBSPlayback;
|
||||
extern bool gbsTimerMode;
|
||||
extern uint8_t inValReads[8];
|
||||
static bool timerPrevTicked = false;
|
||||
//clocked at 262144 Hz (or 2x that in CGB Mode)
|
||||
void memClockTimers()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user