GBHawk: HDMA and GBC halt commits
This commit is contained in:
parent
380b9f085e
commit
d4ee8f480b
|
@ -57,6 +57,7 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
public const ushort RD_F = 42; // special read case to pop value into F
|
||||
public const ushort EI_RETI = 43; // reti has no delay in interrupt enable
|
||||
public const ushort INT_GET = 44;
|
||||
public const ushort GBC_INTERRUPT = 45;
|
||||
|
||||
public LR35902()
|
||||
{
|
||||
|
@ -278,8 +279,21 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
});
|
||||
}
|
||||
halted = false;
|
||||
// call interrupt processor
|
||||
INTERRUPT_();
|
||||
|
||||
if (is_GBC)
|
||||
{
|
||||
// call the interrupt processor after 4 extra cycles
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
GBC_INTERRUPT };
|
||||
}
|
||||
else
|
||||
{
|
||||
// call interrupt processor
|
||||
INTERRUPT_();
|
||||
}
|
||||
}
|
||||
else if (FlagI)
|
||||
{
|
||||
|
@ -295,7 +309,19 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
halted = false;
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null && !CB_prefix) TraceCallback(State());
|
||||
FetchInstruction(ReadMemory(RegPC++));
|
||||
if (is_GBC)
|
||||
{
|
||||
// extra 4 cycles for GBC
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
else
|
||||
{
|
||||
FetchInstruction(ReadMemory(RegPC++));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -419,6 +445,11 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
|
||||
Regs[cur_instr[instr_pntr++]] = INT_vectors[int_src];
|
||||
break;
|
||||
case GBC_INTERRUPT:
|
||||
// only used when exiting HALT from GBC, an extra NOP is added to avoid HALT bug
|
||||
INTERRUPT_();
|
||||
instr_pntr = 0;
|
||||
break;
|
||||
}
|
||||
totalExecutedCycles++;
|
||||
}
|
||||
|
|
|
@ -76,25 +76,42 @@ namespace BizHawk.Emulation.Common.Components.LR35902
|
|||
|
||||
private void HALT_()
|
||||
{
|
||||
|
||||
if (FlagI && (EI_pending == 0))
|
||||
{
|
||||
// if interrupts are disabled,
|
||||
// a glitchy decrement to the program counter happens
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP_G};
|
||||
|
||||
if (is_GBC)
|
||||
{
|
||||
// in GBC mode, the HALT bug is worked around by simply adding a NOP
|
||||
// so it just takes 4 cycles longer to reach the next instruction
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP};
|
||||
}
|
||||
else
|
||||
{ // if interrupts are disabled,
|
||||
// a glitchy decrement to the program counter happens
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP_G};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
HALT };
|
||||
}
|
||||
|
||||
IDLE,
|
||||
IDLE,
|
||||
HALT };
|
||||
}
|
||||
}
|
||||
|
||||
private void JR_COND(bool cond)
|
||||
|
|
|
@ -31,6 +31,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public ushort cur_DMA_dest;
|
||||
public int HDMA_length;
|
||||
public int HDMA_countdown;
|
||||
public int HBL_HDMA_count;
|
||||
public int last_HBL;
|
||||
public bool HBL_HDMA_go;
|
||||
public bool HBL_test;
|
||||
|
||||
public override byte ReadReg(int addr)
|
||||
{
|
||||
|
@ -158,6 +162,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
{
|
||||
// HDMA during HBlank only
|
||||
HDMA_active = true;
|
||||
HBL_HDMA_count = 0x10;
|
||||
last_HBL = LY;
|
||||
HBL_test = true;
|
||||
HBL_HDMA_go = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,8 +236,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
// only transfer during mode 3, otherwise
|
||||
if ((STAT & 3) == 3)
|
||||
// only transfer during mode 3, and only 16 bytes at a time
|
||||
if (((STAT & 3) == 3) && (LY != last_HBL) && HBL_test)
|
||||
{
|
||||
HBL_HDMA_go = true;
|
||||
HBL_test = false;
|
||||
}
|
||||
|
||||
if (HBL_HDMA_go && (HBL_HDMA_count > 0))
|
||||
{
|
||||
Core.HDMA_transfer = true;
|
||||
|
||||
|
@ -239,16 +253,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
HDMA_length--;
|
||||
HBL_HDMA_count--;
|
||||
Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = Core.ReadMemory(cur_DMA_src);
|
||||
cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF);
|
||||
cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF);
|
||||
HDMA_length--;
|
||||
HBL_HDMA_count--;
|
||||
|
||||
if (HDMA_length == 0)
|
||||
{
|
||||
HDMA_active = false;
|
||||
Core.HDMA_transfer = false;
|
||||
}
|
||||
|
||||
if ((HBL_HDMA_count == 0) && (HDMA_length != 0))
|
||||
{
|
||||
HBL_test = true;
|
||||
last_HBL = LY;
|
||||
HBL_HDMA_count = 0x10;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1294,6 +1317,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
ser.Sync("cur_DMA_dest", ref cur_DMA_dest);
|
||||
ser.Sync("HDMA_length", ref HDMA_length);
|
||||
ser.Sync("HDMA_countdown", ref HDMA_countdown);
|
||||
ser.Sync("HBL_HDMA_count", ref HBL_HDMA_count);
|
||||
ser.Sync("last_HBL", ref last_HBL);
|
||||
ser.Sync("HBL_HDMA_go", ref HBL_HDMA_go);
|
||||
ser.Sync("HBL_test", ref HBL_test);
|
||||
|
||||
base.SyncState(ser);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue