openMSX
IRQHelper.hh
Go to the documentation of this file.
1 #ifndef IRQHELPER_HH
2 #define IRQHELPER_HH
3 
4 #include "Probe.hh"
5 #include "MSXMotherBoard.hh"
6 #include "serialize.hh"
7 #include <memory>
8 #include <string>
9 
10 namespace openmsx {
11 
12 class MSXMotherBoard;
13 class MSXCPU;
14 class DeviceConfig;
15 
23 // policy class for IRQ source
24 class IRQSource
25 {
26 protected:
27  explicit IRQSource(MSXCPU& cpu);
28  void raise();
29  void lower();
30 private:
31  MSXCPU& cpu;
32 };
33 
34 // supports <optional_irq> tag in hardware config
35 
36 class IRQSink
37 {
38 public:
39  virtual ~IRQSink() = default;
40  virtual void raise() = 0;
41  virtual void lower() = 0;
42 };
43 
45 {
46 protected:
47  OptionalIRQ(MSXCPU& cpu, const DeviceConfig& config);
48  void raise() { sink->raise(); }
49  void lower() { sink->lower(); }
50 private:
51  std::unique_ptr<IRQSink> sink;
52 };
53 
54 
55 // generic implementation
56 template <typename SOURCE> class IntHelper : public SOURCE
57 {
58 public:
59  IntHelper(const IntHelper&) = delete;
60  IntHelper& operator=(const IntHelper&) = delete;
61 
65  IntHelper(MSXMotherBoard& motherboard, const std::string& name)
66  : SOURCE(motherboard.getCPU())
67  , request(motherboard.getDebugger(), name,
68  "Outgoing IRQ signal.", false)
69  {
70  }
71  IntHelper(MSXMotherBoard& motherboard, const std::string& name,
72  const DeviceConfig& config)
73  : SOURCE(motherboard.getCPU(), config)
74  , request(motherboard.getDebugger(), name,
75  "Outgoing IRQ signal.", false)
76  {
77  }
78 
83  reset();
84  }
85 
88  inline void set() {
89  if (!request) {
90  request = true;
91  SOURCE::raise();
92  }
93  }
94 
97  inline void reset() {
98  if (request) {
99  request = false;
100  SOURCE::lower();
101  }
102  }
103 
106  inline void set(bool s) {
107  if (s) {
108  set();
109  } else {
110  reset();
111  }
112  }
113 
117  inline bool getState() const {
118  return request;
119  }
120 
121  template<typename Archive>
122  void serialize(Archive& ar, unsigned /*version*/)
123  {
124  bool pending = request;
125  ar.serialize("pending", pending);
126  if (ar.isLoader()) {
127  set(pending);
128  }
129  }
130 
131 private:
132  Probe<bool> request;
133 };
134 
135 // convenience types
138 
139 } // namespace openmsx
140 
141 #endif
IntHelper(MSXMotherBoard &motherboard, const std::string &name)
Create a new IntHelper.
Definition: IRQHelper.hh:65
Helper class for doing interrupt request (IRQ) administration.
Definition: IRQHelper.hh:24
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
bool getState() const
Get the interrupt state.
Definition: IRQHelper.hh:117
void reset()
Reset the interrupt request on the bus.
Definition: IRQHelper.hh:97
void serialize(Archive &ar, unsigned)
Definition: IRQHelper.hh:122
IRQSource(MSXCPU &cpu)
Definition: IRQHelper.cc:11
~IntHelper()
Destroy this IntHelper.
Definition: IRQHelper.hh:82
IntHelper(MSXMotherBoard &motherboard, const std::string &name, const DeviceConfig &config)
Definition: IRQHelper.hh:71