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

View File

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

View File

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

View File

@ -9,7 +9,6 @@ using System.Runtime.InteropServices;
using System.Collections.Generic; using System.Collections.Generic;
// TODO: mode1_disableint_gbc.gbc behaves differently between GBC and GBA, why? // 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: Window Position A6 behaves differently
// TODO: Verify open bus behaviour for bad SRAM accesses for other MBCs // 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 // 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 case 0xFF46: // DMA
DMA_addr = value; DMA_addr = value;
DMA_start = true; DMA_start = true;
DMA_OAM_access = true; if (!DMA_bus_control) {DMA_OAM_access = true; }
DMA_clock = 0; DMA_clock = 0;
DMA_inc = 0; DMA_inc = 0;
break; break;
@ -1039,17 +1039,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{ {
if (DMA_clock >= 4) if (DMA_clock >= 4)
{ {
DMA_bus_control = true;
DMA_OAM_access = false; DMA_OAM_access = false;
if ((DMA_clock % 4) == 1) if ((DMA_clock % 4) == 1)
{ {
// the cpu can't access memory during this time, but we still need the ppu to be able to. // 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 // 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) // So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
byte DMA_actual = DMA_addr; byte DMA_actual = DMA_addr;
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; } if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc)); DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
DMA_start = true; DMA_bus_control = true;
} }
else if ((DMA_clock % 4) == 3) else if ((DMA_clock % 4) == 3)
{ {
@ -1065,6 +1066,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (DMA_clock == -1) if (DMA_clock == -1)
{ {
DMA_start = false; DMA_start = false;
DMA_bus_control = false;
DMA_OAM_access = true; DMA_OAM_access = true;
} }
} }

View File

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

View File

@ -32,6 +32,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte window_y; public byte window_y;
public byte window_x; public byte window_x;
public bool DMA_start; public bool DMA_start;
public bool DMA_bus_control;
public int DMA_clock; public int DMA_clock;
public int DMA_inc; public int DMA_inc;
public byte DMA_byte; 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_y), ref window_y);
ser.Sync(nameof(window_x), ref window_x); ser.Sync(nameof(window_x), ref window_x);
ser.Sync(nameof(DMA_start), ref DMA_start); 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_clock), ref DMA_clock);
ser.Sync(nameof(DMA_inc), ref DMA_inc); ser.Sync(nameof(DMA_inc), ref DMA_inc);
ser.Sync(nameof(DMA_byte), ref DMA_byte); 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 ((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 // some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000) if (addr < 0x8000)

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return; 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 // some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000) if (addr < 0x8000)

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
if ((flags & LR35902.eCDLogMemFlags.Write) != 0) return; 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 // some of gekkio's tests require these to be accessible during DMA
if (addr < 0x8000) if (addr < 0x8000)