From b039b1f823058585413404a9884886b85c78bca6 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 29 Mar 2020 12:15:08 -0400 Subject: [PATCH] GBHawk: start cleaning up errors --- .../GBHawk_new/GBHawkNew.IEmulator.cs | 8 +- .../GBHawk_new/GBHawkNew.IStatable.cs | 8 +- .../Consoles/Nintendo/GBHawk_new/GBHawkNew.cs | 9 +- libHawk/GBHawk/GBHawk/Core.h | 13 +- libHawk/GBHawk/GBHawk/GBHawk.vcxproj | 2 +- libHawk/GBHawk/GBHawk/LR35902.h | 60 +++--- libHawk/GBHawk/GBHawk/Memory.h | 175 ++++++++++++++++-- 7 files changed, 206 insertions(+), 69 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IEmulator.cs index 75b23f5814..45a57fab66 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IEmulator.cs @@ -114,20 +114,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkNew #region Video provider - public int[] _vidbuffer; - public int[] frame_buffer; public int[] GetVideoBuffer() { + LibGBHawk.GB_get_video(GB_Pntr, frame_buffer); return frame_buffer; } - public void SendVideoBuffer() - { - - } - public int VirtualWidth => 160; public int VirtualHeight => 144; public int BufferWidth => 160; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IStatable.cs index 4b76beeb54..e1cd913e19 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.IStatable.cs @@ -7,13 +7,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkNew { private void SyncState(Serializer ser) { - byte[] core = null; - if (ser.IsWriter) - { - using var ms = new MemoryStream(); - ms.Close(); - core = ms.ToArray(); - } + ser.BeginSection("GB"); ser.Sync("Frame", ref _frame); ser.Sync("LagCount", ref _lagCount); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.cs index 664100144f..677709a606 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk_new/GBHawkNew.cs @@ -31,8 +31,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkNew [CoreConstructor(new[] { "GB", "GBC" })] public GBHawkNew(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ object settings, object syncSettings) { - var ser = new BasicServiceProvider(this); - + ServiceProvider = new BasicServiceProvider(this); _settings = (GBSettings)settings ?? new GBSettings(); _syncSettings = (GBSyncSettings)syncSettings ?? new GBSyncSettings(); _controllerDeck = new GBHawkNewControllerDeck(_syncSettings.Port1); @@ -69,6 +68,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkNew } _bios = Bios; + _rom = rom; GB_Pntr = LibGBHawk.GB_create(); @@ -101,10 +101,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkNew Console.WriteLine("MD5: " + rom.HashMD5(0, rom.Length)); Console.WriteLine("SHA1: " + rom.HashSHA1(0, rom.Length)); - ser.Register(this); - - ServiceProvider = ser; - HardReset(); iptr0 = LibGBHawk.GB_get_ppu_pntrs(GB_Pntr, 0); @@ -176,7 +172,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkNew { LibGBHawk.GB_Reset(GB_Pntr); - _vidbuffer = new int[VirtualWidth * VirtualHeight]; frame_buffer = new int[VirtualWidth * VirtualHeight]; } diff --git a/libHawk/GBHawk/GBHawk/Core.h b/libHawk/GBHawk/GBHawk/Core.h index 387d0c82ee..d13f861fde 100644 --- a/libHawk/GBHawk/GBHawk/Core.h +++ b/libHawk/GBHawk/GBHawk/Core.h @@ -18,7 +18,8 @@ namespace GBHawk public: GBCore() { - + ppu = nullptr; + mapper = nullptr; }; PPU* ppu; @@ -319,7 +320,7 @@ namespace GBHawk uint32_t* src = MemMap.frame_buffer; uint32_t* dst = dest; - std::memcpy(dst, src, sizeof uint32_t * 256 * 192); + std::memcpy(dst, src, sizeof uint32_t * 160 * 144); } uint32_t GetAudio(int32_t* dest_L, int32_t* n_samp_L, int32_t* dest_R, int32_t* n_samp_R) @@ -562,6 +563,9 @@ namespace GBHawk saver = cpu.SaveState(saver); saver = psg.SaveState(saver); saver = MemMap.SaveState(saver); + saver = timer.SaveState(saver); + saver = serialport.SaveState(saver); + saver = mapper->SaveState(saver); } void LoadState(uint8_t* loader) @@ -570,6 +574,9 @@ namespace GBHawk loader = cpu.LoadState(loader); loader = psg.LoadState(loader); loader = MemMap.LoadState(loader); + loader = timer.SaveState(loader); + loader = serialport.SaveState(loader); + loader = mapper->SaveState(loader); } #pragma endregion @@ -655,7 +662,7 @@ namespace GBHawk int GetRegStringLength() { - return 74 + 1; + return 81 + 1; } void GetHeader(char* h, int l) diff --git a/libHawk/GBHawk/GBHawk/GBHawk.vcxproj b/libHawk/GBHawk/GBHawk/GBHawk.vcxproj index 1a46a4b2ff..6cc7eb9047 100644 --- a/libHawk/GBHawk/GBHawk/GBHawk.vcxproj +++ b/libHawk/GBHawk/GBHawk/GBHawk.vcxproj @@ -81,7 +81,7 @@ false - ..\..\..\output\dll + ..\..\..\output\dll\ diff --git a/libHawk/GBHawk/GBHawk/LR35902.h b/libHawk/GBHawk/GBHawk/LR35902.h index a96a999a31..747ca96eaa 100644 --- a/libHawk/GBHawk/GBHawk/LR35902.h +++ b/libHawk/GBHawk/GBHawk/LR35902.h @@ -228,7 +228,7 @@ namespace GBHawk else { //OnExecFetch ? .Invoke(RegPC); - if (TraceCallback) { TraceCallback(0); } + if (TraceCallback && !CB_prefix) { TraceCallback(0); } //CDLCallback ? .Invoke(RegPC, eCDLogMemFlags.FetchFirst); FetchInstruction(ReadMemory(RegPCget())); RegPCset(RegPCget() + 1); @@ -244,7 +244,7 @@ namespace GBHawk instr_pntr += 3; break; case TR: - TR_Func(instr_table[instr_pntr++], instr_table[instr_pntr + 1]); + TR_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]); instr_pntr += 2; break; case ADD16: @@ -252,30 +252,30 @@ namespace GBHawk instr_pntr += 4; break; case ADD8: - ADD8_Func(instr_table[instr_pntr++], instr_table[instr_pntr + 1]); + 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 + 1]); + 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 + 1]); + 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 + 1]); + 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 + 1]); + 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 + 1]); + DEC16_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]); instr_pntr += 2; break; case DEC8: @@ -306,19 +306,19 @@ namespace GBHawk CCF_Func(instr_table[instr_pntr++]); break; case AND8: - AND8_Func(instr_table[instr_pntr++], instr_table[instr_pntr + 1]); + 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 + 1]); + 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 + 1]); + 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 + 1]); + CP8_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]); instr_pntr += 2; break; case SLA: @@ -334,15 +334,15 @@ namespace GBHawk SWAP_Func(instr_table[instr_pntr++]); break; case BIT: - BIT_Func(instr_table[instr_pntr++], instr_table[instr_pntr + 1]); + 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 + 1]); + 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 + 1]); + SET_Func(instr_table[instr_pntr], instr_table[instr_pntr + 1]); instr_pntr += 2; break; case EI: @@ -521,12 +521,12 @@ namespace GBHawk CB_prefix = true; break; case ASGN: - ASGN_Func(instr_table[instr_pntr++], instr_table[instr_pntr + 1]); + 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 + 1], instr_table[instr_pntr + 2], instr_table[instr_pntr + 3]); - instr_pntr += 2; + instr_pntr += 4; break; case OP_G: //OnExecFetch ? .Invoke(RegPC); @@ -541,7 +541,7 @@ namespace GBHawk break; case RD_F: Read_Func_F(instr_table[instr_pntr], instr_table[instr_pntr + 1], instr_table[instr_pntr + 2]); - instr_pntr += 2; + instr_pntr += 3; break; case EI_RETI: EI_pending = 1; @@ -2633,7 +2633,7 @@ namespace GBHawk const char* IRQ_event = " ====IRQ==== "; const char* Un_stop_event = " ==Un-stopped== "; const char* No_Reg = " "; - 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* Reg_template = "A:AA F:FF B:BB C:CC D:DD E:EE H:HH L:LL SP:SPSP Cy:FEDCBA9876543210 LY:LLY ZNHCIE"; const char* Disasm_template = "PCPC: AA BB CC DD Di Di, XXXXX "; char replacer[32] = {}; @@ -2652,31 +2652,31 @@ namespace GBHawk sprintf_s(val_char_1, 5, "%02X", Regs[A]); reg_state.append(val_char_1, 2); - reg_state = "F:"; + reg_state.append(" F:"); sprintf_s(val_char_1, 5, "%02X", Regs[F]); reg_state.append(val_char_1, 2); - reg_state = "B:"; + reg_state.append(" B:"); sprintf_s(val_char_1, 5, "%02X", Regs[B]); reg_state.append(val_char_1, 2); - reg_state = "C:"; + reg_state.append(" C:"); sprintf_s(val_char_1, 5, "%02X", Regs[C]); reg_state.append(val_char_1, 2); - reg_state = "D:"; + reg_state.append(" D:"); sprintf_s(val_char_1, 5, "%02X", Regs[D]); reg_state.append(val_char_1, 2); - reg_state = "E:"; + reg_state.append(" E:"); sprintf_s(val_char_1, 5, "%02X", Regs[E]); reg_state.append(val_char_1, 2); - reg_state = "H:"; + reg_state.append(" H:"); sprintf_s(val_char_1, 5, "%02X", Regs[H]); reg_state.append(val_char_1, 2); - reg_state = "L:"; + reg_state.append(" L:"); sprintf_s(val_char_1, 5, "%02X", Regs[L]); reg_state.append(val_char_1, 2); @@ -2688,6 +2688,10 @@ namespace GBHawk reg_state.append(" Cy:"); reg_state.append(val_char_1, sprintf_s(val_char_1, 32, "%16u", (unsigned long)TotalExecutedCycles)); reg_state.append(" "); + + reg_state.append(" LY:"); + reg_state.append(val_char_1, sprintf_s(val_char_1, 32, "%3u", LY)); + reg_state.append(" "); reg_state.append(FlagCget() ? "C" : "c"); reg_state.append(FlagNget() ? "N" : "n"); @@ -2818,10 +2822,10 @@ namespace GBHawk if (format.find("r8") != string::npos) { - size_t str_loc = format.find("+d"); + size_t str_loc = format.find("r8"); val_char_1 = replacer; - sprintf_s(val_char_1, 5, "%+04d", (int8_t)PeekMemory(addr[0] & 0xFFFF)); + sprintf_s(val_char_1, 5, "%04X", ((addr[0] + 1) + (int8_t)PeekMemory(addr[0] & 0xFFFF)) & 0xFFFF); string val1(val_char_1, 4); addr[0]++; diff --git a/libHawk/GBHawk/GBHawk/Memory.h b/libHawk/GBHawk/GBHawk/Memory.h index e9ecbaa0a5..6003a6fc3c 100644 --- a/libHawk/GBHawk/GBHawk/Memory.h +++ b/libHawk/GBHawk/GBHawk/Memory.h @@ -58,23 +58,24 @@ namespace GBHawk bool HDMA_transfer; bool Use_MT; bool has_bat; - - uint8_t REG_FFFF, REG_FF0F, REG_FF0F_OLD; - uint8_t _scanlineCallbackLine; - uint8_t input_register; - uint32_t RAM_Bank; - uint32_t VRAM_Bank; uint8_t IR_reg, IR_mask, IR_signal, IR_receive, IR_self; - uint32_t IR_write; - uint32_t addr_access; - uint32_t Acc_X_state; - uint32_t Acc_Y_state; // several undocumented GBC Registers uint8_t undoc_6C, undoc_72, undoc_73, undoc_74, undoc_75, undoc_76, undoc_77; uint8_t controller_state; + uint8_t REG_FFFF, REG_FF0F, REG_FF0F_OLD; + + uint8_t _scanlineCallbackLine; + uint8_t input_register; + uint32_t RAM_Bank; + uint32_t VRAM_Bank; + uint32_t IR_write; + uint32_t addr_access; + uint32_t Acc_X_state; + uint32_t Acc_Y_state; + uint8_t ZP_RAM[0x80] = {}; uint8_t RAM[0x8000] = {}; uint8_t VRAM[0x4000] = {}; @@ -174,20 +175,162 @@ namespace GBHawk uint8_t* SaveState(uint8_t* saver) { - *saver = (uint8_t)(lagged ? 1 : 0); saver++; + saver = bool_saver(lagged, saver); + saver = bool_saver(is_GBC, saver); + saver = bool_saver(GBC_compat, saver); + saver = bool_saver(speed_switch, saver); + saver = bool_saver(double_speed, saver); + saver = bool_saver(in_vblank, saver); + saver = bool_saver(in_vblank_old, saver); + saver = bool_saver(vblank_rise, saver); + saver = bool_saver(GB_bios_register, saver); + saver = bool_saver(HDMA_transfer, saver); + saver = bool_saver(Use_MT, saver); + saver = bool_saver(has_bat, saver); - std::memcpy(saver, &RAM, 0x10000); saver += 0x10000; - //std::memcpy(saver, &cart_ram, 0x8000); saver += 0x8000; + saver = byte_saver(IR_reg, saver); + saver = byte_saver(IR_mask, saver); + saver = byte_saver(IR_signal, saver); + saver = byte_saver(IR_receive, saver); + saver = byte_saver(IR_self, saver); + saver = byte_saver(undoc_6C, saver); + saver = byte_saver(undoc_72, saver); + saver = byte_saver(undoc_73, saver); + saver = byte_saver(undoc_74, saver); + saver = byte_saver(undoc_75, saver); + saver = byte_saver(undoc_76, saver); + saver = byte_saver(undoc_77, saver); + + saver = byte_saver(controller_state, saver); + + saver = byte_saver(REG_FFFF, saver); + saver = byte_saver(REG_FF0F, saver); + saver = byte_saver(REG_FF0F_OLD, saver); + saver = byte_saver(_scanlineCallbackLine, saver); + saver = byte_saver(input_register, saver); + + saver = int_saver(RAM_Bank, saver); + saver = int_saver(VRAM_Bank, saver); + saver = int_saver(IR_write, saver); + saver = int_saver(addr_access, saver); + saver = int_saver(Acc_X_state, saver); + saver = int_saver(Acc_Y_state, saver); + + for (int i = 0; i < 0x80; i++) { saver = byte_saver(ZP_RAM[i], saver); } + for (int i = 0; i < 0x8000; i++) { saver = byte_saver(RAM[i], saver); } + for (int i = 0; i < 0x4000; i++) { saver = byte_saver(VRAM[i], saver); } + for (int i = 0; i < 0xA0; i++) { saver = byte_saver(OAM[i], saver); } + for (int i = 0; i < 0x50; i++) { saver = byte_saver(header[i], saver); } + + for (int i = 0; i < (160 * 144); i++) { saver = int_saver(vidbuffer[i], saver); } + for (int i = 0; i < (160 * 144); i++) { saver = int_saver(frame_buffer[i], saver); } return saver; } uint8_t* LoadState(uint8_t* loader) { - lagged = *loader == 1; loader++; + loader = bool_loader(&lagged, loader); + loader = bool_loader(&is_GBC, loader); + loader = bool_loader(&GBC_compat, loader); + loader = bool_loader(&speed_switch, loader); + loader = bool_loader(&double_speed, loader); + loader = bool_loader(&in_vblank, loader); + loader = bool_loader(&in_vblank_old, loader); + loader = bool_loader(&vblank_rise, loader); + loader = bool_loader(&GB_bios_register, loader); + loader = bool_loader(&HDMA_transfer, loader); + loader = bool_loader(&Use_MT, loader); + loader = bool_loader(&has_bat, loader); - std::memcpy(&RAM, loader, 0x10000); loader += 0x10000; - //std::memcpy(&cart_ram, loader, 0x8000); loader += 0x8000; + loader = byte_loader(&IR_reg, loader); + loader = byte_loader(&IR_mask, loader); + loader = byte_loader(&IR_signal, loader); + loader = byte_loader(&IR_receive, loader); + loader = byte_loader(&IR_self, loader); + loader = byte_loader(&undoc_6C, loader); + loader = byte_loader(&undoc_72, loader); + loader = byte_loader(&undoc_73, loader); + loader = byte_loader(&undoc_74, loader); + loader = byte_loader(&undoc_75, loader); + loader = byte_loader(&undoc_76, loader); + loader = byte_loader(&undoc_77, loader); + + loader = byte_loader(&controller_state, loader); + + loader = byte_loader(®_FFFF, loader); + loader = byte_loader(®_FF0F, loader); + loader = byte_loader(®_FF0F_OLD, loader); + loader = byte_loader(&_scanlineCallbackLine, loader); + loader = byte_loader(&input_register, loader); + + loader = int_loader(&RAM_Bank, loader); + loader = int_loader(&VRAM_Bank, loader); + loader = int_loader(&IR_write, loader); + loader = int_loader(&addr_access, loader); + loader = int_loader(&Acc_X_state, loader); + loader = int_loader(&Acc_Y_state, loader); + + for (int i = 0; i < 0x80; i++) { loader = byte_loader(&ZP_RAM[i], loader); } + for (int i = 0; i < 0x8000; i++) { loader = byte_loader(&RAM[i], loader); } + for (int i = 0; i < 0x4000; i++) { loader = byte_loader(&VRAM[i], loader); } + for (int i = 0; i < 0xA0; i++) { loader = byte_loader(&OAM[i], loader); } + for (int i = 0; i < 0x50; i++) { loader = byte_loader(&header[i], loader); } + + for (int i = 0; i < (160 * 144); i++) { loader = int_loader(&vidbuffer[i], loader); } + for (int i = 0; i < (160 * 144); i++) { loader = int_loader(&frame_buffer[i], loader); } + + return loader; + } + + uint8_t* bool_saver(bool to_save, uint8_t* saver) + { + *saver = (uint8_t)(to_save ? 1 : 0); saver++; + + return saver; + } + + uint8_t* byte_saver(uint8_t to_save, uint8_t* saver) + { + *saver = to_save; saver++; + + return saver; + } + + uint8_t* int_saver(uint32_t to_save, uint8_t* saver) + { + *saver = (uint8_t)(to_save & 0xFF); saver++; *saver = (uint8_t)((to_save >> 8) & 0xFF); saver++; + *saver = (uint8_t)((to_save >> 16) & 0xFF); saver++; *saver = (uint8_t)((to_save >> 24) & 0xFF); saver++; + + return saver; + } + + uint8_t* bool_loader(bool* to_load, uint8_t* loader) + { + to_load[0] = *to_load == 1; loader++; + + return loader; + } + + uint8_t* byte_loader(uint8_t* to_load, uint8_t* loader) + { + to_load[0] = *loader; loader++; + + return loader; + } + + uint8_t* int_loader(uint32_t* to_load, uint8_t* loader) + { + to_load[0] = *loader; loader++; to_load[0] |= (*loader << 8); loader++; + to_load[0] |= (*loader << 16); loader++; to_load[0] |= (*loader << 24); loader++; + + return loader; + } + + uint8_t* sint_loader(int32_t* to_load, uint8_t* loader) + { + to_load[0] = *loader; loader++; to_load[0] |= (*loader << 8); loader++; + to_load[0] |= (*loader << 16); loader++; to_load[0] |= (*loader << 24); loader++; return loader; }