libsidplayfp  1.0.1
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/component.h"
30 
37 class TimerA : public Timer
38 {
39 private:
43  void underFlow();
44 
45  void serialPort();
46 
47 public:
52  Timer("CIA Timer A", context, parent) {}
53 };
54 
61 class TimerB : public Timer
62 {
63 private:
64  void underFlow();
65 
66 public:
71  Timer("CIA Timer B", context, parent) {}
72 
76  void cascade()
77  {
78  /* we pretend that we are CPU doing a write to ctrl register */
79  syncWithCpu();
80  state |= CIAT_STEP;
82  }
83 
89  bool started() const { return (state & CIAT_CR_START) != 0; }
90 };
91 
98 class MOS6526: public component
99 {
100  friend class TimerA;
101  friend class TimerB;
102 
103 private:
104  static const char *credit;
105 
106 protected:
110  uint8_t regs[0x10];
111 
112  // Ports
113  uint8_t &pra, &prb, &ddra, &ddrb;
114 
119  TimerB timerB;
120 
121  // Serial Data Registers
122  uint8_t sdr_out;
123  bool sdr_buffered;
124  int sdr_count;
125 
127  uint8_t icr;
128 
130  uint8_t idr;
131 
136 
137  // TOD
138  bool m_todlatched;
139  bool m_todstopped;
140  uint8_t m_todclock[4], m_todalarm[4], m_todlatch[4];
141  event_clock_t m_todCycles, m_todPeriod;
142 
145 
146  // Events
147  EventCallback<MOS6526> bTickEvent;
148  EventCallback<MOS6526> todEvent;
149  EventCallback<MOS6526> triggerEvent;
150 
151 protected:
157  MOS6526(EventContext *context);
158  ~MOS6526() {}
159 
172  void bTick();
173 
177  void tod();
178 
182  void trigger();
183 
187  void underflowA();
188 
192  void underflowB();
193 
199  void trigger(uint8_t interruptMask);
200 
204  void clear();
205 
209  void serialPort();
210 
217  virtual void interrupt(bool state) = 0;
218 
219  virtual void portA() {}
220  virtual void portB() {}
221 
228  uint8_t read(uint_least8_t addr);
229 
238  void write(uint_least8_t addr, uint8_t data);
239 
240 private:
241  // TOD implementation taken from Vice
242  static uint8_t byte2bcd(uint8_t byte) { return (((byte / 10) << 4) + (byte % 10)) & 0xff; }
243  static uint8_t bcd2byte(uint8_t bcd) { return ((10*((bcd & 0xf0) >> 4)) + (bcd & 0xf)) & 0xff; }
244 
245 public:
249  virtual void reset();
250 
256  const char *credits() const { return credit; }
257 
263  void setDayOfTimeRate(unsigned int clock);
264 };
265 
266 #endif // MOS6526_H