libsidplayfp  2.3.0
interrupt.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2020 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright 2000 Simon White
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INTERRUPT_H
24 #define INTERRUPT_H
25 
26 #include "Event.h"
27 #include "EventScheduler.h"
28 #include "EventCallback.h"
29 
30 #include <stdint.h>
31 
32 #include "sidcxx11.h"
33 
34 namespace libsidplayfp
35 {
36 
37 class MOS652X;
38 
44 {
45 public:
46  enum
47  {
51  INTERRUPT_ALARM = 1 << 2,
52  INTERRUPT_SP = 1 << 3,
53  INTERRUPT_FLAG = 1 << 4,
54  INTERRUPT_REQUEST = 1 << 7
55  };
56 
57 private:
59  MOS652X &parent;
60 
61 protected:
64 
66  event_clock_t last_clear;
67  event_clock_t last_set;
68 
70  uint8_t icr;
71 
73  uint8_t idr;
74 
75  uint8_t idrTemp;
76 
78  bool scheduled;
79 
81  bool asserted;
82 
83 private:
84  EventCallback<InterruptSource> interruptEvent;
85 
86  EventCallback<InterruptSource> updateIdrEvent;
87 
89 
90  EventCallback<InterruptSource> clearIrqEvent;
91 
92 protected:
93  inline bool interruptTriggered() const { return idr & INTERRUPT_REQUEST; }
94 
95  inline bool interruptMasked(uint8_t interruptMask) const
96  {
97  return ((interruptMask != INTERRUPT_NONE) ? interruptMask : idr) & icr;
98  }
99 
100  virtual void triggerInterrupt() =0;
101 
105  inline bool ack0() const { return eventScheduler.getTime(EVENT_CLOCK_PHI2) == (last_clear+1); }
106  inline bool write0() const { return eventScheduler.getTime(EVENT_CLOCK_PHI2) == (last_set+1); }
107 
111  void interrupt();
112 
113  void updateIdr();
114 
115  void setIrq();
116 
117  void clearIrq();
118 
119 protected:
126  InterruptSource(EventScheduler &scheduler, MOS652X &parent) :
127  parent(parent),
128  eventScheduler(scheduler),
129  last_clear(0),
130  last_set(0),
131  icr(0),
132  idr(0),
133  scheduled(false),
134  asserted(false),
135  interruptEvent("CIA Interrupt", *this, &InterruptSource::interrupt),
136  updateIdrEvent("CIA update ICR", *this, &InterruptSource::updateIdr),
137  setIrqEvent("CIA set IRQ", *this, &InterruptSource::setIrq),
138  clearIrqEvent("CIA clear IRQ", *this, &InterruptSource::clearIrq)
139  {}
140 
144  void schedule(int delay)
145  {
146  if (!scheduled)
147  {
148  eventScheduler.schedule(interruptEvent, delay, EVENT_CLOCK_PHI1);
149  scheduled = true;
150  }
151  }
152 
153  void scheduleIrq()
154  {
155  eventScheduler.schedule(setIrqEvent, 1, EVENT_CLOCK_PHI1);
156  }
157 
158  bool isTriggered(uint8_t interruptMask);
159 
160 public:
161  virtual ~InterruptSource() {}
162 
168  virtual void trigger(uint8_t interruptMask) =0;
169 
175  virtual uint8_t clear();
176 
181  virtual void reset()
182  {
183  last_clear = 0;
184  last_set = 0;
185 
186  icr = 0;
187  idr = 0;
188 
189  eventScheduler.cancel(updateIdrEvent);
190  eventScheduler.cancel(setIrqEvent);
191  eventScheduler.cancel(clearIrqEvent);
192  eventScheduler.cancel(interruptEvent);
193  scheduled = false;
194 
195  asserted = false;
196  }
197 
203  void set(uint8_t interruptMask);
204 };
205 
206 }
207 
208 #endif // INTERRUPT_H
Definition: EventCallback.h:36
Definition: EventScheduler.h:62
event_clock_t getTime(event_phase_t phase) const
Definition: EventScheduler.h:162
void cancel(Event &event)
Definition: EventScheduler.cpp:35
Definition: interrupt.h:44
uint8_t idr
Interrupt data register.
Definition: interrupt.h:73
EventScheduler & eventScheduler
Event scheduler.
Definition: interrupt.h:63
event_clock_t last_clear
Clock when clear was called last.
Definition: interrupt.h:66
InterruptSource(EventScheduler &scheduler, MOS652X &parent)
Definition: interrupt.h:126
bool asserted
is the irq pin asserted?
Definition: interrupt.h:81
void set(uint8_t interruptMask)
Definition: interrupt.cpp:93
@ INTERRUPT_NONE
no interrupt
Definition: interrupt.h:48
@ INTERRUPT_REQUEST
control bit
Definition: interrupt.h:54
@ INTERRUPT_SP
serial port
Definition: interrupt.h:52
@ INTERRUPT_UNDERFLOW_B
underflow Timer B
Definition: interrupt.h:50
@ INTERRUPT_FLAG
external flag
Definition: interrupt.h:53
@ INTERRUPT_ALARM
alarm clock
Definition: interrupt.h:51
@ INTERRUPT_UNDERFLOW_A
underflow Timer A
Definition: interrupt.h:49
bool ack0() const
Definition: interrupt.h:105
bool scheduled
Have we already scheduled CIA->CPU interrupt transition?
Definition: interrupt.h:78
uint8_t icr
Interrupt control register.
Definition: interrupt.h:70
virtual void reset()
Definition: interrupt.h:181
void schedule(int delay)
Definition: interrupt.h:144
virtual void trigger(uint8_t interruptMask)=0
virtual uint8_t clear()
Definition: interrupt.cpp:110
void interrupt()
Definition: interrupt.cpp:30
Definition: mos652x.h:154