GBHawk: HDMA fixes and implement reads for GBC visualizer

This commit is contained in:
alyosha-tas 2020-12-04 11:20:56 -05:00
parent d0ca41ecc1
commit 0aea6191ae
5 changed files with 26 additions and 17 deletions

View File

@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
{IDLE, {IDLE,
IDLE, IDLE,
IDLE, IDLE,
IDLE, HDMA_UPD,
IDLE, IDLE,
IDLE, IDLE,
IDLE, IDLE,

View File

@ -61,6 +61,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
public const ushort HALT_FUNC = 49; public const ushort HALT_FUNC = 49;
public const ushort WAIT = 50; // set cpu to wait state during HDMA public const ushort WAIT = 50; // set cpu to wait state during HDMA
public const ushort DIV_RST = 51; // change speed mode and reset divider public const ushort DIV_RST = 51; // change speed mode and reset divider
public const ushort HDMA_UPD = 52; // hdma can occur in between halt and IRQ in GBC
// test conditions // test conditions
public const ushort ALWAYS_T = 0; public const ushort ALWAYS_T = 0;
@ -369,7 +370,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
RegisterInfo = "" RegisterInfo = ""
}); });
halted = false; halted = false;
if (Halt_bug_4) if (Halt_bug_4)
{ {
// TODO: If interrupt priotrity is checked differently in GBC, then this is incorrect // TODO: If interrupt priotrity is checked differently in GBC, then this is incorrect
@ -738,6 +739,9 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
case DIV_RST: case DIV_RST:
SpeedFunc(1); SpeedFunc(1);
break; break;
case HDMA_UPD:
instruction_start = TotalExecutedCycles + 1;
break;
} }
TotalExecutedCycles++; TotalExecutedCycles++;
} }

View File

