MCUME/MCUME_teensy41/teensyhandy/c65c02.h

1831 wiersze
53 KiB
C++

//
// Copyright (c) 2004 K. Wilkins
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from
// the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
//////////////////////////////////////////////////////////////////////////////
// Handy - An Atari Lynx Emulator //
// Copyright (c) 1996,1997 //
// K. Wilkins //
//////////////////////////////////////////////////////////////////////////////
// 65C02 Emulation class //
//////////////////////////////////////////////////////////////////////////////
// //
// This class emulates a 65C02 processor. It is interfaced to the rest of //
// the system via the PEEK/POKE macros and a number of global variables //
// //
// K. Wilkins //
// August 1997 //
// //
//////////////////////////////////////////////////////////////////////////////
// Revision History: //
// ----------------- //
// //
// 01Aug1997 KW Document header added & class documented. //
// //
//////////////////////////////////////////////////////////////////////////////
#ifndef C65C02_H
#define C65C02_H
//#include <crtdbg.h>
//#define TRACE_CPU
#ifdef TRACE_CPU
#define TRACE_CPU0(msg) _RPT1(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",gSystemCycleCount)
#define TRACE_CPU1(msg,arg1) _RPT2(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,gSystemCycleCount)
#define TRACE_CPU2(msg,arg1,arg2) _RPT3(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,arg2,gSystemCycleCount)
#define TRACE_CPU3(msg,arg1,arg2,arg3) _RPT4(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,arg2,arg3,gSystemCycleCount)
#else
#define TRACE_CPU0(msg)
#define TRACE_CPU1(msg,arg1)
#define TRACE_CPU2(msg,arg1,arg2)
#define TRACE_CPU3(msg,arg1,arg2,arg3)
#endif
//
// Handy definitions
//
#define NMI_VECTOR 0xfffa
#define BOOT_VECTOR 0xfffc
#define IRQ_VECTOR 0xfffe
#define MAX_CPU_BREAKPOINTS 8
#define CPU_RDWR_CYC 5
//
// ACCESS MACROS
//
#define CPU_PEEK_RAM(m) (mRamPointer[m])
#define CPU_POKE_RAM(m1,m2) mRamPointer[m1]=m2
#define CPU_PEEK(m) (((m<0xfc00)?CPU_PEEK_RAM(m):mSystem.Peek_CPU(m)))
#define CPU_PEEKW(m) (((m<0xfc00)?(mRamPointer[m]+(mRamPointer[m+1]<<8)):mSystem.PeekW_CPU(m)))
#define CPU_POKE(m1,m2) {if(m1<0xfc00) CPU_POKE_RAM(m1,m2); else mSystem.Poke_CPU(m1,m2);}
enum
{
illegal=0,
accu,
imm,
absl,
zp,
zpx,
zpy,
absx,
absy,
iabsx,
impl,
rel,
zrel,
indx,
indy,
iabs,
ind
};
typedef struct
{
int PS; // Processor status register 8 bits
int A; // Accumulator 8 bits
int X; // X index register 8 bits
int Y; // Y index register 8 bits
int SP; // Stack Pointer 8 bits
int Opcode; // Instruction opcode 8 bits
int Operand;// Intructions operand 16 bits
int PC; // Program Counter 16 bits
bool NMI;
bool IRQ;
bool WAIT;
#ifdef _LYNXDBG
int cpuBreakpoints[MAX_CPU_BREAKPOINTS];
#endif
}C6502_REGS;
//
// The CPU emulation macros
//
#include "c6502mak.h"
//
// The CPU emulation macros
//
class C65C02
{
public:
C65C02(CSystemBase& parent)
:mSystem(parent)
{
TRACE_CPU0("C65C02()");
// Compute the BCD lookup table
// for(UWORD t=0;t<256;++t)
// {
// mBCDTable[0][t]=((t >> 4) * 10) + (t & 0x0f);
// mBCDTable[1][t]=(((t % 100) / 10) << 4) | (t % 10);
// }
#ifdef _LYNXDBG
for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++) mPcBreakpoints[loop]=0xfffffff;
mDbgFlag=0;
#endif
Reset();
}
~C65C02()
{
TRACE_CPU0("~C65C02()");
}
public:
inline void Reset(void)
{
TRACE_CPU0("Reset()");
mRamPointer=mSystem.GetRamPointer();
mA=0;
mX=0;
mY=0;
mSP=0xff;
mOpcode=0;
mOperand=0;
mPC=CPU_PEEKW(BOOT_VECTOR);
mN=FALSE;
mV=FALSE;
mB=FALSE;
mD=FALSE;
mI=TRUE;
mZ=TRUE;
mC=FALSE;
mIRQActive=FALSE;
gSystemNMI=FALSE;
gSystemIRQ=FALSE;
gSystemCPUSleep=FALSE;
gSystemCPUSleep_Saved=FALSE;
}
inline bool ContextSave(LSS_FILE *fp)
{
TRACE_CPU0("ContextSave()");
int mPS;
mPS=PS();
if(!lss_printf(fp,"C6502::ContextSave")) return 0;
if(!lss_write(&mA,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&mX,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&mY,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&mSP,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&mPS,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&mPC,sizeof(ULONG),1,fp)) return 0;
if(!lss_write(&mIRQActive,sizeof(ULONG),1,fp)) return 0;
return 1;
}
inline bool ContextLoad(LSS_FILE *fp)
{
TRACE_CPU0("ContextLoad()");
int mPS;
char teststr[32]="XXXXXXXXXXXXXXXXXX";
if(!lss_read(teststr,sizeof(char),18,fp)) return 0;
if(strcmp(teststr,"C6502::ContextSave")!=0) return 0;
if(!lss_read(&mA,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&mX,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&mY,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&mSP,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&mPS,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&mPC,sizeof(ULONG),1,fp)) return 0;
if(!lss_read(&mIRQActive,sizeof(ULONG),1,fp)) return 0;
PS(mPS);
return 1;
}
inline void Update(void)
{
//
// NMI is currently unused by the lynx so lets save some time
//
// Check NMI & IRQ status, prioritise NMI then IRQ
// if(mNMI)
// {
// // Mark the NMI as services
// mNMI=FALSE;
// mProcessingInterrupt++;
//
// // Push processor status
// CPU_POKE(0x0100+mSP--,mPC>>8);
// CPU_POKE(0x0100+mSP--,mPC&0x00ff);
// CPU_POKE(0x0100+mSP--,PS());
//
// // Pick up the new PC
// mPC=CPU_PEEKW(NMI_VECTOR);
// }
if(gSystemIRQ && !mI)
{
TRACE_CPU1("Update() IRQ taken at PC=%04x",mPC);
// IRQ signal clearance is handled by CMikie::Update() as this
// is the only source of interrupts
// Push processor status
PUSH(mPC>>8);
PUSH(mPC&0xff);
PUSH(PS()&0xef); // Clear B flag on stack
mI=TRUE; // Stop further interrupts
mD=FALSE; // Clear decimal mode
// Pick up the new PC
mPC=CPU_PEEKW(IRQ_VECTOR);
// Save the sleep state as an irq has possibly woken the processor
gSystemCPUSleep_Saved=gSystemCPUSleep;
gSystemCPUSleep=FALSE;
// Log the irq entry time
gIRQEntryCycle=gSystemCycleCount;
// Clear the interrupt status line
gSystemIRQ=FALSE;
}
//
// If the CPU is asleep then skip to the next timer event
//
if(gSystemCPUSleep) return;
// Fetch opcode
mOpcode=CPU_PEEK(mPC);
TRACE_CPU2("Update() PC=$%04x, Opcode=%02x",mPC,mOpcode);
mPC++;
// Execute Opcode
switch(mOpcode)
{
//
// 0x00
//
case 0x00:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
// IMPLIED
xBRK();
break;
case 0x01:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xORA();
break;
case 0x02:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x03:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x04:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xTSB();
break;
case 0x05:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xORA();
break;
case 0x06:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xASL();
break;
case 0x07:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x08:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
// IMPLIED
xPHP();
break;
case 0x09:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xIMMEDIATE();
xORA();
break;
case 0x0A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xASLA();
break;
case 0x0B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x0C:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xTSB();
break;
case 0x0D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xORA();
break;
case 0x0E:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xASL();
break;
case 0x0F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x10
//
case 0x10:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBPL();
break;
case 0x11:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xORA();
break;
case 0x12:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xORA();
break;
case 0x13:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x14:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xTRB();
break;
case 0x15:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xORA();
break;
case 0x16:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xZEROPAGE_X();
xASL();
break;
case 0x17:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x18:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xCLC();
break;
case 0x19:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xORA();
break;
case 0x1A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xINCA();
break;
case 0x1B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x1C:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xTRB();
break;
case 0x1D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xORA();
break;
case 0x1E:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
xABSOLUTE_X();
xASL();
break;
case 0x1F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x20
//
case 0x20:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xJSR();
break;
case 0x21:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xAND();
break;
case 0x22:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x23:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x24:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xBIT();
break;
case 0x25:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xAND();
break;
case 0x26:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xROL();
break;
case 0x27:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x28:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// IMPLIED
xPLP();
break;
case 0x29:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xAND();
break;
case 0x2A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xROLA();
break;
case 0x2B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x2C:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xBIT();
break;
case 0x2D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xAND();
break;
case 0x2E:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xROL();
break;
case 0x2F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x30
//
case 0x30:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBMI();
break;
case 0x31:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xAND();
break;
case 0x32:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xAND();
break;
case 0x33:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x34:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xBIT();
break;
case 0x35:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xAND();
break;
case 0x36:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xZEROPAGE_X();
xROL();
break;
case 0x37:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x38:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xSEC();
break;
case 0x39:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xAND();
break;
case 0x3A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xDECA();
break;
case 0x3B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x3C:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xBIT();
break;
case 0x3D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xAND();
break;
case 0x3E:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
xABSOLUTE_X();
xROL();
break;
case 0x3F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x40
//
case 0x40:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
// Only clear IRQ if this is not a BRK instruction based RTI
// B flag is on the stack cant test the flag
int tmp;
PULL(tmp);
PUSH (tmp);
if(!(tmp&0x10))
{
gSystemCPUSleep=gSystemCPUSleep_Saved;
// If were in sleep mode then we need to push the
// wakeup counter along by the same number of cycles
// we have used during the sleep period
if(gSystemCPUSleep)
{
gCPUWakeupTime+=gSystemCycleCount-gIRQEntryCycle;
}
}
// IMPLIED
xRTI();
break;
case 0x41:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xEOR();
break;
case 0x42:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x43:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x44:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x45:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xEOR();
break;
case 0x46:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xLSR();
break;
case 0x47:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x48:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
// IMPLIED
xPHA();
break;
case 0x49:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xEOR();
break;
case 0x4A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xLSRA();
break;
case 0x4B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x4C:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xABSOLUTE();
xJMP();
break;
case 0x4D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xEOR();
break;
case 0x4E:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xLSR();
break;
case 0x4F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x50
//
case 0x50:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBVC();
break;
case 0x51:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xEOR();
break;
case 0x52:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xEOR();
break;
case 0x53:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x54:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x55:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xEOR();
break;
case 0x56:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xZEROPAGE_X();
xLSR();
break;
case 0x57:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x58:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xCLI();
break;
case 0x59:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xEOR();
break;
case 0x5A:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
// IMPLIED
xPHY();
break;
case 0x5B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x5C:
gSystemCycleCount+=(1+(7*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x5D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xEOR();
break;
case 0x5E:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
xABSOLUTE_X();
xLSR();
break;
case 0x5F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x60
//
case 0x60:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
// IMPLIED
xRTS();
break;
case 0x61:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xADC();
break;
case 0x62:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x63:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x64:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xSTZ();
break;
case 0x65:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xADC();
break;
case 0x66:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xROR();
break;
case 0x67:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x68:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// IMPLIED
xPLA();
break;
case 0x69:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xADC();
break;
case 0x6A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xRORA();
break;
case 0x6B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x6C:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_ABSOLUTE();
xJMP();
break;
case 0x6D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xADC();
break;
case 0x6E:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xROR();
break;
case 0x6F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x70
//
case 0x70:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBVS();
break;
case 0x71:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xADC();
break;
case 0x72:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xADC();
break;
case 0x73:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x74:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xSTZ();
break;
case 0x75:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xADC();
break;
case 0x76:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xZEROPAGE_X();
xROR();
break;
case 0x77:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x78:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xSEI();
break;
case 0x79:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xADC();
break;
case 0x7A:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// IMPLIED
xPLY();
break;
case 0x7B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x7C:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_ABSOLUTE_X();
xJMP();
break;
case 0x7D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xADC();
break;
case 0x7E:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
xABSOLUTE_X();
xROR();
break;
case 0x7F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x80
//
case 0x80:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBRA();
break;
case 0x81:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xSTA();
break;
case 0x82:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x83:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x84:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xSTY();
break;
case 0x85:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xSTA();
break;
case 0x86:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xSTX();
break;
case 0x87:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x88:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xDEY();
break;
case 0x89:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xBIT();
break;
case 0x8A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xTXA();
break;
case 0x8B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x8C:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xSTY();
break;
case 0x8D:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xSTA();
break;
case 0x8E:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xSTX();
break;
case 0x8F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0x90
//
case 0x90:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBCC();
break;
case 0x91:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_Y();
xSTA();
break;
case 0x92:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xSTA();
break;
case 0x93:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x94:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xSTY();
break;
case 0x95:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xSTA();
break;
case 0x96:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_Y();
xSTX();
break;
case 0x97:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x98:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xTYA();
break;
case 0x99:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xABSOLUTE_Y();
xSTA();
break;
case 0x9A:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xTXS();
break;
case 0x9B:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0x9C:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xSTZ();
break;
case 0x9D:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xABSOLUTE_X();
xSTA();
break;
case 0x9E:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xABSOLUTE_X();
xSTZ();
break;
case 0x9F:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0xA0
//
case 0xA0:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xLDY();
break;
case 0xA1:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xLDA();
break;
case 0xA2:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xLDX();
break;
case 0xA3:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xA4:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xLDY();
break;
case 0xA5:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xLDA();
break;
case 0xA6:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xLDX();
break;
case 0xA7:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xA8:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xTAY();
break;
case 0xA9:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xLDA();
break;
case 0xAA:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xTAX();
break;
case 0xAB:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xAC:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xLDY();
break;
case 0xAD:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xLDA();
break;
case 0xAE:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xLDX();
break;
case 0xAF:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0xB0
//
case 0xB0:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBCS();
break;
case 0xB1:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xLDA();
break;
case 0xB2:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xLDA();
break;
case 0xB3:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xB4:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xLDY();
break;
case 0xB5:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xLDA();
break;
case 0xB6:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_Y();
xLDX();
break;
case 0xB7:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xB8:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xCLV();
break;
case 0xB9:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xLDA();
break;
case 0xBA:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xTSX();
break;
case 0xBB:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xBC:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xLDY();
break;
case 0xBD:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xLDA();
break;
case 0xBE:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xLDX();
break;
case 0xBF:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0xC0
//
case 0xC0:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xCPY();
break;
case 0xC1:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xCMP();
break;
case 0xC2:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xC3:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xC4:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xCPY();
break;
case 0xC5:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xCMP();
break;
case 0xC6:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xDEC();
break;
case 0xC7:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xC8:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xINY();
break;
case 0xC9:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xCMP();
break;
case 0xCA:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xDEX();
break;
case 0xCB:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xWAI();
break;
case 0xCC:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xCPY();
break;
case 0xCD:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xCMP();
break;
case 0xCE:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xDEC();
break;
case 0xCF:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0xD0
//
case 0xD0:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBNE();
break;
case 0xD1:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xCMP();
break;
case 0xD2:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xCMP();
break;
case 0xD3:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xD4:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xD5:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xCMP();
break;
case 0xD6:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xZEROPAGE_X();
xDEC();
break;
case 0xD7:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xD8:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xCLD();
break;
case 0xD9:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xCMP();
break;
case 0xDA:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
// IMPLIED
xPHX();
break;
case 0xDB:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xSTP();
break;
case 0xDC:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xDD:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xCMP();
break;
case 0xDE:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
xABSOLUTE_X();
xDEC();
break;
case 0xDF:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0xE0
//
case 0xE0:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xCPX();
break;
case 0xE1:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xINDIRECT_X();
xSBC();
break;
case 0xE2:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xE3:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xE4:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xCPX();
break;
case 0xE5:
gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
xZEROPAGE();
xSBC();
break;
case 0xE6:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xZEROPAGE();
xINC();
break;
case 0xE7:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xE8:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xINX();
break;
case 0xE9:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
xIMMEDIATE();
xSBC();
break;
case 0xEA:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xNOP();
break;
case 0xEB:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xEC:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xCPX();
break;
case 0xED:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE();
xSBC();
break;
case 0xEE:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xABSOLUTE();
xINC();
break;
case 0xEF:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
//
// 0xF0
//
case 0xF0:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// RELATIVE (IN FUNCTION)
xBEQ();
break;
case 0xF1:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT_Y();
xSBC();
break;
case 0xF2:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
xINDIRECT();
xSBC();
break;
case 0xF3:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xF4:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xF5:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xZEROPAGE_X();
xSBC();
break;
case 0xF6:
gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
xZEROPAGE_X();
xINC();
break;
case 0xF7:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xF8:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// IMPLIED
xSED();
break;
case 0xF9:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_Y();
xSBC();
break;
case 0xFA:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// IMPLIED
xPLX();
break;
case 0xFB:
gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xFC:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
case 0xFD:
gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
xABSOLUTE_X();
xSBC();
break;
case 0xFE:
gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
xABSOLUTE_X();
xINC();
break;
case 0xFF:
gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
// *** ILLEGAL ***
xILLEGAL();
break;
}
#ifdef _LYNXDBG
// Trigger breakpoint if required
for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++)
{
if(mPcBreakpoints[loop]==mPC)
{
gBreakpointHit=TRUE;
mSystem.DebugTrace(0);
}
}
// Check code level debug features
// back to back CPX ($Absolute)
// on the 2nd Occurance we do some debug
if(mOpcode==0xec)
{
if(mDbgFlag)
{
// We shoud do some debug now
if(!mOperand)
{
// Trigger a breakpoint
gBreakpointHit=TRUE;
// Generate a debug trail output
mSystem.DebugTrace(0);
}
else
{
// Generate a debug trail output
mSystem.DebugTrace(mOperand);
}
mDbgFlag=0;
}
else
{
if(mOperand==0x5aa5) mDbgFlag=1; else mDbgFlag=0;
}
}
else
{
mDbgFlag=0;
}
#endif
}
// inline void SetBreakpoint(ULONG breakpoint) {mPcBreakpoint=breakpoint;};
inline void SetRegs(C6502_REGS &regs)
{
PS(regs.PS);
mA=regs.A;
mX=regs.X;
mY=regs.Y;
mSP=regs.SP;
mOpcode=regs.Opcode;
mOperand=regs.Operand;
mPC=regs.PC;
gSystemCPUSleep=regs.WAIT;
#ifdef _LYNXDBG
for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++) mPcBreakpoints[loop]=regs.cpuBreakpoints[loop];
#endif
gSystemNMI=regs.NMI;
gSystemIRQ=regs.IRQ;
}
inline void GetRegs(C6502_REGS &regs)
{
regs.PS=PS();
regs.A=mA;
regs.X=mX;
regs.Y=mY;
regs.SP=mSP;
regs.Opcode=mOpcode;
regs.Operand=mOperand;
regs.PC=mPC;
regs.WAIT=(gSystemCPUSleep)?true:false;
#ifdef _LYNXDBG
for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++) regs.cpuBreakpoints[loop]=mPcBreakpoints[loop];
#endif
regs.NMI=(gSystemNMI)?true:false;
regs.IRQ=(gSystemIRQ)?true:false;
}
inline int GetPC(void) { return mPC; }
inline void xILLEGAL(void)
{
log_printf("CPU: Illegal opcode $%02x at PC=$%04x.\n", mOpcode, mPC);
}
private:
CSystemBase &mSystem;
// CPU Flags & status
int mA; // Accumulator 8 bits
int mX; // X index register 8 bits
int mY; // Y index register 8 bits
int mSP; // Stack Pointer 8 bits
int mOpcode; // Instruction opcode 8 bits
int mOperand; // Intructions operand 16 bits
int mPC; // Program Counter 16 bits
int mN; // N flag for processor status register
int mV; // V flag for processor status register
int mB; // B flag for processor status register
int mD; // D flag for processor status register
int mI; // I flag for processor status register
int mZ; // Z flag for processor status register
int mC; // C flag for processor status register
int mIRQActive;
#ifdef _LYNXDBG
int mPcBreakpoints[MAX_CPU_BREAKPOINTS];
int mDbgFlag;
#endif
UBYTE *mRamPointer;
// Associated lookup tables
// int mBCDTable[2][256];
//
// Opcode prototypes
//
private:
// Answers value of the Processor Status register
int PS() const
{
UBYTE ps = 0x20;
if(mN) ps|=0x80;
if(mV) ps|=0x40;
if(mB) ps|=0x10;
if(mD) ps|=0x08;
if(mI) ps|=0x04;
if(mZ) ps|=0x02;
if(mC) ps|=0x01;
return ps;
}
// Change the processor flags to correspond to the given value
void PS(int ps)
{
mN=ps&0x80;
mV=ps&0x40;
mB=ps&0x10;
mD=ps&0x08;
mI=ps&0x04;
mZ=ps&0x02;
mC=ps&0x01;
}
};
#endif