GBHawk: more hdma improvements
This commit is contained in:
parent
239fa0b22c
commit
cfbdde4cc7
|
@ -214,7 +214,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
break;
|
||||
case 0xFF53: // HDMA3
|
||||
HDMA_dest_hi = value;
|
||||
cur_DMA_dest = (ushort)(((HDMA_dest_hi & 0x1F) << 8) | (cur_DMA_dest & 0xF0));
|
||||
cur_DMA_dest = (ushort)(((HDMA_dest_hi & 0xFF) << 8) | (cur_DMA_dest & 0xF0));
|
||||
break;
|
||||
case 0xFF54: // HDMA4
|
||||
HDMA_dest_lo = value;
|
||||
|
@ -262,8 +262,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
//terminate the transfer
|
||||
if (!value.Bit(7))
|
||||
// terminate the transfer if disabling
|
||||
if (HDMA_active && HDMA_mode && HDMA_can_start)
|
||||
{
|
||||
// too late to stop the next trnasfer, so make it the last one instead
|
||||
if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 90))
|
||||
{
|
||||
HDMA_length = 1;
|
||||
}
|
||||
else if (HBL_HDMA_go)
|
||||
{
|
||||
HDMA_length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
HDMA_active = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HDMA_active = false;
|
||||
}
|
||||
|
@ -357,14 +373,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte;
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + (cur_DMA_dest & 0x1FFF)] = HDMA_byte;
|
||||
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
// DMA destination address does not wrap and terminates DMA
|
||||
if (cur_DMA_dest == 0xFFFF)
|
||||
{
|
||||
HDMA_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0xFFFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
|
||||
HDMA_length--;
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
|
||||
HDMA_length--;
|
||||
}
|
||||
}
|
||||
|
||||
HDMA_tick++;
|
||||
|
@ -430,15 +455,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte;
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + (cur_DMA_dest & 0x1FFF)] = HDMA_byte;
|
||||
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
// DMA destination address does not wrap and terminates DMA
|
||||
if (cur_DMA_dest == 0xFFFF)
|
||||
{
|
||||
HDMA_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0xFFFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
|
||||
HDMA_length--;
|
||||
HBL_HDMA_count--;
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
|
||||
HDMA_length--;
|
||||
HBL_HDMA_count--;
|
||||
}
|
||||
}
|
||||
|
||||
if ((HBL_HDMA_count == 0) && (HDMA_length != 0))
|
||||
|
@ -1202,7 +1236,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
VRAM_access_write_PPU = true;
|
||||
VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA;
|
||||
|
||||
//HDMA_can_start = true;
|
||||
read_case = 18;
|
||||
break;
|
||||
|
||||
|
@ -1224,6 +1257,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
read_case--;
|
||||
break;
|
||||
case 18:
|
||||
HDMA_can_start = true;
|
||||
rendering_complete = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1358,7 +1392,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
STAT |= 0x00;
|
||||
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
HDMA_can_start = true;
|
||||
|
||||
// TODO: If Window is turned on midscanline what happens? When is this check done exactly?
|
||||
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY > window_y_latch)))
|
||||
{
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
break;
|
||||
case 0xFF53: // HDMA3
|
||||
HDMA_dest_hi = value;
|
||||
cur_DMA_dest = (ushort)(((HDMA_dest_hi & 0x1F) << 8) | (cur_DMA_dest & 0xF0));
|
||||
cur_DMA_dest = (ushort)(((HDMA_dest_hi & 0xFF) << 8) | (cur_DMA_dest & 0xF0));
|
||||
break;
|
||||
case 0xFF54: // HDMA4
|
||||
HDMA_dest_lo = value;
|
||||
|
@ -260,10 +260,29 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
//terminate the transfer if disabling
|
||||
// terminate the transfer if disabling
|
||||
if (!value.Bit(7))
|
||||
{
|
||||
HDMA_active = false;
|
||||
if (HDMA_active && HDMA_mode && HDMA_can_start)
|
||||
{
|
||||
// too late to stop the next trnasfer, so make it the last one instead
|
||||
if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 90))
|
||||
{
|
||||
HDMA_length = 1;
|
||||
}
|
||||
else if (HBL_HDMA_go)
|
||||
{
|
||||
HDMA_length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
HDMA_active = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HDMA_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
// always update length
|
||||
|
@ -355,14 +374,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte;
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + (cur_DMA_dest & 0x1FFF)] = HDMA_byte;
|
||||
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
// DMA destination address does not wrap and terminates DMA
|
||||
if (cur_DMA_dest == 0xFFFF)
|
||||
{
|
||||
HDMA_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0xFFFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
|
||||
HDMA_length--;
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
|
||||
HDMA_length--;
|
||||
}
|
||||
}
|
||||
|
||||
HDMA_tick++;
|
||||
|
@ -428,15 +456,24 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte;
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + (cur_DMA_dest & 0x1FFF)] = HDMA_byte;
|
||||
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
// DMA destination address does not wrap and terminates DMA
|
||||
if (cur_DMA_dest == 0xFFFF)
|
||||
{
|
||||
HDMA_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0xFFFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
|
||||
HDMA_length--;
|
||||
HBL_HDMA_count--;
|
||||
// similar to normal DMA, except HDMA transfers when A14 is high always access SRAM
|
||||
if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; }
|
||||
|
||||
HDMA_length--;
|
||||
HBL_HDMA_count--;
|
||||
}
|
||||
}
|
||||
|
||||
if ((HBL_HDMA_count == 0) && (HDMA_length != 0))
|
||||
|
@ -1210,6 +1247,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA;
|
||||
|
||||
if (Core.double_speed) { HDMA_can_start = true; }
|
||||
|
||||
read_case = 18;
|
||||
|
||||
break;
|
||||
|
@ -1232,6 +1270,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
read_case--;
|
||||
break;
|
||||
case 18:
|
||||
if (!Core.double_speed) { HDMA_can_start = true; }
|
||||
rendering_complete = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1325,7 +1364,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
STAT |= 0x00;
|
||||
if (STAT.Bit(3)) { HBL_INT = true; }
|
||||
// the CPU has to be able to see the transition from mode 3 to mode 0 to start HDMA
|
||||
if (!Core.double_speed) { HDMA_can_start = true; }
|
||||
// TODO: If Window is turned on midscanline what happens? When is this check done exactly?
|
||||
if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY > window_y_latch)))
|
||||
{
|
||||
|
|
|
@ -9,9 +9,10 @@ using System.Runtime.InteropServices;
|
|||
|
||||
// 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: LYC interrupt behaves differently in GBC and GB compat mode
|
||||
// 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
|
||||
// mode 3 change, see 10spritesPrLine_10xposA7_m0irq_2_dmg08_cgb04c_out2.gbc
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||
{
|
||||
|
|
|
@ -37,7 +37,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
|
||||
// Interrupt flags
|
||||
case 0xFF0F:
|
||||
// TODO: Maybe some PPU bits are immediately visible, see 10spritesPrLine_10xposA7_m0irq_2_dmg08_cgb04c_out2.gbc
|
||||
//Console.WriteLine("FF0F " + cpu.TotalExecutedCycles);
|
||||
ret = REG_FF0F_OLD;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue