Skip to content

Commit

Permalink
Take into account the cycles spent during the interrupt prologue
Browse files Browse the repository at this point in the history
  • Loading branch information
LemonBoy committed Apr 6, 2013
1 parent d5c1034 commit 63b76fb
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 15 deletions.
2 changes: 1 addition & 1 deletion arm9/include/gbcpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ extern int cyclesToExecute;
void initCPU();
void enableInterrupts();
void disableInterrupts();
void handleInterrupts(int interruptTriggered);
int handleInterrupts(int interruptTriggered);
int runOpcode(int cycles);
16 changes: 6 additions & 10 deletions arm9/source/gameboy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ int mode2Cycles, mode3Cycles;
int scanlineCounter;
int doubleSpeed;

int fps;
int turbo;
int turboFrameSkip;
int frameskip;
Expand Down Expand Up @@ -146,13 +147,8 @@ void runEmul()
goto emuLoopStart;

int interruptTriggered = ioRam[0x0F] & ioRam[0xFF];
// Run another opcode before triggering an interrupt.
// Robocop 2 needs this.
if (interruptTriggered) {
if (!halt)
extraCycles += runOpcode(4);
handleInterrupts(interruptTriggered);
}
if (interruptTriggered)
extraCycles += handleInterrupts(interruptTriggered);
}
}

Expand Down Expand Up @@ -324,7 +320,7 @@ inline void updateTimers(int cycles)
timerCounter -= cycles;
while (timerCounter <= 0)
{
timerCounter = timerPeriod + timerCounter;
timerCounter += timerPeriod;
if ((++ioRam[0x05]) == 0)
{
requestInterrupt(TIMER);
Expand All @@ -334,9 +330,9 @@ inline void updateTimers(int cycles)
setEventCycles(timerCounter+timerPeriod*(255-ioRam[0x05]));
}
dividerCounter -= cycles;
if (dividerCounter <= 0)
while (dividerCounter <= 0)
{
dividerCounter = 256+dividerCounter;
dividerCounter += 256;
ioRam[0x04]++;
}
//setEventCycles(dividerCounter);
Expand Down
9 changes: 5 additions & 4 deletions arm9/source/gbcpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ DTCM_BSS
;
int halt;

u8 buttonsPressed = 0xff;
int fps;
int gbMode;

u8 opCycles[0x100]
Expand Down Expand Up @@ -116,7 +114,7 @@ void initCPU()
ime = 1; // Correct default value?

halt = 0;
doubleSpeed = 0;
setDoubleSpeed(0);

gbRegs.af.w = 0x11B0;
gbRegs.bc.w = 0x0013;
Expand Down Expand Up @@ -165,7 +163,7 @@ void disableInterrupts()
ime = 0;
}

void handleInterrupts(int interruptTriggered)
int handleInterrupts(int interruptTriggered)
{
if (interruptTriggered & VBLANK)
{
Expand Down Expand Up @@ -222,6 +220,9 @@ void handleInterrupts(int interruptTriggered)
ime = 0;
}
}

/* The interrupt prologue takes 20 cycles, take it into account */
return (ime) ? (20 << doubleSpeed) : 0;
}

const u8 reg8Offsets[] = {
Expand Down
2 changes: 2 additions & 0 deletions arm9/source/mmu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ bool biosExists = false;
bool biosEnabled = false;
bool biosOn = false;

u8 buttonsPressed = 0xff;

u8* memory[0x10]
#ifdef DS
DTCM_BSS
Expand Down

4 comments on commit 63b76fb

@Stewmath
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey this fixed Megaman's boss intros! But Robocop 2 is broken again. There seems to be a bit of a delay between requesting and executing interrupts, in which time an opcode or 2 can be executed. If I recall correctly, Robocop 2 needs to read 0x90 (or 144) from LY before the Vblank interrupt takes over.

@LemonBoy
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh nice :)
In the other comment I've written why Robocop2 wasn't working (tbh it didn't work before too). The vblank kicks in too early.
When GameYob passes blaarg's instr_timings test then I'm sure lots of games will be fixed :)

@Stewmath
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed, shouldn't this be the last line in handleInterrupts?

return (ime) ? 0 : (20 << doubleSpeed);

An interrupt was triggered if ime has been disabled since entering the function. Either way, MMV still works.

Edit: Unless ime was off in the first place... I guess another variable is needed.

@LemonBoy
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah, right :) that line should be executed before resetting the ime

Please sign in to comment.