libsidplayfp  2.11.0
mos652x.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2021 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 MOS652X_H
25 #define MOS652X_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 MOS652X;
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 protected:
113  void triggerInterrupt() override
114  {
116  idrTemp |= INTERRUPT_REQUEST;
117 
118  if (ack0())
119  scheduleIrq();
120  }
121 
122 public:
123  InterruptSource8521(EventScheduler &scheduler, MOS652X &parent) :
124  InterruptSource(scheduler, parent)
125  {}
126 
127  void trigger(uint8_t interruptMask) override;
128 };
129 
134 {
135 protected:
136  void triggerInterrupt() override { idr |= INTERRUPT_REQUEST; }
137 
138 public:
139  InterruptSource6526(EventScheduler &scheduler, MOS652X &parent) :
140  InterruptSource(scheduler, parent)
141  {}
142 
143  void trigger(uint8_t interruptMask) override;
144 
145  uint8_t clear() override;
146 };
147 
153 class MOS652X
154 {
155  friend class InterruptSource;
156  friend class SerialPort;
157  friend class TimerA;
158  friend class TimerB;
159  friend class Tod;
160 
161 public:
162  enum class model_t
163  {
164  MOS6526 = 0
165  ,MOS8521
166  ,MOS6526W4485
167  };
168 
169 private:
170  static const char *credit;
171 
172 protected:
175 
177 
178  uint8_t &pra, &prb, &ddra, &ddrb;
180 
182  uint8_t regs[0x10];
183 
185 
187  TimerB timerB;
189 
191  std::unique_ptr<InterruptSource> interruptSource;
192 
195 
198 
200 
203 
204 private:
208  void todInterrupt();
209 
213  void spInterrupt();
214 
227  void bTick();
228 
232  void underflowA();
233 
235  void underflowB();
236 
240  void handleSerialPort();
241 
242 protected:
248  MOS652X(EventScheduler &scheduler);
249 
256  virtual void interrupt(bool state) = 0;
257 
258  virtual void portA() {}
259  virtual void portB() {}
260 
264  uint8_t adjustDataPort(uint8_t data);
265 
272  uint8_t read(uint_least8_t addr);
273 
282  void write(uint_least8_t addr, uint8_t data);
283 
284 public:
290  void setModel(model_t model);
291 
295  virtual void reset();
296 
302  static const char *credits();
303 
309  void setDayOfTimeRate(unsigned int clock) { tod.setPeriod(clock); }
310 };
311 
312 }
313 
314 #endif // MOS6526_H
Definition: EventCallback.h:36
Definition: EventScheduler.h:62
Definition: mos652x.h:134
void trigger(uint8_t interruptMask) override
Definition: mos652x.cpp:86
uint8_t clear() override
Definition: mos652x.cpp:104
Definition: mos652x.h:111
void trigger(uint8_t interruptMask) override
Definition: mos652x.cpp:76
Definition: interrupt.h:44
uint8_t idr
Interrupt data register.
Definition: interrupt.h:73
InterruptSource(EventScheduler &scheduler, MOS652X &parent)
Definition: interrupt.h:126
@ INTERRUPT_REQUEST
control bit
Definition: interrupt.h:54
bool ack0() const
Definition: interrupt.h:105
Definition: mos652x.h:154
TimerA timerA
Timers A and B.
Definition: mos652x.h:186
void write(uint_least8_t addr, uint8_t data)
Definition: mos652x.cpp:221
uint8_t regs[0x10]
These are all CIA registers.
Definition: mos652x.h:182
uint8_t adjustDataPort(uint8_t data)
Definition: mos652x.cpp:165
EventScheduler & eventScheduler
Event context.
Definition: mos652x.h:174
MOS652X(EventScheduler &scheduler)
Definition: mos652x.cpp:122
uint8_t & pra
Ports.
Definition: mos652x.h:178
Tod tod
TOD.
Definition: mos652x.h:194
model_t
Definition: mos652x.h:163
@ MOS6526W4485
A batch of old CIA model with unique serial port behavior.
@ MOS6526
Old CIA model, interrupts are delayed by 1 clock.
static const char * credits()
Definition: mos652x.cpp:112
void setModel(model_t model)
Definition: mos652x.cpp:322
virtual void reset()
Definition: mos652x.cpp:146
EventCallback< MOS652X > bTickEvent
Events.
Definition: mos652x.h:201
uint8_t read(uint_least8_t addr)
Definition: mos652x.cpp:182
std::unique_ptr< InterruptSource > interruptSource
Interrupt Source.
Definition: mos652x.h:191
SerialPort serialPort
Serial Data Registers.
Definition: mos652x.h:197
void setDayOfTimeRate(unsigned int clock)
Definition: mos652x.h:309
virtual void interrupt(bool state)=0
Definition: SerialPort.h:37
Definition: mos652x.h:53
TimerA(EventScheduler &scheduler, MOS652X &parent)
Definition: mos652x.h:66
Definition: mos652x.h:77
TimerB(EventScheduler &scheduler, MOS652X &parent)
Definition: mos652x.h:85
void cascade()
Definition: mos652x.h:91
bool started() const
Definition: mos652x.h:104
Definition: timer.h:43
void wakeUpAfterSyncWithCpu()
Definition: timer.cpp:60
void syncWithCpu()
Definition: timer.cpp:37
int_least32_t state
CRA/CRB control register / state.
Definition: timer.h:95
MOS652X & parent
Pointer to the MOS6526 which this Timer belongs to.
Definition: timer.h:92
Definition: tod.h:40
void setPeriod(event_clock_t clock)
Definition: tod.h:118