GBHawk: controller IRQs enabled by write delayed 4 cycles

This commit is contained in:
alyosha-tas 2020-05-22 12:17:42 -04:00
parent f03fb06370
commit 78f0b9252d
4 changed files with 32 additions and 12 deletions

View File

@ -14,15 +14,13 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
OP };
}
private void INC_16(ushort srcL, ushort srcH)
private void INC_16(ushort src_l, ushort src_h)
{
cur_instr = new[]
{IDLE,
IDLE,
IDLE,
INC16,
srcL,
srcH,
INC16, src_l, src_h,
IDLE,
IDLE,
HALT_CHK,
@ -35,9 +33,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
{IDLE,
IDLE,
IDLE,
DEC16,
src_l,
src_h,
DEC16, src_l, src_h,
IDLE,
IDLE,
HALT_CHK,

View File

@ -18,6 +18,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool in_vblank;
public bool vblank_rise;
public bool controller_was_checked;
public bool delays_to_process;
public int controller_delay_cd;
public bool FrameAdvance(IController controller, bool render, bool rendersound)
{
@ -108,12 +110,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
if (delays_to_process) { process_delays(); }
}
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
timer.tick();
if (delays_to_process) { process_delays(); }
}
else
{
@ -121,10 +125,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
cpu.TotalExecutedCycles++;
timer.tick();
if (delays_to_process) { process_delays(); }
}
cpu.TotalExecutedCycles++;
timer.tick();
if (delays_to_process) { process_delays(); }
}
if (in_vblank && !in_vblank_old)
@ -186,6 +192,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
if (delays_to_process) { process_delays(); }
if (double_speed)
{
@ -193,17 +200,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
if (delays_to_process) { process_delays(); }
}
}
else
{
cpu.TotalExecutedCycles++;
timer.tick();
if (delays_to_process) { process_delays(); }
if (double_speed)
{
cpu.TotalExecutedCycles++;
timer.tick();
timer.tick();
if (delays_to_process) { process_delays(); }
}
}
@ -251,6 +261,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
REG_FF0F |= 0x10;
}
}
public void process_delays()
{
// triggering an interrupt with a write to the control register takes 4 cycles to trigger interrupt
controller_delay_cd--;
if (controller_delay_cd == 0)
{
if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
REG_FF0F |= 0x10;
delays_to_process = false;
}
}
// Switch Speed (GBC only)
public int SpeedFunc(int temp)

View File

@ -38,6 +38,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(controller_was_checked), ref controller_was_checked);
ser.Sync(nameof(GB_bios_register), ref GB_bios_register);
ser.Sync(nameof(input_register), ref input_register);
ser.Sync(nameof(delays_to_process), ref delays_to_process);
ser.Sync(nameof(controller_delay_cd), ref controller_delay_cd);
ser.Sync(nameof(REG_FFFF), ref REG_FFFF);
ser.Sync(nameof(REG_FF0F), ref REG_FF0F);

View File

@ -267,13 +267,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
// check for interrupts
// if an interrupt is triggered, it is delayed by 4 cycles
if (((contr_prev & 8) > 0) && ((input_register & 8) == 0) ||
((contr_prev & 4) > 0) && ((input_register & 4) == 0) ||
((contr_prev & 2) > 0) && ((input_register & 2) == 0) ||
((contr_prev & 1) > 0) && ((input_register & 1) == 0))
{
if (REG_FFFF.Bit(4)) { cpu.FlagI = true; }
REG_FF0F |= 0x10;
controller_delay_cd = 4; delays_to_process = true;
}
break;