libsidplayfp  2.0.4
mos6526.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 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  inline uint_least16_t getLatchTimerDiff() const { return latch-timer; }
70 };
71 
78 class TimerB final : public Timer
79 {
80 private:
81  void underFlow() override;
82 
83 public:
88  Timer("CIA Timer B", scheduler, parent) {}
89 
93  void cascade()
94  {
95  // we pretend that we are CPU doing a write to ctrl register
96  syncWithCpu();
97  state |= CIAT_STEP;
99  }
100 
106  bool started() const { return (state & CIAT_CR_START) != 0; }
107 };
108 
113 {
114 public:
115  InterruptSource8521(EventScheduler &scheduler, MOS6526 &parent) :
116  InterruptSource(scheduler, parent)
117  {}
118 
119  void trigger(uint8_t interruptMask) override;
120 
121  uint8_t clear() override;
122 };
123 
128 {
129 private:
131  bool tbBug;
132 
133 private:
134  void triggerBug() { idr &= ~INTERRUPT_UNDERFLOW_B; }
135 
136 public:
137  InterruptSource6526(EventScheduler &scheduler, MOS6526 &parent) :
138  InterruptSource(scheduler, parent),
139  tbBug(false)
140  {}
141 
142  void trigger(uint8_t interruptMask) override;
143 
144  uint8_t clear() override;
145 
146  void reset() override;
147 };
148 
155 class MOS6526
156 {
157  friend class InterruptSource;
158  friend class SerialPort;
159  friend class TimerA;
160  friend class TimerB;
161  friend class Tod;
162 
163 private:
164  static const char *credit;
165 
166 protected:
169 
171 
172  uint8_t &pra, &prb, &ddra, &ddrb;
174 
176  uint8_t regs[0x10];
177 
179 
181  TimerB timerB;
183 
185  std::unique_ptr<InterruptSource> interruptSource;
186 
189 
192 
194 
197 
198 private:
202  void todInterrupt();
203 
207  void spInterrupt();
208 
221  void bTick();
222 
226  void underflowA();
227 
229  void underflowB();
230 
234  void handleSerialPort();
235 
236 protected:
242  MOS6526(EventScheduler &scheduler);
243 
250  virtual void interrupt(bool state) = 0;
251 
252  virtual void portA() {}
253  virtual void portB() {}
254 
258  uint8_t adjustDataPort(uint8_t data);
259 
266  uint8_t read(uint_least8_t addr);
267 
276  void write(uint_least8_t addr, uint8_t data);
277 
278 public:
284  void setModel(bool newModel);
285 
289  virtual void reset();
290 
296  static const char *credits();
297 
303  void setDayOfTimeRate(unsigned int clock) { tod.setPeriod(clock); }
304 };
305 
306 }
307 
308 #endif // MOS6526_H
libsidplayfp::TimerA
Definition: mos6526.h:53
libsidplayfp::MOS6526::write
void write(uint_least8_t addr, uint8_t data)
Definition: mos6526.cpp:269
libsidplayfp::MOS6526::regs
uint8_t regs[0x10]
These are all CIA registers.
Definition: mos6526.h:176
libsidplayfp::MOS6526::read
uint8_t read(uint_least8_t addr)
Definition: mos6526.cpp:230
libsidplayfp::MOS6526::pra
uint8_t & pra
Ports.
Definition: mos6526.h:172
libsidplayfp::Tod::setPeriod
void setPeriod(event_clock_t clock)
Definition: tod.h:118
libsidplayfp::MOS6526
Definition: mos6526.h:156
libsidplayfp::MOS6526::timerA
TimerA timerA
Timers A and B.
Definition: mos6526.h:180
libsidplayfp::InterruptSource8521::trigger
void trigger(uint8_t interruptMask) override
Definition: mos6526.cpp:75
libsidplayfp::InterruptSource6526::trigger
void trigger(uint8_t interruptMask) override
Definition: mos6526.cpp:106
libsidplayfp::MOS6526::interrupt
virtual void interrupt(bool state)=0
libsidplayfp::EventScheduler
Definition: EventScheduler.h:62
libsidplayfp::Timer::latch
uint_least16_t latch
Timer start value (Latch).
Definition: timer.h:95
libsidplayfp::MOS6526::bTickEvent
EventCallback< MOS6526 > bTickEvent
Events.
Definition: mos6526.h:195
libsidplayfp::MOS6526::serialPort
SerialPort serialPort
Serial Data Registers.
Definition: mos6526.h:191
libsidplayfp::InterruptSource6526::clear
uint8_t clear() override
Definition: mos6526.cpp:137
libsidplayfp::MOS6526::adjustDataPort
uint8_t adjustDataPort(uint8_t data)
Definition: mos6526.cpp:213
libsidplayfp::Timer::wakeUpAfterSyncWithCpu
void wakeUpAfterSyncWithCpu()
Definition: timer.cpp:60
libsidplayfp::InterruptSource::INTERRUPT_UNDERFLOW_B
@ INTERRUPT_UNDERFLOW_B
underflow Timer B
Definition: interrupt.h:48
libsidplayfp::InterruptSource8521
Definition: mos6526.h:113
libsidplayfp::Timer::state
int_least32_t state
CRA/CRB control register / state.
Definition: timer.h:89
libsidplayfp::InterruptSource
Definition: interrupt.h:42
libsidplayfp::Timer::syncWithCpu
void syncWithCpu()
Definition: timer.cpp:37
libsidplayfp::MOS6526::eventScheduler
EventScheduler & eventScheduler
Event context.
Definition: mos6526.h:168
libsidplayfp::MOS6526::setModel
void setModel(bool newModel)
Definition: mos6526.cpp:371
libsidplayfp::TimerA::TimerA
TimerA(EventScheduler &scheduler, MOS6526 &parent)
Definition: mos6526.h:66
libsidplayfp::MOS6526::interruptSource
std::unique_ptr< InterruptSource > interruptSource
Interrupt Source.
Definition: mos6526.h:185
libsidplayfp::MOS6526::tod
Tod tod
TOD.
Definition: mos6526.h:188
libsidplayfp::InterruptSource8521::clear
uint8_t clear() override
Definition: mos6526.cpp:94
libsidplayfp::Timer
Definition: timer.h:43
libsidplayfp::InterruptSource6526::reset
void reset() override
Definition: mos6526.cpp:153
libsidplayfp::MOS6526::credits
static const char * credits()
Definition: mos6526.cpp:160
libsidplayfp::InterruptSource::InterruptSource
InterruptSource(EventScheduler &scheduler, MOS6526 &parent)
Definition: interrupt.h:90
libsidplayfp::TimerB::TimerB
TimerB(EventScheduler &scheduler, MOS6526 &parent)
Definition: mos6526.h:87
libsidplayfp::SerialPort
Definition: SerialPort.h:37
libsidplayfp::MOS6526::setDayOfTimeRate
void setDayOfTimeRate(unsigned int clock)
Definition: mos6526.h:303
libsidplayfp::Tod
Definition: tod.h:40
libsidplayfp::Timer::timer
uint_least16_t timer
Current timer value.
Definition: timer.h:92
libsidplayfp::InterruptSource6526
Definition: mos6526.h:128
libsidplayfp::TimerB
Definition: mos6526.h:79
libsidplayfp::TimerB::started
bool started() const
Definition: mos6526.h:106
libsidplayfp::TimerB::cascade
void cascade()
Definition: mos6526.h:93
libsidplayfp::Timer::parent
MOS6526 & parent
Pointer to the MOS6526 which this Timer belongs to.
Definition: timer.h:86
libsidplayfp::InterruptSource::idr
uint8_t idr
Interrupt data register.
Definition: interrupt.h:70
libsidplayfp::MOS6526::reset
virtual void reset()
Definition: mos6526.cpp:194
libsidplayfp::MOS6526::MOS6526
MOS6526(EventScheduler &scheduler)
Definition: mos6526.cpp:170
libsidplayfp::EventCallback
Definition: EventCallback.h:36