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;
|
||||
}
|
||||
|
||||
if (stop_time == (32768 - 2))
|
||||
if (stop_time == (32769))
|
||||
{
|
||||
SpeedFunc(1);
|
||||
}
|
||||
|
|
|
@ -896,25 +896,29 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer_bit_old = Core.double_speed ? Core.timer.divider_reg.Bit(13) : Core.timer.divider_reg.Bit(12);
|
||||
|
||||
if (sequencer_reset_cd > 0)
|
||||
{
|
||||
sequencer_reset_cd--;
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
sequencer_len = Core.timer.divider_reg.Bit(13) ? 0 : 1;
|
||||
sequencer_vol = Core.timer.divider_reg.Bit(13) ? 0 : 1;
|
||||
sequencer_swp = Core.timer.divider_reg.Bit(13) ? 0 : 1;
|
||||
|
||||
sequencer_len = (Core.timer.divider_reg - 1).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
|
||||
{
|
||||
sequencer_len = Core.timer.divider_reg.Bit(12) ? 0 : 1;
|
||||
sequencer_vol = Core.timer.divider_reg.Bit(12) ? 0 : 1;
|
||||
sequencer_swp = 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 + 1).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(); }
|
||||
serialport.serial_transfer_tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
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();
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (double_speed)
|
||||
{
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
if (delays_to_process) { process_delays(); }
|
||||
}
|
||||
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
|
||||
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
|
||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||
serialport.serial_transfer_tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
if (double_speed)
|
||||
{
|
||||
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
|
||||
serialport.serial_transfer_tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.tick();
|
||||
cpu.ExecuteOne();
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
|
||||
if (double_speed)
|
||||
{
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.tick();
|
||||
cpu.TotalExecutedCycles++;
|
||||
timer.divider_reg++;
|
||||
|
||||
if (delays_to_process) { process_delays(); }
|
||||
}
|
||||
}
|
||||
|
@ -286,9 +300,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
speed_switch = false;
|
||||
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
|
||||
return ret;
|
||||
}
|
||||
|
@ -302,6 +313,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
@ -330,7 +343,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
switch (addr)
|
||||
{
|
||||
case 0xFF04: ret = (byte)(divider_reg >> 8); break; // DIV register
|
||||
case 0xFF04: ret = (byte)(divider_reg >> 8); break; // DIV register
|
||||
case 0xFF05: ret = timer; break; // TIMA (Timer Counter)
|
||||
case 0xFF06: ret = timer_reload; break; // TMA (Timer Modulo)
|
||||
case 0xFF07: ret = timer_control; break; // TAC (Timer Control)
|
||||
|
@ -56,6 +56,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
// DIV register
|
||||
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;
|
||||
break;
|
||||
|
||||
|
@ -143,8 +145,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
public void tick()
|
||||
{
|
||||
divider_reg++;
|
||||
|
||||
IRQ_block = false;
|
||||
|
||||
// pick a bit to test based on the current value of timer control
|
||||
switch (timer_control & 3)
|
||||
{
|
||||
|
@ -201,20 +203,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
next_free_cycle = 4 + Core.cpu.TotalExecutedCycles;
|
||||
|
||||
// set interrupts
|
||||
if (!IRQ_block)
|
||||
{
|
||||
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
||||
Core.REG_FF0F |= 0x04;
|
||||
}
|
||||
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
||||
Core.REG_FF0F |= 0x04;
|
||||
IRQ_block = true;
|
||||
}
|
||||
}
|
||||
|
||||
IRQ_block = false;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
divider_reg = (ushort)(Core.is_GBC ? 0xFFFF : 0x1);
|
||||
divider_reg = (ushort)(Core.is_GBC ? 0xFFFE : 0xFFFE);
|
||||
timer_reload = 0;
|
||||
timer = 0;
|
||||
timer_old = 0;
|
||||
|
|
Loading…
Reference in New Issue