GBHawk: work on double speed mode
This commit is contained in:
parent
7596b97218
commit
cd7cc7f939
|
@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
// variables for executing instructions
|
||||
public int instr_pntr = 0;
|
||||
public ushort[] cur_instr = new ushort [60];
|
||||
public ushort[] instr_table = new ushort[256 * 2 * 60 + 60 * 9];
|
||||
public ushort[] instr_table = new ushort[256 * 2 * 60 + 60 * 10];
|
||||
public bool CB_prefix;
|
||||
public bool halted;
|
||||
public bool stopped;
|
||||
|
@ -622,6 +622,12 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
|
||||
// wait state during HDMA
|
||||
instr_table[256 * 60 * 2 + 60 * 8] = WAIT;
|
||||
|
||||
// Speed Change Loop
|
||||
instr_table[256 * 60 * 2 + 60 * 9] = IDLE;
|
||||
instr_table[256 * 60 * 2 + 60 * 9 + 1] = DIV_RST;
|
||||
instr_table[256 * 60 * 2 + 60 * 9 + 2] = HALT_CHK;
|
||||
instr_table[256 * 60 * 2 + 60 * 9 + 3] = STOP;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
public const ushort COND_CHECK = 48;
|
||||
public const ushort HALT_FUNC = 49;
|
||||
public const ushort WAIT = 50; // set cpu to wait state during HDMA
|
||||
public const ushort DIV_RST = 51; // change speed mode
|
||||
|
||||
// test conditions
|
||||
public const ushort ALWAYS_T = 0;
|
||||
|
@ -512,9 +513,13 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
break;
|
||||
}
|
||||
|
||||
if (stop_time == (32769))
|
||||
if (stop_time == 32770)
|
||||
{
|
||||
// point to speed cange loop
|
||||
SpeedFunc(1);
|
||||
instr_pntr = 256 * 60 * 2 + 60 * 9;
|
||||
stop_time--;
|
||||
break;
|
||||
}
|
||||
|
||||
stop_time--;
|
||||
|
@ -730,6 +735,9 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
|||
case WAIT:
|
||||
instr_pntr--;
|
||||
break;
|
||||
case DIV_RST:
|
||||
SpeedFunc(2);
|
||||
break;
|
||||
}
|
||||
TotalExecutedCycles++;
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
speed_switch = false;
|
||||
Console.WriteLine("Speed Switch: " + cpu.TotalExecutedCycles);
|
||||
|
||||
int ret = double_speed ? 32769 : 32769; // actual time needs checking
|
||||
int ret = double_speed ? 32770 : 32770; // actual time needs checking
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -298,16 +298,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
// if we are in GB mode, return 0, cannot switch speed
|
||||
return 0;
|
||||
}
|
||||
else if (temp == 1)
|
||||
{
|
||||
double_speed = !double_speed;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset the divider (only way for speed_change_timing_fine.gbc and speed_change_cancel.gbc to both work)
|
||||
//Console.WriteLine("at stop " + timer.divider_reg);
|
||||
timer.divider_reg = 0x1;
|
||||
// Console.WriteLine("at stop " + timer.divider_reg + " " + timer.timer_control);
|
||||
|
||||
// TODO: resetting the divider causes an increment, but exact timing unclear
|
||||
//timer.tick();
|
||||
// only if the timer mode is 1, an extra tick of the timer is counted before the reset
|
||||
// this varies between console revisions
|
||||
if ((timer.timer_control & 3) == 1)
|
||||
{
|
||||
if((timer.divider_reg & 0x7) == 7)
|
||||
{
|
||||
timer.old_state = true;
|
||||
}
|
||||
}
|
||||
|
||||
double_speed = !double_speed;
|
||||
timer.divider_reg = 0xFFFF;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -341,9 +352,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public void SetIntRegs(byte r)
|
||||
{
|
||||
// For timer interrupts or serial interrupts that occur on the same cycle as the IRQ clear
|
||||
// the cear wins on GB and GBA (tested on GBP.) Assuming true for GBC E too.
|
||||
if (((REG_FF0F & 4) == 4) && ((r & 4) == 0) && timer.IRQ_block) { r |= 4; }
|
||||
if (((REG_FF0F & 8) == 8) && ((r & 8) == 0) && serialport.IRQ_block) { r |= 8; }
|
||||
// the clear wins on GB and GBA (tested on GBP.) Assuming true for GBC E too.
|
||||
// but only in single speed
|
||||
if (((REG_FF0F & 4) == 4) && ((r & 4) == 0) && timer.IRQ_block && !double_speed) { r |= 4; }
|
||||
if (((REG_FF0F & 8) == 8) && ((r & 8) == 0) && serialport.IRQ_block && !double_speed) { r |= 8; }
|
||||
REG_FF0F = r;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue