GBHawk: more integration work

This commit is contained in:
alyosha-tas 2020-03-28 20:21:43 -04:00
parent a072879dca
commit 47704b94fd
6 changed files with 444 additions and 74 deletions

View File

@ -35,9 +35,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
/// <param name="core">opaque state pointer</param>
/// <param name="romdata_1">the rom data, can be disposed of once this function returns</param>
/// <param name="length_1">length of romdata in bytes</param>
/// <param name="MD5">Hash used for mapper loading</param>
/// <param name="RTC_init">Initial RTC time</param>
/// <param name="RTC_offset">Clck offset for RTC</param>
/// <returns>0 on success, negative value on failure.</returns>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GB_load(IntPtr core, byte[] romdata_1, uint length_1, uint RTC_init, uint RTC_offset);
public static extern int GB_load(IntPtr core, byte[] romdata_1, uint length_1, char[] MD5, uint RTC_init, uint RTC_offset);
/// <summary>
/// Advance a frame and send controller data.
@ -93,12 +96,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
#region Memory Domain Functions
/// <summary>
/// Read the system bus
/// Read the RAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">system bus address</param>
/// <param name="addr">ram address</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_getsysbus(IntPtr core, int addr);
public static extern byte GB_getram(IntPtr core, int addr);
/// <summary>
/// Read the VRAM
@ -108,13 +111,74 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_getvram(IntPtr core, int addr);
/// <summary>
/// Read the VRAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">vram address</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_getoam(IntPtr core, int addr);
/// <summary>
/// Read the VRAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">vram address</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_gethram(IntPtr core, int addr);
/// <summary>
/// Read the system bus
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">system bus address</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_getsysbus(IntPtr core, int addr);
/// <summary>
/// Read the RAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">ram address</param>
/// <param name="value">write value</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_getram(IntPtr core, int addr);
public static extern void GB_setram(IntPtr core, int addr, byte value);
/// <summary>
/// Read the VRAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">vram address</param>
/// <param name="value">write value</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_setvram(IntPtr core, int addr, byte value);
/// <summary>
/// Read the VRAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">vram address</param>
/// <param name="value">write value</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_setoam(IntPtr core, int addr, byte value);
/// <summary>
/// Read the VRAM
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">vram address</param>
/// <param name="value">write value</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_sethram(IntPtr core, int addr, byte value);
/// <summary>
/// Read the system bus
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="addr">system bus address</param>
/// <param name="value">write value</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_setsysbus(IntPtr core, int addr, byte value);
#endregion
@ -175,7 +239,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
public static extern void GB_getregisterstate(IntPtr core, StringBuilder h, int t, int l);
/// <summary>
/// get the register state from the cpu
/// get the opcode disassembly
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="d">pointer to const char *</param>
@ -184,5 +248,88 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_getdisassembly(IntPtr core, StringBuilder h, int t, int l);
#endregion
#region PPU_Viewer
/// <summary>
/// type of the cpu trace callback
/// </summary>
/// <param name="lcdc">type of event</param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ScanlineCallback(byte lcdc);
/// <summary>
/// Get PPU Pointers
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="sel">region to get</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GB_get_ppu_pntrs(IntPtr core, int sel);
/// <summary>
/// Get PPU Pointers
/// </summary>
/// <param name="core">opaque state pointer</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_get_LCDC(IntPtr core);
/// <summary>
/// set a callback to occur when ly reaches a particular scanline (so at the beginning of the scanline).
/// when the LCD is active, typically 145 will be the first callback after the beginning of frame advance,
/// and 144 will be the last callback right before frame advance returns
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="callback">null to clear</param>
/// <param name="sl">0-153 inclusive</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_setscanlinecallback(IntPtr core, ScanlineCallback callback, int sl);
#endregion
#region debuggable funcitons
/// <summary>
/// get the current cpu cycle count
/// </summary>
/// <param name="core">opaque state pointer</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GB_cpu_cycles(IntPtr core);
/// <summary>
/// get the registers
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="reg">reg number (see the DLL)</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern byte GB_cpu_get_regs(IntPtr core, int reg);
/// <summary>
/// get the flags
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="flag">flag number (see the DLL)</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool GB_cpu_get_flags(IntPtr core, int flag);
/// <summary>
/// get the registers
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="reg">reg number (see the DLL)</param>
/// <param name="value">value to set</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_cpu_set_regs(IntPtr core, int reg, byte value);
/// <summary>
/// get the flags
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="flag">flag number (see the DLL)</param>
/// <param name="value">value to set</param>
[DllImport("GBHawk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void GB_cpu_set_flags(IntPtr core, int flag, bool value);
#endregion
}
}

