openMSX
VDPAccessSlots.hh
Go to the documentation of this file.
1 #ifndef VDPACCESSSLOTS_HH
2 #define VDPACCESSSLOTS_HH
3 
4 #include "VDP.hh"
5 #include "likely.hh"
6 #include <cassert>
7 #include <cstdint>
8 
9 namespace openmsx::VDPAccessSlots {
10 
11 constexpr int TICKS = VDP::TICKS_PER_LINE;
12 
13 enum Delta : int {
14  DELTA_0 = 0 * TICKS,
15  DELTA_1 = 1 * TICKS,
16  DELTA_16 = 2 * TICKS,
17  DELTA_24 = 3 * TICKS,
18  DELTA_28 = 4 * TICKS,
19  DELTA_32 = 5 * TICKS,
20  DELTA_40 = 6 * TICKS,
21  DELTA_48 = 7 * TICKS,
22  DELTA_64 = 8 * TICKS,
23  DELTA_72 = 9 * TICKS,
24  DELTA_88 = 10 * TICKS,
25  DELTA_104 = 11 * TICKS,
26  DELTA_120 = 12 * TICKS,
27  DELTA_128 = 13 * TICKS,
28  DELTA_136 = 14 * TICKS,
29  NUM_DELTAS = 15,
30 };
31 
38 {
39 public:
41  Calculator(EmuTime::param frame, EmuTime::param time,
42  EmuTime::param limit_, const uint8_t* tab_)
43  : ref(frame), tab(tab_)
44  {
45  assert(frame <= time);
46  assert(frame <= limit_);
47  // not required that time <= limit
48 
49  ticks = ref.getTicksTill_fast(time);
50  limit = ref.getTicksTill_fast(limit_);
51  int lines = ticks / TICKS;
52  ticks -= lines * TICKS;
53  limit -= lines * TICKS; // might be negative
54  ref += lines * TICKS;
55  assert(0 <= ticks); assert(ticks < TICKS);
56  }
57 
59  inline bool limitReached() const {
60  return ticks >= limit;
61  }
62 
66  inline EmuTime getTime() const {
67  return ref.getFastAdd(ticks);
68  }
69 
72  inline void next(Delta delta) {
73  ticks += tab[delta + ticks];
74  if (unlikely(ticks >= TICKS)) {
75  ticks -= TICKS;
76  limit -= TICKS;
77  ref += TICKS;
78  }
79  }
80 
81 private:
82  int ticks;
83  int limit;
84  VDP::VDPClock ref;
85  const uint8_t* const tab;
86 };
87 
91 EmuTime getAccessSlot(EmuTime::param frame, EmuTime::param time, Delta delta,
92  const VDP& vdp);
93 
97  EmuTime::param frame, EmuTime::param time, EmuTime::param limit,
98  const VDP& vdp);
99 
100 } // namespace openmsx::VDPAccessSlots
101 
102 #endif
Calculator getCalculator(EmuTime::param frame, EmuTime::param time, EmuTime::param limit, const VDP &vdp)
When many calls to getAccessSlot() are needed, it&#39;s more efficient to instead use this function...
constexpr EmuTime getFastAdd(unsigned n) const
Like operator+() but faster, though the step can&#39;t be too big (max a little over 1 second)...
Definition: Clock.hh:93
#define unlikely(x)
Definition: likely.hh:15
EmuTime getAccessSlot(EmuTime::param frame_, EmuTime::param time, Delta delta, const VDP &vdp)
Return the time of the next available access slot that is at least &#39;delta&#39; cycles later than &#39;time&#39;...
void next(Delta delta)
Advance time to the earliest access slot that is at least &#39;delta&#39; ticks later than the current time...
static constexpr int TICKS_PER_LINE
Number of VDP clock ticks per line.
Definition: VDP.hh:72
Calculator(EmuTime::param frame, EmuTime::param time, EmuTime::param limit_, const uint8_t *tab_)
This shouldn&#39;t be called directly, instead use getCalculator().
constexpr unsigned getTicksTill_fast(EmuTime::param e) const
Same as above, only faster, Though the time interval may not be too large.
Definition: Clock.hh:70
EmuTime getTime() const
Get the current time.
VDP-VRAM access slot calculator, meant to be used in the inner loops of the VDPCmdEngine commands...
Unified implementation of MSX Video Display Processors (VDPs).
Definition: VDP.hh:61
bool limitReached() const
Has &#39;time&#39; advanced to or past &#39;limit&#39;?