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