GBhawk: some C# optimizations

This commit is contained in:
alyosha-tas 2020-03-31 23:03:40 -04:00
parent 00471ac530
commit 0e0b94cd0c
8 changed files with 166 additions and 176 deletions

View File

@ -176,37 +176,47 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
I_use = false;
break;
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;
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;
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;
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;
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;
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;
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;
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;
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;
case INC8:
INC8_Func(instr_table[instr_pntr++]);
break;
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;
case DEC8:
DEC8_Func(instr_table[instr_pntr++]);
@ -236,16 +246,20 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
CCF_Func(instr_table[instr_pntr++]);
break;
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;
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;
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;
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;
case SLA:
SLA_Func(instr_table[instr_pntr++]);
@ -260,13 +274,16 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
SWAP_Func(instr_table[instr_pntr++]);
break;
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;
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;
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;
case EI:
if (EI_pending == 0) { EI_pending = 2; }
@ -457,10 +474,12 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
CB_prefix = true;
break;
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;
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;
case OP_G:
OnExecFetch?.Invoke(RegPC);
@ -474,7 +493,8 @@ namespace BizHawk.Emulation.Cores.Components.LR35902
instr_pntr--;
break;
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;
case EI_RETI:
EI_pending = 1;

View File

@ -526,7 +526,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// x-scroll is expected to be latched one cycle later
// this is fine since nothing has started in the rendering until the second cycle
// 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;
}
@ -586,7 +586,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// x-scroll is expected to be latched one cycle later
// this is fine since nothing has started in the rendering until the second cycle
// 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;
}
@ -947,7 +947,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((internal_cycle % 2) == 1)
{
// 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;
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
@ -1343,9 +1343,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// normal DMA moves twice as fast in double speed mode on GBC
// So give it it's own function so we can seperate it from PPU tick
public override void DMA_tick()
{
// Note that DMA is halted when the CPU is halted
if (DMA_start && !Core.cpu.halted)
{
if (DMA_clock >= 4)
{
@ -1377,7 +1374,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
DMA_OAM_access = true;
}
}
}
// order sprites according to x coordinate
// note that for sprites of equal x coordinate, priority goes to first on the list

View File

@ -522,7 +522,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// x-scroll is expected to be latched one cycle later
// this is fine since nothing has started in the rendering until the second cycle
// 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;
}
@ -582,7 +582,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// x-scroll is expected to be latched one cycle later
// this is fine since nothing has started in the rendering until the second cycle
// 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;
}
@ -913,7 +913,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((internal_cycle % 2) == 1)
{
// 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;
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
@ -1311,9 +1311,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// normal DMA moves twice as fast in double speed mode on GBC
// So give it it's own function so we can seperate it from PPU tick
public override void DMA_tick()
{
// Note that DMA is halted when the CPU is halted
if (DMA_start && !Core.cpu.halted)
{
if (DMA_clock >= 4)
{
@ -1345,7 +1342,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
DMA_OAM_access = true;
}
}
}
// order sprites according to x coordinate
// note that for sprites of equal x coordinate, priority goes to first on the list

View File

@ -87,31 +87,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!HDMA_transfer)
{
// These things all tick twice as fast in GBC double speed mode
ppu.DMA_tick();
timer.tick_1();
// Note that DMA is halted when the CPU is halted
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
timer.tick();
if (double_speed)
{
ppu.DMA_tick();
timer.tick_1();
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
timer.tick();
}
}
else
{
timer.tick_1();
timer.tick_2();
cpu.TotalExecutedCycles++;
timer.tick();
if (double_speed)
{
timer.tick_1();
timer.tick_2();
cpu.TotalExecutedCycles++;
timer.tick();
}
}
@ -155,31 +152,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if (!HDMA_transfer)
{
// These things all tick twice as fast in GBC double speed mode
ppu.DMA_tick();
timer.tick_1();
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
timer.tick();
if (double_speed)
{
ppu.DMA_tick();
timer.tick_1();
if (ppu.DMA_start && !cpu.halted) { ppu.DMA_tick(); }
serialport.serial_transfer_tick();
cpu.ExecuteOne(ref REG_FF0F, REG_FFFF);
timer.tick_2();
timer.tick();
}
}
else
{
timer.tick_1();
timer.tick_2();
cpu.TotalExecutedCycles++;
timer.tick();
if (double_speed)
{
timer.tick_1();
timer.tick_2();
cpu.TotalExecutedCycles++;
timer.tick();
}
}

View File

@ -298,7 +298,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// x-scroll is expected to be latched one cycle later
// this is fine since nothing has started in the rendering until the second cycle
// 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;
}
@ -360,7 +360,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// x-scroll is expected to be latched one cycle later
// this is fine since nothing has started in the rendering until the second cycle
// 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;
}
@ -654,7 +654,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
if ((internal_cycle % 2) == 1)
{
// 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;
tile_byte = Core.VRAM[0x1800 + (LCDC.Bit(3) ? 1 : 0) * 0x400 + temp_fetch];
@ -1017,9 +1017,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// normal DMA moves twice as fast in double speed mode on GBC
// So give it it's own function so we can seperate it from PPU tick
public override void DMA_tick()
{
// Note that DMA is halted when the CPU is halted
if (DMA_start && !Core.cpu.halted)
{
if (DMA_clock >= 4)
{
@ -1051,7 +1048,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
DMA_OAM_access = true;
}
}
}
// order sprites according to x coordinate
// note that for sprites of equal x coordinate, priority goes to first on the list

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common;
using System;
/*

View File

@ -14,11 +14,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public byte timer_old;
public byte timer_control;
public byte pending_reload;
public byte write_ignore;
public bool old_state;
public bool state;
public bool reload_block;
public bool TMA_coincidence;
public ulong next_free_cycle;
public byte ReadReg(int addr)
{
@ -46,7 +45,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// TIMA (Timer Counter)
case 0xFF05:
if (write_ignore == 0)
if (Core.cpu.TotalExecutedCycles >= next_free_cycle)
{
timer_old = timer;
timer = value;
@ -57,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
// TMA (Timer Modulo)
case 0xFF06:
timer_reload = value;
if (TMA_coincidence)
if (Core.cpu.TotalExecutedCycles < next_free_cycle)
{
timer = timer_reload;
timer_old = timer;
@ -71,35 +70,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
}
public void tick_1()
{
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()
public void tick()
{
divider_reg++;
@ -148,6 +119,22 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
}
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()
@ -158,11 +145,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
timer_old = 0;
timer_control = 0xF8;
pending_reload = 0;
write_ignore = 0;
old_state = false;
state = false;
reload_block = false;
TMA_coincidence = false;
next_free_cycle = 0;
}
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_control), ref timer_control);
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(state), ref state);
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);
}
}
}

View File

@ -179,12 +179,13 @@ namespace GBHawk
}
else
{
timer.tick();
cpu.TotalExecutedCycles++;
timer.tick();
if (MemMap.double_speed)
{
timer.tick();
cpu.TotalExecutedCycles++;
timer.tick();
}
}
@ -230,12 +231,13 @@ namespace GBHawk
}
else
{
timer.tick();
cpu.TotalExecutedCycles++;
timer.tick();
if (MemMap.double_speed)
{
timer.tick();
cpu.TotalExecutedCycles++;
timer.tick();
}
}