GBHawk: work on some accuracy edge cases

This commit is contained in:
alyosha-tas 2020-04-28 18:44:24 -04:00
parent 15f69cf80e
commit cb5c21f8d3
4 changed files with 80 additions and 23 deletions

View File

@ -58,6 +58,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
do_frame(controller);
// if the game is stopped but controller interrupts are on, check for interrupts
if ((cpu.stopped || cpu.halted) && _islag && ((REG_FFFF & 0x10) == 0x10))
{
// update the controller state on VBlank
GetControllerState(controller);
do_controller_check();
}
if (_scanlineCallback != null)
{
if (_scanlineCallbackLine == -1)
@ -88,14 +97,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
// These things all tick twice as fast in GBC double speed mode
// Note that DMA is halted when the CPU is halted
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
if (double_speed)
{
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
@ -104,11 +113,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
else
{
cpu.TotalExecutedCycles++;
timer.tick();
timer.tick();
if (double_speed)
{
cpu.TotalExecutedCycles++;
timer.tick();
timer.tick();
}
}
@ -165,14 +174,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!HDMA_transfer)
{
// These things all tick twice as fast in GBC double speed mode
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
if (double_speed)
{
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
if (ppu.DMA_start && !cpu.halted && !cpu.stopped) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne();
timer.tick();
@ -244,7 +253,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
speed_switch = false;
Console.WriteLine("Speed Switch: " + cpu.TotalExecutedCycles);
int ret = double_speed ? 35112 : 35112; // actual time needs checking
int ret = double_speed ? (32768 - 19) : (32768 - 19); // actual time needs checking
double_speed = !double_speed;
return ret;
}

View File

@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return ret ? PutSettingsDirtyBits.RebootCore : PutSettingsDirtyBits.None;
}
private GBSettings _settings = new GBSettings();
public GBSettings _settings = new GBSettings();
public GBSyncSettings _syncSettings = new GBSyncSettings();
public class GBSettings

View File

@ -47,16 +47,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return mapper.ReadMemoryLow(addr);
}
if (addr >= 0xE000 && (addr < 0xF000))
if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
{
return RAM[addr - 0xE000];
// on GBC only, cart is accessible during DMA
return mapper.ReadMemoryHigh(addr);
}
if (addr >= 0xE000 && addr < 0xF000)
{
return RAM[addr - 0xE000];
}
if (addr >= 0xF000 && addr < 0xFE00)
{
return RAM[(RAM_Bank * 0x1000) + (addr - 0xF000)];
}
if (addr >= 0xFE00 && addr < 0xFEA0 && ppu.DMA_OAM_access)
{
return OAM[addr - 0xFE00];
@ -67,13 +71,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return Read_Registers(addr);
}
if ((addr >= 0xFF80))
if (addr >= 0xFF80)
{
// register FFFF?
return ZP_RAM[addr - 0xFF80];
if (addr != 0xFFFF)
{
return ZP_RAM[addr - 0xFF80];
}
else
{
return Read_Registers(addr);
}
}
return 0xFF;
return ppu.DMA_byte;
}
if (addr < 0x8000)
@ -171,6 +181,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (ppu.DMA_start)
{
// some of gekkio's tests require this to be accessible during DMA
if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
{
// on GBC only, cart is accessible during DMA
mapper.WriteMemory(addr, value);
}
if (addr >= 0xE000 && addr < 0xF000)
{
RAM[addr - 0xE000] = value;
@ -189,7 +206,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
else if (addr >= 0xFF80)
{
ZP_RAM[addr - 0xFF80] = value;
if (addr != 0xFFFF)
{
ZP_RAM[addr - 0xFF80] = value;
}
else
{
Write_Registers(addr, value);
}
}
return;
@ -284,11 +308,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return mapper.PeekMemoryLow(addr);
}
if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
{
// on GBC only, cart is accessible during DMA
return mapper.ReadMemoryHigh(addr);
}
if (addr >= 0xE000 && addr < 0xF000)
{
return RAM[addr - 0xE000];
}
if (addr >= 0xF000 && addr < 0xFE00)
{
return RAM[(RAM_Bank * 0x1000) + (addr - 0xF000)];
@ -306,10 +335,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (addr >= 0xFF80)
{
return ZP_RAM[addr - 0xFF80];
if (addr != 0xFFFF)
{
return ZP_RAM[addr - 0xFF80];
}
else
{
return Read_Registers(addr);
}
}
return 0xFF;
return ppu.DMA_byte;
}
if (addr < 0x8000)

View File

@ -48,12 +48,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (((value & 2) > 0) && Core.GBC_compat)
{
clk_rate = 16;
serial_clock = (15 - (int)(Core.cpu.TotalExecutedCycles % 16)) + 1;
serial_clock = (16 - (int)(Core.cpu.TotalExecutedCycles % 8)) + 1;
}
else
{
clk_rate = 512;
serial_clock = (511 - (int)(Core.cpu.TotalExecutedCycles % 512)) + 1;
serial_clock = 512 - (int)(Core.cpu.TotalExecutedCycles % 256) + 1;
// there seems to be some clock inverting happening on some transfers
// not sure of the exact nature of it, here is one methor that gives correct result on one test rom but not others
/*
if (Core._syncSettings.GBACGB && Core.is_GBC)
{
if ((Core.TotalExecutedCycles % 256) > 127)
{
serial_clock = (8 - (int)(Core.cpu.TotalExecutedCycles % 8)) + 1;
}
}
*/
}
can_pulse = true;
}
@ -71,12 +83,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (((value & 2) > 0) && Core.GBC_compat)
{
clk_rate = 16;
serial_clock = (15 - (int)(Core.cpu.TotalExecutedCycles % 16)) + 1;
serial_clock = (16 - (int)(Core.cpu.TotalExecutedCycles % 8)) + 1;
}
else
{
clk_rate = 512;
serial_clock = (511 - (int)(Core.cpu.TotalExecutedCycles % 512)) + 1;
serial_clock = 512 - (int)(Core.cpu.TotalExecutedCycles % 256) + 1;
}
can_pulse = true;
}