GBHawk: update bad SRAm access emulation

This commit is contained in:
alyosha-tas 2020-11-23 19:41:10 -05:00
parent af38023ba8
commit 1afcbe3ab5
10 changed files with 47 additions and 22 deletions

View File

@ -7,9 +7,6 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
private int EI_pending; private int EI_pending;
public bool interrupts_enabled; public bool interrupts_enabled;
// we need the last value on the bus for proper emulation of blocked SRAM
public byte bus_value;
// 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];

View File

@ -815,7 +815,6 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
ser.Sync(nameof(LY), ref LY); ser.Sync(nameof(LY), ref LY);
ser.Sync(nameof(FlagI), ref FlagI); ser.Sync(nameof(FlagI), ref FlagI);
ser.Sync(nameof(was_FlagI), ref was_FlagI); ser.Sync(nameof(was_FlagI), ref was_FlagI);
ser.Sync(nameof(bus_value), ref bus_value);
ser.EndSection(); ser.EndSection();
} }

View File

@ -18,21 +18,20 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
if (src_l == PCl) CDLCallback(addr, eCDLogMemFlags.FetchOperand); if (src_l == PCl) CDLCallback(addr, eCDLogMemFlags.FetchOperand);
else CDLCallback(addr, eCDLogMemFlags.Data); else CDLCallback(addr, eCDLogMemFlags.Data);
} }
Regs[dest] = bus_value = ReadMemory(addr); Regs[dest] = ReadMemory(addr);
} }
// special read for POP AF that always clears the lower 4 bits of F // special read for POP AF that always clears the lower 4 bits of F
public void Read_Func_F(ushort dest, ushort src_l, ushort src_h) public void Read_Func_F(ushort dest, ushort src_l, ushort src_h)
{ {
Regs[dest] = bus_value = (byte)(ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)) & 0xF0); Regs[dest] = (byte)(ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)) & 0xF0);
} }
public void Write_Func(ushort dest_l, ushort dest_h, ushort src) public void Write_Func(ushort dest_l, ushort dest_h, ushort src)
{ {
ushort addr = (ushort)(Regs[dest_l] | (Regs[dest_h]) << 8); ushort addr = (ushort)(Regs[dest_l] | (Regs[dest_h]) << 8);
CDLCallback?.Invoke(addr, eCDLogMemFlags.Write | eCDLogMemFlags.Data); CDLCallback?.Invoke(addr, eCDLogMemFlags.Write | eCDLogMemFlags.Data);
bus_value = (byte)Regs[src]; WriteMemory(addr, (byte)Regs[src]);
WriteMemory(addr, bus_value);
} }
public void TR_Func(ushort dest, ushort src) public void TR_Func(ushort dest, ushort src)

View File

@ -52,6 +52,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
ser.Sync(nameof(double_speed), ref double_speed); ser.Sync(nameof(double_speed), ref double_speed);
ser.Sync(nameof(speed_switch), ref speed_switch); ser.Sync(nameof(speed_switch), ref speed_switch);
ser.Sync(nameof(HDMA_transfer), ref HDMA_transfer); ser.Sync(nameof(HDMA_transfer), ref HDMA_transfer);
ser.Sync(nameof(bus_value), ref bus_value);
ser.Sync(nameof(bus_access_time), ref bus_access_time);
ser.Sync(nameof(IR_reg), ref IR_reg); ser.Sync(nameof(IR_reg), ref IR_reg);
ser.Sync(nameof(IR_mask), ref IR_mask); ser.Sync(nameof(IR_mask), ref IR_mask);

View File

@ -65,6 +65,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public bool double_speed; public bool double_speed;
public bool speed_switch; public bool speed_switch;
public bool HDMA_transfer; // stalls CPU when in progress public bool HDMA_transfer; // stalls CPU when in progress
public byte bus_value; // we need the last value on the bus for proper emulation of blocked SRAM
public ulong bus_access_time; // also need to keep track of the time of the access since it doesn't last very long
public byte IR_reg, IR_mask, IR_signal, IR_receive, IR_self; public byte IR_reg, IR_mask, IR_signal, IR_receive, IR_self;
public int IR_write; public int IR_write;

