libgambatte: fix interrupt execution anatomy

This commit is contained in:
MrWint 2019-05-26 20:24:58 +02:00
parent 7e851b19f3
commit 1547d324e7
4 changed files with 55 additions and 49 deletions

View File

@ -277,8 +277,8 @@ void CPU::loadState(SaveState const &state) {
// push rr (16 cycles):
// Push value of register pair onto stack:
#define push_rr(r1, r2) do { \
PUSH(r1, r2); \
cycleCounter += 4; \
PUSH(r1, r2); \
} while (0)
// pop rr (12 cycles):
@ -461,8 +461,9 @@ void CPU::loadState(SaveState const &state) {
// rst n (16 Cycles):
// Push present address onto stack, jump to address n (one of 00h,08h,10h,18h,20h,28h,30h,38h):
#define rst_n(n) do { \
cycleCounter += 4; \
PUSH(pc >> 8, pc & 0xFF); \
PC_MOD(n); \
pc = n; \
} while (0)
// ret (16 cycles):
@ -475,9 +476,10 @@ void CPU::loadState(SaveState const &state) {
void CPU::process(unsigned long const cycles) {
mem_.setEndtime(cycleCounter_, cycles);
hitInterruptAddress = 0;
mem_.updateInput();
hitInterruptAddress = -1;
//unsigned char a = a_;
unsigned long cycleCounter = cycleCounter_;
@ -490,50 +492,51 @@ void CPU::process(unsigned long const cycles) {
cycleCounter += cycles + (-cycles & 3);
}
} else while (cycleCounter < mem_.nextEventTime()) {
unsigned char opcode = 0x00;
unsigned char opcode;
int FullPC = pc;
#ifdef DLLABLES
for (int i = 0; i < numInterruptAddresses; ++i) {
if (pc == (interruptAddresses[i] & 0xFFFF)) {
unsigned bank = interruptAddresses[i] >> 16;
if (pc >= 0x4000 && pc <= 0x7FFF)
FullPC |= mem_.curRomBank() << 16;
for (int i = 0; i < numInterruptAddresses; i++) {
if (FullPC == interruptAddresses[i]) {
hitInterruptAddress = interruptAddresses[i];
mem_.setEndtime(cycleCounter, 0);
break;
if (!bank || bank == mem_.curRomBank()) {
hitInterruptAddress = interruptAddresses[i];
mem_.setEndtime(cycleCounter, 0);
break;
}
}
}
if (!hitInterruptAddress)
{
if (tracecallback) {
int result[14];
result[0] = cycleCounter;
result[1] = pc;
result[2] = sp;
result[3] = a;
result[4] = b;
result[5] = c;
result[6] = d;
result[7] = e;
result[8] = toF(hf2, cf, zf);
result[9] = h;
result[10] = l;
result[11] = skip_;
PC_READ_FIRST(opcode);
result[12] = opcode;
result[13] = mem_.debugGetLY();
tracecallback((void *)result);
}
else {
PC_READ_FIRST(opcode);
}
if (hitInterruptAddress != -1)
break;
#endif
if (skip_) {
pc = (pc - 1) & 0xFFFF;
skip_ = false;
}
if (tracecallback) {
int result[14];
result[0] = cycleCounter;
result[1] = pc;
result[2] = sp;
result[3] = a;
result[4] = b;
result[5] = c;
result[6] = d;
result[7] = e;
result[8] = toF(hf2, cf, zf);
result[9] = h;
result[10] = l;
result[11] = skip_;
PC_READ_FIRST(opcode);
result[12] = opcode;
result[13] = mem_.debugGetLY();
tracecallback((void *)result);
}
else {
PC_READ_FIRST(opcode);
}
if (skip_) {
pc = (pc - 1) & 0xFFFF;
skip_ = false;
}
switch (opcode) {

View File

@ -48,6 +48,7 @@ Memory::Memory(unsigned short &sp, unsigned short &pc)
intreq_.setEventTime<intevent_blit>(144 * 456ul);
intreq_.setEventTime<intevent_end>(0);
}
Memory::~Memory() {
delete []bios_;
}
@ -166,11 +167,11 @@ unsigned long Memory::event(unsigned long cc) {
switch (intreq_.minEventId()) {
case intevent_unhalt:
intreq_.unhalt();
intreq_.setEventTime<intevent_unhalt>(disabled_time);
nontrivial_ff_write(0xFF04, 0, cc);
pc_ = (pc_ + 1) & 0xFFFF;
cc += 4;
intreq_.unhalt();
intreq_.setEventTime<intevent_unhalt>(disabled_time);
break;
case intevent_end:
intreq_.setEventTime<intevent_end>(disabled_time - 1);
@ -324,6 +325,7 @@ unsigned long Memory::event(unsigned long cc) {
} else
address = 0x50 + n;
updateIrqs(cc);
intreq_.ackIrq(n);
cc += 2;
@ -980,7 +982,6 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
if(cgbSwitching_) {
lcd_.copyCgbPalettesToDmg();
lcd_.setCgb(false);
cgbSwitching_ = false;
}
return;
case 0x51:
@ -1050,8 +1051,10 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
return;
case 0x6C:
ioamhram_[0x16C] = data | 0xFE;
cgbSwitching_ = true;
if (isCgb()) {
ioamhram_[0x16C] = data | 0xFE;
cgbSwitching_ = true;
}
return;
case 0x70:

View File

@ -139,7 +139,7 @@ void LCD::loadState(SaveState const &state, unsigned char const *const oamram) {
SpriteMapper::schedule(ppu_.lyCounter(), ppu_.now()));
eventTimes_.setm<memevent_lycirq>(lycIrq_.time());
eventTimes_.setm<memevent_m1irq>(
ppu_.lyCounter().nextFrameCycle(144 * 456, ppu_.now()));
ppu_.lyCounter().nextFrameCycle(144 * 456, ppu_.now()) - 2);
eventTimes_.setm<memevent_m2irq>(
mode2IrqSchedule(statReg_, ppu_.lyCounter(), ppu_.now()));
eventTimes_.setm<memevent_m0irq>(statReg_ & lcdstat_m0irqen
@ -230,7 +230,7 @@ void LCD::speedChange(unsigned long const cc) {
eventTimes_.set<event_ly>(ppu_.lyCounter().time());
eventTimes_.setm<memevent_spritemap>(SpriteMapper::schedule(ppu_.lyCounter(), cc));
eventTimes_.setm<memevent_lycirq>(lycIrq_.time());
eventTimes_.setm<memevent_m1irq>(ppu_.lyCounter().nextFrameCycle(144 * 456, cc));
eventTimes_.setm<memevent_m1irq>(ppu_.lyCounter().nextFrameCycle(144 * 456, cc) - 2);
eventTimes_.setm<memevent_m2irq>(mode2IrqSchedule(statReg_, ppu_.lyCounter(), cc));
if (eventTimes_(memevent_m0irq) != disabled_time
@ -458,7 +458,7 @@ void LCD::lcdcChange(unsigned const data, unsigned long const cc) {
SpriteMapper::schedule(ppu_.lyCounter(), cc));
eventTimes_.setm<memevent_lycirq>(lycIrq_.time());
eventTimes_.setm<memevent_m1irq>(
ppu_.lyCounter().nextFrameCycle(144 * 456, cc));
ppu_.lyCounter().nextFrameCycle(144 * 456, cc) - 2);
eventTimes_.setm<memevent_m2irq>(
mode2IrqSchedule(statReg_, ppu_.lyCounter(), cc));
if (statReg_ & lcdstat_m0irqen) {

Binary file not shown.