GBHawk: add setting to sync domains to vblank (reads only). works better with LUA

This commit is contained in:
alyosha-tas 2020-04-24 10:14:48 -04:00
parent a977bb382d
commit 60af8a36fc
5 changed files with 101 additions and 9 deletions

View File

@ -124,6 +124,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// send the image on VBlank
SendVideoBuffer();
if (_settings.VBL_sync)
{
for (int j = 0; j < 0x8000; j++) { RAM_vbls[j] = RAM[j]; }
for (int j = 0; j < 0x4000; j++) { VRAM_vbls[j] = VRAM[j]; }
for (int j = 0; j < 0x80; j++) { ZP_RAM_vbls[j] = ZP_RAM[j]; }
for (int j = 0; j < 0xA0; j++) { OAM_vbls[j] = OAM[j]; }
if (cart_RAM != null)
{
for (int j = 0; j < cart_RAM.Length; j++) { cart_RAM_vbls[j] = cart_RAM[j]; }
}
}
}
REG_FF0F_OLD = REG_FF0F;

View File

@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
"WRAM",
RAM.Length,
MemoryDomain.Endian.Little,
addr => RAM[addr],
addr => PeekRAM(addr),
(addr, value) => RAM[addr] = value,
1),
new MemoryDomainDelegate(
@ -29,21 +29,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
"VRAM",
VRAM.Length,
MemoryDomain.Endian.Little,
addr => VRAM[addr],
addr => PeekVRAM(addr),
(addr, value) => VRAM[addr] = value,
1),
new MemoryDomainDelegate(
"OAM",
OAM.Length,
MemoryDomain.Endian.Little,
addr => OAM[addr],
addr => PeekOAM(addr),
(addr, value) => OAM[addr] = value,
1),
new MemoryDomainDelegate(
"HRAM",
ZP_RAM.Length,
MemoryDomain.Endian.Little,
addr => ZP_RAM[addr],
addr => PeekHRAM(addr),
(addr, value) => ZP_RAM[addr] = value,
1),
new MemoryDomainDelegate(
@ -61,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
"CartRAM",
cart_RAM.Length,
MemoryDomain.Endian.Little,
addr => cart_RAM[addr],
addr => PeekCART(addr),
(addr, value) => cart_RAM[addr] = value,
1);
domains.Add(CartRam);
@ -71,6 +71,68 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
}
private byte PeekRAM(long addr)
{
ushort addr2 = (ushort)(addr & 0x7FFF);
if (_settings.VBL_sync)
{
return RAM_vbls[addr2];
}
return RAM[addr2];
}
private byte PeekVRAM(long addr)
{
ushort addr2 = (ushort)(addr & 0x3FFF);
if (_settings.VBL_sync)
{
return VRAM_vbls[addr2];
}
return VRAM[addr2];
}
private byte PeekHRAM(long addr)
{
ushort addr2 = (ushort)(addr & 0x7F);
if (_settings.VBL_sync)
{
return ZP_RAM_vbls[addr2];
}
return ZP_RAM[addr2];
}
private byte PeekOAM(long addr)
{
if (addr < 0xA0)
{
if (_settings.VBL_sync)
{
return OAM_vbls[addr];
}
return OAM[addr];
}
return 0xFF;
}
private byte PeekCART(long addr)
{
if (cart_RAM != null)
{
if (addr < cart_RAM.Length)
{
if (_settings.VBL_sync)
{
return cart_RAM_vbls[addr];
}
return cart_RAM[addr];
}
return 0xFF;
}
return 0xFF;
}
private byte PeekSystemBus(long addr)
{
ushort addr2 = (ushort)(addr & 0xFFFF);

View File

@ -49,6 +49,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
[DefaultValue(PaletteType.BW)]
public PaletteType Palette { get; set; }
[DisplayName("Read Domains on VBlank")]
[Description("When true, memory domains are only updated on VBlank. More consistent for LUA. NOTE: Does not work for system bus, does not apply to writes.")]
[DefaultValue(false)]
public bool VBL_sync { get; set; }
public GBSettings Clone()
{
return (GBSettings)MemberwiseClone();

View File

@ -80,10 +80,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(vid_buffer), ref vid_buffer, false);
// probably a better way to do this
if (cart_RAM != null)
{
ser.Sync(nameof(cart_RAM), ref cart_RAM, false);
}
if (cart_RAM != null) { ser.Sync(nameof(cart_RAM), ref cart_RAM, false); }
ser.Sync(nameof(RAM_vbls), ref RAM_vbls, false);
ser.Sync(nameof(ZP_RAM_vbls), ref ZP_RAM_vbls, false);
ser.Sync(nameof(VRAM_vbls), ref VRAM_vbls, false);
ser.Sync(nameof(OAM_vbls), ref OAM_vbls, false);
if (cart_RAM != null) { ser.Sync(nameof(cart_RAM_vbls), ref cart_RAM_vbls, false); }
ser.EndSection();
}

View File

@ -47,6 +47,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte[] VRAM = new byte[0x4000];
public byte[] OAM = new byte[0xA0];
// vblank memory domains
public byte[] RAM_vbls = new byte[0x8000];
public byte[] ZP_RAM_vbls = new byte[0x80];
public byte[] VRAM_vbls = new byte[0x4000];
public byte[] OAM_vbls = new byte[0xA0];
public int RAM_Bank;
public byte VRAM_Bank;
internal bool is_GBC;
@ -65,6 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public readonly byte[] header = new byte[0x50];
public byte[] cart_RAM;
public byte[] cart_RAM_vbls;
public bool has_bat;
private int _frame = 0;
@ -173,6 +180,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
Console.WriteLine("SHA1: " + rom.HashSHA1(0, rom.Length));
_rom = rom;
Setup_Mapper();
if (cart_RAM != null) { cart_RAM_vbls = new byte[cart_RAM.Length]; }
timer.Core = this;
audio.Core = this;