GBHawk: make timer <> cpu loop interaction consistent
This commit is contained in:
parent
96fa21e238
commit
6e8362eef0
|
@ -462,7 +462,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stop_time == (32768 - 2))
|
if (stop_time == (32769))
|
||||||
{
|
{
|
||||||
SpeedFunc(1);
|
SpeedFunc(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -896,6 +896,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_bit_old = Core.double_speed ? Core.timer.divider_reg.Bit(13) : Core.timer.divider_reg.Bit(12);
|
timer_bit_old = Core.double_speed ? Core.timer.divider_reg.Bit(13) : Core.timer.divider_reg.Bit(12);
|
||||||
|
|
||||||
if (sequencer_reset_cd > 0)
|
if (sequencer_reset_cd > 0)
|
||||||
|
@ -904,17 +905,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
if (sequencer_reset_cd == 0)
|
if (sequencer_reset_cd == 0)
|
||||||
{
|
{
|
||||||
|
// seems to be off by one issues here, hard to tell since the write takes place in the cpu loop
|
||||||
|
// but the effect takes place in the sound loop
|
||||||
if (Core.double_speed)
|
if (Core.double_speed)
|
||||||
{
|
{
|
||||||
sequencer_len = Core.timer.divider_reg.Bit(13) ? 0 : 1;
|
|
||||||
sequencer_vol = Core.timer.divider_reg.Bit(13) ? 0 : 1;
|
sequencer_len = (Core.timer.divider_reg - 1).Bit(13) ? 0 : 1;
|
||||||
sequencer_swp = Core.timer.divider_reg.Bit(13) ? 0 : 1;
|
sequencer_vol = (Core.timer.divider_reg - 1).Bit(13) ? 0 : 1;
|
||||||
|
sequencer_swp = (Core.timer.divider_reg - 1).Bit(13) ? 0 : 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sequencer_len = Core.timer.divider_reg.Bit(12) ? 0 : 1;
|
sequencer_len = (Core.timer.divider_reg + 1).Bit(12) ? 0 : 1;
|
||||||
sequencer_vol = Core.timer.divider_reg.Bit(12) ? 0 : 1;
|
sequencer_vol = (Core.timer.divider_reg + 1).Bit(12) ? 0 : 1;
|
||||||
sequencer_swp = Core.timer.divider_reg.Bit(12) ? 0 : 1;
|
sequencer_swp = (Core.timer.divider_reg + 1).Bit(12) ? 0 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,28 +108,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
{
|
{
|
||||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne();
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.ExecuteOne();
|
||||||
|
timer.divider_reg++;
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne();
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.ExecuteOne();
|
||||||
|
timer.divider_reg++;
|
||||||
|
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
cpu.TotalExecutedCycles++;
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.divider_reg++;
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.TotalExecutedCycles++;
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.divider_reg++;
|
||||||
|
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,29 +196,37 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// These things all tick twice as fast in GBC double speed mode
|
// These things all tick twice as fast in GBC double speed mode
|
||||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne();
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.ExecuteOne();
|
||||||
|
timer.divider_reg++;
|
||||||
|
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
|
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne();
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.ExecuteOne();
|
||||||
|
timer.divider_reg++;
|
||||||
|
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cpu.TotalExecutedCycles++;
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.divider_reg++;
|
||||||
|
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
|
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
cpu.TotalExecutedCycles++;
|
|
||||||
timer.tick();
|
timer.tick();
|
||||||
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.divider_reg++;
|
||||||
|
|
||||||
if (delays_to_process) { process_delays(); }
|
if (delays_to_process) { process_delays(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,9 +300,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
speed_switch = false;
|
speed_switch = false;
|
||||||
Console.WriteLine("Speed Switch: " + cpu.TotalExecutedCycles);
|
Console.WriteLine("Speed Switch: " + cpu.TotalExecutedCycles);
|
||||||
|
|
||||||
// reset the divider (only way for speed_change_timing_fine.gbc and speed_change_cancel.gbc to both work)
|
|
||||||
timer.divider_reg = 0;
|
|
||||||
|
|
||||||
int ret = double_speed ? 32769 : 32769; // actual time needs checking
|
int ret = double_speed ? 32769 : 32769; // actual time needs checking
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -302,6 +313,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// reset the divider (only way for speed_change_timing_fine.gbc and speed_change_cancel.gbc to both work)
|
||||||
|
timer.divider_reg = 1;
|
||||||
double_speed = !double_speed;
|
double_speed = !double_speed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -330,7 +343,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
public void SetIntRegs(byte r)
|
public void SetIntRegs(byte r)
|
||||||
{
|
{
|
||||||
if (((REG_FF0F & 4) == 4) && ((r & 4) == 0) && is_GBC) { timer.IRQ_block = true; }
|
if (((REG_FF0F & 4) == 4) && ((r & 4) == 0) && timer.IRQ_block && !is_GBC) { r |= 4; }
|
||||||
REG_FF0F = r;
|
REG_FF0F = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
{
|
{
|
||||||
// DIV register
|
// DIV register
|
||||||
case 0xFF04:
|
case 0xFF04:
|
||||||
|
// NOTE: even though there is an automatic increment directly after the CPU loop,
|
||||||
|
// it is still expected that 0 is written here
|
||||||
divider_reg = 0;
|
divider_reg = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
public void tick()
|
public void tick()
|
||||||
{
|
{
|
||||||
divider_reg++;
|
IRQ_block = false;
|
||||||
|
|
||||||
// pick a bit to test based on the current value of timer control
|
// pick a bit to test based on the current value of timer control
|
||||||
switch (timer_control & 3)
|
switch (timer_control & 3)
|
||||||
|
@ -201,20 +203,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
next_free_cycle = 4 + Core.cpu.TotalExecutedCycles;
|
next_free_cycle = 4 + Core.cpu.TotalExecutedCycles;
|
||||||
|
|
||||||
// set interrupts
|
// set interrupts
|
||||||
if (!IRQ_block)
|
|
||||||
{
|
|
||||||
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
||||||
Core.REG_FF0F |= 0x04;
|
Core.REG_FF0F |= 0x04;
|
||||||
|
IRQ_block = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IRQ_block = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
divider_reg = (ushort)(Core.is_GBC ? 0xFFFF : 0x1);
|
divider_reg = (ushort)(Core.is_GBC ? 0xFFFE : 0xFFFE);
|
||||||
timer_reload = 0;
|
timer_reload = 0;
|
||||||
timer = 0;
|
timer = 0;
|
||||||
timer_old = 0;
|
timer_old = 0;
|
||||||
|
|
Loading…
Reference in New Issue