libsidplayfp  2.2.2
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 
51 
61 class MOS6510
62 {
63 #ifdef DEBUG
64  friend void MOS6510Debug::DumpState(event_clock_t time, MOS6510 &cpu);
65 #endif
66 
67 public:
68  class haltInstruction {};
69 
70 private:
76  static const int MAX = 65536;
77 
79  static const uint8_t SP_PAGE = 0x01;
80 
81 public:
83  static const int SR_INTERRUPT = 2;
84 
85 private:
86  struct ProcessorCycle
87  {
88  void (MOS6510::*func)();
89  bool nosteal;
90  ProcessorCycle() :
91  func(0),
92  nosteal(false) {}
93  };
94 
95 private:
97  EventScheduler &eventScheduler;
98 
100  int cycleCount;
101 
103  int interruptCycle;
104 
106  bool irqAssertedOnPin;
107 
109  bool nmiFlag;
110 
112  bool rstFlag;
113 
115  bool rdy;
116 
118  bool adl_carry;
119 
120  bool d1x1;
121 
123  bool rdyOnThrowAwayRead;
124 
126  Flags flags;
127 
128  // Data regarding current instruction
129  uint_least16_t Register_ProgramCounter;
130  uint_least16_t Cycle_EffectiveAddress;
131  uint_least16_t Cycle_Pointer;
132 
133  uint8_t Cycle_Data;
134  uint8_t Register_StackPointer;
135  uint8_t Register_Accumulator;
136  uint8_t Register_X;
137  uint8_t Register_Y;
138 
139 #ifdef DEBUG
140  // Debug info
141  int_least32_t instrStartPC;
142  uint_least16_t instrOperand;
143 
144  FILE *m_fdbg;
145 
146  bool dodump;
147 #endif
148 
150  struct ProcessorCycle instrTable[0x101 << 3];
151 
152 private:
154  EventCallback<MOS6510> m_nosteal;
155 
157  EventCallback<MOS6510> m_steal;
158 
159  EventCallback<MOS6510> clearInt;
160 
161  void eventWithoutSteals();
162  void eventWithSteals();
163  void removeIRQ();
164 
165  inline void Initialise();
166 
167  // Declare Interrupt Routines
168  inline void IRQLoRequest();
169  inline void IRQHiRequest();
170  inline void interruptsAndNextOpcode();
171  inline void calculateInterruptTriggerCycle();
172 
173  // Declare Instruction Routines
174  inline void fetchNextOpcode();
175  inline void throwAwayFetch();
176  inline void throwAwayRead();
177  inline void FetchDataByte();
178  inline void FetchLowAddr();
179  inline void FetchLowAddrX();
180  inline void FetchLowAddrY();
181  inline void FetchHighAddr();
182  inline void FetchHighAddrX();
183  inline void FetchHighAddrX2();
184  inline void FetchHighAddrY();
185  inline void FetchHighAddrY2();
186  inline void FetchLowEffAddr();
187  inline void FetchHighEffAddr();
188  inline void FetchHighEffAddrY();
189  inline void FetchHighEffAddrY2();
190  inline void FetchLowPointer();
191  inline void FetchLowPointerX();
192  inline void FetchHighPointer();
193  inline void FetchEffAddrDataByte();
194  inline void PutEffAddrDataByte();
195  inline void PushLowPC();
196  inline void PushHighPC();
197  inline void PushSR();
198  inline void PopLowPC();
199  inline void PopHighPC();
200  inline void PopSR();
201  inline void brkPushLowPC();
202  inline void WasteCycle();
203 
204  inline void Push(uint8_t data);
205  inline uint8_t Pop();
206  inline void compare(uint8_t data);
207 
208  // Delcare Instruction Operation Routines
209  inline void adc_instr();
210  inline void alr_instr();
211  inline void anc_instr();
212  inline void and_instr();
213  inline void ane_instr();
214  inline void arr_instr();
215  inline void asl_instr();
216  inline void asla_instr();
217  inline void aso_instr();
218  inline void axa_instr();
219  inline void axs_instr();
220  inline void bcc_instr();
221  inline void bcs_instr();
222  inline void beq_instr();
223  inline void bit_instr();
224  inline void bmi_instr();
225  inline void bne_instr();
226  inline void branch_instr(bool condition);
227  inline void fix_branch();
228  inline void bpl_instr();
229  inline void bvc_instr();
230  inline void bvs_instr();
231  inline void clc_instr();
232  inline void cld_instr();
233  inline void cli_instr();
234  inline void clv_instr();
235  inline void cmp_instr();
236  inline void cpx_instr();
237  inline void cpy_instr();
238  inline void dcm_instr();
239  inline void dec_instr();
240  inline void dex_instr();
241  inline void dey_instr();
242  inline void eor_instr();
243  inline void inc_instr();
244  inline void ins_instr();
245  inline void inx_instr();
246  inline void iny_instr();
247  inline void jmp_instr();
248  inline void las_instr();
249  inline void lax_instr();
250  inline void lda_instr();
251  inline void ldx_instr();
252  inline void ldy_instr();
253  inline void lse_instr();
254  inline void lsr_instr();
255  inline void lsra_instr();
256  inline void oal_instr();
257  inline void ora_instr();
258  inline void pha_instr();
259  inline void pla_instr();
260  inline void rla_instr();
261  inline void rol_instr();
262  inline void rola_instr();
263  inline void ror_instr();
264  inline void rora_instr();
265  inline void rra_instr();
266  inline void rti_instr();
267  inline void rts_instr();
268  inline void sbx_instr();
269  inline void say_instr();
270  inline void sbc_instr();
271  inline void sec_instr();
272  inline void sed_instr();
273  inline void sei_instr();
274  inline void shs_instr();
275  inline void sta_instr();
276  inline void stx_instr();
277  inline void sty_instr();
278  inline void tax_instr();
279  inline void tay_instr();
280  inline void tsx_instr();
281  inline void txa_instr();
282  inline void txs_instr();
283  inline void tya_instr();
284  inline void xas_instr();
285  inline void sh_instr(uint8_t offset);
286 
290  void invalidOpcode();
291 
292  // Declare Arithmetic Operations
293  inline void doADC();
294  inline void doSBC();
295 
296  inline bool checkInterrupts() const { return rstFlag || nmiFlag || (irqAssertedOnPin && !flags.getI()); }
297 
298  inline void buildInstructionTable();
299 
300 protected:
301  MOS6510(EventScheduler &scheduler);
302  ~MOS6510() {}
303 
310  virtual uint8_t cpuRead(uint_least16_t addr) =0;
311 
318  virtual void cpuWrite(uint_least16_t addr, uint8_t data) =0;
319 
320 public:
321  void reset();
322 
323  static const char *credits();
324 
325  void debug(bool enable, FILE *out);
326  void setRDY(bool newRDY);
327 
328  // Non-standard functions
329  void triggerRST();
330  void triggerNMI();
331  void triggerIRQ();
332  void clearIRQ();
333 };
334 
335 }
336 
337 #endif // MOS6510_H
Definition: EventCallback.h:36
Definition: EventScheduler.h:62
Definition: flags.h:35
Definition: mos6510.h:62
virtual uint8_t cpuRead(uint_least16_t addr)=0
void setRDY(bool newRDY)
Definition: mos6510.cpp:120
MOS6510(EventScheduler &scheduler)
Definition: mos6510.cpp:1458
void triggerNMI()
Definition: mos6510.cpp:182
static const char * credits()
Definition: mos6510.cpp:2188
void triggerRST()
Definition: mos6510.cpp:168
virtual void cpuWrite(uint_least16_t addr, uint8_t data)=0
void reset()
Definition: mos6510.cpp:2169
static const int SR_INTERRUPT
Status register interrupt bit.
Definition: mos6510.h:83
void triggerIRQ()
Definition: mos6510.cpp:198
void clearIRQ()
Definition: mos6510.cpp:214