diff --git a/core/emulator.cpp b/core/emulator.cpp index 3600b924f..6fefe58cc 100644 --- a/core/emulator.cpp +++ b/core/emulator.cpp @@ -301,6 +301,7 @@ void dc_reset(bool hard) NetworkHandshake::term(); if (hard) _vmem_unprotect_vram(0, VRAM_SIZE); + sh4_sched_reset(hard); libPvr_Reset(hard); libAICA_Reset(hard); libARM_Reset(hard); @@ -531,13 +532,13 @@ void Emulator::term() debugger::term(); sh4_cpu.Term(); custom_texture.Terminate(); // lr: avoid deadlock on exit (win32) + reios_term(); libARM_Term(); libAICA_Term(); libPvr_Term(); mem_Term(); - _vmem_release(); - mcfg_DestroyDevices(); + _vmem_release(); state = Terminated; } } @@ -633,7 +634,6 @@ bool dc_loadstate(const void **data, u32 size) mmu_set_state(); sh4_cpu.ResetCache(); - sh4_sched_ffts(); return true; } diff --git a/core/hw/aica/aica.cpp b/core/hw/aica/aica.cpp index b290148b4..537175b42 100644 --- a/core/hw/aica/aica.cpp +++ b/core/hw/aica/aica.cpp @@ -258,10 +258,7 @@ s32 libAICA_Init() sgc_Init(); if (aica_schid == -1) - { aica_schid = sh4_sched_register(0, &AicaUpdate); - sh4_sched_request(aica_schid, AICA_TICK); - } return 0; } @@ -272,6 +269,7 @@ void libAICA_Reset(bool hard) { init_mem(); sgc_Init(); + sh4_sched_request(aica_schid, AICA_TICK); } for (u32 i = 0; i < 3; i++) timers[i].Init(aica_reg, i); @@ -282,4 +280,6 @@ void libAICA_Term() { sgc_Term(); term_mem(); + sh4_sched_unregister(aica_schid); + aica_schid = -1; } diff --git a/core/hw/aica/aica_if.cpp b/core/hw/aica/aica_if.cpp index ca4415b41..402397239 100644 --- a/core/hw/aica/aica_if.cpp +++ b/core/hw/aica/aica_if.cpp @@ -20,7 +20,7 @@ VArray2 aica_ram; u32 VREG; u32 ARMRST; u32 rtc_EN; -int dma_sched_id; +int dma_sched_id = -1; u32 RealTimeClock; int rtc_schid = -1; u32 SB_ADST; @@ -168,23 +168,24 @@ void aica_Init() { RealTimeClock = GetRTC_now(); if (rtc_schid == -1) - { rtc_schid = sh4_sched_register(0, &DreamcastSecond); - sh4_sched_request(rtc_schid, SH4_MAIN_CLOCK); - } } void aica_Reset(bool hard) { if (hard) + { aica_Init(); + sh4_sched_request(rtc_schid, SH4_MAIN_CLOCK); + } VREG = 0; ARMRST = 0; } void aica_Term() { - + sh4_sched_unregister(rtc_schid); + rtc_schid = -1; } static int dma_end_sched(int tag, int cycl, int jitt) @@ -475,4 +476,6 @@ void aica_sb_Reset(bool hard) void aica_sb_Term() { + sh4_sched_unregister(dma_sched_id); + dma_sched_id = -1; } diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index 90063b3ba..c096496fe 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -1201,7 +1201,8 @@ void gdrom_reg_Init() void gdrom_reg_Term() { - + sh4_sched_unregister(gdrom_schid); + gdrom_schid = -1; } void gdrom_reg_Reset(bool hard) diff --git a/core/hw/holly/sb.cpp b/core/hw/holly/sb.cpp index 8217a3d5b..18c65b21f 100644 --- a/core/hw/holly/sb.cpp +++ b/core/hw/holly/sb.cpp @@ -597,7 +597,7 @@ void sb_Reset(bool hard) SB_FFST = 0; bba_Reset(hard); - ModemTerm(); + ModemReset(); asic_reg_Reset(hard); if (settings.platform.system == DC_PLATFORM_DREAMCAST) diff --git a/core/hw/maple/maple_if.cpp b/core/hw/maple/maple_if.cpp index 3852872eb..c3d9e5732 100644 --- a/core/hw/maple/maple_if.cpp +++ b/core/hw/maple/maple_if.cpp @@ -333,7 +333,9 @@ void maple_Reset(bool hard) void maple_Term() { - + mcfg_DestroyDevices(); + sh4_sched_unregister(maple_schid); + maple_schid = -1; } static u64 reconnect_time; diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 00d0c04db..1aadc30b2 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -331,11 +331,6 @@ void _vmem_mirror_mapping(u32 new_region,u32 start,u32 size) //init/reset/term void _vmem_init() -{ - _vmem_reset(); -} - -void _vmem_reset() { //clear read tables memset(_vmem_RF8,0,sizeof(_vmem_RF8)); @@ -363,7 +358,7 @@ void _vmem_term() u8* virt_ram_base; bool vmem_4gb_space; -static VMemType vmemstatus; +static VMemType vmemstatus = MemTypeError; static void* malloc_pages(size_t size) { #ifdef _WIN32 @@ -441,7 +436,8 @@ bool _vmem_reserve() { static_assert((sizeof(Sh4RCB) % PAGE_SIZE) == 0, "sizeof(Sh4RCB) not multiple of PAGE_SIZE"); - vmemstatus = MemTypeError; + if (vmemstatus != MemTypeError) + return true; // Use vmem only if settings mandate so, and if we have proper exception handlers. #if !defined(TARGET_NO_EXCEPTIONS) @@ -595,16 +591,22 @@ void _vmem_init_mappings() #define freedefptr(x) \ if (x) { free(x); x = NULL; } -void _vmem_release() { +void _vmem_release() +{ if (virt_ram_base) + { vmem_platform_destroy(); - else { + virt_ram_base = nullptr; + } + else + { _vmem_unprotect_vram(0, VRAM_SIZE); freedefptr(p_sh4rcb); freedefptr(vram.data); freedefptr(aica_ram.data); freedefptr(mem_b.data); } + vmemstatus = MemTypeError; } void _vmem_protect_vram(u32 addr, u32 size) diff --git a/core/hw/mem/_vmem.h b/core/hw/mem/_vmem.h index 184e1d2eb..6bec333d5 100644 --- a/core/hw/mem/_vmem.h +++ b/core/hw/mem/_vmem.h @@ -53,7 +53,6 @@ typedef u32 _vmem_handler; //init/reset/term void _vmem_init(); -void _vmem_reset(); void _vmem_term(); void _vmem_init_mappings(); diff --git a/core/hw/modem/modem.cpp b/core/hw/modem/modem.cpp index c11f473c2..680d2fdfe 100644 --- a/core/hw/modem/modem.cpp +++ b/core/hw/modem/modem.cpp @@ -319,11 +319,18 @@ void ModemInit() modem_sched = sh4_sched_register(0, &modem_sched_func); } -void ModemTerm() +void ModemReset() { stop_pico(); } +void ModemTerm() +{ + ModemReset(); + sh4_sched_unregister(modem_sched); + modem_sched = -1; +} + static void schedule_callback(int ms) { sh4_sched_request(modem_sched, SH4_MAIN_CLOCK / 1000 * ms); diff --git a/core/hw/modem/modem.h b/core/hw/modem/modem.h index 4563b288f..41a87d394 100644 --- a/core/hw/modem/modem.h +++ b/core/hw/modem/modem.h @@ -25,6 +25,7 @@ #include "types.h" void ModemInit(); +void ModemReset(); void ModemTerm(); u32 ModemReadMem_A0_006(u32 addr,u32 size); void ModemWriteMem_A0_006(u32 addr,u32 data,u32 size); diff --git a/core/hw/pvr/spg.cpp b/core/hw/pvr/spg.cpp index 5f5ce1eae..c812da047 100755 --- a/core/hw/pvr/spg.cpp +++ b/core/hw/pvr/spg.cpp @@ -74,6 +74,7 @@ void CalculateSync() Frame_Cycles = pvr_numscanlines * Line_Cycles; prv_cur_scanline = 0; + clc_pvr_scanline = 0; sh4_sched_request(vblank_schid, Line_Cycles); } @@ -293,6 +294,10 @@ bool spg_Init() void spg_Term() { + sh4_sched_unregister(render_end_schid); + render_end_schid = -1; + sh4_sched_unregister(vblank_schid); + vblank_schid = -1; } void spg_Reset(bool hard) diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index 2249afa94..285339ee0 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -19,14 +19,12 @@ sh4_icache icache; sh4_ocache ocache; -s32 sh4InterpCycles; - static void ExecuteOpcode(u16 op) { if (sr.FD == 1 && OpDesc[op]->IsFloatingPoint()) RaiseFPUDisableException(); OpPtr[op](op); - sh4InterpCycles -= CPU_RATIO; + p_sh4rcb->cntx.cycle_counter -= CPU_RATIO; } static u16 ReadNexOp() @@ -42,8 +40,6 @@ static void Sh4_int_Run() sh4_int_bCpuRun = true; RestoreHostRoundingMode(); - sh4InterpCycles += SH4_TIMESLICE; - try { do { @@ -53,12 +49,12 @@ static void Sh4_int_Run() u32 op = ReadNexOp(); ExecuteOpcode(op); - } while (sh4InterpCycles > 0); - sh4InterpCycles += SH4_TIMESLICE; + } while (p_sh4rcb->cntx.cycle_counter > 0); + p_sh4rcb->cntx.cycle_counter += SH4_TIMESLICE; UpdateSystem_INTC(); } catch (const SH4ThrownException& ex) { Do_Exception(ex.epc, ex.expEvn, ex.callVect); - sh4InterpCycles -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles + p_sh4rcb->cntx.cycle_counter -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles } } while (sh4_int_bCpuRun); } catch (const debugger::Stop& e) { @@ -82,7 +78,7 @@ static void Sh4_int_Step() ExecuteOpcode(op); } catch (const SH4ThrownException& ex) { Do_Exception(ex.epc, ex.expEvn, ex.callVect); - sh4InterpCycles -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles + p_sh4rcb->cntx.cycle_counter -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles } catch (const debugger::Stop& e) { } } @@ -92,7 +88,11 @@ static void Sh4_int_Reset(bool hard) verify(!sh4_int_bCpuRun); if (hard) + { + int schedNext = p_sh4rcb->cntx.sh4_sched_next; memset(&p_sh4rcb->cntx, 0, sizeof(p_sh4rcb->cntx)); + p_sh4rcb->cntx.sh4_sched_next = schedNext; + } next_pc = 0xA0000000; memset(r,0,sizeof(r)); @@ -110,7 +110,7 @@ static void Sh4_int_Reset(bool hard) UpdateFPSCR(); icache.Reset(hard); ocache.Reset(hard); - sh4InterpCycles = 0; + p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE; INFO_LOG(INTERPRETER, "Sh4 Reset"); } diff --git a/core/hw/sh4/modules/tmu.cpp b/core/hw/sh4/modules/tmu.cpp index 6e07b4c8a..d3d77406c 100644 --- a/core/hw/sh4/modules/tmu.cpp +++ b/core/hw/sh4/modules/tmu.cpp @@ -322,4 +322,9 @@ void tmu_reset(bool hard) void tmu_term() { + for (int& sched_id : tmu_sched) + { + sh4_sched_unregister(sched_id); + sched_id = -1; + } } diff --git a/core/hw/sh4/sh4_if.h b/core/hw/sh4/sh4_if.h index da3d8307e..40761b86d 100644 --- a/core/hw/sh4/sh4_if.h +++ b/core/hw/sh4/sh4_if.h @@ -269,6 +269,7 @@ struct alignas(64) Sh4Context u32 interrupt_pend; u32 temp_reg; + int cycle_counter; }; u64 raw[64-8]; }; diff --git a/core/hw/sh4/sh4_interpreter.h b/core/hw/sh4/sh4_interpreter.h index 85b31f46e..aa3e5104f 100644 --- a/core/hw/sh4/sh4_interpreter.h +++ b/core/hw/sh4/sh4_interpreter.h @@ -45,5 +45,3 @@ void ExecuteDelayslot_RTE(); int UpdateSystem(); int UpdateSystem_INTC(); - -extern s32 sh4InterpCycles; diff --git a/core/hw/sh4/sh4_sched.cpp b/core/hw/sh4/sh4_sched.cpp index ad34f005f..34ddfd14c 100755 --- a/core/hw/sh4/sh4_sched.cpp +++ b/core/hw/sh4/sh4_sched.cpp @@ -18,66 +18,84 @@ sh4_sched_now() */ + u64 sh4_sched_ffb; +std::vector sch_list; +int sh4_sched_next_id = -1; +static u32 sh4_sched_now(); -std::vector sch_list; // using list as external inside a macro confuses clang and msc - -int sh4_sched_next_id=-1; - -u32 sh4_sched_remaining(size_t id, u32 reference) +static u32 sh4_sched_remaining(const sched_list& sched, u32 reference) { - if (sch_list[id].end != -1) - return sch_list[id].end - reference; + if (sched.end != -1) + return sched.end - reference; else return -1; } -u32 sh4_sched_remaining(size_t id) -{ - return sh4_sched_remaining(id, sh4_sched_now()); -} - void sh4_sched_ffts() { - u32 diff=-1; - int slot=-1; + u32 diff = -1; + int slot = -1; - for (size_t i=0;i= 0 && cycles <= SH4_MAIN_CLOCK)); - sch_list[id].start=sh4_sched_now(); +void sh4_sched_request(int id, int cycles) +{ + verify(cycles == -1 || (cycles >= 0 && cycles <= SH4_MAIN_CLOCK)); + + sched_list& sched = sch_list[id]; + sched.start = sh4_sched_now(); if (cycles == -1) { - sch_list[id].end = -1; + sched.end = -1; } else { - sch_list[id].end = sch_list[id].start + cycles; - if (sch_list[id].end == -1) - sch_list[id].end++; + sched.end = sched.start + cycles; + if (sched.end == -1) + sched.end++; } sh4_sched_ffts(); } /* Returns how much time has passed for this callback */ -static int sh4_sched_elapsed(size_t id) +static int sh4_sched_elapsed(sched_list& sched) { - if (sch_list[id].end!=-1) + if (sched.end != -1) { - int rv=sh4_sched_now()-sch_list[id].start; - sch_list[id].start=sh4_sched_now(); + int rv = sh4_sched_now() - sched.start; + sched.start = sh4_sched_now(); return rv; } else return -1; } -static void handle_cb(size_t id) +static void handle_cb(sched_list& sched) { - int remain=sch_list[id].end-sch_list[id].start; - int elapsd=sh4_sched_elapsed(id); - int jitter=elapsd-remain; + int remain = sched.end - sched.start; + int elapsd = sh4_sched_elapsed(sched); + int jitter = elapsd - remain; - sch_list[id].end=-1; - int re_sch=sch_list[id].cb(sch_list[id].tag,remain,jitter); + sched.end = -1; + int re_sch = sched.cb(sched.tag, remain, jitter); if (re_sch > 0) - sh4_sched_request(id, std::max(0, re_sch - jitter)); + sh4_sched_request(&sched - &sch_list[0], std::max(0, re_sch - jitter)); } void sh4_sched_tick(int cycles) { - /* - Sh4cntx.sh4_sched_time+=cycles; - Sh4cntx.sh4_sched_next-=cycles; - */ + if (Sh4cntx.sh4_sched_next >= 0) + return; - if (Sh4cntx.sh4_sched_next<0) + u32 fztime = sh4_sched_now() - cycles; + if (sh4_sched_next_id != -1) { - u32 fztime=sh4_sched_now()-cycles; - if (sh4_sched_next_id!=-1) + for (sched_list& sched : sch_list) { - for (size_t i = 0; i < sch_list.size(); i++) - { - u32 remaining = sh4_sched_remaining(i, fztime); - verify(remaining >= 0 || remaining == -1); - if (remaining >= 0 && remaining <= (u32)cycles) - handle_cb(i); - } + int remaining = sh4_sched_remaining(sched, fztime); + verify(remaining >= 0 || remaining == -1); + if (remaining >= 0 && remaining <= (int)cycles) + handle_cb(sched); } - sh4_sched_ffts(); + } + sh4_sched_ffts(); +} + +void sh4_sched_reset(bool hard) +{ + if (hard) + { + sh4_sched_ffb = 0; + sh4_sched_next_id = -1; + for (sched_list& sched : sch_list) + sched.start = sched.end = -1; + Sh4cntx.sh4_sched_next = 0; } } diff --git a/core/hw/sh4/sh4_sched.h b/core/hw/sh4/sh4_sched.h index ba4016bf7..1625beb2f 100644 --- a/core/hw/sh4/sh4_sched.h +++ b/core/hw/sh4/sh4_sched.h @@ -11,16 +11,15 @@ typedef int sh4_sched_callback(int tag, int sch_cycl, int jitter); /* - Registed a callback to the scheduler. The returned id - is used for sh4_sched_request and sh4_sched_elapsed calls + Register a callback to the scheduler. The returned id + is used for sh4_sched_request and sh4_sched_unregister calls */ int sh4_sched_register(int tag, sh4_sched_callback* ssc); -/* - current time in SH4 cycles, referenced to boot. - Wraps every ~21 secs -*/ -u32 sh4_sched_now(); +/*** + * Unregister a callback from the scheduler. + */ +void sh4_sched_unregister(int id); /* current time, in SH4 cycles, referenced to boot. @@ -35,7 +34,7 @@ u64 sh4_sched_now64(); Passing a value of 0 disables the callback. If called multiple times, only the last call is in effect */ -void sh4_sched_request(size_t id, int cycles); +void sh4_sched_request(int id, int cycles); /* Tick for *cycles* @@ -43,6 +42,7 @@ void sh4_sched_request(size_t id, int cycles); void sh4_sched_tick(int cycles); void sh4_sched_ffts(); +void sh4_sched_reset(bool hard); struct sched_list { diff --git a/core/rec-ARM/rec_arm.cpp b/core/rec-ARM/rec_arm.cpp index ee63097bc..a511f3abc 100644 --- a/core/rec-ARM/rec_arm.cpp +++ b/core/rec-ARM/rec_arm.cpp @@ -2046,9 +2046,9 @@ void ngen_Compile(RuntimeBlockInfo* block, bool force_checks, bool reset, bool s } else { - ass.Ldr(r0, MemOperand(sp)); + ass.Ldr(r0, MemOperand(r8, rcbOffset(cntx.cycle_counter))); ass.Sub(SetFlags, r0, r0, cyc); - ass.Str(r0, MemOperand(sp)); + ass.Str(r0, MemOperand(r8, rcbOffset(cntx.cycle_counter))); // FIXME condition? ass.Mov(r4, block->vaddr); storeSh4Reg(r4, reg_nextpc); @@ -2184,14 +2184,15 @@ static void generate_mainloop() Label longjumpLabel; if (!mmu_enabled()) { - ass.Mov(r8, r0); // r8: context - ass.Mov(r9, SH4_TIMESLICE); // r9: cycle counter + // r8: context + ass.Mov(r8, r0); + // r9: cycle counter + ass.Ldr(r9, MemOperand(r0, rcbOffset(cntx.cycle_counter))); } else { + ass.Sub(sp, sp, 4); ass.Push(r0); // push context - ass.Mov(r1, SH4_TIMESLICE); - ass.Push(r1); // cycle counter on stack ass.Mov(r0, reinterpret_cast(&jmp_stack)); ass.Mov(r1, sp); @@ -2199,7 +2200,7 @@ static void generate_mainloop() ass.Bind(&longjumpLabel); - ass.Ldr(r8, MemOperand(sp, 4)); // r8: context + ass.Ldr(r8, MemOperand(sp)); // r8: context ass.Mov(r9, (uintptr_t)mmuAddressLUT); // r9: mmu LUT } ass.Ldr(r4, MemOperand(r8, rcbOffset(cntx.pc))); // r4: pc @@ -2213,9 +2214,9 @@ static void generate_mainloop() ass.Add(r9, r9, SH4_TIMESLICE); else { - ass.Ldr(r0, MemOperand(sp)); + ass.Ldr(r0, MemOperand(r8, rcbOffset(cntx.cycle_counter))); ass.Add(r0, r0, SH4_TIMESLICE); - ass.Str(r0, MemOperand(sp)); + ass.Str(r0, MemOperand(r8, rcbOffset(cntx.cycle_counter))); } ass.Mov(r4, lr); call((void *)UpdateSystem); @@ -2256,7 +2257,9 @@ static void generate_mainloop() // cleanup: ass.Bind(&cleanup); if (mmu_enabled()) - ass.Add(sp, sp, 8); // pop cycle counter & context + ass.Add(sp, sp, 8); // pop context & alignment + else + ass.Str(r9, MemOperand(r8, rcbOffset(cntx.cycle_counter))); { UseScratchRegisterScope scope(&ass); scope.ExcludeAll(); diff --git a/core/rec-ARM64/rec_arm64.cpp b/core/rec-ARM64/rec_arm64.cpp index 608cd553a..d8417dd18 100644 --- a/core/rec-ARM64/rec_arm64.cpp +++ b/core/rec-ARM64/rec_arm64.cpp @@ -300,10 +300,9 @@ public: // scheduler if (mmu_enabled()) { - Mov(x1, reinterpret_cast(&cycle_counter)); - Ldr(w0, MemOperand(x1)); + Ldr(w0, sh4_context_mem_operand(&Sh4cntx.cycle_counter)); Subs(w0, w0, block->guest_cycles); - Str(w0, MemOperand(x1)); + Str(w0, sh4_context_mem_operand(&Sh4cntx.cycle_counter)); } else { @@ -1390,12 +1389,9 @@ public: Label reenterLabel; if (mmu_enabled()) { - Ldr(x1, reinterpret_cast(&cycle_counter)); - // Push context, cycle_counter address + // Push context Stp(x0, x1, MemOperand(sp, -16, PreIndex)); unwinder.allocStack(0, 16); - Mov(w0, SH4_TIMESLICE); - Str(w0, MemOperand(x1)); Ldr(x0, reinterpret_cast(&jmp_stack)); Mov(x1, sp); @@ -1410,7 +1406,7 @@ public: // Use x28 as sh4 context pointer Mov(x28, x0); // Use x27 as cycle_counter - Mov(w27, SH4_TIMESLICE); + Ldr(w27, sh4_context_mem_operand(&Sh4cntx.cycle_counter)); } Label do_interrupts; @@ -1427,10 +1423,9 @@ public: } else { - Ldr(x1, MemOperand(sp, 8)); // &cycle_counter - Ldr(w0, MemOperand(x1)); // cycle_counter + Ldr(w0, sh4_context_mem_operand(&Sh4cntx.cycle_counter)); Add(w0, w0, SH4_TIMESLICE); - Str(w0, MemOperand(x1)); + Str(w0, sh4_context_mem_operand(&Sh4cntx.cycle_counter)); } Mov(x29, lr); // Trashing pc here but it will be reset at the end of the block or in DoInterrupts GenCallRuntime(UpdateSystem); @@ -1450,6 +1445,9 @@ public: if (mmu_enabled()) // Pop context Add(sp, sp, 16); + else + // save cycle counter + Str(w27, sh4_context_mem_operand(&Sh4cntx.cycle_counter)); // Restore registers Ldp(x29, x30, MemOperand(sp, 144)); Ldp(d12, d13, MemOperand(sp, 128)); diff --git a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp index b6c29c056..b57d53051 100644 --- a/core/rec-x64/rec_x64.cpp +++ b/core/rec-x64/rec_x64.cpp @@ -32,7 +32,6 @@ struct DynaRBI : RuntimeBlockInfo } }; -static int cycle_counter; static void (*mainloop)(); static void (*handleException)(); @@ -106,7 +105,7 @@ static void handle_sh4_exception(SH4ThrownException& ex, u32 pc) pc--; } Do_Exception(pc, ex.expEvn, ex.callVect); - cycle_counter += 4; // probably more is needed + p_sh4rcb->cntx.cycle_counter += 4; // probably more is needed handleException(); } @@ -176,14 +175,9 @@ public: jmp(exit_block, T_NEAR); L(fpu_enabled); } -#ifdef FEAT_NO_RWX_PAGES - // Use absolute addressing for this one - // TODO(davidgfnet) remove the ifsef using CC_RX2RW/CC_RW2RX - mov(rax, (uintptr_t)&cycle_counter); + mov(rax, (uintptr_t)&p_sh4rcb->cntx.cycle_counter); sub(dword[rax], block->guest_cycles); -#else - sub(dword[rip + &cycle_counter], block->guest_cycles); -#endif + regalloc.DoAlloc(block); for (current_opid = 0; current_opid < block->oplist.size(); current_opid++) @@ -655,7 +649,6 @@ public: #endif unwinder.endProlog(getSize()); - mov(dword[rip + &cycle_counter], SH4_TIMESLICE); mov(qword[rip + &jmp_rsp], rsp); //run_loop: @@ -675,12 +668,13 @@ public: mov(call_regs[0], dword[rax]); call(bm_GetCodeByVAddr); call(rax); - mov(ecx, dword[rip + &cycle_counter]); + mov(rax, (uintptr_t)&p_sh4rcb->cntx.cycle_counter); + mov(ecx, dword[rax]); test(ecx, ecx); jg(slice_loop); add(ecx, SH4_TIMESLICE); - mov(dword[rip + &cycle_counter], ecx); + mov(dword[rax], ecx); call(UpdateSystem_INTC); jmp(run_loop); diff --git a/core/rec-x86/rec_x86.cpp b/core/rec-x86/rec_x86.cpp index f0fc4b0bd..9ec8e5d4b 100644 --- a/core/rec-x86/rec_x86.cpp +++ b/core/rec-x86/rec_x86.cpp @@ -28,7 +28,6 @@ #include "hw/mem/_vmem.h" #include "oslib/oslib.h" -static int cycle_counter; static void (*mainloop)(); static void (*ngen_FailedToFindBlock_)(); @@ -110,7 +109,7 @@ void X86Compiler::compile(RuntimeBlockInfo* block, bool force_checks, bool optim checkBlock(force_checks, block); - sub(dword[&cycle_counter], block->guest_cycles); + sub(dword[&Sh4cntx.cycle_counter], block->guest_cycles); Xbyak::Label no_up; jns(no_up); call((const void *)intc_sched); @@ -396,8 +395,6 @@ void X86Compiler::genMainloop() mov(ecx, dword[&Sh4cntx.pc]); - mov(dword[&cycle_counter], SH4_TIMESLICE); - mov(eax, 0); //next_pc _MUST_ be on ecx Xbyak::Label cleanup; @@ -452,7 +449,7 @@ void X86Compiler::genMainloop() unwinder.endProlog(0); Xbyak::Label intc_schedLabel; L(intc_schedLabel); - add(dword[&cycle_counter], SH4_TIMESLICE); + add(dword[&Sh4cntx.cycle_counter], SH4_TIMESLICE); call((void *)UpdateSystem); cmp(eax, 0); jnz(do_iter); diff --git a/core/serialize.cpp b/core/serialize.cpp index 39c489d3a..2d73c3de3 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -392,7 +392,6 @@ bool dc_serialize(void **data, unsigned int *total_size, bool rollback) REICAST_S((*p_sh4rcb).cntx); - REICAST_S(sh4InterpCycles); REICAST_S(sh4_sched_ffb); std::array schedIds = getSchedulerIds(); if (sh4_sched_next_id == -1) @@ -693,6 +692,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size, seria REICAST_US((*p_sh4rcb).sq_buffer); REICAST_US((*p_sh4rcb).cntx); + p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE; if (version < V9_LIBRETRO) { @@ -700,7 +700,6 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size, seria REICAST_SKIP(4); // old_dn } - sh4InterpCycles = 0; REICAST_US(sh4_sched_ffb); if (version < V9_LIBRETRO) REICAST_SKIP(4); // sh4_sched_intr @@ -1080,10 +1079,10 @@ bool dc_unserialize(void **data, unsigned int *total_size, bool rollback) REICAST_SKIP(4); REICAST_SKIP(4); } - if (version >= V19) - REICAST_US(sh4InterpCycles); - else - sh4InterpCycles = 0; + if (version >= V19 && version < V21) + REICAST_SKIP(4); // sh4InterpCycles + if (version < V21) + p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE; REICAST_US(sh4_sched_ffb); std::array schedIds = getSchedulerIds(); @@ -1125,6 +1124,8 @@ bool dc_unserialize(void **data, unsigned int *total_size, bool rollback) REICAST_US(sch_list[modem_sched].start); REICAST_US(sch_list[modem_sched].end); } + if (version < V19) + sh4_sched_ffts(); ModemDeserialize(data, total_size, version); REICAST_US(SCIF_SCFSR2); diff --git a/core/types.h b/core/types.h index 50d83e63b..37855fced 100644 --- a/core/types.h +++ b/core/types.h @@ -490,5 +490,6 @@ enum serialize_version_enum { V18 = 813, V19 = 814, V20 = 815, - VCUR_FLYCAST = V20, + V21 = 816, + VCUR_FLYCAST = V21, }; diff --git a/tests/src/serialize_test.cpp b/tests/src/serialize_test.cpp index b12afb3ae..c5d21fb90 100644 --- a/tests/src/serialize_test.cpp +++ b/tests/src/serialize_test.cpp @@ -31,7 +31,7 @@ TEST_F(SerializeTest, SizeTest) unsigned int total_size = 0; void *data = nullptr; ASSERT_TRUE(dc_serialize(&data, &total_size)); - ASSERT_EQ(28192084u, total_size); + ASSERT_EQ(28192080u, total_size); }