diff options
Diffstat (limited to 'libsidplay2/sidplay-libs-2.1.0/libsidplay/src/mos6510/cycle_based/sid6510c.i')
-rw-r--r-- | libsidplay2/sidplay-libs-2.1.0/libsidplay/src/mos6510/cycle_based/sid6510c.i | 409 |
1 files changed, 0 insertions, 409 deletions
diff --git a/libsidplay2/sidplay-libs-2.1.0/libsidplay/src/mos6510/cycle_based/sid6510c.i b/libsidplay2/sidplay-libs-2.1.0/libsidplay/src/mos6510/cycle_based/sid6510c.i deleted file mode 100644 index bc573d3b..00000000 --- a/libsidplay2/sidplay-libs-2.1.0/libsidplay/src/mos6510/cycle_based/sid6510c.i +++ /dev/null @@ -1,409 +0,0 @@ -/*************************************************************************** - sid6510c.i - Sidplay Specific 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: sid6510c.i,v $ - * Revision 1.28 2002/12/03 23:24:52 s_a_white - * Let environment know when cpu sleeps in real c64 mode. - * - * Revision 1.27 2002/12/02 22:19:43 s_a_white - * sid_brk fix to prevent it running some of the real brk cycles in old emulation - * modes. - * - * Revision 1.26 2002/11/25 21:07:34 s_a_white - * Allow setting of program counter on reset. - * - * Revision 1.25 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.24 2002/11/19 22:56:25 s_a_white - * Sidplay1 modes modified to make them nolonger require the psid driver. - * - * Revision 1.23 2002/11/01 17:35:27 s_a_white - * Frame based support for old sidplay1 modes. - * - * Revision 1.22 2002/10/15 23:52:14 s_a_white - * Fix sidplay2 cpu sleep optimisation and NMIs. - * - * Revision 1.21 2002/09/23 22:50:55 s_a_white - * Reverted update 1.20 as was incorrect. Only need to - * change MOS6510 to SID6510 for compliancy. - * - * Revision 1.20 2002/09/23 19:42:14 s_a_white - * Newer compilers don't allow pointers to be taken directly - * from base class member functions. - * - * Revision 1.19 2002/03/12 18:47:13 s_a_white - * Made IRQ in sidplay1 compatibility modes behaves like JSR. This fixes tunes - * that have kernel switched out. - * - * Revision 1.18 2002/02/07 18:02:10 s_a_white - * Real C64 compatibility fixes. Debug of BRK works again. Fixed illegal - * instructions to work like sidplay1. - * - * Revision 1.17 2002/02/06 17:49:12 s_a_white - * Fixed sign comparison warning. - * - * Revision 1.16 2002/02/04 23:53:23 s_a_white - * Improved compatibilty of older sidplay1 modes. Fixed BRK to work like sidplay1 - * only when stack is 0xff in real mode for better compatibility with C64. - * - * Revision 1.15 2002/01/28 19:32:16 s_a_white - * PSID sample improvements. - * - * Revision 1.14 2001/10/02 18:00:37 s_a_white - * Removed un-necessary cli. - * - * Revision 1.13 2001/09/18 07:51:39 jpaana - * Small fix to rti-processing. - * - * Revision 1.12 2001/09/03 22:23:06 s_a_white - * Fixed faked IRQ trigger on BRK for sidplay1 environment modes. - * - * Revision 1.11 2001/09/01 11:08:06 s_a_white - * Fixes for sidplay1 environment 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 13:17:40 s_a_white - * Sidplay1 optimisations moved to here. Stack & PC invalid tests now only - * performed on a BRK. - * - * Revision 1.8 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.7 2001/03/22 22:40:07 s_a_white - * Replaced tabs characters. - * - * Revision 1.6 2001/03/21 22:26:24 s_a_white - * Fake interrupts now been moved into here from player.cpp. At anytime it's - * now possible to ditch this compatibility class and use the real thing. - * - * Revision 1.5 2001/03/09 22:28:03 s_a_white - * Speed optimisation update. - * - * Revision 1.4 2001/02/13 21:02:16 s_a_white - * Small tidy up and possibly a small performace increase. - * - * Revision 1.3 2000/12/11 19:04:32 s_a_white - * AC99 Update. - * - ***************************************************************************/ - -#include "sid6510c.h" - - -SID6510::SID6510 (EventContext *context) -:MOS6510(context), - m_mode(sid2_envR), - m_framelock(false) -{ // Ok start all the hacks for sidplay. This prevents - // execution of code in roms. For real c64 emulation - // create object from base class! Also stops code - // rom execution when bad code switches roms in over - // itself. - for (uint i = 0; i < OPCODE_MAX; i++) - { - procCycle = instrTable[i].cycle; - if (procCycle == NULL) continue; - - for (uint n = 0; n < instrTable[i].cycles; n++) - { - if (procCycle[n] == &SID6510::illegal_instr) - { // Rev 1.2 (saw) - Changed nasty union to reinterpret_cast - procCycle[n] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_illegal); - } - else if (procCycle[n] == &SID6510::jmp_instr) - { // Stop jumps into rom code - procCycle[n] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_jmp); - } - else if (procCycle[n] == &SID6510::cli_instr) - { // No overlapping IRQs allowed - procCycle[n] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_cli); - } - } - } - - { // Since no real IRQs, all RTIs mapped to RTS - // Required for fix bad tunes in old modes - uint n; - procCycle = instrTable[RTIn].cycle; - for (n = 0; n < instrTable[RTIn].cycles; n++) - { - if (procCycle[n] == &SID6510::PopSR) - { - procCycle[n] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_rti); - break; - } - } - - procCycle = interruptTable[oIRQ].cycle; - for (n = 0; n < interruptTable[oIRQ].cycles; n++) - { - if (procCycle[n] == &SID6510::IRQRequest) - { - procCycle[n] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_irq); - break; - } - } - } - - { // Support of sidplays BRK functionality - procCycle = instrTable[BRKn].cycle; - for (uint n = 0; n < instrTable[BRKn].cycles; n++) - { - if (procCycle[n] == &SID6510::PushHighPC) - { - procCycle[n] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_brk); - break; - } - } - } - - // Used to insert busy delays into the CPU emulation - delayCycle[0] = reinterpret_cast <void (MOS6510::*)()> - (&SID6510::sid_delay); -} - -void SID6510::reset (uint_least16_t pc, uint8_t a, uint8_t x, uint8_t y) -{ // Reset the processor - reset (); - - // Registers not touched by a reset - Register_Accumulator = a; - Register_X = x; - Register_Y = y; - Register_ProgramCounter = pc; -} - -void SID6510::reset () -{ - m_sleeping = false; - // Call inherited reset - MOS6510::reset (); -} - -// Send CPU is about to sleep. Only a reset or -// interrupt will wake up the processor -void SID6510::sleep () -{ // Simulate a delay for JMPw - m_delayClk = eventContext.getTime (); - m_sleeping = true; - procCycle = delayCycle; - cycleCount = 0; - eventContext.cancel (this); - envSleep (); - - // Check for outstanding interrupts - if (interrupts.irqs) - { - interrupts.irqs--; - triggerIRQ (); - } - else if (interrupts.pending) - { - m_sleeping = false; - eventContext.schedule (this, 1); - } -} - -void SID6510::FetchOpcode (void) -{ - if (m_mode == sid2_envR) - { - MOS6510::FetchOpcode (); - return; - } - - // Sid tunes end by wrapping the stack. For compatibilty it - // has to be handled. - m_sleeping |= (endian_16hi8 (Register_StackPointer) != SP_PAGE); - m_sleeping |= (endian_32hi16 (Register_ProgramCounter) != 0); - if (!m_sleeping) - MOS6510::FetchOpcode (); - - if (m_framelock == false) - { - m_framelock = true; - // Simulate sidplay1 frame based execution - while (!m_sleeping) - MOS6510::clock (); - sleep (); - m_framelock = false; - } -} - - -//************************************************************************************** -// For sidplay compatibility implement those instructions which don't behave properly. -//************************************************************************************** -void SID6510::sid_brk (void) -{ - if (m_mode == sid2_envR) - { - MOS6510::PushHighPC (); - return; - } - - sei_instr (); -#if !defined(NO_RTS_UPON_BRK) - sid_rts (); -#endif - FetchOpcode (); -} - -void SID6510::sid_jmp (void) -{ // For sidplay compatibility, inherited from environment - if (m_mode == sid2_envR) - { // If a busy loop then just sleep - if (Cycle_EffectiveAddress != instrStartPC) - jmp_instr (); - else - { - Register_ProgramCounter = Cycle_EffectiveAddress; - sleep (); - } - return; - } - - if (envCheckBankJump (Cycle_EffectiveAddress)) - jmp_instr (); - else - sid_rts (); -} - -// Will do a full rts in 1 cycle, to -// destroy current function and quit -void SID6510::sid_rts (void) -{ - PopLowPC(); - PopHighPC(); - rts_instr(); -} - -void SID6510::sid_cli (void) -{ - if (m_mode == sid2_envR) - cli_instr (); -} - -void SID6510::sid_rti (void) -{ - if (m_mode == sid2_envR) - { - PopSR (); - return; - } - - // Fake RTS - sid_rts (); - FetchOpcode (); -} - -void SID6510::sid_irq (void) -{ - MOS6510::IRQRequest (); - if (m_mode != sid2_envR) - { // RTI behaves like RTI in sidplay1 modes - Register_StackPointer++; - } -} - -// Sidplay Suppresses Illegal Instructions -void SID6510::sid_illegal (void) -{ - if (m_mode == sid2_envR) - { - MOS6510::illegal_instr (); - return; - } -#ifdef MOS6510_DEBUG - DumpState (); -#endif -} - -void SID6510::sid_delay (void) -{ - cycleCount = 0; - if (++m_delayCycles >= 3) - { - (void) interruptPending (); - m_delayCycles = 0; - } -} - - -//************************************************************************************** -// Sidplay compatibility interrupts. Basically wakes CPU if it is m_sleeping -//************************************************************************************** -void SID6510::triggerRST (void) -{ // All modes - MOS6510::triggerRST (); - if (m_sleeping) - { - m_sleeping = false; - eventContext.schedule (this, 1); - } -} - -void SID6510::triggerNMI (void) -{ // Only in Real C64 mode - if (m_mode == sid2_envR) - { - MOS6510::triggerNMI (); - if (m_sleeping) - { - m_delayCycles = eventContext.getTime (m_delayClk) % 3; - m_sleeping = false; - eventContext.schedule (this, 1); - } - } -} - -void SID6510::triggerIRQ (void) -{ - switch (m_mode) - { - default: -#ifdef MOS6510_DEBUG - if (dodump) - { - printf ("****************************************************\n"); - printf (" Fake IRQ Routine\n"); - printf ("****************************************************\n"); - } -#endif - return; - case sid2_envR: - MOS6510::triggerIRQ (); - if (m_sleeping) - { // Simulate busy loop - m_delayCycles = eventContext.getTime (m_delayClk) % 3; - m_sleeping = false; - eventContext.schedule (this, 1); - } - } -} |