libsidplayfp 2.8.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;
67 event_clock_t last_set;
68
70 uint8_t icr;
71
73 uint8_t idr;
74
75 uint8_t idrTemp;
76
79
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 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
160public:
161 virtual ~InterruptSource() = default;
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