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; 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;

View File

@ -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;
} }
} }

View File

@ -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;
} }
} }

View File

@ -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();
} }
} }

View File

@ -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;
} }
} }

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common; 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_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);
} }
} }
} }

View File

@ -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();
} }
} }