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