GBhawk: some C# optimizations
This commit is contained in:
parent
00471ac530
commit
0e0b94cd0c
|
@ -176,37 +176,47 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
||||||
I_use = false;
|
I_use = false;
|
||||||
break;
|
break;
|
||||||
case RD:
|
case RD:
|
||||||
Read_Func(instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
Read_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1], instr_table[instr_pntr + 2]);
|
||||||
|
instr_pntr += 3;
|
||||||
break;
|
break;
|
||||||
case WR:
|
case WR:
|
||||||
Write_Func(instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
Write_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1], instr_table[instr_pntr + 2]);
|
||||||
|
instr_pntr += 3;
|
||||||
break;
|
break;
|
||||||
case TR:
|
case TR:
|
||||||
TR_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
TR_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case ADD16:
|
case ADD16:
|
||||||
ADD16_Func(instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
ADD16_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1], instr_table[instr_pntr + 2], instr_table[instr_pntr + 3]);
|
||||||
|
instr_pntr += 4;
|
||||||
break;
|
break;
|
||||||
case ADD8:
|
case ADD8:
|
||||||
ADD8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
ADD8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case SUB8:
|
case SUB8:
|
||||||
SUB8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
SUB8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case ADC8:
|
case ADC8:
|
||||||
ADC8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
ADC8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case SBC8:
|
case SBC8:
|
||||||
SBC8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
SBC8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case INC16:
|
case INC16:
|
||||||
INC16_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
INC16_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case INC8:
|
case INC8:
|
||||||
INC8_Func(instr_table[instr_pntr++]);
|
INC8_Func(instr_table[instr_pntr++]);
|
||||||
break;
|
break;
|
||||||
case DEC16:
|
case DEC16:
|
||||||
DEC16_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
DEC16_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case DEC8:
|
case DEC8:
|
||||||
DEC8_Func(instr_table[instr_pntr++]);
|
DEC8_Func(instr_table[instr_pntr++]);
|
||||||
|
@ -236,16 +246,20 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
||||||
CCF_Func(instr_table[instr_pntr++]);
|
CCF_Func(instr_table[instr_pntr++]);
|
||||||
break;
|
break;
|
||||||
case AND8:
|
case AND8:
|
||||||
AND8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
AND8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case XOR8:
|
case XOR8:
|
||||||
XOR8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
XOR8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case OR8:
|
case OR8:
|
||||||
OR8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
OR8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case CP8:
|
case CP8:
|
||||||
CP8_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
CP8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case SLA:
|
case SLA:
|
||||||
SLA_Func(instr_table[instr_pntr++]);
|
SLA_Func(instr_table[instr_pntr++]);
|
||||||
|
@ -260,13 +274,16 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
||||||
SWAP_Func(instr_table[instr_pntr++]);
|
SWAP_Func(instr_table[instr_pntr++]);
|
||||||
break;
|
break;
|
||||||
case BIT:
|
case BIT:
|
||||||
BIT_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
BIT_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case RES:
|
case RES:
|
||||||
RES_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
RES_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case SET:
|
case SET:
|
||||||
SET_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
SET_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case EI:
|
case EI:
|
||||||
if (EI_pending == 0) { EI_pending = 2; }
|
if (EI_pending == 0) { EI_pending = 2; }
|
||||||
|
@ -457,10 +474,12 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
||||||
CB_prefix = true;
|
CB_prefix = true;
|
||||||
break;
|
break;
|
||||||
case ASGN:
|
case ASGN:
|
||||||
ASGN_Func(instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
ASGN_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]);
|
||||||
|
instr_pntr += 2;
|
||||||
break;
|
break;
|
||||||
case ADDS:
|
case ADDS:
|
||||||
ADDS_Func(instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
ADDS_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1], instr_table[instr_pntr + 2], instr_table[instr_pntr + 3]);
|
||||||
|
instr_pntr += 4;
|
||||||
break;
|
break;
|
||||||
case OP_G:
|
case OP_G:
|
||||||
OnExecFetch?.Invoke(RegPC);
|
OnExecFetch?.Invoke(RegPC);
|
||||||
|
@ -474,7 +493,8 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
|
||||||
instr_pntr--;
|
instr_pntr--;
|
||||||
break;
|
break;
|
||||||
case RD_F:
|
case RD_F:
|
||||||
Read_Func_F(instr_table[instr_pntr++], instr_table[instr_pntr++], instr_table[instr_pntr++]);
|
Read_Func_F(instr_table[instr_pntr], instr_table[instr_pntr + 1], instr_table[instr_pntr + 2]);
|
||||||
|
instr_pntr += 3;
|
||||||
break;
|
break;
|
||||||
case EI_RETI:
|
case EI_RETI:
|
||||||
EI_pending = 1;
|
EI_pending = 1;
|
||||||
|
|
|
@ -526,7 +526,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// x-scroll is expected to be latched one cycle later
|
// x-scroll is expected to be latched one cycle later
|
||||||
// this is fine since nothing has started in the rendering until the second cycle
|
// this is fine since nothing has started in the rendering until the second cycle
|
||||||
// calculate the column number of the tile to start with
|
// calculate the column number of the tile to start with
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = scroll_x >> 3;
|
||||||
render_offset = scroll_x % 8;
|
render_offset = scroll_x % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,7 +586,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// x-scroll is expected to be latched one cycle later
|
// x-scroll is expected to be latched one cycle later
|
||||||
// this is fine since nothing has started in the rendering until the second cycle
|
// this is fine since nothing has started in the rendering until the second cycle
|
||||||
// calculate the column number of the tile to start with
|
// calculate the column number of the tile to start with
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = scroll_x >> 3;
|
||||||
render_offset = scroll_x % 8;
|
render_offset = scroll_x % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,9 +945,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
{
|
{
|
||||||
case 0: // read a background tile
|
case 0: // read a background tile
|
||||||
if ((internal_cycle % 2) == 1)
|
if ((internal_cycle % 2) == 1)
|
||||||
{
|
{
|
||||||
// calculate the row number of the tiles to be fetched
|
// calculate the row number of the tiles to be fetched
|
||||||
y_tile = ((int)Math.Floor((float)(scroll_y + LY) / 8)) % 32;
|
y_tile = (((int)scroll_y + LY) >> 3) % 32;
|
||||||
|
|
||||||
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
|
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
|
||||||
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
|
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
|
||||||
|
@ -1344,38 +1344,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// So give it it's own function so we can seperate it from PPU tick
|
// So give it it's own function so we can seperate it from PPU tick
|
||||||
public override void DMA_tick()
|
public override void DMA_tick()
|
||||||
{
|
{
|
||||||
// Note that DMA is halted when the CPU is halted
|
if (DMA_clock >= 4)
|
||||||
if (DMA_start && !Core.cpu.halted)
|
|
||||||
{
|
{
|
||||||
if (DMA_clock >= 4)
|
DMA_OAM_access = false;
|
||||||
{
|
if ((DMA_clock % 4) == 1)
|
||||||
DMA_OAM_access = false;
|
|
||||||
if ((DMA_clock % 4) == 1)
|
|
||||||
{
|
|
||||||
// the cpu can't access memory during this time, but we still need the ppu to be able to.
|
|
||||||
DMA_start = false;
|
|
||||||
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
|
|
||||||
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
|
|
||||||
byte DMA_actual = DMA_addr;
|
|
||||||
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
|
|
||||||
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
|
|
||||||
DMA_start = true;
|
|
||||||
}
|
|
||||||
else if ((DMA_clock % 4) == 3)
|
|
||||||
{
|
|
||||||
Core.OAM[DMA_inc] = DMA_byte;
|
|
||||||
|
|
||||||
if (DMA_inc < (0xA0 - 1)) { DMA_inc++; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DMA_clock++;
|
|
||||||
|
|
||||||
if (DMA_clock == 648)
|
|
||||||
{
|
{
|
||||||
|
// the cpu can't access memory during this time, but we still need the ppu to be able to.
|
||||||
DMA_start = false;
|
DMA_start = false;
|
||||||
DMA_OAM_access = true;
|
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
|
||||||
|
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
|
||||||
|
byte DMA_actual = DMA_addr;
|
||||||
|
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
|
||||||
|
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
|
||||||
|
DMA_start = true;
|
||||||
}
|
}
|
||||||
|
else if ((DMA_clock % 4) == 3)
|
||||||
|
{
|
||||||
|
Core.OAM[DMA_inc] = DMA_byte;
|
||||||
|
|
||||||
|
if (DMA_inc < (0xA0 - 1)) { DMA_inc++; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DMA_clock++;
|
||||||
|
|
||||||
|
if (DMA_clock == 648)
|
||||||
|
{
|
||||||
|
DMA_start = false;
|
||||||
|
DMA_OAM_access = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -522,7 +522,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// x-scroll is expected to be latched one cycle later
|
// x-scroll is expected to be latched one cycle later
|
||||||
// this is fine since nothing has started in the rendering until the second cycle
|
// this is fine since nothing has started in the rendering until the second cycle
|
||||||
// calculate the column number of the tile to start with
|
// calculate the column number of the tile to start with
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = scroll_x >> 3;
|
||||||
render_offset = scroll_x % 8;
|
render_offset = scroll_x % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,7 +582,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// x-scroll is expected to be latched one cycle later
|
// x-scroll is expected to be latched one cycle later
|
||||||
// this is fine since nothing has started in the rendering until the second cycle
|
// this is fine since nothing has started in the rendering until the second cycle
|
||||||
// calculate the column number of the tile to start with
|
// calculate the column number of the tile to start with
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = scroll_x >> 3;
|
||||||
render_offset = scroll_x % 8;
|
render_offset = scroll_x % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -911,9 +911,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
{
|
{
|
||||||
case 0: // read a background tile
|
case 0: // read a background tile
|
||||||
if ((internal_cycle % 2) == 1)
|
if ((internal_cycle % 2) == 1)
|
||||||
{
|
{
|
||||||
// calculate the row number of the tiles to be fetched
|
// calculate the row number of the tiles to be fetched
|
||||||
y_tile = ((int)Math.Floor((float)(scroll_y + LY) / 8)) % 32;
|
y_tile = (((int)scroll_y + LY) >> 3) % 32;
|
||||||
|
|
||||||
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
|
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
|
||||||
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
|
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
|
||||||
|
@ -1312,38 +1312,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// So give it it's own function so we can seperate it from PPU tick
|
// So give it it's own function so we can seperate it from PPU tick
|
||||||
public override void DMA_tick()
|
public override void DMA_tick()
|
||||||
{
|
{
|
||||||
// Note that DMA is halted when the CPU is halted
|
if (DMA_clock >= 4)
|
||||||
if (DMA_start && !Core.cpu.halted)
|
|
||||||
{
|
{
|
||||||
if (DMA_clock >= 4)
|
DMA_OAM_access = false;
|
||||||
{
|
if ((DMA_clock % 4) == 1)
|
||||||
DMA_OAM_access = false;
|
|
||||||
if ((DMA_clock % 4) == 1)
|
|
||||||
{
|
|
||||||
// the cpu can't access memory during this time, but we still need the ppu to be able to.
|
|
||||||
DMA_start = false;
|
|
||||||
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
|
|
||||||
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
|
|
||||||
byte DMA_actual = DMA_addr;
|
|
||||||
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
|
|
||||||
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
|
|
||||||
DMA_start = true;
|
|
||||||
}
|
|
||||||
else if ((DMA_clock % 4) == 3)
|
|
||||||
{
|
|
||||||
Core.OAM[DMA_inc] = DMA_byte;
|
|
||||||
|
|
||||||
if (DMA_inc < (0xA0 - 1)) { DMA_inc++; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DMA_clock++;
|
|
||||||
|
|
||||||
if (DMA_clock == 648)
|
|
||||||
{
|
{
|
||||||
|
// the cpu can't access memory during this time, but we still need the ppu to be able to.
|
||||||
DMA_start = false;
|
DMA_start = false;
|
||||||
DMA_OAM_access = true;
|
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
|
||||||
|
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
|
||||||
|
byte DMA_actual = DMA_addr;
|
||||||
|
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
|
||||||
|
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
|
||||||
|
DMA_start = true;
|
||||||
}
|
}
|
||||||
|
else if ((DMA_clock % 4) == 3)
|
||||||
|
{
|
||||||
|
Core.OAM[DMA_inc] = DMA_byte;
|
||||||
|
|
||||||
|
if (DMA_inc < (0xA0 - 1)) { DMA_inc++; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DMA_clock++;
|
||||||
|
|
||||||
|
if (DMA_clock == 648)
|
||||||
|
{
|
||||||
|
DMA_start = false;
|
||||||
|
DMA_OAM_access = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,31 +87,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
if (!HDMA_transfer)
|
if (!HDMA_transfer)
|
||||||
{
|
{
|
||||||
// These things all tick twice as fast in GBC double speed mode
|
// These things all tick twice as fast in GBC double speed mode
|
||||||
ppu.DMA_tick();
|
// Note that DMA is halted when the CPU is halted
|
||||||
timer.tick_1();
|
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
||||||
timer.tick_2();
|
timer.tick();
|
||||||
|
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
ppu.DMA_tick();
|
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
|
||||||
timer.tick_1();
|
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
||||||
timer.tick_2();
|
timer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timer.tick_1();
|
|
||||||
timer.tick_2();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
timer.tick_1();
|
|
||||||
timer.tick_2();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,31 +152,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
if (!HDMA_transfer)
|
if (!HDMA_transfer)
|
||||||
{
|
{
|
||||||
// These things all tick twice as fast in GBC double speed mode
|
// These things all tick twice as fast in GBC double speed mode
|
||||||
ppu.DMA_tick();
|
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
|
||||||
timer.tick_1();
|
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
||||||
timer.tick_2();
|
timer.tick();
|
||||||
|
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
ppu.DMA_tick();
|
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
|
||||||
timer.tick_1();
|
|
||||||
serialport.serial_transfer_tick();
|
serialport.serial_transfer_tick();
|
||||||
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
|
||||||
timer.tick_2();
|
timer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timer.tick_1();
|
|
||||||
timer.tick_2();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
|
|
||||||
if (double_speed)
|
if (double_speed)
|
||||||
{
|
{
|
||||||
timer.tick_1();
|
|
||||||
timer.tick_2();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// x-scroll is expected to be latched one cycle later
|
// x-scroll is expected to be latched one cycle later
|
||||||
// this is fine since nothing has started in the rendering until the second cycle
|
// this is fine since nothing has started in the rendering until the second cycle
|
||||||
// calculate the column number of the tile to start with
|
// calculate the column number of the tile to start with
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = scroll_x >> 3;
|
||||||
render_offset = scroll_x % 8;
|
render_offset = scroll_x % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// x-scroll is expected to be latched one cycle later
|
// x-scroll is expected to be latched one cycle later
|
||||||
// this is fine since nothing has started in the rendering until the second cycle
|
// this is fine since nothing has started in the rendering until the second cycle
|
||||||
// calculate the column number of the tile to start with
|
// calculate the column number of the tile to start with
|
||||||
x_tile = (int)Math.Floor((float)(scroll_x) / 8);
|
x_tile = scroll_x >> 3;
|
||||||
render_offset = scroll_x % 8;
|
render_offset = scroll_x % 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
if ((internal_cycle % 2) == 1)
|
if ((internal_cycle % 2) == 1)
|
||||||
{
|
{
|
||||||
// calculate the row number of the tiles to be fetched
|
// calculate the row number of the tiles to be fetched
|
||||||
y_tile = ((int)Math.Floor((float)(scroll_y + LY) / 8)) % 32;
|
y_tile = (((int)scroll_y + LY) >> 3) % 32;
|
||||||
|
|
||||||
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
|
temp_fetch = y_tile * 32 + (x_tile + tile_inc) % 32;
|
||||||
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
|
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
|
||||||
|
@ -1018,38 +1018,34 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// So give it it's own function so we can seperate it from PPU tick
|
// So give it it's own function so we can seperate it from PPU tick
|
||||||
public override void DMA_tick()
|
public override void DMA_tick()
|
||||||
{
|
{
|
||||||
// Note that DMA is halted when the CPU is halted
|
if (DMA_clock >= 4)
|
||||||
if (DMA_start && !Core.cpu.halted)
|
|
||||||
{
|
{
|
||||||
if (DMA_clock >= 4)
|
DMA_OAM_access = false;
|
||||||
{
|
if ((DMA_clock % 4) == 1)
|
||||||
DMA_OAM_access = false;
|
|
||||||
if ((DMA_clock % 4) == 1)
|
|
||||||
{
|
|
||||||
// the cpu can't access memory during this time, but we still need the ppu to be able to.
|
|
||||||
DMA_start = false;
|
|
||||||
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
|
|
||||||
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
|
|
||||||
byte DMA_actual = DMA_addr;
|
|
||||||
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
|
|
||||||
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
|
|
||||||
DMA_start = true;
|
|
||||||
}
|
|
||||||
else if ((DMA_clock % 4) == 3)
|
|
||||||
{
|
|
||||||
Core.OAM[DMA_inc] = DMA_byte;
|
|
||||||
|
|
||||||
if (DMA_inc < (0xA0 - 1)) { DMA_inc++; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DMA_clock++;
|
|
||||||
|
|
||||||
if (DMA_clock == 648)
|
|
||||||
{
|
{
|
||||||
|
// the cpu can't access memory during this time, but we still need the ppu to be able to.
|
||||||
DMA_start = false;
|
DMA_start = false;
|
||||||
DMA_OAM_access = true;
|
// Gekkio reports that A14 being high on DMA transfers always represent WRAM accesses
|
||||||
|
// So transfers nominally from higher memory areas are actually still from there (i.e. FF -> DF)
|
||||||
|
byte DMA_actual = DMA_addr;
|
||||||
|
if (DMA_addr > 0xDF) { DMA_actual &= 0xDF; }
|
||||||
|
DMA_byte = Core.ReadMemory((ushort)((DMA_actual << 8) + DMA_inc));
|
||||||
|
DMA_start = true;
|
||||||
}
|
}
|
||||||
|
else if ((DMA_clock % 4) == 3)
|
||||||
|
{
|
||||||
|
Core.OAM[DMA_inc] = DMA_byte;
|
||||||
|
|
||||||
|
if (DMA_inc < (0xA0 - 1)) { DMA_inc++; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DMA_clock++;
|
||||||
|
|
||||||
|
if (DMA_clock == 648)
|
||||||
|
{
|
||||||
|
DMA_start = false;
|
||||||
|
DMA_OAM_access = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -14,11 +14,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
public byte timer_old;
|
public byte timer_old;
|
||||||
public byte timer_control;
|
public byte timer_control;
|
||||||
public byte pending_reload;
|
public byte pending_reload;
|
||||||
public byte write_ignore;
|
|
||||||
public bool old_state;
|
public bool old_state;
|
||||||
public bool state;
|
public bool state;
|
||||||
public bool reload_block;
|
public bool reload_block;
|
||||||
public bool TMA_coincidence;
|
public ulong next_free_cycle;
|
||||||
|
|
||||||
public byte ReadReg(int addr)
|
public byte ReadReg(int addr)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +45,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
// TIMA (Timer Counter)
|
// TIMA (Timer Counter)
|
||||||
case 0xFF05:
|
case 0xFF05:
|
||||||
if (write_ignore == 0)
|
if (Core.cpu.TotalExecutedCycles >= next_free_cycle)
|
||||||
{
|
{
|
||||||
timer_old = timer;
|
timer_old = timer;
|
||||||
timer = value;
|
timer = value;
|
||||||
|
@ -57,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
// TMA (Timer Modulo)
|
// TMA (Timer Modulo)
|
||||||
case 0xFF06:
|
case 0xFF06:
|
||||||
timer_reload = value;
|
timer_reload = value;
|
||||||
if (TMA_coincidence)
|
if (Core.cpu.TotalExecutedCycles < next_free_cycle)
|
||||||
{
|
{
|
||||||
timer = timer_reload;
|
timer = timer_reload;
|
||||||
timer_old = timer;
|
timer_old = timer;
|
||||||
|
@ -71,35 +70,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick_1()
|
public void tick()
|
||||||
{
|
|
||||||
if (write_ignore > 0)
|
|
||||||
{
|
|
||||||
write_ignore--;
|
|
||||||
if (write_ignore==0)
|
|
||||||
{
|
|
||||||
TMA_coincidence = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pending_reload > 0)
|
|
||||||
{
|
|
||||||
pending_reload--;
|
|
||||||
if (pending_reload == 0 && !reload_block)
|
|
||||||
{
|
|
||||||
timer = timer_reload;
|
|
||||||
timer_old = timer;
|
|
||||||
write_ignore = 4;
|
|
||||||
TMA_coincidence = true;
|
|
||||||
|
|
||||||
// set interrupts
|
|
||||||
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
|
||||||
Core.REG_FF0F |= 0x04;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick_2()
|
|
||||||
{
|
{
|
||||||
divider_reg++;
|
divider_reg++;
|
||||||
|
|
||||||
|
@ -148,6 +119,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
old_state = state;
|
old_state = state;
|
||||||
|
|
||||||
|
if (pending_reload > 0)
|
||||||
|
{
|
||||||
|
pending_reload--;
|
||||||
|
if (pending_reload == 0 && !reload_block)
|
||||||
|
{
|
||||||
|
timer = timer_reload;
|
||||||
|
timer_old = timer;
|
||||||
|
|
||||||
|
next_free_cycle = 4 + Core.cpu.TotalExecutedCycles;
|
||||||
|
|
||||||
|
// set interrupts
|
||||||
|
if (Core.REG_FFFF.Bit(2)) { Core.cpu.FlagI = true; }
|
||||||
|
Core.REG_FF0F |= 0x04;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
|
@ -158,11 +145,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
timer_old = 0;
|
timer_old = 0;
|
||||||
timer_control = 0xF8;
|
timer_control = 0xF8;
|
||||||
pending_reload = 0;
|
pending_reload = 0;
|
||||||
write_ignore = 0;
|
|
||||||
old_state = false;
|
old_state = false;
|
||||||
state = false;
|
state = false;
|
||||||
reload_block = false;
|
reload_block = false;
|
||||||
TMA_coincidence = false;
|
next_free_cycle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SyncState(Serializer ser)
|
public void SyncState(Serializer ser)
|
||||||
|
@ -173,11 +159,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
ser.Sync(nameof(timer_old), ref timer_old);
|
ser.Sync(nameof(timer_old), ref timer_old);
|
||||||
ser.Sync(nameof(timer_control), ref timer_control);
|
ser.Sync(nameof(timer_control), ref timer_control);
|
||||||
ser.Sync(nameof(pending_reload), ref pending_reload);
|
ser.Sync(nameof(pending_reload), ref pending_reload);
|
||||||
ser.Sync(nameof(write_ignore), ref write_ignore);
|
|
||||||
ser.Sync(nameof(old_state), ref old_state);
|
ser.Sync(nameof(old_state), ref old_state);
|
||||||
ser.Sync(nameof(state), ref state);
|
ser.Sync(nameof(state), ref state);
|
||||||
ser.Sync(nameof(reload_block), ref reload_block);
|
ser.Sync(nameof(reload_block), ref reload_block);
|
||||||
ser.Sync(nameof(TMA_coincidence), ref TMA_coincidence);
|
ser.Sync(nameof(next_free_cycle), ref next_free_cycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -179,12 +179,13 @@ namespace GBHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timer.tick();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
|
|
||||||
if (MemMap.double_speed)
|
if (MemMap.double_speed)
|
||||||
{
|
{
|
||||||
timer.tick();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,12 +231,13 @@ namespace GBHawk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timer.tick();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
|
|
||||||
if (MemMap.double_speed)
|
if (MemMap.double_speed)
|
||||||
{
|
{
|
||||||
timer.tick();
|
|
||||||
cpu.TotalExecutedCycles++;
|
cpu.TotalExecutedCycles++;
|
||||||
|
timer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue