summaryrefslogtreecommitdiff
path: root/plugins/sid/sidplay-libs/libsidplay/src/mos6510/cycle_based/mos6510c.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sid/sidplay-libs/libsidplay/src/mos6510/cycle_based/mos6510c.h')
-rw-r--r--plugins/sid/sidplay-libs/libsidplay/src/mos6510/cycle_based/mos6510c.h311
1 files changed, 311 insertions, 0 deletions
diff --git a/plugins/sid/sidplay-libs/libsidplay/src/mos6510/cycle_based/mos6510c.h b/plugins/sid/sidplay-libs/libsidplay/src/mos6510/cycle_based/mos6510c.h
new file mode 100644
index 00000000..9a046d2e
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidplay/src/mos6510/cycle_based/mos6510c.h
@@ -0,0 +1,311 @@
+/***************************************************************************
+ mos6510c.h - Cycle Accurate 6510 Emulation
+ -------------------
+ begin : Thu May 11 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ * $Log: mos6510c.h,v $
+ * Revision 1.15 2002/11/28 20:35:06 s_a_white
+ * Reduced number of thrown exceptions when dma occurs.
+ *
+ * Revision 1.14 2002/11/25 20:10:55 s_a_white
+ * A bus access failure should stop the CPU dead like the cycle never started.
+ * This is currently simulated using throw (execption handling) for now.
+ *
+ * Revision 1.13 2002/11/21 19:52:48 s_a_white
+ * CPU upgraded to be like other components. Theres nolonger a clock call,
+ * instead events are registered to occur at a specific time.
+ *
+ * Revision 1.12 2002/11/19 22:57:33 s_a_white
+ * Initial support for external DMA to steal cycles away from the CPU.
+ *
+ * Revision 1.11 2002/11/01 17:35:27 s_a_white
+ * Frame based support for old sidplay1 modes.
+ *
+ * Revision 1.10 2001/08/05 15:46:02 s_a_white
+ * No longer need to check on which cycle an instruction ends or when to print
+ * debug information.
+ *
+ * Revision 1.9 2001/07/14 16:48:03 s_a_white
+ * cycleCount and related must roject.Syn
+ *
+ * Revision 1.8 2001/07/14 13:15:30 s_a_white
+ * Accumulator is now unsigned, which improves code readability. Emulation
+ * tested with testsuite 2.15. Various instructions required modification.
+ *
+ * Revision 1.7 2001/03/28 21:17:34 s_a_white
+ * Added support for proper RMW instructions.
+ *
+ * Revision 1.6 2001/03/24 18:09:17 s_a_white
+ * On entry to interrupt routine the first instruction in the handler is now always
+ * executed before pending interrupts are re-checked.
+ *
+ * Revision 1.5 2001/03/19 23:48:21 s_a_white
+ * Interrupts made virtual to allow for redefintion for Sidplay1 compatible
+ * interrupts.
+ *
+ * Revision 1.4 2001/03/09 22:28:03 s_a_white
+ * Speed optimisation update.
+ *
+ * Revision 1.3 2001/02/13 21:03:33 s_a_white
+ * Changed inlines to non-inlines due to function bodies not being in header.
+ *
+ * Revision 1.2 2000/12/11 19:04:32 s_a_white
+ * AC99 Update.
+ *
+ ***************************************************************************/
+
+#ifndef _mos6510c_h_
+#define _mos6510c_h_
+
+#include "sidtypes.h"
+#include "sidendian.h"
+
+
+class MOS6510: public C64Environment, public Event
+{
+private:
+ // External signals
+ bool aec; /* Address Controller, blocks all */
+ bool rdy; /* Bus Access, blocks reads */
+ bool m_blocked;
+
+protected:
+ bool dodump;
+ EventContext &eventContext;
+
+ // Declare processor operations
+ struct ProcessorOperations
+ {
+ void (MOS6510::**cycle)(void);
+ uint cycles;
+ uint_least8_t opcode;
+ };
+
+ void (MOS6510::*fetchCycle[1]) (void);
+ struct ProcessorOperations instrTable[0x100];
+ struct ProcessorOperations interruptTable[3];
+ struct ProcessorOperations *instrCurrent;
+
+ uint_least16_t instrStartPC;
+ uint_least8_t instrOpcode;
+ void (MOS6510::**procCycle) (void);
+ int_least8_t lastAddrCycle;
+ int_least8_t cycleCount;
+
+ // Pointers to the current instruction cycle
+ uint_least16_t Cycle_EffectiveAddress;
+ uint8_t Cycle_Data;
+ uint_least16_t Cycle_Pointer;
+
+ uint8_t Register_Accumulator;
+ uint8_t Register_X;
+ uint8_t Register_Y;
+ uint_least32_t Register_ProgramCounter;
+ uint8_t Register_Status;
+ uint_least8_t Register_c_Flag;
+ uint_least8_t Register_n_Flag;
+ uint_least8_t Register_v_Flag;
+ uint_least8_t Register_z_Flag;
+ uint_least16_t Register_StackPointer;
+ uint_least16_t Instr_Operand;
+
+ // Interrupts
+ struct
+ {
+ uint_least8_t pending;
+ uint_least8_t irqs;
+ event_clock_t nmiClock;
+ event_clock_t irqClock;
+ event_clock_t delay;
+ bool irqRequest;
+ bool irqLatch;
+ } interrupts;
+
+ uint8_t Debug_Data;
+ uint_least16_t Debug_EffectiveAddress;
+ uint_least8_t Debug_Opcode;
+ uint_least16_t Debug_Operand;
+ uint_least16_t Debug_ProgramCounter;
+
+protected:
+ void clock (void);
+ void event (void);
+ void Initialise (void);
+ // Declare Interrupt Routines
+ inline void RSTRequest (void);
+ inline void RST1Request (void);
+ inline void NMIRequest (void);
+ inline void NMI1Request (void);
+ inline void IRQRequest (void);
+ inline void IRQ1Request (void);
+ inline void IRQ2Request (void);
+ bool interruptPending (void);
+
+ // Declare Instruction Routines
+ virtual void FetchOpcode (void);
+ void NextInstr (void);
+ inline void FetchDataByte (void);
+ inline void FetchLowAddr (void);
+ inline void FetchLowAddrX (void);
+ inline void FetchLowAddrY (void);
+ inline void FetchHighAddr (void);
+ inline void FetchHighAddrX (void);
+ inline void FetchHighAddrX2 (void);
+ inline void FetchHighAddrY (void);
+ inline void FetchHighAddrY2 (void);
+ inline void FetchLowEffAddr (void);
+ inline void FetchHighEffAddr (void);
+ inline void FetchHighEffAddrY (void);
+ inline void FetchHighEffAddrY2 (void);
+ inline void FetchLowPointer (void);
+ inline void FetchLowPointerX (void);
+ inline void FetchHighPointer (void);
+ inline void FetchEffAddrDataByte (void);
+ inline void PutEffAddrDataByte (void);
+ inline void FetchPutEffAddrDataByte (void);
+ inline void PushLowPC (void);
+ inline void PushHighPC (void);
+ inline void PushSR (bool b_flag);
+ inline void PushSR (void);
+ inline void PopLowPC (void);
+ inline void PopHighPC (void);
+ inline void PopSR (void);
+ inline void WasteCycle (void);
+ inline void DebugCycle (void);
+
+ // Delcare Instruction Operation Routines
+ inline void adc_instr (void);
+ inline void alr_instr (void);
+ inline void anc_instr (void);
+ inline void and_instr (void);
+ inline void ane_instr (void);
+ inline void arr_instr (void);
+ inline void asl_instr (void);
+ inline void asla_instr (void);
+ inline void aso_instr (void);
+ inline void axa_instr (void);
+ inline void axs_instr (void);
+ inline void bcc_instr (void);
+ inline void bcs_instr (void);
+ inline void beq_instr (void);
+ inline void bit_instr (void);
+ inline void bmi_instr (void);
+ inline void bne_instr (void);
+ inline void branch_instr (bool condition);
+ inline void bpl_instr (void);
+ inline void brk_instr (void);
+ inline void bvc_instr (void);
+ inline void bvs_instr (void);
+ inline void clc_instr (void);
+ inline void cld_instr (void);
+ inline void cli_instr (void);
+ inline void clv_instr (void);
+ inline void cmp_instr (void);
+ inline void cpx_instr (void);
+ inline void cpy_instr (void);
+ inline void dcm_instr (void);
+ inline void dec_instr (void);
+ inline void dex_instr (void);
+ inline void dey_instr (void);
+ inline void eor_instr (void);
+ inline void inc_instr (void);
+ inline void ins_instr (void);
+ inline void inx_instr (void);
+ inline void iny_instr (void);
+ inline void jmp_instr (void);
+ inline void jsr_instr (void);
+ inline void las_instr (void);
+ inline void lax_instr (void);
+ inline void lda_instr (void);
+ inline void ldx_instr (void);
+ inline void ldy_instr (void);
+ inline void lse_instr (void);
+ inline void lsr_instr (void);
+ inline void lsra_instr (void);
+ inline void oal_instr (void);
+ inline void ora_instr (void);
+ inline void pha_instr (void);
+ inline void pla_instr (void);
+ inline void rla_instr (void);
+ inline void rol_instr (void);
+ inline void rola_instr (void);
+ inline void ror_instr (void);
+ inline void rora_instr (void);
+ inline void rra_instr (void);
+ inline void rti_instr (void);
+ inline void rts_instr (void);
+ inline void sbx_instr (void);
+ inline void say_instr (void);
+ inline void sbc_instr (void);
+ inline void sec_instr (void);
+ inline void sed_instr (void);
+ inline void sei_instr (void);
+ inline void shs_instr (void);
+ inline void sta_instr (void);
+ inline void stx_instr (void);
+ inline void sty_instr (void);
+ inline void tas_instr (void);
+ inline void tax_instr (void);
+ inline void tay_instr (void);
+ inline void tsx_instr (void);
+ inline void txa_instr (void);
+ inline void txs_instr (void);
+ inline void tya_instr (void);
+ inline void xas_instr (void);
+ void illegal_instr (void);
+
+ // Declare Arithmatic Operations
+ inline void Perform_ADC (void);
+ inline void Perform_SBC (void);
+
+public:
+ MOS6510 (EventContext *context);
+ virtual ~MOS6510 ();
+ virtual void reset (void);
+ virtual void credits (char *str);
+ virtual void DumpState (void);
+ void debug (bool enable) {dodump = enable;}
+ void aecSignal (bool state);
+ void rdySignal (bool state);
+
+ // Non-standard functions
+ virtual void triggerRST (void);
+ virtual void triggerNMI (void);
+ virtual void triggerIRQ (void);
+ void clearIRQ (void);
+};
+
+
+//-------------------------------------------------------------------------//
+// Emulate One Complete Cycle //
+inline void MOS6510::clock (void)
+{
+ int_least8_t i = cycleCount++;
+ try {
+ (this->*procCycle[i]) ();
+ } catch (int_least8_t delta) {
+ cycleCount += delta;
+ m_blocked = true;
+ eventContext.cancel (this);
+ }
+}
+
+inline void MOS6510::event (void)
+{
+ eventContext.schedule (this, 1);
+ clock ();
+}
+
+#endif // _mos6510c_h_