libsidplayfp 2.8.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
37class EventContext;
38
39namespace libsidplayfp
40{
41
42#ifdef DEBUG
43class MOS6510;
44
45namespace MOS6510Debug
46{
47 void DumpState(event_clock_t time, MOS6510 &cpu);
48}
49#endif
50
51
62{
63#ifdef DEBUG
64 friend void MOS6510Debug::DumpState(event_clock_t time, MOS6510 &cpu);
65#endif
66
67public:
69
70private:
76 static const int MAX = 65536;
77
79 static const uint8_t SP_PAGE = 0x01;
80
81public:
83 static const int SR_INTERRUPT = 2;
84
85private:
86 struct ProcessorCycle
87 {
88 void (*func)(MOS6510&);
89 bool nosteal;
90 ProcessorCycle() :
91 func(nullptr),
92 nosteal(false) {}
93 };
94
95private:
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
152private:
153 void eventWithoutSteals();
154 void eventWithSteals();
155 void removeIRQ();
156
159
162
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();
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
300protected:
301 MOS6510(EventScheduler &scheduler);
302 ~MOS6510() = default;
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
320public:
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 EventScheduler.h:62
Definition EventCallback.h:57
Definition flags.h:35
Definition mos6510.h:62
virtual uint8_t cpuRead(uint_least16_t addr)=0
void setRDY(bool newRDY)
Definition mos6510.cpp:128
MOS6510(EventScheduler &scheduler)
Definition mos6510.cpp:1472
void triggerNMI()
Definition mos6510.cpp:193
static const char * credits()
Definition mos6510.cpp:2202
void triggerRST()
Definition mos6510.cpp:179
virtual void cpuWrite(uint_least16_t addr, uint8_t data)=0
void reset()
Definition mos6510.cpp:2183
static const int SR_INTERRUPT
Status register interrupt bit.
Definition mos6510.h:83
void triggerIRQ()
Definition mos6510.cpp:209
void clearIRQ()
Definition mos6510.cpp:225