flycast/core/hw/sh4/sh4_sched.cpp

169 lines
2.7 KiB
C++
Raw Normal View History

2013-12-19 17:10:14 +00:00
#include "types.h"
#include "sh4_interrupts.h"
#include "sh4_core.h"
#include "sh4_sched.h"
#include "oslib/oslib.h"
//sh4 scheduler
/*
register handler
request callback at time
single fire events only
sh4_sched_register(id)
sh4_sched_request(id, in_cycles)
sh4_sched_now()
*/
u64 sh4_sched_ffb;
vector<sched_list> sch_list; // using list as external inside a macro confuses clang and msc
2013-12-19 17:10:14 +00:00
int sh4_sched_next_id=-1;
u32 sh4_sched_remaining(int id, u32 reference)
2013-12-19 17:10:14 +00:00
{
if (sch_list[id].end != -1)
2013-12-19 17:10:14 +00:00
{
return sch_list[id].end - reference;
2013-12-19 17:10:14 +00:00
}
else
{
2013-12-19 17:10:14 +00:00
return -1;
}
2013-12-19 17:10:14 +00:00
}
u32 sh4_sched_remaining(int id)
{
return sh4_sched_remaining(id, sh4_sched_now());
}
2013-12-19 17:10:14 +00:00
void sh4_sched_ffts()
{
u32 diff=-1;
int slot=-1;
for (size_t i=0;i<sch_list.size();i++)
2013-12-19 17:10:14 +00:00
{
if (sh4_sched_remaining(i)<diff)
{
slot=i;
diff=sh4_sched_remaining(i);
}
}
sh4_sched_ffb-=Sh4cntx.sh4_sched_next;
sh4_sched_next_id=slot;
if (slot!=-1)
{
Sh4cntx.sh4_sched_next=diff;
}
else
{
2013-12-29 12:35:31 +00:00
Sh4cntx.sh4_sched_next=SH4_MAIN_CLOCK;
2013-12-19 17:10:14 +00:00
}
sh4_sched_ffb+=Sh4cntx.sh4_sched_next;
}
int sh4_sched_register(int tag, sh4_sched_callback* ssc)
{
sched_list t={ssc,tag,-1,-1};
sch_list.push_back(t);
2013-12-19 17:10:14 +00:00
return sch_list.size()-1;
2013-12-19 17:10:14 +00:00
}
2015-01-06 12:10:48 +00:00
/*
Return current cycle count, in 32 bits (wraps after 21 dreamcast seconds)
*/
2013-12-19 17:10:14 +00:00
u32 sh4_sched_now()
{
return sh4_sched_ffb-Sh4cntx.sh4_sched_next;
}
2015-01-06 12:10:48 +00:00
/*
Return current cycle count, in 64 bits (effectivelly never wraps)
*/
2013-12-19 17:10:14 +00:00
u64 sh4_sched_now64()
{
return sh4_sched_ffb-Sh4cntx.sh4_sched_next;
}
void sh4_sched_request(int id, int cycles)
{
verify(cycles== -1 || (cycles >= 0 && cycles <= SH4_MAIN_CLOCK));
2015-01-06 12:10:48 +00:00
sch_list[id].start=sh4_sched_now();
if (cycles == -1) {
sch_list[id].end = -1;
}
else
{
sch_list[id].end = sch_list[id].start + cycles;
if (sch_list[id].end == -1)
sch_list[id].end++;
}
2013-12-19 17:10:14 +00:00
sh4_sched_ffts();
}
int sh4_sched_elapsed(int id)
{
if (sch_list[id].end!=-1)
2013-12-19 17:10:14 +00:00
{
int rv=sh4_sched_now()-sch_list[id].start;
sch_list[id].start=sh4_sched_now();
2013-12-19 17:10:14 +00:00
return rv;
}
else
return -1;
}
void handle_cb(int id)
{
int remain=sch_list[id].end-sch_list[id].start;
2013-12-19 17:10:14 +00:00
int elapsd=sh4_sched_elapsed(id);
int jitter=elapsd-remain;
sch_list[id].end=-1;
int re_sch=sch_list[id].cb(sch_list[id].tag,remain,jitter);
2013-12-19 17:10:14 +00:00
if (re_sch > 0)
sh4_sched_request(id, max(0, re_sch - jitter));
2013-12-19 17:10:14 +00:00
}
void sh4_sched_tick(int cycles)
{
/*
Sh4cntx.sh4_sched_time+=cycles;
Sh4cntx.sh4_sched_next-=cycles;
*/
if (Sh4cntx.sh4_sched_next<0)
{
u32 fztime=sh4_sched_now()-cycles;
if (sh4_sched_next_id!=-1)
{
for (int i=0;i<sch_list.size();i++)
2013-12-19 17:10:14 +00:00
{
int remaining = sh4_sched_remaining(i, fztime);
verify(remaining >= 0 || remaining == -1);
if (remaining >= 0 && remaining <= (u32)cycles) {
2013-12-19 17:10:14 +00:00
handle_cb(i);
}
}
}
sh4_sched_ffts();
}
2018-09-02 13:49:23 +00:00
}