libsidplayfp
1.0.3
|
00001 /* 00002 * This file is part of libsidplayfp, a SID player engine. 00003 * 00004 * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net> 00005 * Copyright 2007-2010 Antti Lankila 00006 * Copyright 2000 Simon White 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #ifndef MOS6510_H 00024 #define MOS6510_H 00025 00026 #include <stdio.h> 00027 #include <stdint.h> 00028 00029 #include "sidplayfp/sidendian.h" 00030 #include "sidplayfp/component.h" 00031 #include "sidplayfp/EventScheduler.h" 00032 00033 #ifdef HAVE_CONFIG_H 00034 # include "config.h" 00035 #endif 00036 00046 class MOS6510 00047 { 00048 friend class MOS6510Debug; 00049 private: 00050 static const char *credit; 00051 00052 private: 00058 static const int MAX = 65536; 00059 00061 static const uint8_t SP_PAGE = 0x01; 00062 00063 public: 00065 static const int SR_INTERRUPT = 2; 00066 00067 protected: 00068 struct ProcessorCycle 00069 { 00070 void (MOS6510::*func)(); 00071 bool nosteal; 00072 ProcessorCycle () : 00073 func(0), 00074 nosteal(false) {} 00075 }; 00076 00077 protected: 00079 EventContext &eventContext; 00080 00082 int cycleCount; 00083 00085 int interruptCycle; 00086 00088 bool irqAssertedOnPin; 00089 00091 bool nmiFlag; 00092 00094 bool rstFlag; 00095 00097 bool rdy; 00098 00099 bool flagN; 00100 bool flagC; 00101 bool flagD; 00102 bool flagZ; 00103 bool flagV; 00104 bool flagI; 00105 bool flagB; 00106 00108 uint_least16_t Register_ProgramCounter; 00109 uint_least16_t Cycle_EffectiveAddress; 00110 uint_least16_t Cycle_HighByteWrongEffectiveAddress; 00111 uint_least16_t Cycle_Pointer; 00112 00113 uint8_t Cycle_Data; 00114 uint8_t Register_StackPointer; 00115 uint8_t Register_Accumulator; 00116 uint8_t Register_X; 00117 uint8_t Register_Y; 00118 00119 #ifdef DEBUG 00120 00121 uint_least16_t instrStartPC; 00122 uint_least16_t instrOperand; 00123 00124 FILE *m_fdbg; 00125 00126 bool dodump; 00127 #endif 00128 00130 struct ProcessorCycle instrTable[0x101 << 3]; 00131 00132 protected: 00133 MOS6510(EventContext *context); 00134 ~MOS6510() {} 00135 00137 EventCallback<MOS6510> m_nosteal; 00138 00140 EventCallback<MOS6510> m_steal; 00141 00142 void eventWithoutSteals(); 00143 void eventWithSteals(); 00144 00145 void Initialise(); 00146 00147 // Flag utility functions 00148 inline void setFlagsNZ(uint8_t value); 00149 inline uint8_t getStatusRegister(); 00150 inline void setStatusRegister(uint8_t sr); 00151 00152 // Declare Interrupt Routines 00153 inline void IRQLoRequest(); 00154 inline void IRQHiRequest(); 00155 inline void interruptsAndNextOpcode(); 00156 inline void calculateInterruptTriggerCycle(); 00157 00158 // Declare Instruction Routines 00159 inline void fetchNextOpcode(); 00160 inline void throwAwayFetch(); 00161 inline void throwAwayRead(); 00162 inline void FetchDataByte(); 00163 inline void FetchLowAddr(); 00164 inline void FetchLowAddrX(); 00165 inline void FetchLowAddrY(); 00166 inline void FetchHighAddr(); 00167 inline void FetchHighAddrX(); 00168 inline void FetchHighAddrX2(); 00169 inline void FetchHighAddrY(); 00170 inline void FetchHighAddrY2(); 00171 inline void FetchLowEffAddr(); 00172 inline void FetchHighEffAddr(); 00173 inline void FetchHighEffAddrY(); 00174 inline void FetchHighEffAddrY2(); 00175 inline void FetchLowPointer(); 00176 inline void FetchLowPointerX(); 00177 inline void FetchHighPointer(); 00178 inline void FetchEffAddrDataByte (); 00179 inline void PutEffAddrDataByte(); 00180 inline void PushLowPC(); 00181 inline void PushHighPC(); 00182 inline void PushSR(); 00183 inline void PopLowPC(); 00184 inline void PopHighPC(); 00185 inline void PopSR(); 00186 inline void brkPushLowPC(); 00187 inline void WasteCycle(); 00188 00189 // Delcare Instruction Operation Routines 00190 inline void adc_instr(); 00191 inline void alr_instr(); 00192 inline void anc_instr(); 00193 inline void and_instr(); 00194 inline void ane_instr(); 00195 inline void arr_instr(); 00196 inline void asl_instr(); 00197 inline void asla_instr(); 00198 inline void aso_instr(); 00199 inline void axa_instr(); 00200 inline void axs_instr(); 00201 inline void bcc_instr(); 00202 inline void bcs_instr(); 00203 inline void beq_instr(); 00204 inline void bit_instr(); 00205 inline void bmi_instr(); 00206 inline void bne_instr(); 00207 inline void branch_instr(bool condition); 00208 inline void bpl_instr(); 00209 inline void brk_instr(); 00210 inline void bvc_instr(); 00211 inline void bvs_instr(); 00212 inline void clc_instr(); 00213 inline void cld_instr(); 00214 inline void cli_instr(); 00215 inline void clv_instr(); 00216 inline void cmp_instr(); 00217 inline void cpx_instr(); 00218 inline void cpy_instr(); 00219 inline void dcm_instr(); 00220 inline void dec_instr(); 00221 inline void dex_instr(); 00222 inline void dey_instr(); 00223 inline void eor_instr(); 00224 inline void inc_instr(); 00225 inline void ins_instr(); 00226 inline void inx_instr(); 00227 inline void iny_instr(); 00228 inline void jmp_instr(); 00229 inline void las_instr(); 00230 inline void lax_instr(); 00231 inline void lda_instr(); 00232 inline void ldx_instr(); 00233 inline void ldy_instr(); 00234 inline void lse_instr(); 00235 inline void lsr_instr(); 00236 inline void lsra_instr(); 00237 inline void oal_instr(); 00238 inline void ora_instr(); 00239 inline void pha_instr(); 00240 inline void pla_instr(); 00241 inline void plp_instr(); 00242 inline void rla_instr(); 00243 inline void rol_instr(); 00244 inline void rola_instr(); 00245 inline void ror_instr(); 00246 inline void rora_instr(); 00247 inline void rra_instr(); 00248 inline void rti_instr(); 00249 inline void rts_instr(); 00250 inline void sbx_instr(); 00251 inline void say_instr(); 00252 inline void sbc_instr(); 00253 inline void sec_instr(); 00254 inline void sed_instr(); 00255 inline void sei_instr(); 00256 inline void shs_instr(); 00257 inline void sta_instr(); 00258 inline void stx_instr(); 00259 inline void sty_instr(); 00260 inline void tax_instr(); 00261 inline void tay_instr(); 00262 inline void tsx_instr(); 00263 inline void txa_instr(); 00264 inline void txs_instr(); 00265 inline void tya_instr(); 00266 inline void xas_instr(); 00267 00268 void illegal_instr(); 00269 00270 // Declare Arithmetic Operations 00271 inline void doADC(); 00272 inline void doSBC(); 00273 00274 inline void doJSR(); 00275 00276 public: 00283 virtual uint8_t cpuRead(uint_least16_t addr) =0; 00284 00291 virtual void cpuWrite(uint_least16_t addr, uint8_t data) =0; 00292 00293 #ifdef PC64_TESTSUITE 00294 virtual void loadFile (const char *file) =0; 00295 #endif 00296 00297 virtual void reset(); 00298 00299 const char *credits() const { return credit; } 00300 00301 void debug(bool enable, FILE *out); 00302 void setRDY(bool newRDY); 00303 00304 // Non-standard functions 00305 void triggerRST(); 00306 void triggerNMI(); 00307 void triggerIRQ(); 00308 void clearIRQ(); 00309 }; 00310 00311 #endif // MOS6510_H