View File

@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
return 0xFF; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }

View File

@ -59,12 +59,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
return Core.cpu.bus_value; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }
else else
{ {
return Core.cpu.bus_value; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }

View File

@ -58,13 +58,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
return Core.cpu.bus_value; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }
else else
{ {
return Core.cpu.bus_value; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }

View File

@ -70,7 +70,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
return 0xFF; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }
@ -86,7 +86,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
return 0xFF; return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value;
} }
} }

View File

@ -47,13 +47,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return 0xFF; return 0xFF;
} }
return mapper.ReadMemoryLow(addr); bus_value = mapper.ReadMemoryLow(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
if (addr >= 0xA000 && addr < 0xC000 && is_GBC) if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
{ {
// on GBC only, cart is accessible during DMA // on GBC only, cart is accessible during DMA
return mapper.ReadMemoryHigh(addr); bus_value = mapper.ReadMemoryHigh(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
if (addr >= 0xE000 && addr < 0xF000) if (addr >= 0xE000 && addr < 0xF000)
@ -104,7 +108,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{ {
if (addr >= 0x900) if (addr >= 0x900)
{ {
return mapper.ReadMemoryLow(addr); bus_value = mapper.ReadMemoryLow(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
if (addr < 0x100) if (addr < 0x100)
@ -115,7 +121,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return _bios[addr]; // Return BIOS return _bios[addr]; // Return BIOS
} }
return mapper.ReadMemoryLow(addr); bus_value = mapper.ReadMemoryLow(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
if (addr >= 0x200) if (addr >= 0x200)
@ -126,10 +134,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
return _bios[addr]; // Return BIOS return _bios[addr]; // Return BIOS
} }
return mapper.ReadMemoryLow(addr); bus_value = mapper.ReadMemoryLow(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
return mapper.ReadMemoryLow(addr); bus_value = mapper.ReadMemoryLow(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
if (addr < 0xA000) if (addr < 0xA000)
@ -174,7 +186,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (addr < 0xC000) if (addr < 0xC000)
{ {
return mapper.ReadMemoryHigh(addr); bus_value = mapper.ReadMemoryHigh(addr);
bus_access_time = cpu.TotalExecutedCycles;
return bus_value;
} }
if (addr < 0xFE00) if (addr < 0xFE00)
@ -261,6 +275,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (addr >= 0xA000 && addr < 0xC000 && is_GBC) if (addr >= 0xA000 && addr < 0xC000 && is_GBC)
{ {
// on GBC only, cart is accessible during DMA // on GBC only, cart is accessible during DMA
bus_value = value;
bus_access_time = cpu.TotalExecutedCycles;
mapper.WriteMemory(addr, value); mapper.WriteMemory(addr, value);
} }
@ -350,6 +366,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else if (addr >= 0xA000) else if (addr >= 0xA000)
{ {
bus_value = value;
bus_access_time = cpu.TotalExecutedCycles;
mapper.WriteMemory(addr, value); mapper.WriteMemory(addr, value);
} }
else if (addr >= 0x8000) else if (addr >= 0x8000)
@ -363,6 +381,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
{ {
if (addr >= 0x900) if (addr >= 0x900)
{ {
bus_value = value;
bus_access_time = cpu.TotalExecutedCycles;
mapper.WriteMemory(addr, value); mapper.WriteMemory(addr, value);
} }
else else
@ -375,6 +395,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
bus_value = value;
bus_access_time = cpu.TotalExecutedCycles;
mapper.WriteMemory(addr, value); mapper.WriteMemory(addr, value);
} }
} }
@ -386,11 +408,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
else else
{ {
bus_value = value;
bus_access_time = cpu.TotalExecutedCycles;
mapper.WriteMemory(addr, value); mapper.WriteMemory(addr, value);
} }
} }
else else
{ {
bus_value = value;
bus_access_time = cpu.TotalExecutedCycles;
mapper.WriteMemory(addr, value); mapper.WriteMemory(addr, value);
} }
} }