View File

@ -109,6 +109,25 @@ namespace GBHawk
MemMap.mapper_pntr->Cart_RAM = &MemMap.Cart_RAM[0];
}
void Reset()
{
MemMap.GB_bios_register = 0; // bios enable
MemMap.GBC_compat = MemMap.is_GBC;
MemMap.in_vblank = true; // we start off in vblank since the LCD is off
MemMap.in_vblank_old = true;
MemMap.double_speed = false;
MemMap.VRAM_Bank = 0;
MemMap.RAM_Bank = 1; // RAM bank always starts as 1 (even writing zero still sets 1)
MemMap.Register_Reset();
timer.Reset();
ppu->Reset();
psg.Reset();
serialport.Reset();
mapper->Reset();
cpu.Reset();
}
bool FrameAdvance(uint8_t controller_1, uint8_t controller_2, uint8_t* kb_rows_ptr, bool render, bool rendersound)
{
@ -384,19 +403,56 @@ namespace GBHawk
#pragma region Memory Domain Functions
uint8_t GetSysBus(uint32_t addr)
uint8_t GetRAM(uint32_t addr)
{
return cpu.PeekMemory(addr);
return MemMap.RAM[addr & 0x7FFF];
}
uint8_t GetVRAM(uint32_t addr)
uint8_t GetVRAM(uint32_t addr)
{
return MemMap.VRAM[addr & 0x3FFF];
}
uint8_t GetRAM(uint32_t addr)
uint8_t GetOAM(uint32_t addr)
{
return MemMap.RAM[addr & 0xFFFF];
return MemMap.OAM[addr];
}
uint8_t GetHRAM(uint32_t addr)
{
return MemMap.ZP_RAM[addr & 0x7F];
}
uint8_t GetSysBus(uint32_t addr)
{
return MemMap.PeekMemory(addr);
}
void SetRAM(uint32_t addr, uint8_t value)
{
MemMap.RAM[addr & 0x7FFF] = value;
}
void SetVRAM(uint32_t addr, uint8_t value)
{
MemMap.VRAM[addr & 0x3FFF] = value;
}
void SetOAM(uint32_t addr, uint8_t value)
{
MemMap.OAM[addr] = value;
}
void SetHRAM(uint32_t addr, uint8_t value)
{
MemMap.ZP_RAM[addr & 0x7F] = value;
}
void SetSysBus(uint32_t addr, uint8_t value)
{
// make poke?
MemMap.WriteMemory(addr, value);
}
#pragma endregion
@ -408,6 +464,12 @@ namespace GBHawk
cpu.TraceCallback = callback;
}
void SetScanlineCallback(void (*callback)(void), int sl)
{
ppu->scanlineCallback = callback;
MemMap._scanlineCallbackLine = sl;
}
int GetHeaderLength()
{
return 105 + 1;
@ -420,7 +482,7 @@ namespace GBHawk
int GetRegStringLength()
{
return 86 + 1;
return 74 + 1;
}
void GetHeader(char* h, int l)

View File

@ -33,13 +33,18 @@ GBHawk_EXPORT void GB_load_bios(GBCore* p, uint8_t* bios, bool GBC_console, bool
}
// load a rom into the core
GBHawk_EXPORT void GB_load(GBCore* p, uint8_t* rom_1, uint32_t size_1, uint32_t RTC_initial, uint32_t RTC_offset)
GBHawk_EXPORT void GB_load(GBCore* p, uint8_t* rom_1, uint32_t size_1, char* MD5, uint32_t RTC_initial, uint32_t RTC_offset)
{
string MD5;
string MD5_s(MD5, 32);
p->Load_ROM(rom_1, size_1, MD5, RTC_initial, RTC_offset);
p->Load_ROM(rom_1, size_1, MD5_s, RTC_initial, RTC_offset);
}
// Hard reset (note: does not change RTC, that only happens on load)
GBHawk_EXPORT void GB_Reset(GBCore* p)
{
p->Reset();
}
// advance a frame
GBHawk_EXPORT bool GB_frame_advance(GBCore* p, uint8_t ctrl1, uint8_t ctrl2, uint8_t* kbrows, bool render, bool sound)
{
@ -57,6 +62,7 @@ GBHawk_EXPORT uint32_t GB_get_audio(GBCore* p, int32_t* dest_L, int32_t* n_samp_
{
return p->GetAudio(dest_L, n_samp_L, dest_R, n_samp_R);
}
#pragma endregion
#pragma region State Save / Load
@ -76,21 +82,48 @@ GBHawk_EXPORT void GB_load_state(GBCore* p, uint8_t* loader)
#pragma region Memory Domain Functions
GBHawk_EXPORT uint8_t GB_getsysbus(GBCore* p, uint32_t addr) {
return p->GetSysBus(addr);
GBHawk_EXPORT uint8_t GB_getram(GBCore* p, uint32_t addr) {
return p->GetRAM(addr);
}
GBHawk_EXPORT uint8_t GB_getvram(GBCore* p, uint32_t addr) {
return p->GetVRAM(addr);
}
GBHawk_EXPORT uint8_t GB_getram(GBCore* p, uint32_t addr) {
return p->GetRAM(addr);
GBHawk_EXPORT uint8_t GB_getoam(GBCore* p, uint32_t addr) {
return p->GetOAM(addr);
}
GBHawk_EXPORT uint8_t GB_gethram(GBCore* p, uint32_t addr) {
return p->GetHRAM(addr);
}
GBHawk_EXPORT uint8_t GB_getsysbus(GBCore* p, uint32_t addr) {
return p->GetSysBus(addr);
}
GBHawk_EXPORT void GB_setram(GBCore* p, uint32_t addr, uint8_t value) {
p->SetRAM(addr, value);
}
GBHawk_EXPORT void GB_setvram(GBCore* p, uint32_t addr, uint8_t value) {
p->SetVRAM(addr, value);
}
GBHawk_EXPORT void GB_setoam(GBCore* p, uint32_t addr, uint8_t value) {
p->SetOAM(addr, value);
}
GBHawk_EXPORT void GB_sethram(GBCore* p, uint32_t addr, uint8_t value) {
p->SetHRAM(addr, value);
}
GBHawk_EXPORT void GB_setsysbus(GBCore* p, uint32_t addr, uint8_t value) {
p->SetSysBus(addr, value);
}
#pragma endregion
#pragma region Tracer
// set tracer callback
@ -128,4 +161,94 @@ GBHawk_EXPORT void GB_getdisassembly(GBCore* p, char* d, int t, int l) {
p->GetDisassembly(d, t, l);
}
#pragma endregion
#pragma region PPU Viewer
// set tracer callback
GBHawk_EXPORT uint8_t* GB_get_ppu_pntrs(GBCore* p, int sel) {
if (p->MemMap.is_GBC)
{
switch (sel)
{
case 0: return p->MemMap.VRAM; break;
case 1: return p->MemMap.OAM; break;
case 2: return (uint8_t*)p->ppu->OBJ_palette; break;
case 3: return (uint8_t*)p->ppu->BG_palette; break;
}
}
else
{
// need to fix this for GB
switch (sel)
{
case 0: return p->MemMap.VRAM; break;
case 1: return p->MemMap.OAM; break;
case 2: return (uint8_t*)p->ppu->OBJ_palette; break;
case 3: return (uint8_t*)p->ppu->BG_palette; break;
}
}
return nullptr;
}
// return LCDC state for the ppu viewer
GBHawk_EXPORT uint8_t GB_get_LCDC(GBCore* p) {
return p->ppu->LCDC;
}
// set scanline callback
GBHawk_EXPORT void GB_setscanlinecallback(GBCore* p, void (*callback)(void), int sl) {
p->SetScanlineCallback(callback, sl);
}
#pragma endregion
#pragma region Debuggable functions
// return cpu cycle count
GBHawk_EXPORT uint64_t GB_cpu_cycles(GBCore* p) {
return p->cpu.TotalExecutedCycles;
}
// return cpu registers
GBHawk_EXPORT uint8_t GB_cpu_get_regs(GBCore* p, int reg) {
return p->cpu.Regs[reg];
}
// return cpu flags
GBHawk_EXPORT bool GB_cpu_get_flags(GBCore* p, int reg) {
bool ret = false;
switch (reg)
{
case (0): ret = p->cpu.FlagI; break;
case (1): ret = p->cpu.FlagCget(); break;
case (2): ret = p->cpu.FlagHget(); break;
case (3): ret = p->cpu.FlagNget(); break;
case (4): ret = p->cpu.FlagZget(); break;
}
return ret;
}
// set cpu registers
GBHawk_EXPORT void GB_cpu_set_regs(GBCore* p, int reg, uint8_t value) {
p->cpu.Regs[reg] = value;
}
// set cpu flags
GBHawk_EXPORT void GB_cpu_set_flags(GBCore* p, int reg, bool value) {
switch (reg)
{
case (0): p->cpu.FlagI = value; break;
case (1): p->cpu.FlagCset(value); break;
case (2): p->cpu.FlagHset(value); break;
case (3): p->cpu.FlagNset(value); break;
case (4): p->cpu.FlagZset(value); break;
}
}
#pragma endregion

View File

@ -166,6 +166,8 @@ namespace GBHawk
CB_prefix = false;
}
void Reset()
{
ResetRegisters();
@ -2626,12 +2628,12 @@ namespace GBHawk
#pragma region Disassemble
// disassemblies will also return strings of the same length
const char* TraceHeader = "Z80A: PC, machine code, mnemonic, operands, registers (AF, BC, DE, HL, IX, IY, SP, Cy), flags (CNP3H5ZS)";
const char* TraceHeader = "LR35902: PC, machine code, mnemonic, operands, registers (A, F, B, C, D, E, H, L, SP), Cy, flags(ZNHCIE)";
const char* Un_halt_event = " ==Un-halted== ";
const char* IRQ_event = " ====IRQ==== ";
const char* Un_stop_event = " ==Un-stopped== ";
const char* No_Reg = " ";
const char* Reg_template = "AF:AAFF BC:BBCC DE:DDEE HL:HHLL Ix:IxIx Iy:IyIy SP:SPSP Cy:FEDCBA9876543210 CNP3H5ZSE";
const char* Reg_template = "A:AA F:FF B:BB C:CC D:DD E:EE H:HH L:LL SP:SPSP Cy:FEDCBA9876543210 ZNHCIE";
const char* Disasm_template = "PCPC: AA BB CC DD Di Di, XXXXX ";
char replacer[32] = {};
@ -2646,25 +2648,37 @@ namespace GBHawk
{
val_char_1 = replacer;
string reg_state = "AF:";
temp_reg = (Regs[A] << 8) + Regs[F];
sprintf_s(val_char_1, 5, "%04X", temp_reg);
reg_state.append(val_char_1, 4);
string reg_state = "A:";
sprintf_s(val_char_1, 5, "%02X", Regs[A]);
reg_state.append(val_char_1, 2);
reg_state.append(" BC:");
temp_reg = (Regs[B] << 8) + Regs[C];
sprintf_s(val_char_1, 5, "%04X", temp_reg);
reg_state.append(val_char_1, 4);
reg_state = "F:";
sprintf_s(val_char_1, 5, "%02X", Regs[F]);
reg_state.append(val_char_1, 2);
reg_state.append(" DE:");
temp_reg = (Regs[D] << 8) + Regs[E];
sprintf_s(val_char_1, 5, "%04X", temp_reg);
reg_state.append(val_char_1, 4);
reg_state = "B:";
sprintf_s(val_char_1, 5, "%02X", Regs[B]);
reg_state.append(val_char_1, 2);
reg_state.append(" HL:");
temp_reg = (Regs[H] << 8) + Regs[L];
sprintf_s(val_char_1, 5, "%04X", temp_reg);
reg_state.append(val_char_1, 4);
reg_state = "C:";
sprintf_s(val_char_1, 5, "%02X", Regs[C]);
reg_state.append(val_char_1, 2);
reg_state = "D:";
sprintf_s(val_char_1, 5, "%02X", Regs[D]);
reg_state.append(val_char_1, 2);
reg_state = "E:";
sprintf_s(val_char_1, 5, "%02X", Regs[E]);
reg_state.append(val_char_1, 2);
reg_state = "H:";
sprintf_s(val_char_1, 5, "%02X", Regs[H]);
reg_state.append(val_char_1, 2);
reg_state = "L:";
sprintf_s(val_char_1, 5, "%02X", Regs[L]);
reg_state.append(val_char_1, 2);
reg_state.append(" SP:");
temp_reg = (Regs[SPh] << 8) + Regs[SPl];
@ -2679,7 +2693,8 @@ namespace GBHawk
reg_state.append(FlagNget() ? "N" : "n");
reg_state.append(FlagHget() ? "H" : "h");
reg_state.append(FlagZget() ? "Z" : "z");
reg_state.append(FlagI ? "E" : "e");
reg_state.append(FlagI ? "I" : "i");
reg_state.append(interrupts_enabled ? "E" : "e");
return reg_state;
}
@ -2734,9 +2749,9 @@ namespace GBHawk
//n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present)
if (format.find("nn") != string::npos)
if (format.find("a16") != string::npos)
{
size_t str_loc = format.find("nn");
size_t str_loc = format.find("a16");
val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%02X", PeekMemory(addr[0] & 0xFFFF));
@ -2748,25 +2763,60 @@ namespace GBHawk
string val2(val_char_2, 2);
addr[0]++;
format.erase(str_loc, 2);
format.erase(str_loc, 3);
format.insert(str_loc, val1);
format.insert(str_loc, val2);
}
if (format.find("n") != string::npos)
if (format.find("d16") != string::npos)
{
size_t str_loc = format.find("n");
size_t str_loc = format.find("d16");
val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%02X", PeekMemory(addr[0] & 0xFFFF));
string val1(val_char_1, 2);
addr[0]++;
format.erase(str_loc, 1);
val_char_2 = replacer;
sprintf_s(val_char_2, 5, "%02X", PeekMemory(addr[0] & 0xFFFF));
string val2(val_char_2, 2);
addr[0]++;
format.erase(str_loc, 3);
format.insert(str_loc, val1);
format.insert(str_loc, val2);
}
if (format.find("d8") != string::npos)
{
size_t str_loc = format.find("d8");
val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%02X", PeekMemory(addr[0] & 0xFFFF));
string val1(val_char_1, 2);
addr[0]++;
format.erase(str_loc, 2);
format.insert(str_loc, val1);
}
if (format.find("+d") != string::npos)
if (format.find("a8") != string::npos)
{
size_t str_loc = format.find("a8");
val_char_2 = replacer;
sprintf_s(val_char_1, 5, "%02X", PeekMemory(addr[0] & 0xFFFF));
string val1(val_char_1, 2);
addr[0]++;
string val2 = "FF";
format.erase(str_loc, 2);
format.insert(str_loc, val1);
format.insert(str_loc, val2);
}
if (format.find("r8") != string::npos)
{
size_t str_loc = format.find("+d");
@ -2778,18 +2828,6 @@ namespace GBHawk
format.erase(str_loc, 2);
format.insert(str_loc, val1);
}
if (format.find("d") != string::npos)
{
size_t str_loc = format.find("d");
val_char_1 = replacer;
sprintf_s(val_char_1, 5, "%+04d", (int8_t)PeekMemory(addr[0] & 0xFFFF));
string val1(val_char_1, 4);
addr[0]++;
format.erase(str_loc, 1);
format.insert(str_loc, val1);
}
return format;
}

View File

@ -56,6 +56,7 @@ namespace GBHawk
bool GBC_compat;
bool speed_switch, double_speed;
bool in_vblank;
bool in_vblank_old;
bool GB_bios_register;
bool HDMA_transfer;
bool _islag;

View File

@ -19,6 +19,8 @@ namespace GBHawk
}
void (*scanlineCallback)(void);
uint8_t ReadMemory(uint32_t);
MemoryManager* mem_ctrl;
@ -725,11 +727,10 @@ namespace GBHawk
// scanline callback
if ((LY + LY_inc) == _scanlineCallbackLine[0])
{
//if (Core._scanlineCallback != null)
//{
//Core.GetGPU();
//Core._scanlineCallback(LCDC);
//}
if (scanlineCallback)
{
scanlineCallback();
}
}
cycle = 0;
@ -2146,11 +2147,10 @@ namespace GBHawk
// scanline callback
if ((LY + LY_inc) == _scanlineCallbackLine[0])
{
//if (Core._scanlineCallback != null)
//{
// Core.GetGPU();
// Core._scanlineCallback(LCDC);
//}
if (scanlineCallback)
{
scanlineCallback();
}
}
cycle = 0;
@ -3707,11 +3707,10 @@ namespace GBHawk
// scanline callback
if ((LY + LY_inc) == _scanlineCallbackLine[0])
{
//if (Core._scanlineCallback != null)
//{
// Core.GetGPU();
// Core._scanlineCallback(LCDC);
//}
if (scanlineCallback)
{
scanlineCallback();
}
}
cycle = 0;