libsidplayfp 2.15.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
34namespace libsidplayfp
35{
36
37class MOS652X;
38
44{
45public:
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
57private:
59 MOS652X &parent;
60
61protected:
64
66 event_clock_t last_clear = 0;
67 event_clock_t last_set = 0;
68
70 uint8_t icr = 0;
71
73 uint8_t idr = 0;
74
75 uint8_t idrTemp = 0;
76
78 bool scheduled = false;
79
81 bool asserted = false;
82
83private:
84 EventCallback<InterruptSource> interruptEvent;
85
86 EventCallback<InterruptSource> updateIdrEvent;
87
89
91
92protected:
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
119protected:
127 parent(parent),
128 eventScheduler(scheduler),
129 interruptEvent("CIA Interrupt", *this, &InterruptSource::interrupt),
130 updateIdrEvent("CIA update ICR", *this, &InterruptSource::updateIdr),
131 setIrqEvent("CIA set IRQ", *this, &InterruptSource::setIrq),
132 clearIrqEvent("CIA clear IRQ", *this, &InterruptSource::clearIrq)
133 {}
134
138 void schedule(int delay)
139 {
140 if (!scheduled)
141 {
142 eventScheduler.schedule(interruptEvent, delay, EVENT_CLOCK_PHI1);
143 scheduled = true;
144 }
145 }
146
147 void scheduleIrq()
148 {
149 eventScheduler.schedule(setIrqEvent, 1, EVENT_CLOCK_PHI1);
150 }
151
152 bool isTriggered(uint8_t interruptMask);
153
154public:
155 virtual ~InterruptSource() = default;
156
162 virtual void trigger(uint8_t interruptMask) =0;
163
169 virtual uint8_t clear();
170
175 virtual void reset()
176 {
177 last_clear = 0;
178 last_set = 0;
179
180 icr = 0;
181 idr = 0;
182
183 eventScheduler.cancel(updateIdrEvent);
184 eventScheduler.cancel(setIrqEvent);
185 eventScheduler.cancel(clearIrqEvent);
186 eventScheduler.cancel(interruptEvent);
187 scheduled = false;
188
189 asserted = false;
190 }
191
197 void set(uint8_t interruptMask);
198};
199
200}
201
202#endif // INTERRUPT_H
Definition EventCallback.h:36
Definition EventScheduler.h:62
event_clock_t getTime(event_phase_t phase) const
Definition EventScheduler.h:158
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:175
void schedule(int delay)
Definition interrupt.h:138
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