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  [[nodiscard]] inline bool limitReached() const {
60  return ticks >= limit;
61  }
62 
66  [[nodiscard]] 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 [[nodiscard]] EmuTime getAccessSlot(EmuTime::param frame, EmuTime::param time, Delta delta,
92  const VDP& vdp);
93 
96 [[nodiscard]] Calculator getCalculator(
97  EmuTime::param frame, EmuTime::param time, EmuTime::param limit,
98  const VDP& vdp);
99 
100 } // namespace openmsx::VDPAccessSlots
101 
102 #endif
constexpr EmuTime getFastAdd(unsigned n) const
Like operator+() but faster, though the step can't be too big (max a little over 1 second).
Definition: Clock.hh:93
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
VDP-VRAM access slot calculator, meant to be used in the inner loops of the VDPCmdEngine commands.
void next(Delta delta)
Advance time to the earliest access slot that is at least 'delta' ticks later than the current time.
bool limitReached() const
Has 'time' advanced to or past 'limit'?
Calculator(EmuTime::param frame, EmuTime::param time, EmuTime::param limit_, const uint8_t *tab_)
This shouldn't be called directly, instead use getCalculator().
EmuTime getTime() const
Get the current time.
Unified implementation of MSX Video Display Processors (VDPs).
Definition: VDP.hh:63
static constexpr int TICKS_PER_LINE
Number of VDP clock ticks per line.
Definition: VDP.hh:72
#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 'delta' cycles later than 'time'.
Calculator getCalculator(EmuTime::param frame, EmuTime::param time, EmuTime::param limit, const VDP &vdp)
When many calls to getAccessSlot() are needed, it's more efficient to instead use this function.