libsidplayfp  2.0.1
mos6526.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2018 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2009-2014 VICE Project
6  * Copyright 2007-2010 Antti Lankila
7  * Copyright 2000 Simon White
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef MOS6526_H
25 #define MOS6526_H
26 
27 #include <memory>
28 
29 #include <stdint.h>
30 
31 #include "interrupt.h"
32 #include "timer.h"
33 #include "tod.h"
34 #include "SerialPort.h"
35 #include "EventScheduler.h"
36 
37 #include "sidcxx11.h"
38 
39 class EventContext;
40 
41 namespace libsidplayfp
42 {
43 
44 class MOS6526;
45 
52 class TimerA final : public Timer
53 {
54 private:
58  void underFlow() override;
59 
60  void serialPort() override;
61 
62 public:
67  Timer("CIA Timer A", scheduler, parent) {}
68 };
69 
76 class TimerB final : public Timer
77 {
78 private:
79  void underFlow() override;
80 
81 public:
86  Timer("CIA Timer B", scheduler, parent) {}
87 
91  void cascade()
92  {
93  // we pretend that we are CPU doing a write to ctrl register
94  syncWithCpu();
95  state |= CIAT_STEP;
97  }
98 
104  bool started() const { return (state & CIAT_CR_START) != 0; }
105 };
106 
111 {
112 public:
114  InterruptSource(scheduler, parent)
115  {}
116 
117  void trigger(uint8_t interruptMask) override;
118 
119  uint8_t clear() override;
120 
121  void event() override
122  {
123  throw "8521 event called unexpectedly";
124  }
125 };
126 
131 {
132 private:
134  event_clock_t last_clear;
135 
137  bool scheduled;
138 
140  bool tbBug;
141 
142 private:
146  void schedule()
147  {
148  if (!scheduled)
149  {
150  eventScheduler.schedule(*this, 1, EVENT_CLOCK_PHI1);
151  scheduled = true;
152  }
153  }
154 
155 public:
157  InterruptSource(scheduler, parent),
158  last_clear(0),
159  scheduled(false),
160  tbBug(false)
161  {}
162 
163  void trigger(uint8_t interruptMask) override;
164 
165  uint8_t clear() override;
166 
170  void event() override;
171 
172  void reset() override;
173 };
174 
181 class MOS6526
182 {
183  friend class InterruptSource6526;
184  friend class InterruptSource8521;
185  friend class SerialPort;
186  friend class TimerA;
187  friend class TimerB;
188  friend class Tod;
189 
190 private:
191  static const char *credit;
192 
193 protected:
196 
198 
199  uint8_t &pra, &prb, &ddra, &ddrb;
201 
203  uint8_t regs[0x10];
204 
206 
210 
212  std::unique_ptr<InterruptSource> interruptSource;
213 
216 
219 
221 
224 
225 private:
229  void todInterrupt();
230 
234  void spInterrupt();
235 
248  void bTick();
249 
253  void underflowA();
254 
256  void underflowB();
257 
261  void handleSerialPort();
262 
263 protected:
269  MOS6526(EventScheduler &scheduler);
270 
277  virtual void interrupt(bool state) = 0;
278 
279  virtual void portA() {}
280  virtual void portB() {}
281 
288  uint8_t read(uint_least8_t addr);
289 
298  void write(uint_least8_t addr, uint8_t data);
299 
300 public:
306  void setModel(bool newModel);
307 
311  virtual void reset();
312 
318  static const char *credits();
319 
325  void setDayOfTimeRate(unsigned int clock) { tod.setPeriod(clock); }
326 };
327 
328 }
329 
330 #endif // MOS6526_H
Definition: mos6526.h:110
bool started() const
Definition: mos6526.h:104
Definition: mos6526.h:181
uint8_t clear() override
Definition: mos6526.cpp:128
uint8_t & ddra
Ports.
Definition: mos6526.h:199
void trigger(uint8_t interruptMask) override
Definition: mos6526.cpp:75
void setModel(bool newModel)
Definition: mos6526.cpp:376
Definition: EventCallback.h:35
void trigger(uint8_t interruptMask) override
Definition: mos6526.cpp:98
Definition: mos6526.h:76
EventScheduler & eventScheduler
Event scheduler.
Definition: interrupt.h:60
virtual void reset()
Definition: mos6526.cpp:202
MOS6526 & parent
Pointer to the MOS6526 which this Timer belongs to.
Definition: timer.h:92
InterruptSource(EventScheduler &scheduler, MOS6526 &parent)
Definition: interrupt.h:85
uint8_t regs[0x10]
These are all CIA registers.
Definition: mos6526.h:203
Definition: mos6526.h:52
uint8_t & prb
Ports.
Definition: mos6526.h:199
void reset() override
Definition: mos6526.cpp:160
TimerB(EventScheduler &scheduler, MOS6526 &parent)
Definition: mos6526.h:85
Definition: interrupt.h:41
static const char * credits()
Definition: mos6526.cpp:168
SerialPort serialPort
Serial Data Registers.
Definition: mos6526.h:218
uint8_t clear() override
Definition: mos6526.cpp:86
void syncWithCpu()
Definition: timer.cpp:37
void event() override
Definition: mos6526.h:121
uint8_t & pra
Ports.
Definition: mos6526.h:199
MOS6526(EventScheduler &scheduler)
Definition: mos6526.cpp:178
void setDayOfTimeRate(unsigned int clock)
Definition: mos6526.h:325
TimerA timerA
Timers A and B.
Definition: mos6526.h:207
int_least32_t state
CRA/CRB control register / state.
Definition: timer.h:95
Definition: SerialPort.h:36
uint8_t read(uint_least8_t addr)
Definition: mos6526.cpp:221
TimerA(EventScheduler &scheduler, MOS6526 &parent)
Definition: mos6526.h:66
Definition: timer.h:42
void wakeUpAfterSyncWithCpu()
Definition: timer.cpp:60
Definition: EventScheduler.h:61
Definition: mos6526.h:130
Definition: tod.h:39
uint8_t & ddrb
Ports.
Definition: mos6526.h:199
Tod tod
TOD.
Definition: mos6526.h:215
void event() override
Definition: mos6526.cpp:152
void cascade()
Definition: mos6526.h:91
std::unique_ptr< InterruptSource > interruptSource
Interrupt Source.
Definition: mos6526.h:212
EventScheduler & eventScheduler
Event context.
Definition: mos6526.h:195
void write(uint_least8_t addr, uint8_t data)
Definition: mos6526.cpp:276
TimerB timerB
Timers A and B.
Definition: mos6526.h:208
void setPeriod(event_clock_t clock)
Definition: tod.h:118
EventCallback< MOS6526 > bTickEvent
Events.
Definition: mos6526.h:222
virtual void interrupt(bool state)=0
MOS6526 & parent
Pointer to the MOS6526 which this Interrupt belongs to.
Definition: interrupt.h:57