libsidplayfp  2.12.0
mos6510.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2019 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 MOS6510_H
24 #define MOS6510_H
25 
26 #include <stdint.h>
27 #include <cstdio>
28 
29 #include "flags.h"
30 #include "EventCallback.h"
31 #include "EventScheduler.h"
32 
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36 
37 class EventContext;
38 
39 namespace libsidplayfp
40 {
41 
42 #ifdef DEBUG
43 class MOS6510;
44 
45 namespace MOS6510Debug
46 {
47  void DumpState(event_clock_t time, MOS6510 &cpu);
48 }
49 #endif
50 
52 {
53 public:
54  virtual ~CPUDataBus() = default;
55 
56  virtual uint8_t cpuRead(uint_least16_t addr) =0;
57 
58  virtual void cpuWrite(uint_least16_t addr, uint8_t data) =0;
59 };
60 
70 class MOS6510
71 {
72 #ifdef DEBUG
73  friend void MOS6510Debug::DumpState(event_clock_t time, MOS6510 &cpu);
74 #endif
75 
76 public:
77  class haltInstruction {};
78 
79 private:
85  static const int MAX = 65536;
86 
88  static const uint8_t SP_PAGE = 0x01;
89 
90 public:
92  static const int SR_INTERRUPT = 2;
93 
94 private:
95  struct ProcessorCycle
96  {
97  void (*func)(MOS6510&);
98  bool nosteal;
99  ProcessorCycle() :
100  func(nullptr),
101  nosteal(false) {}
102  };
103 
104 private:
106  EventScheduler &eventScheduler;
107 
109  CPUDataBus &dataBus;
110 
112  int cycleCount;
113 
115  int interruptCycle;
116 
118  bool irqAssertedOnPin;
119 
121  bool nmiFlag;
122 
124  bool rstFlag;
125 
127  bool rdy;
128 
130  bool adl_carry;
131 
132  bool d1x1;
133 
135  bool rdyOnThrowAwayRead;
136 
138  Flags flags;
139 
140  // Data regarding current instruction
141  uint_least16_t Register_ProgramCounter;
142  uint_least16_t Cycle_EffectiveAddress;
143  uint_least16_t Cycle_Pointer;
144 
145  uint8_t Cycle_Data;
146  uint8_t Register_StackPointer;
147  uint8_t Register_Accumulator;
148  uint8_t Register_X;
149  uint8_t Register_Y;
150 
151 #ifdef DEBUG
152  // Debug info
153  int_least32_t instrStartPC;
154  uint_least16_t instrOperand;
155 
156  FILE *m_fdbg;
157 
158  bool dodump;
159 #endif
160 
162  struct ProcessorCycle instrTable[0x101 << 3];
163 
164 private:
165  void eventWithoutSteals();
166  void eventWithSteals();
167  void removeIRQ();
168 
171 
174 
176 
177  inline void Initialise();
178 
179  // Declare Interrupt Routines
180  inline void IRQLoRequest();
181  inline void IRQHiRequest();
182  inline void interruptsAndNextOpcode();
183  inline void calculateInterruptTriggerCycle();
184 
185  // Declare Instruction Routines
186  inline void fetchNextOpcode();
187  inline void throwAwayFetch();
188  inline void throwAwayRead();
189  inline void FetchDataByte();
190  inline void FetchLowAddr();
191  inline void FetchLowAddrX();
192  inline void FetchLowAddrY();
193  inline void FetchHighAddr();
194  inline void FetchHighAddrX();
195  inline void FetchHighAddrX2();
196  inline void FetchHighAddrY();
197  inline void FetchHighAddrY2();
198  inline void FetchLowEffAddr();
199  inline void FetchHighEffAddr();
200  inline void FetchHighEffAddrY();
201  inline void FetchHighEffAddrY2();
202  inline void FetchLowPointer();
203  inline void FetchLowPointerX();
204  inline void FetchHighPointer();
205  inline void FetchEffAddrDataByte();
206  inline void PutEffAddrDataByte();
207  inline void PushLowPC();
208  inline void PushHighPC();
209  inline void PushSR();
210  inline void PopLowPC();
211  inline void PopHighPC();
212  inline void PopSR();
213  inline void brkPushLowPC();
214  inline void WasteCycle();
215 
216  inline void Push(uint8_t data);
217  inline uint8_t Pop();
218  inline void compare(uint8_t data);
219 
220  // Delcare Instruction Operation Routines
221  inline void adc_instr();
222  inline void alr_instr();
223  inline void anc_instr();
224  inline void and_instr();
225  inline void ane_instr();
226  inline void arr_instr();
227  inline void asl_instr();
228  inline void asla_instr();
229  inline void aso_instr();
230  inline void axa_instr();
231  inline void axs_instr();
232  inline void bcc_instr();
233  inline void bcs_instr();
234  inline void beq_instr();
235  inline void bit_instr();
236  inline void bmi_instr();
237  inline void bne_instr();
238  inline void branch_instr(bool condition);
239  inline void fix_branch();
240  inline void bpl_instr();
241  inline void bvc_instr();
242  inline void bvs_instr();
243  inline void clc_instr();
244  inline void cld_instr();
245  inline void cli_instr();
246  inline void clv_instr();
247  inline void cmp_instr();
248  inline void cpx_instr();
249  inline void cpy_instr();
250  inline void dcm_instr();
251  inline void dec_instr();
252  inline void dex_instr();
253  inline void dey_instr();
254  inline void eor_instr();
255  inline void inc_instr();
256  inline void ins_instr();
257  inline void inx_instr();
258  inline void iny_instr();
259  inline void jmp_instr();
260  inline void las_instr();
261  inline void lax_instr();
262  inline void lda_instr();
263  inline void ldx_instr();
264  inline void ldy_instr();
265  inline void lse_instr();
266  inline void lsr_instr();
267  inline void lsra_instr();
268  inline void oal_instr();
269  inline void ora_instr();
270  inline void pha_instr();
271  inline void pla_instr();
272  inline void rla_instr();
273  inline void rol_instr();
274  inline void rola_instr();
275  inline void ror_instr();
276  inline void rora_instr();
277  inline void rra_instr();
278  inline void rti_instr();
279  inline void rts_instr();
280  inline void sbx_instr();
281  inline void say_instr();
282  inline void sbc_instr();
283  inline void sec_instr();
284  inline void sed_instr();
285  inline void sei_instr();
286  inline void shs_instr();
287  inline void sta_instr();
288  inline void stx_instr();
289  inline void sty_instr();
290  inline void tax_instr();
291  inline void tay_instr();
292  inline void tsx_instr();
293  inline void txa_instr();
294  inline void txs_instr();
295  inline void tya_instr();
296  inline void xas_instr();
297  inline void sh_instr();
298 
302  void invalidOpcode();
303 
304  // Declare Arithmetic Operations
305  inline void doADC();
306  inline void doSBC();
307 
308  inline bool checkInterrupts() const { return rstFlag || nmiFlag || (irqAssertedOnPin && !flags.getI()); }
309 
310  inline void buildInstructionTable();
311 
312 public:
313  MOS6510(EventScheduler &scheduler, CPUDataBus& bus);
314 
315  inline uint8_t cpuRead(uint_least16_t addr) { return dataBus.cpuRead(addr); }
316 
317  inline void cpuWrite(uint_least16_t addr, uint8_t data) { dataBus.cpuWrite(addr, data); }
318 
319  void reset();
320 
321  static const char *credits();
322 
323  void debug(bool enable, FILE *out);
324  void setRDY(bool newRDY);
325 
326  // Non-standard functions
327  void triggerRST();
328  void triggerNMI();
329  void triggerIRQ();
330  void clearIRQ();
331 };
332 
333 }
334 
335 #endif // MOS6510_H
Definition: mos6510.h:52
Definition: EventScheduler.h:62
Definition: EventCallback.h:57
Definition: flags.h:35
Definition: mos6510.h:71
void setRDY(bool newRDY)
Definition: mos6510.cpp:128
void triggerNMI()
Definition: mos6510.cpp:193
MOS6510(EventScheduler &scheduler, CPUDataBus &bus)
Definition: mos6510.cpp:1472
static const char * credits()
Definition: mos6510.cpp:2203
void triggerRST()
Definition: mos6510.cpp:179
void reset()
Definition: mos6510.cpp:2184
static const int SR_INTERRUPT
Status register interrupt bit.
Definition: mos6510.h:92
void triggerIRQ()
Definition: mos6510.cpp:209
void clearIRQ()
Definition: mos6510.cpp:225