GBHawk: fix #2709 , also fixes a test that previously passed for the wrong reason

This commit is contained in:
alyosha-tas 2021-05-17 17:10:25 -04:00
parent 9f71f9b424
commit 4f24c6ac70
10 changed files with 27 additions and 20 deletions

View File

@ -185,7 +185,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFF46: // DMA
DMA_addr = value;
DMA_start = true;
DMA_OAM_access = true;
if (!DMA_bus_control) { DMA_OAM_access = true; }
DMA_clock = 0;
DMA_inc = 0;
break;
@ -1542,17 +1542,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (DMA_clock >= 4)
{
DMA_bus_control = true;
DMA_OAM_access = false;
if ((DMA_clock % 4) == 1)
{
// the cpu can't access memory during this time, but we still need the ppu to be able to.
DMA_start = false;
DMA_bus_control = false;
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
byte DMA_actual = DMA_addr;
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
DMA_start = true;
DMA_bus_control = true;
}
else if ((DMA_clock % 4) == 3)
{
@ -1579,6 +1580,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (DMA_clock == -1)
{
DMA_start = false;
DMA_bus_control = false;
DMA_OAM_access = true;
}
}

View File

@ -185,7 +185,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFF46: // DMA
DMA_addr = value;
DMA_start = true;
DMA_OAM_access = true;
if (!DMA_bus_control) { DMA_OAM_access = true; }
DMA_clock = 0;
DMA_inc = 0;
break;
@ -1511,17 +1511,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (DMA_clock >= 4)
{
DMA_bus_control = true;
DMA_OAM_access = false;
if ((DMA_clock % 4) == 1)
{
// the cpu can't access memory during this time, but we still need the ppu to be able to.
DMA_start = false;
DMA_bus_control = false;
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
byte DMA_actual = DMA_addr;
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
DMA_start = true;
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
DMA_bus_control = true;
}
else if ((DMA_clock % 4) == 3)
{
@ -1548,6 +1549,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (DMA_clock == -1)
{
DMA_start = false;
DMA_bus_control = false;
DMA_OAM_access = true;
}
}

View File

@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return;
}
if (ppu.DMA_start)
if (ppu.DMA_bus_control)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)

View File

@ -9,7 +9,6 @@ using System.Runtime.InteropServices;
using System.Collections.Generic;
// TODO: mode1_disableint_gbc.gbc behaves differently between GBC and GBA, why?
// TODO: oam_dma_start.gb does not behave as expected but test still passes through lucky coincidences / test deficiency
// TODO: Window Position A6 behaves differently
// TODO: Verify open bus behaviour for bad SRAM accesses for other MBCs
// TODO: Apparently sprites at x=A7 do not stop the trigger for FF0F bit flip, but still do not dispatch interrupt or

View File

@ -110,7 +110,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
case 0xFF46: // DMA
DMA_addr = value;
DMA_start = true;
DMA_OAM_access = true;
if (!DMA_bus_control) {DMA_OAM_access = true; }
DMA_clock = 0;
DMA_inc = 0;
break;
@ -1039,17 +1039,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{
if (DMA_clock >= 4)
{
DMA_bus_control = true;
DMA_OAM_access = false;
if ((DMA_clock % 4) == 1)
{
// the cpu can't access memory during this time, but we still need the ppu to be able to.
DMA_start = false;
DMA_bus_control = false;
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
byte DMA_actual = DMA_addr;
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
DMA_start = true;
DMA_bus_control = true;
}
else if ((DMA_clock % 4) == 3)
{
@ -1065,6 +1066,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (DMA_clock == -1)
{
DMA_start = false;
DMA_bus_control = false;
DMA_OAM_access = true;
}
}

View File

@ -37,14 +37,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
addr_access = addr;
if (ppu.DMA_start)
if (ppu.DMA_bus_control)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)
{
if (ppu.DMA_addr < 0x80)
{
return 0xFF;
return ppu.DMA_byte;
}
bus_value = mapper.ReadMemoryLow(addr);
@ -269,7 +269,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
addr_access = addr;
if (ppu.DMA_start)
if (ppu.DMA_bus_control)
{
// some of gekkio's tests require this to be accessible during DMA
if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
@ -424,14 +424,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte PeekMemory(ushort addr)
{
if (ppu.DMA_start)
if (ppu.DMA_bus_control)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)
{
if (ppu.DMA_addr < 0x80)
{
return 0xFF;
return ppu.DMA_byte;
}
return mapper.PeekMemoryLow(addr);

View File

@ -32,6 +32,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte window_y;
public byte window_x;
public bool DMA_start;
public bool DMA_bus_control;
public int DMA_clock;
public int DMA_inc;
public byte DMA_byte;
@ -203,6 +204,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(window_y), ref window_y);
ser.Sync(nameof(window_x), ref window_x);
ser.Sync(nameof(DMA_start), ref DMA_start);
ser.Sync(nameof(DMA_bus_control), ref DMA_bus_control);
ser.Sync(nameof(DMA_clock), ref DMA_clock);
ser.Sync(nameof(DMA_inc), ref DMA_inc);
ser.Sync(nameof(DMA_byte), ref DMA_byte);

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return;
}
if (L.ppu.DMA_start)
if (L.ppu.DMA_bus_control)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return;
}
if (L.ppu.DMA_start)
if (L.ppu.DMA_bus_control)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return;
}
if (A.ppu.DMA_start)
if (A.ppu.DMA_bus_control)
{
// some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000)