@ -234,7 +234,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
HDMA_active = true; HDMA_active = true;
HBL_HDMA_count = 0x10; HBL_HDMA_count = 0x10;
last_HBL = LY - 1; last_HBL = LY_read - 1;
HBL_test = true; HBL_test = true;
HBL_HDMA_go = false; HBL_HDMA_go = false;
@ -266,7 +266,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (HDMA_active && HDMA_mode && HDMA_can_start) if (HDMA_active && HDMA_mode && HDMA_can_start)
{ {
// too late to stop the next trnasfer, so make it the last one instead // 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)) if (((STAT & 3) == 0) && (LY_read != last_HBL) && HBL_test && (LY_inc == 1) && !glitch_state)
{ {
HDMA_length = 1; HDMA_length = 1;
} }
@ -398,8 +398,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
else else
{ {
// only transfer during mode 0, and only 16 bytes at a time // only transfer during mode 0, and only 16 bytes at a time
// cycle > 90 prevents triggering early when turning on LCD (presumably the real event is transition from mode 3 to 0.) // NOTE: state when first enabling ppu does not count as mode 0
if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 90) && HDMA_can_start) if (((STAT & 3) == 0) && (LY_read != last_HBL) && HBL_test && (LY_inc == 1) && !glitch_state && HDMA_can_start)
{ {
HBL_HDMA_go = true; HBL_HDMA_go = true;
HBL_test = false; HBL_test = false;
@ -430,7 +430,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// reading from open bus still returns 0xFF on DMA access, see dma_hiram_read_result_cgb04c_out1.gbc // reading from open bus still returns 0xFF on DMA access, see dma_hiram_read_result_cgb04c_out1.gbc
Core.bus_value = 0xFF; Core.bus_value = 0xFF;
if (LCDC.Bit(7)) { last_HBL = LY; } if (LCDC.Bit(7)) { last_HBL = LY_read; }
else { last_HBL = 0xFF; } else { last_HBL = 0xFF; }
} }
else else
@ -767,9 +767,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
// here LY=LYC will be asserted or cleared (but only if LY isnt 0 as that's a special case) // here LY=LYC will be asserted or cleared (but only if LY isnt 0 as that's a special case)
// it is also the boundary where HDMA can no longe start if triggered by a write
if ((cycle == 2) && (LY != 0)) if ((cycle == 2) && (LY != 0))
{ {
LY_read = LY; LY_read = LY;
HDMA_can_start = false;
} }
else if ((cycle == 4) && (LY != 0)) else if ((cycle == 4) && (LY != 0))
{ {
@ -868,7 +870,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
evaled_sprites = 0; evaled_sprites = 0;
window_pre_render = false; window_pre_render = false;
window_latch = LCDC.Bit(5); window_latch = LCDC.Bit(5);
HDMA_can_start = false;
total_counter = 0; total_counter = 0;

View File

@ -232,7 +232,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
HDMA_active = true; HDMA_active = true;
HBL_HDMA_count = 0x10; HBL_HDMA_count = 0x10;
last_HBL = LY - 1; last_HBL = LY_read - 1;
HBL_test = true; HBL_test = true;
HBL_HDMA_go = false; HBL_HDMA_go = false;
@ -266,7 +266,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (HDMA_active && HDMA_mode && HDMA_can_start) if (HDMA_active && HDMA_mode && HDMA_can_start)
{ {
// too late to stop the next trnasfer, so make it the last one instead // 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)) if (((STAT & 3) == 0) && (LY_read != last_HBL) && HBL_test && (LY_inc == 1) && !glitch_state)
{ {
HDMA_length = 1; HDMA_length = 1;
} }
@ -287,7 +287,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// always update length // always update length
HDMA_length = ((value & 0x7F) + 1) * 16; HDMA_length = ((value & 0x7F) + 1) * 16;
} }
break; break;
@ -399,8 +398,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
else else
{ {
// only transfer during mode 0, and only 16 bytes at a time // only transfer during mode 0, and only 16 bytes at a time
// cycle > 90 prevents triggering early when turning on LCD (presumably the real event is transition from mode 3 to 0.) // NOTE: state when first enabling ppu does not count as mode 0
if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 90) && HDMA_can_start) if (((STAT & 3) == 0) && (LY_read != last_HBL) && HBL_test && (LY_inc == 1) && !glitch_state && HDMA_can_start)
{ {
HBL_HDMA_go = true; HBL_HDMA_go = true;
HBL_test = false; HBL_test = false;
@ -431,7 +430,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// reading from open bus still returns 0xFF on DMA access, see dma_hiram_read_result_cgb04c_out1.gbc // reading from open bus still returns 0xFF on DMA access, see dma_hiram_read_result_cgb04c_out1.gbc
Core.bus_value = 0xFF; Core.bus_value = 0xFF;
if (LCDC.Bit(7)) { last_HBL = LY; } if (LCDC.Bit(7)) { last_HBL = LY_read; }
else { last_HBL = 0xFF; } else { last_HBL = 0xFF; }
} }
else else
@ -773,9 +772,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
} }
// here LY=LYC will be asserted or cleared (but only if LY isnt 0 as that's a special case) // here LY=LYC will be asserted or cleared (but only if LY isnt 0 as that's a special case)
// it is also the boundary where HDMA can no longe start if triggered by a write
if ((cycle == 2) && (LY != 0)) if ((cycle == 2) && (LY != 0))
{ {
LY_read = LY; LY_read = LY;
HDMA_can_start = false;
} }
else if ((cycle == (2 + 1 * LYC_offset)) && (LY != 0)) else if ((cycle == (2 + 1 * LYC_offset)) && (LY != 0))
{ {
@ -874,7 +875,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
evaled_sprites = 0; evaled_sprites = 0;
window_pre_render = false; window_pre_render = false;
window_latch = LCDC.Bit(5); window_latch = LCDC.Bit(5);
HDMA_can_start = false;
total_counter = 0; total_counter = 0;

View File

@ -213,12 +213,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
break; break;
case 0xFF76: case 0xFF76:
if (is_GBC) { ret = undoc_76; } byte ret1 = audio.SQ1_output >= Audio.DAC_OFST ? (byte)(audio.SQ1_output - Audio.DAC_OFST) : 0;
byte ret2 = audio.SQ2_output >= Audio.DAC_OFST ? (byte)(audio.SQ2_output - Audio.DAC_OFST) : 0;
if (is_GBC) { ret = (byte)(ret1 | (ret2 << 4)); }
else { ret = 0xFF; } else { ret = 0xFF; }
break; break;
case 0xFF77: case 0xFF77:
if (is_GBC) { ret = undoc_77; } byte retN = audio.NOISE_output >= Audio.DAC_OFST ? (byte)(audio.NOISE_output - Audio.DAC_OFST) : 0;
byte retW = audio.WAVE_output >= Audio.DAC_OFST ? (byte)(audio.WAVE_output - Audio.DAC_OFST) : 0;
if (is_GBC) { ret = (byte)(retN | (retW << 4)); }
else { ret = 0xFF; } else { ret = 0xFF; }
break; break;