libsidplayfp 2.15.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
39class EventContext;
40
41namespace libsidplayfp
42{
43
44class MOS652X;
45
52class TimerA final : public Timer
53{
54private:
58 void underFlow() override;
59
60 void serialPort() override;
61
62public:
67 Timer("CIA Timer A", scheduler, parent) {}
68};
69
76class TimerB final : public Timer
77{
78private:
79 void underFlow() override;
80
81public:
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
95 state |= CIAT_STEP;
97 }
98
104 bool started() const { return (state & CIAT_CR_START) != 0; }
105};
106
111{
112protected:
113 void triggerInterrupt() override
114 {
116 idrTemp |= INTERRUPT_REQUEST;
117
118 if (ack0())
119 scheduleIrq();
120 }
121
122public:
123 InterruptSource8521(EventScheduler &scheduler, MOS652X &parent) :
124 InterruptSource(scheduler, parent)
125 {}
126
127 void trigger(uint8_t interruptMask) override;
128};
129
134{
135protected:
136 void triggerInterrupt() override { idr |= INTERRUPT_REQUEST; }
137
138public:
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
154{
155 friend class InterruptSource;
156 friend class SerialPort;
157 friend class TimerA;
158 friend class TimerB;
159 friend class Tod;
160
161public:
162 enum class model_t
163 {
164 MOS6526 = 0
165 ,MOS8521
167 };
168
169private:
170 static const char *credit;
171
172protected:
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
204private:
208 void todInterrupt();
209
213 void spInterrupt();
214
227 void bTick();
228
232 void underflowA();
233
235 void underflowB();
236
240 void handleSerialPort();
241
242protected:
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
284public:
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
@ 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
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