libsidplayfp  1.5.3
mos6526.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2013 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 MOS6526_H
24 #define MOS6526_H
25 
26 #include <stdint.h>
27 
28 #include "timer.h"
29 #include "sidplayfp/EventScheduler.h"
30 #include "sidplayfp/component.h"
31 
32 class EventContext;
33 class MOS6526;
34 
41 class TimerA : public Timer
42 {
43 private:
47  void underFlow();
48 
49  void serialPort();
50 
51 public:
56  Timer("CIA Timer A", context, parent) {}
57 };
58 
65 class TimerB : public Timer
66 {
67 private:
68  void underFlow();
69 
70 public:
75  Timer("CIA Timer B", context, parent) {}
76 
80  void cascade()
81  {
82  /* we pretend that we are CPU doing a write to ctrl register */
83  syncWithCpu();
84  state |= CIAT_STEP;
86  }
87 
93  bool started() const { return (state & CIAT_CR_START) != 0; }
94 };
95 
102 class MOS6526: public component
103 {
104  friend class TimerA;
105  friend class TimerB;
106 
107 private:
108  static const char *credit;
109 
110 protected:
112  uint8_t regs[0x10];
113 
115 
116  uint8_t &pra, &prb, &ddra, &ddrb;
118 
120 
124 
126 
127  uint8_t sdr_out;
131 
133  uint8_t icr;
134 
136  uint8_t idr;
137 
140 
142 
145  uint8_t m_todclock[4], m_todalarm[4], m_todlatch[4];
146  event_clock_t m_todCycles, m_todPeriod;
148 
151 
153 
158 
159 protected:
165  MOS6526(EventContext *context);
166  ~MOS6526() {}
167 
180  void bTick();
181 
185  void tod();
186 
190  void trigger();
191 
195  void underflowA();
196 
198  void underflowB();
199 
205  void trigger(uint8_t interruptMask);
206 
210  void clear();
211 
215  void serialPort();
216 
223  virtual void interrupt(bool state) = 0;
224 
225  virtual void portA() {}
226  virtual void portB() {}
227 
234  uint8_t read(uint_least8_t addr);
235 
244  void write(uint_least8_t addr, uint8_t data);
245 
246 private:
247  void setTodReg(uint_least8_t addr, uint8_t data);
248 
249  // TOD implementation taken from Vice
250  static uint8_t byte2bcd(uint8_t byte) { return (((byte / 10) << 4) + (byte % 10)) & 0xff; }
251  static uint8_t bcd2byte(uint8_t bcd) { return ((10*((bcd & 0xf0) >> 4)) + (bcd & 0xf)) & 0xff; }
252 
253 public:
257  virtual void reset();
258 
264  const char *credits() const { return credit; }
265 
271  void setDayOfTimeRate(unsigned int clock);
272 };
273 
274 #endif // MOS6526_H
void bTick()
Definition: mos6526.cpp:377
uint8_t regs[0x10]
These are all CIA registers.
Definition: mos6526.h:112
uint8_t & ddrb
Ports.
Definition: mos6526.h:116
bool m_todstopped
TOD.
Definition: mos6526.h:144
Definition: mos6526.h:65
Definition: mos6526.h:102
uint8_t idr
Interrupt data register.
Definition: mos6526.h:136
TimerB(EventContext *context, MOS6526 *parent)
Definition: mos6526.h:74
TimerA timerA
Timers A and B.
Definition: mos6526.h:121
int sdr_count
Serial Data Registers.
Definition: mos6526.h:129
uint8_t sdr_out
Serial Data Registers.
Definition: mos6526.h:127
Definition: mos6526.h:41
bool started() const
Definition: mos6526.h:93
void cascade()
Definition: mos6526.h:80
uint8_t m_todlatch[4]
TOD.
Definition: mos6526.h:145
uint8_t read(uint_least8_t addr)
Definition: mos6526.cpp:167
Definition: event.h:107
void trigger()
Definition: mos6526.cpp:356
EventCallback< MOS6526 > bTickEvent
Events.
Definition: mos6526.h:154
void clear()
Definition: mos6526.cpp:124
MOS6526 *const parent
Pointer to the MOS6526 which this Timer belongs to.
Definition: timer.h:88
uint8_t & ddra
Ports.
Definition: mos6526.h:116
event_clock_t m_todPeriod
TOD.
Definition: mos6526.h:146
void underflowA()
Definition: mos6526.cpp:382
EventCallback< MOS6526 > triggerEvent
Events.
Definition: mos6526.h:156
Definition: component.h:28
bool triggerScheduled
Have we already scheduled CIA->CPU interrupt transition?
Definition: mos6526.h:150
void serialPort()
Definition: mos6526.cpp:103
bool m_todlatched
TOD.
Definition: mos6526.h:143
int_least32_t state
CRA/CRB control register / state.
Definition: timer.h:91
void underflowB()
Definition: mos6526.cpp:394
uint8_t & prb
Ports.
Definition: mos6526.h:116
bool sdr_buffered
Serial Data Registers.
Definition: mos6526.h:128
void write(uint_least8_t addr, uint8_t data)
Definition: mos6526.cpp:265
uint8_t icr
Interrupt control register.
Definition: mos6526.h:133
MOS6526(EventContext *context)
Definition: mos6526.cpp:86
void tod()
Definition: mos6526.cpp:399
virtual void reset()
Definition: mos6526.cpp:137
virtual void interrupt(bool state)=0
void syncWithCpu()
Definition: timer.cpp:34
event_clock_t m_todCycles
TOD.
Definition: mos6526.h:146
uint8_t m_todalarm[4]
TOD.
Definition: mos6526.h:145
void wakeUpAfterSyncWithCpu()
Definition: timer.cpp:57
TimerA(EventContext *context, MOS6526 *parent)
Definition: mos6526.h:55
EventContext & event_context
Event context.
Definition: mos6526.h:139
uint8_t & pra
Ports.
Definition: mos6526.h:116
Definition: timer.h:38
void setDayOfTimeRate(unsigned int clock)
Definition: mos6526.cpp:132
EventCallback< MOS6526 > todEvent
Events.
Definition: mos6526.h:155
uint8_t m_todclock[4]
TOD.
Definition: mos6526.h:145
TimerB timerB
Timers A and B.
Definition: mos6526.h:122
const char * credits() const
Definition: mos6526.h:264