libsidplayfp  0.3.5
mos6510c.h
1 /***************************************************************************
2  mos6510c.h - Cycle Accurate 6510 Emulation
3  -------------------
4  begin : Thu May 11 2000
5  copyright : (C) 2000 by Simon White
6  email : s_a_white@email.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 /***************************************************************************
18  * $Log: mos6510c.h,v $
19  * Revision 1.26 2004/06/26 11:10:47 s_a_white
20  * Changes to support new calling convention for event scheduler.
21  *
22  * Revision 1.25 2004/04/23 01:01:37 s_a_white
23  * Added debug clock to record cycle instructions starts on.
24  *
25  * Revision 1.24 2004/03/07 22:38:57 s_a_white
26  * Rename write to nosteal since it needs setting for non memory access cycles to
27  *
28  * Revision 1.23 2004/03/06 21:07:12 s_a_white
29  * Don't start a new cycle stealing sequence if one is already started! This can
30  * happen if an interrupt occurs during an optimised sleep.
31  *
32  * Revision 1.22 2004/02/29 14:33:59 s_a_white
33  * If an interrupt occurs during a branch instruction but after the decision
34  * has occured then it should not be delayed.
35  *
36  * Revision 1.21 2003/10/29 22:18:03 s_a_white
37  * IRQs are now only taken in on phase 1 as previously they could be clocked
38  * in on both phases of the cycle resulting in them sometimes not being
39  * delayed long enough.
40  *
41  * Revision 1.20 2003/10/28 00:22:53 s_a_white
42  * getTime now returns a time with respect to the clocks desired phase.
43  *
44  * Revision 1.19 2003/10/16 07:48:32 s_a_white
45  * Allow redirection of debug information of file.
46  *
47  * Revision 1.18 2003/01/20 23:10:48 s_a_white
48  * Fixed RMW instructions to perform memory re-write on the correct cycle.
49  *
50  * Revision 1.17 2003/01/20 18:37:08 s_a_white
51  * Stealing update. Apparently the cpu does a memory read from any non
52  * write cycle (whether it needs to or not) resulting in those cycles
53  * being stolen.
54  *
55  * Revision 1.16 2003/01/17 08:42:09 s_a_white
56  * Event scheduler phase support. Better handling the operation of IRQs
57  * during stolen cycles.
58  *
59  * Revision 1.15 2002/11/28 20:35:06 s_a_white
60  * Reduced number of thrown exceptions when dma occurs.
61  *
62  * Revision 1.14 2002/11/25 20:10:55 s_a_white
63  * A bus access failure should stop the CPU dead like the cycle never started.
64  * This is currently simulated using throw (execption handling) for now.
65  *
66  * Revision 1.13 2002/11/21 19:52:48 s_a_white
67  * CPU upgraded to be like other components. Theres nolonger a clock call,
68  * instead events are registered to occur at a specific time.
69  *
70  * Revision 1.12 2002/11/19 22:57:33 s_a_white
71  * Initial support for external DMA to steal cycles away from the CPU.
72  *
73  * Revision 1.11 2002/11/01 17:35:27 s_a_white
74  * Frame based support for old sidplay1 modes.
75  *
76  * Revision 1.10 2001/08/05 15:46:02 s_a_white
77  * No longer need to check on which cycle an instruction ends or when to print
78  * debug information.
79  *
80  * Revision 1.9 2001/07/14 16:48:03 s_a_white
81  * cycleCount and related must roject.Syn
82  *
83  * Revision 1.8 2001/07/14 13:15:30 s_a_white
84  * Accumulator is now unsigned, which improves code readability. Emulation
85  * tested with testsuite 2.15. Various instructions required modification.
86  *
87  * Revision 1.7 2001/03/28 21:17:34 s_a_white
88  * Added support for proper RMW instructions.
89  *
90  * Revision 1.6 2001/03/24 18:09:17 s_a_white
91  * On entry to interrupt routine the first instruction in the handler is now always
92  * executed before pending interrupts are re-checked.
93  *
94  * Revision 1.5 2001/03/19 23:48:21 s_a_white
95  * Interrupts made virtual to allow for redefintion for Sidplay1 compatible
96  * interrupts.
97  *
98  * Revision 1.4 2001/03/09 22:28:03 s_a_white
99  * Speed optimisation update.
100  *
101  * Revision 1.3 2001/02/13 21:03:33 s_a_white
102  * Changed inlines to non-inlines due to function bodies not being in header.
103  *
104  * Revision 1.2 2000/12/11 19:04:32 s_a_white
105  * AC99 Update.
106  *
107  ***************************************************************************/
108 
109 #ifndef _mos6510c_h_
110 #define _mos6510c_h_
111 
112 #include <stdio.h>
113 
114 #include "sidplayfp/sidtypes.h"
115 #include "sidplayfp/sidendian.h"
116 
120 class MOS6510
121 {
122 protected:
124  {
125  void (MOS6510::*func)(void);
126  bool nosteal;
127  ProcessorCycle ()
128  :func(0), nosteal(false) {}
129  };
130 
131 protected:
132  C64Environment *env;
133 
136 
137  struct ProcessorCycle *instrCurrent;
138 
139  int cycleCount;
140 
141  uint_least16_t instrStartPC;
142  int_least8_t lastAddrCycle;
143 
145  uint_least16_t Cycle_EffectiveAddress;
146  uint_least16_t Cycle_HighByteWrongEffectiveAddress;
147  uint8_t Cycle_Data;
148  uint_least16_t Cycle_Pointer;
149 
150  uint8_t Register_Accumulator;
151  uint8_t Register_X;
152  uint8_t Register_Y;
153  uint_least32_t Register_ProgramCounter;
154  bool flagN;
155  bool flagC;
156  bool flagD;
157  bool flagZ;
158  bool flagV;
159  bool flagI;
160  bool flagB;
161  uint_least16_t Register_StackPointer;
162 
163  /* Interrupts */
164 
166  int irqs;
167 
169  bool irqFlag;
170 
172  event_clock_t irqClk;
173 
175  int nmis;
176 
178  bool nmiFlag;
179 
181  event_clock_t nmiClk;
182 
184  bool aec;
185 
186  struct ProcessorCycle fetchCycle;
187 
189  uint_least16_t Instr_Operand;
190 
191  FILE *m_fdbg;
192 
193  event_clock_t m_dbgClk;
194 
195  bool dodump;
196 
198  struct ProcessorCycle instrTable[0x103][8];
199 
200 protected:
201  EventCallback<MOS6510> m_nosteal;
202  EventCallback<MOS6510> m_steal;
203 
204  void eventWithoutSteals (void);
205  void eventWithSteals (void);
206 
207  void Initialise (void);
208 
209  // Flag utility functions
210  inline void setFlagsNZ(const uint8_t value);
211  inline uint8_t getStatusRegister(void);
212  inline void setStatusRegister(const uint8_t sr);
213 
214  // Declare Interrupt Routines
215  inline void RSTLoRequest (void);
216  inline void RSTHiRequest (void);
217  inline void NMILoRequest (void);
218  inline void NMIHiRequest (void);
219  inline void IRQRequest (void);
220  inline void IRQLoRequest (void);
221  inline void IRQHiRequest (void);
222  void interruptsAndNextOpcode (void);
223 
224  // Declare Instruction Routines
225  virtual void FetchOpcode (void);
226  inline void throwAwayFetch (void);
227  inline void throwAwayRead (void);
228  inline void FetchDataByte (void);
229  inline void FetchLowAddr (void);
230  inline void FetchLowAddrX (void);
231  inline void FetchLowAddrY (void);
232  inline void FetchHighAddr (void);
233  inline void FetchHighAddrX (void);
234  inline void FetchHighAddrX2 (void);
235  inline void FetchHighAddrY (void);
236  inline void FetchHighAddrY2 (void);
237  inline void FetchLowEffAddr (void);
238  inline void FetchHighEffAddr (void);
239  inline void FetchHighEffAddrY (void);
240  inline void FetchHighEffAddrY2 (void);
241  inline void FetchLowPointer (void);
242  inline void FetchLowPointerX (void);
243  inline void FetchHighPointer (void);
244  inline void FetchEffAddrDataByte (void);
245  inline void PutEffAddrDataByte (void);
246  inline void PushLowPC (void);
247  inline void PushHighPC (void);
248  inline void PushSR (const bool b_flag);
249  inline void PushSR (void);
250  inline void PopLowPC (void);
251  inline void PopHighPC (void);
252  inline void PopSR (void);
253  inline void WasteCycle (void);
254 
255  // Delcare Instruction Operation Routines
256  inline void adc_instr (void);
257  inline void alr_instr (void);
258  inline void anc_instr (void);
259  inline void and_instr (void);
260  inline void ane_instr (void);
261  inline void arr_instr (void);
262  inline void asl_instr (void);
263  inline void asla_instr (void);
264  inline void aso_instr (void);
265  inline void axa_instr (void);
266  inline void axs_instr (void);
267  inline void bcc_instr (void);
268  inline void bcs_instr (void);
269  inline void beq_instr (void);
270  inline void bit_instr (void);
271  inline void bmi_instr (void);
272  inline void bne_instr (void);
273  inline void branch_instr (const bool condition);
274  inline void bpl_instr (void);
275  inline void brk_instr (void);
276  inline void bvc_instr (void);
277  inline void bvs_instr (void);
278  inline void clc_instr (void);
279  inline void cld_instr (void);
280  inline void cli_instr (void);
281  inline void clv_instr (void);
282  inline void cmp_instr (void);
283  inline void cpx_instr (void);
284  inline void cpy_instr (void);
285  inline void dcm_instr (void);
286  inline void dec_instr (void);
287  inline void dex_instr (void);
288  inline void dey_instr (void);
289  inline void eor_instr (void);
290  inline void inc_instr (void);
291  inline void ins_instr (void);
292  inline void inx_instr (void);
293  inline void iny_instr (void);
294  inline void jmp_instr (void);
295  inline void las_instr (void);
296  inline void lax_instr (void);
297  inline void lda_instr (void);
298  inline void ldx_instr (void);
299  inline void ldy_instr (void);
300  inline void lse_instr (void);
301  inline void lsr_instr (void);
302  inline void lsra_instr (void);
303  inline void oal_instr (void);
304  inline void ora_instr (void);
305  inline void pha_instr (void);
306  inline void pla_instr (void);
307  inline void plp_instr (void);
308  inline void rla_instr (void);
309  inline void rol_instr (void);
310  inline void rola_instr (void);
311  inline void ror_instr (void);
312  inline void rora_instr (void);
313  inline void rra_instr (void);
314  inline void rti_instr (void);
315  inline void rts_instr (void);
316  inline void sbx_instr (void);
317  inline void say_instr (void);
318  inline void sbc_instr (void);
319  inline void sec_instr (void);
320  inline void sed_instr (void);
321  inline void sei_instr (void);
322  inline void shs_instr (void);
323  inline void sta_instr (void);
324  inline void stx_instr (void);
325  inline void sty_instr (void);
326  inline void tas_instr (void);
327  inline void tax_instr (void);
328  inline void tay_instr (void);
329  inline void tsx_instr (void);
330  inline void txa_instr (void);
331  inline void txs_instr (void);
332  inline void tya_instr (void);
333  inline void xas_instr (void);
334  void illegal_instr (void);
335 
336  // Declare Arithmatic Operations
337  inline void Perform_ADC (void);
338  inline void Perform_SBC (void);
339 
340 public:
341  MOS6510 (EventContext *context);
342  virtual ~MOS6510 () {}
343  virtual void reset (void);
344  virtual void credits (char *str);
345  virtual void DumpState (void);
346  void debug (const bool enable, FILE *out);
347  void aecSignal (const bool state);
348  void setEnvironment(C64Environment *env) { this->env = env; }
349 
350  // Non-standard functions
351  virtual void triggerRST (void);
352  virtual void triggerNMI (void);
353  virtual void triggerIRQ (void);
354  void clearIRQ (void);
355 };
356 
357 #endif // _mos6510c_h_