c65c02.h
   1  //
   2  // Copyright (c) 2004 K. Wilkins
   3  //
   4  // This software is provided 'as-is', without any express or implied warranty.
   5  // In no event will the authors be held liable for any damages arising from
   6  // the use of this software.
   7  //
   8  // Permission is granted to anyone to use this software for any purpose,
   9  // including commercial applications, and to alter it and redistribute it
  10  // freely, subject to the following restrictions:
  11  //
  12  // 1. The origin of this software must not be misrepresented; you must not
  13  //    claim that you wrote the original software. If you use this software
  14  //    in a product, an acknowledgment in the product documentation would be
  15  //    appreciated but is not required.
  16  //
  17  // 2. Altered source versions must be plainly marked as such, and must not
  18  //    be misrepresented as being the original software.
  19  //
  20  // 3. This notice may not be removed or altered from any source distribution.
  21  //
  22  
  23  //////////////////////////////////////////////////////////////////////////////
  24  //                       Handy - An Atari Lynx Emulator                     //
  25  //                          Copyright (c) 1996,1997                         //
  26  //                                 K. Wilkins                               //
  27  //////////////////////////////////////////////////////////////////////////////
  28  // 65C02 Emulation class                                                    //
  29  //////////////////////////////////////////////////////////////////////////////
  30  //                                                                          //
  31  // This class emulates a 65C02 processor. It is interfaced to the rest of   //
  32  // the system via the PEEK/POKE macros and a number of global variables     //
  33  //                                                                          //
  34  //    K. Wilkins                                                            //
  35  // August 1997                                                              //
  36  //                                                                          //
  37  //////////////////////////////////////////////////////////////////////////////
  38  // Revision History:                                                        //
  39  // -----------------                                                        //
  40  //                                                                          //
  41  // 01Aug1997 KW Document header added & class documented.                   //
  42  //                                                                          //
  43  //////////////////////////////////////////////////////////////////////////////
  44  
  45  #ifndef C65C02_H
  46  #define C65C02_H
  47  
  48  //#include <crtdbg.h>
  49  //#define	TRACE_CPU
  50  
  51  #ifdef TRACE_CPU
  52  
  53  #define TRACE_CPU0(msg)					_RPT1(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",gSystemCycleCount)
  54  #define TRACE_CPU1(msg,arg1)			_RPT2(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,gSystemCycleCount)
  55  #define TRACE_CPU2(msg,arg1,arg2)		_RPT3(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,arg2,gSystemCycleCount)
  56  #define TRACE_CPU3(msg,arg1,arg2,arg3)	_RPT4(_CRT_WARN,"C65C02::"msg" (Time=%012d)\n",arg1,arg2,arg3,gSystemCycleCount)
  57  
  58  #else
  59  
  60  #define TRACE_CPU0(msg)
  61  #define TRACE_CPU1(msg,arg1)
  62  #define TRACE_CPU2(msg,arg1,arg2)
  63  #define TRACE_CPU3(msg,arg1,arg2,arg3)
  64  
  65  #endif
  66  
  67  //
  68  // Handy definitions
  69  //
  70  
  71  #define NMI_VECTOR	0xfffa
  72  #define BOOT_VECTOR	0xfffc
  73  #define IRQ_VECTOR	0xfffe
  74  
  75  #define MAX_CPU_BREAKPOINTS	8
  76  
  77  #define CPU_RDWR_CYC	5
  78  
  79  //
  80  // ACCESS MACROS
  81  //
  82  #define CPU_PEEK_RAM(m)				(mRamPointer[m])
  83  #define CPU_POKE_RAM(m1,m2)		mRamPointer[m1]=m2
  84  
  85  #define CPU_PEEK(m)				(((m<0xfc00)?CPU_PEEK_RAM(m):mSystem.Peek_CPU(m)))
  86  #define CPU_PEEKW(m)			   (((m<0xfc00)?(mRamPointer[m]+(mRamPointer[m+1]<<8)):mSystem.PeekW_CPU(m)))
  87  #define CPU_POKE(m1,m2)			{if(m1<0xfc00) CPU_POKE_RAM(m1,m2); else mSystem.Poke_CPU(m1,m2);}
  88  
  89  
  90  enum
  91  {
  92     illegal=0,
  93     accu,
  94     imm,
  95     absl,
  96     zp,
  97     zpx,
  98     zpy,
  99     absx,
 100     absy,
 101     iabsx,
 102     impl,
 103     rel,
 104     zrel,
 105     indx,
 106     indy,
 107     iabs,
 108     ind
 109  };
 110  
 111  typedef struct
 112  {
 113     int PS;		// Processor status register   8 bits
 114     int A;		// Accumulator                 8 bits
 115     int X;		// X index register            8 bits
 116     int Y;		// Y index register            8 bits
 117     int SP;		// Stack Pointer               8 bits
 118     int Opcode;	// Instruction opcode          8 bits
 119     int Operand;// Intructions operand		  16 bits
 120     int PC;		// Program Counter            16 bits
 121     bool NMI;
 122     bool IRQ;
 123     bool WAIT;
 124  #ifdef _LYNXDBG
 125     int	cpuBreakpoints[MAX_CPU_BREAKPOINTS];
 126  #endif
 127  }C6502_REGS;
 128  
 129  //
 130  // The CPU emulation macros
 131  //
 132  #include "c6502mak.h"
 133  //
 134  // The CPU emulation macros
 135  //
 136  
 137  class C65C02
 138  {
 139     public:
 140        C65C02(CSystemBase& parent)
 141           :mSystem(parent)
 142        {
 143           TRACE_CPU0("C65C02()");
 144           // Compute the BCD lookup table
 145           // for(UWORD t=0;t<256;++t)
 146           // {
 147           //    mBCDTable[0][t]=((t >> 4) * 10) + (t & 0x0f);
 148           //    mBCDTable[1][t]=(((t % 100) / 10) << 4) | (t % 10);
 149           // }
 150  #ifdef _LYNXDBG
 151           for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++)	mPcBreakpoints[loop]=0xfffffff;
 152           mDbgFlag=0;
 153  #endif
 154           Reset();
 155  
 156        }
 157  
 158        ~C65C02()
 159        {
 160           TRACE_CPU0("~C65C02()");
 161        }
 162  
 163     public:
 164        inline void Reset(void)
 165        {
 166           TRACE_CPU0("Reset()");
 167           mRamPointer=mSystem.GetRamPointer();
 168           mA=0;
 169           mX=0;
 170           mY=0;
 171           mSP=0xff;
 172           mOpcode=0;
 173           mOperand=0;
 174           mPC=CPU_PEEKW(BOOT_VECTOR);
 175           mN=FALSE;
 176           mV=FALSE;
 177           mB=FALSE;
 178           mD=FALSE;
 179           mI=TRUE;
 180           mZ=TRUE;
 181           mC=FALSE;
 182           mIRQActive=FALSE;
 183  
 184           gSystemNMI=FALSE;
 185           gSystemIRQ=FALSE;
 186           gSystemCPUSleep=FALSE;
 187           gSystemCPUSleep_Saved=FALSE;
 188        }
 189  
 190  
 191        inline bool ContextSave(LSS_FILE *fp)
 192        {
 193           TRACE_CPU0("ContextSave()");
 194           int mPS;
 195           mPS=PS();
 196           if(!lss_printf(fp,"C6502::ContextSave")) return 0;
 197           if(!lss_write(&mA,sizeof(ULONG),1,fp)) return 0;
 198           if(!lss_write(&mX,sizeof(ULONG),1,fp)) return 0;
 199           if(!lss_write(&mY,sizeof(ULONG),1,fp)) return 0;
 200           if(!lss_write(&mSP,sizeof(ULONG),1,fp)) return 0;
 201           if(!lss_write(&mPS,sizeof(ULONG),1,fp)) return 0;
 202           if(!lss_write(&mPC,sizeof(ULONG),1,fp)) return 0;
 203           if(!lss_write(&mIRQActive,sizeof(ULONG),1,fp)) return 0;
 204           return 1;
 205        }
 206  
 207        inline bool ContextLoad(LSS_FILE *fp)
 208        {
 209           TRACE_CPU0("ContextLoad()");
 210           int mPS;
 211           char teststr[32]="XXXXXXXXXXXXXXXXXX";
 212           if(!lss_read(teststr,sizeof(char),18,fp)) return 0;
 213           if(strcmp(teststr,"C6502::ContextSave")!=0) return 0;
 214           if(!lss_read(&mA,sizeof(ULONG),1,fp)) return 0;
 215           if(!lss_read(&mX,sizeof(ULONG),1,fp)) return 0;
 216           if(!lss_read(&mY,sizeof(ULONG),1,fp)) return 0;
 217           if(!lss_read(&mSP,sizeof(ULONG),1,fp)) return 0;
 218           if(!lss_read(&mPS,sizeof(ULONG),1,fp)) return 0;
 219           if(!lss_read(&mPC,sizeof(ULONG),1,fp)) return 0;
 220           if(!lss_read(&mIRQActive,sizeof(ULONG),1,fp)) return 0;
 221           PS(mPS);
 222           return 1;
 223        }
 224  
 225        inline void Update(void)
 226        {
 227           //
 228           // NMI is currently unused by the lynx so lets save some time
 229           //
 230           //			Check NMI & IRQ status, prioritise NMI then IRQ
 231           //			if(mNMI)
 232           //			{
 233           //				// Mark the NMI as services
 234           //				mNMI=FALSE;
 235           //				mProcessingInterrupt++;
 236           //
 237           //				// Push processor status
 238           //				CPU_POKE(0x0100+mSP--,mPC>>8);
 239           //				CPU_POKE(0x0100+mSP--,mPC&0x00ff);
 240           //				CPU_POKE(0x0100+mSP--,PS());
 241           //
 242           //				// Pick up the new PC
 243           //				mPC=CPU_PEEKW(NMI_VECTOR);
 244           //			}
 245  
 246           if(gSystemIRQ && !mI)
 247           {
 248              TRACE_CPU1("Update() IRQ taken at PC=%04x",mPC);
 249              // IRQ signal clearance is handled by CMikie::Update() as this
 250              // is the only source of interrupts
 251  
 252              // Push processor status
 253              PUSH(mPC>>8);
 254              PUSH(mPC&0xff);
 255              PUSH(PS()&0xef);		// Clear B flag on stack
 256  
 257              mI=TRUE;				// Stop further interrupts
 258              mD=FALSE;				// Clear decimal mode
 259  
 260              // Pick up the new PC
 261              mPC=CPU_PEEKW(IRQ_VECTOR);
 262  
 263              // Save the sleep state as an irq has possibly woken the processor
 264              gSystemCPUSleep_Saved=gSystemCPUSleep;
 265              gSystemCPUSleep=FALSE;
 266  
 267              // Log the irq entry time
 268              gIRQEntryCycle=gSystemCycleCount;
 269  
 270              // Clear the interrupt status line
 271              gSystemIRQ=FALSE;
 272           }
 273  
 274           //
 275           // If the CPU is asleep then skip to the next timer event
 276           //
 277           if(gSystemCPUSleep) return;
 278  
 279           // Fetch opcode
 280           mOpcode=CPU_PEEK(mPC);
 281           TRACE_CPU2("Update() PC=$%04x, Opcode=%02x",mPC,mOpcode);
 282           mPC++;
 283  
 284           // Execute Opcode
 285  
 286           switch(mOpcode)
 287           {
 288  
 289              //
 290              // 0x00
 291              //
 292              case 0x00:
 293                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
 294                 // IMPLIED
 295                 xBRK();
 296                 break;
 297              case 0x01:
 298                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 299                 xINDIRECT_X();
 300                 xORA();
 301                 break;
 302              case 0x02:
 303                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 304                 // *** ILLEGAL ***
 305                 xILLEGAL();
 306                 break;
 307              case 0x03:
 308                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 309                 // *** ILLEGAL ***
 310                 xILLEGAL();
 311                 break;
 312              case 0x04:
 313                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 314                 xZEROPAGE();
 315                 xTSB();
 316                 break;
 317              case 0x05:
 318                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 319                 xZEROPAGE();
 320                 xORA();
 321                 break;
 322              case 0x06:
 323                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 324                 xZEROPAGE();
 325                 xASL();
 326                 break;
 327              case 0x07:
 328                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 329                 // *** ILLEGAL ***
 330                 xILLEGAL();
 331                 break;
 332  
 333              case 0x08:
 334                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 335                 // IMPLIED
 336                 xPHP();
 337                 break;
 338              case 0x09:
 339                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 340                 xIMMEDIATE();
 341                 xORA();
 342                 break;
 343              case 0x0A:
 344                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 345                 // IMPLIED
 346                 xASLA();
 347                 break;
 348              case 0x0B:
 349                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 350                 // *** ILLEGAL ***
 351                 xILLEGAL();
 352                 break;
 353              case 0x0C:
 354                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 355                 xABSOLUTE();
 356                 xTSB();
 357                 break;
 358              case 0x0D:
 359                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 360                 xABSOLUTE();
 361                 xORA();
 362                 break;
 363              case 0x0E:
 364                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 365                 xABSOLUTE();
 366                 xASL();
 367                 break;
 368              case 0x0F:
 369                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 370                 // *** ILLEGAL ***
 371                 xILLEGAL();
 372                 break;
 373  
 374                 //
 375                 // 0x10
 376                 //
 377              case 0x10:
 378                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 379                 // RELATIVE (IN FUNCTION)
 380                 xBPL();
 381                 break;
 382              case 0x11:
 383                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 384                 xINDIRECT_Y();
 385                 xORA();
 386                 break;
 387              case 0x12:
 388                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 389                 xINDIRECT();
 390                 xORA();
 391                 break;
 392              case 0x13:
 393                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 394                 // *** ILLEGAL ***
 395                 xILLEGAL();
 396                 break;
 397              case 0x14:
 398                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 399                 xZEROPAGE();
 400                 xTRB();
 401                 break;
 402              case 0x15:
 403                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 404                 xZEROPAGE_X();
 405                 xORA();
 406                 break;
 407              case 0x16:
 408                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 409                 xZEROPAGE_X();
 410                 xASL();
 411                 break;
 412              case 0x17:
 413                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 414                 // *** ILLEGAL ***
 415                 xILLEGAL();
 416                 break;
 417  
 418              case 0x18:
 419                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 420                 // IMPLIED
 421                 xCLC();
 422                 break;
 423              case 0x19:
 424                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 425                 xABSOLUTE_Y();
 426                 xORA();
 427                 break;
 428              case 0x1A:
 429                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 430                 // IMPLIED
 431                 xINCA();
 432                 break;
 433              case 0x1B:
 434                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 435                 // *** ILLEGAL ***
 436                 xILLEGAL();
 437                 break;
 438              case 0x1C:
 439                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 440                 xABSOLUTE();
 441                 xTRB();
 442                 break;
 443              case 0x1D:
 444                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 445                 xABSOLUTE_X();
 446                 xORA();
 447                 break;
 448              case 0x1E:
 449                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
 450                 xABSOLUTE_X();
 451                 xASL();
 452                 break;
 453              case 0x1F:
 454                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 455                 // *** ILLEGAL ***
 456                 xILLEGAL();
 457                 break;
 458  
 459                 //
 460                 // 0x20
 461                 //
 462              case 0x20:
 463                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 464                 xABSOLUTE();
 465                 xJSR();
 466                 break;
 467              case 0x21:
 468                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 469                 xINDIRECT_X();
 470                 xAND();
 471                 break;
 472              case 0x22:
 473                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 474                 // *** ILLEGAL ***
 475                 xILLEGAL();
 476                 break;
 477              case 0x23:
 478                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 479                 // *** ILLEGAL ***
 480                 xILLEGAL();
 481                 break;
 482              case 0x24:
 483                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 484                 xZEROPAGE();
 485                 xBIT();
 486                 break;
 487              case 0x25:
 488                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 489                 xZEROPAGE();
 490                 xAND();
 491                 break;
 492              case 0x26:
 493                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 494                 xZEROPAGE();
 495                 xROL();
 496                 break;
 497              case 0x27:
 498                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 499                 // *** ILLEGAL ***
 500                 xILLEGAL();
 501                 break;
 502  
 503              case 0x28:
 504                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 505                 // IMPLIED
 506                 xPLP();
 507                 break;
 508              case 0x29:
 509                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 510                 xIMMEDIATE();
 511                 xAND();
 512                 break;
 513              case 0x2A:
 514                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 515                 // IMPLIED
 516                 xROLA();
 517                 break;
 518              case 0x2B:
 519                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 520                 // *** ILLEGAL ***
 521                 xILLEGAL();
 522                 break;
 523              case 0x2C:
 524                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 525                 xABSOLUTE();
 526                 xBIT();
 527                 break;
 528              case 0x2D:
 529                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 530                 xABSOLUTE();
 531                 xAND();
 532                 break;
 533              case 0x2E:
 534                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 535                 xABSOLUTE();
 536                 xROL();
 537                 break;
 538              case 0x2F:
 539                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 540                 // *** ILLEGAL ***
 541                 xILLEGAL();
 542                 break;
 543  
 544                 //
 545                 // 0x30
 546                 //
 547              case 0x30:
 548                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 549                 // RELATIVE (IN FUNCTION)
 550                 xBMI();
 551                 break;
 552              case 0x31:
 553                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 554                 xINDIRECT_Y();
 555                 xAND();
 556                 break;
 557              case 0x32:
 558                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 559                 xINDIRECT();
 560                 xAND();
 561                 break;
 562              case 0x33:
 563                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 564                 // *** ILLEGAL ***
 565                 xILLEGAL();
 566                 break;
 567              case 0x34:
 568                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 569                 xZEROPAGE_X();
 570                 xBIT();
 571                 break;
 572              case 0x35:
 573                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 574                 xZEROPAGE_X();
 575                 xAND();
 576                 break;
 577              case 0x36:
 578                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 579                 xZEROPAGE_X();
 580                 xROL();
 581                 break;
 582              case 0x37:
 583                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 584                 // *** ILLEGAL ***
 585                 xILLEGAL();
 586                 break;
 587  
 588              case 0x38:
 589                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 590                 // IMPLIED
 591                 xSEC();
 592                 break;
 593              case 0x39:
 594                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 595                 xABSOLUTE_Y();
 596                 xAND();
 597                 break;
 598              case 0x3A:
 599                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 600                 // IMPLIED
 601                 xDECA();
 602                 break;
 603              case 0x3B:
 604                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 605                 // *** ILLEGAL ***
 606                 xILLEGAL();
 607                 break;
 608              case 0x3C:
 609                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 610                 xABSOLUTE_X();
 611                 xBIT();
 612                 break;
 613              case 0x3D:
 614                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 615                 xABSOLUTE_X();
 616                 xAND();
 617                 break;
 618              case 0x3E:
 619                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
 620                 xABSOLUTE_X();
 621                 xROL();
 622                 break;
 623              case 0x3F:
 624                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 625                 // *** ILLEGAL ***
 626                 xILLEGAL();
 627                 break;
 628  
 629                 //
 630                 // 0x40
 631                 //
 632              case 0x40:
 633                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 634                 // Only clear IRQ if this is not a BRK instruction based RTI
 635  
 636                 // B flag is on the stack cant test the flag
 637                 int tmp;
 638                 PULL(tmp);
 639                 PUSH (tmp);
 640                 if(!(tmp&0x10))
 641                 {
 642                    gSystemCPUSleep=gSystemCPUSleep_Saved;
 643  
 644                    // If were in sleep mode then we need to push the
 645                    // wakeup counter along by the same number of cycles
 646                    // we have used during the sleep period
 647                    if(gSystemCPUSleep)
 648                    {
 649                       gCPUWakeupTime+=gSystemCycleCount-gIRQEntryCycle;
 650                    }
 651                 }
 652                 // IMPLIED
 653                 xRTI();
 654                 break;
 655              case 0x41:
 656                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 657                 xINDIRECT_X();
 658                 xEOR();
 659                 break;
 660              case 0x42:
 661                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 662                 // *** ILLEGAL ***
 663                 xILLEGAL();
 664                 break;
 665              case 0x43:
 666                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 667                 // *** ILLEGAL ***
 668                 xILLEGAL();
 669                 break;
 670              case 0x44:
 671                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 672                 // *** ILLEGAL ***
 673                 xILLEGAL();
 674                 break;
 675              case 0x45:
 676                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 677                 xZEROPAGE();
 678                 xEOR();
 679                 break;
 680              case 0x46:
 681                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 682                 xZEROPAGE();
 683                 xLSR();
 684                 break;
 685              case 0x47:
 686                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 687                 // *** ILLEGAL ***
 688                 xILLEGAL();
 689                 break;
 690  
 691              case 0x48:
 692                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 693                 // IMPLIED
 694                 xPHA();
 695                 break;
 696              case 0x49:
 697                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 698                 xIMMEDIATE();
 699                 xEOR();
 700                 break;
 701              case 0x4A:
 702                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 703                 // IMPLIED
 704                 xLSRA();
 705                 break;
 706              case 0x4B:
 707                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 708                 // *** ILLEGAL ***
 709                 xILLEGAL();
 710                 break;
 711              case 0x4C:
 712                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 713                 xABSOLUTE();
 714                 xJMP();
 715                 break;
 716              case 0x4D:
 717                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 718                 xABSOLUTE();
 719                 xEOR();
 720                 break;
 721              case 0x4E:
 722                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 723                 xABSOLUTE();
 724                 xLSR();
 725                 break;
 726              case 0x4F:
 727                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 728                 // *** ILLEGAL ***
 729                 xILLEGAL();
 730                 break;
 731  
 732                 //
 733                 // 0x50
 734                 //
 735              case 0x50:
 736                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 737                 // RELATIVE (IN FUNCTION)
 738                 xBVC();
 739                 break;
 740              case 0x51:
 741                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 742                 xINDIRECT_Y();
 743                 xEOR();
 744                 break;
 745              case 0x52:
 746                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 747                 xINDIRECT();
 748                 xEOR();
 749                 break;
 750              case 0x53:
 751                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 752                 // *** ILLEGAL ***
 753                 xILLEGAL();
 754                 break;
 755              case 0x54:
 756                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 757                 // *** ILLEGAL ***
 758                 xILLEGAL();
 759                 break;
 760              case 0x55:
 761                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 762                 xZEROPAGE_X();
 763                 xEOR();
 764                 break;
 765              case 0x56:
 766                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 767                 xZEROPAGE_X();
 768                 xLSR();
 769                 break;
 770              case 0x57:
 771                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 772                 // *** ILLEGAL ***
 773                 xILLEGAL();
 774                 break;
 775  
 776              case 0x58:
 777                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 778                 // IMPLIED
 779                 xCLI();
 780                 break;
 781              case 0x59:
 782                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 783                 xABSOLUTE_Y();
 784                 xEOR();
 785                 break;
 786              case 0x5A:
 787                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 788                 // IMPLIED
 789                 xPHY();
 790                 break;
 791              case 0x5B:
 792                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 793                 // *** ILLEGAL ***
 794                 xILLEGAL();
 795                 break;
 796              case 0x5C:
 797                 gSystemCycleCount+=(1+(7*CPU_RDWR_CYC));
 798                 // *** ILLEGAL ***
 799                 xILLEGAL();
 800                 break;
 801              case 0x5D:
 802                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 803                 xABSOLUTE_X();
 804                 xEOR();
 805                 break;
 806              case 0x5E:
 807                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
 808                 xABSOLUTE_X();
 809                 xLSR();
 810                 break;
 811              case 0x5F:
 812                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 813                 // *** ILLEGAL ***
 814                 xILLEGAL();
 815                 break;
 816  
 817                 //
 818                 // 0x60
 819                 //
 820              case 0x60:
 821                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 822                 // IMPLIED
 823                 xRTS();
 824                 break;
 825              case 0x61:
 826                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 827                 xINDIRECT_X();
 828                 xADC();
 829                 break;
 830              case 0x62:
 831                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 832                 // *** ILLEGAL ***
 833                 xILLEGAL();
 834                 break;
 835              case 0x63:
 836                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 837                 // *** ILLEGAL ***
 838                 xILLEGAL();
 839                 break;
 840              case 0x64:
 841                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 842                 xZEROPAGE();
 843                 xSTZ();
 844                 break;
 845              case 0x65:
 846                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 847                 xZEROPAGE();
 848                 xADC();
 849                 break;
 850              case 0x66:
 851                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 852                 xZEROPAGE();
 853                 xROR();
 854                 break;
 855              case 0x67:
 856                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 857                 // *** ILLEGAL ***
 858                 xILLEGAL();
 859                 break;
 860  
 861              case 0x68:
 862                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 863                 // IMPLIED
 864                 xPLA();
 865                 break;
 866              case 0x69:
 867                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 868                 xIMMEDIATE();
 869                 xADC();
 870                 break;
 871              case 0x6A:
 872                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 873                 // IMPLIED
 874                 xRORA();
 875                 break;
 876              case 0x6B:
 877                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 878                 // *** ILLEGAL ***
 879                 xILLEGAL();
 880                 break;
 881              case 0x6C:
 882                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 883                 xINDIRECT_ABSOLUTE();
 884                 xJMP();
 885                 break;
 886              case 0x6D:
 887                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 888                 xABSOLUTE();
 889                 xADC();
 890                 break;
 891              case 0x6E:
 892                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 893                 xABSOLUTE();
 894                 xROR();
 895                 break;
 896              case 0x6F:
 897                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 898                 // *** ILLEGAL ***
 899                 xILLEGAL();
 900                 break;
 901  
 902                 //
 903                 // 0x70
 904                 //
 905              case 0x70:
 906                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 907                 // RELATIVE (IN FUNCTION)
 908                 xBVS();
 909                 break;
 910              case 0x71:
 911                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 912                 xINDIRECT_Y();
 913                 xADC();
 914                 break;
 915              case 0x72:
 916                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 917                 xINDIRECT();
 918                 xADC();
 919                 break;
 920              case 0x73:
 921                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 922                 // *** ILLEGAL ***
 923                 xILLEGAL();
 924                 break;
 925              case 0x74:
 926                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 927                 xZEROPAGE_X();
 928                 xSTZ();
 929                 break;
 930              case 0x75:
 931                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 932                 xZEROPAGE_X();
 933                 xADC();
 934                 break;
 935              case 0x76:
 936                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 937                 xZEROPAGE_X();
 938                 xROR();
 939                 break;
 940              case 0x77:
 941                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 942                 // *** ILLEGAL ***
 943                 xILLEGAL();
 944                 break;
 945  
 946              case 0x78:
 947                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 948                 // IMPLIED
 949                 xSEI();
 950                 break;
 951              case 0x79:
 952                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 953                 xABSOLUTE_Y();
 954                 xADC();
 955                 break;
 956              case 0x7A:
 957                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 958                 // IMPLIED
 959                 xPLY();
 960                 break;
 961              case 0x7B:
 962                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
 963                 // *** ILLEGAL ***
 964                 xILLEGAL();
 965                 break;
 966              case 0x7C:
 967                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 968                 xINDIRECT_ABSOLUTE_X();
 969                 xJMP();
 970                 break;
 971              case 0x7D:
 972                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
 973                 xABSOLUTE_X();
 974                 xADC();
 975                 break;
 976              case 0x7E:
 977                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
 978                 xABSOLUTE_X();
 979                 xROR();
 980                 break;
 981              case 0x7F:
 982                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
 983                 // *** ILLEGAL ***
 984                 xILLEGAL();
 985                 break;
 986  
 987                 //
 988                 // 0x80
 989                 //
 990              case 0x80:
 991                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
 992                 // RELATIVE (IN FUNCTION)
 993                 xBRA();
 994                 break;
 995              case 0x81:
 996                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
 997                 xINDIRECT_X();
 998                 xSTA();
 999                 break;
1000              case 0x82:
1001                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1002                 // *** ILLEGAL ***
1003                 xILLEGAL();
1004                 break;
1005              case 0x83:
1006                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1007                 // *** ILLEGAL ***
1008                 xILLEGAL();
1009                 break;
1010              case 0x84:
1011                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1012                 xZEROPAGE();
1013                 xSTY();
1014                 break;
1015              case 0x85:
1016                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1017                 xZEROPAGE();
1018                 xSTA();
1019                 break;
1020              case 0x86:
1021                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1022                 xZEROPAGE();
1023                 xSTX();
1024                 break;
1025              case 0x87:
1026                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1027                 // *** ILLEGAL ***
1028                 xILLEGAL();
1029                 break;
1030  
1031              case 0x88:
1032                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1033                 // IMPLIED
1034                 xDEY();
1035                 break;
1036              case 0x89:
1037                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1038                 xIMMEDIATE();
1039                 xBIT();
1040                 break;
1041              case 0x8A:
1042                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1043                 // IMPLIED
1044                 xTXA();
1045                 break;
1046              case 0x8B:
1047                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1048                 // *** ILLEGAL ***
1049                 xILLEGAL();
1050                 break;
1051              case 0x8C:
1052                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1053                 xABSOLUTE();
1054                 xSTY();
1055                 break;
1056              case 0x8D:
1057                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1058                 xABSOLUTE();
1059                 xSTA();
1060                 break;
1061              case 0x8E:
1062                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1063                 xABSOLUTE();
1064                 xSTX();
1065                 break;
1066              case 0x8F:
1067                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1068                 // *** ILLEGAL ***
1069                 xILLEGAL();
1070                 break;
1071  
1072                 //
1073                 // 0x90
1074                 //
1075              case 0x90:
1076                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1077                 // RELATIVE (IN FUNCTION)
1078                 xBCC();
1079                 break;
1080              case 0x91:
1081                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1082                 xINDIRECT_Y();
1083                 xSTA();
1084                 break;
1085              case 0x92:
1086                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1087                 xINDIRECT();
1088                 xSTA();
1089                 break;
1090              case 0x93:
1091                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1092                 // *** ILLEGAL ***
1093                 xILLEGAL();
1094                 break;
1095              case 0x94:
1096                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1097                 xZEROPAGE_X();
1098                 xSTY();
1099                 break;
1100              case 0x95:
1101                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1102                 xZEROPAGE_X();
1103                 xSTA();
1104                 break;
1105              case 0x96:
1106                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1107                 xZEROPAGE_Y();
1108                 xSTX();
1109                 break;
1110              case 0x97:
1111                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1112                 // *** ILLEGAL ***
1113                 xILLEGAL();
1114                 break;
1115  
1116              case 0x98:
1117                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1118                 // IMPLIED
1119                 xTYA();
1120                 break;
1121              case 0x99:
1122                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1123                 xABSOLUTE_Y();
1124                 xSTA();
1125                 break;
1126              case 0x9A:
1127                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1128                 // IMPLIED
1129                 xTXS();
1130                 break;
1131              case 0x9B:
1132                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1133                 // *** ILLEGAL ***
1134                 xILLEGAL();
1135                 break;
1136              case 0x9C:
1137                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1138                 xABSOLUTE();
1139                 xSTZ();
1140                 break;
1141              case 0x9D:
1142                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1143                 xABSOLUTE_X();
1144                 xSTA();
1145                 break;
1146              case 0x9E:
1147                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1148                 xABSOLUTE_X();
1149                 xSTZ();
1150                 break;
1151              case 0x9F:
1152                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1153                 // *** ILLEGAL ***
1154                 xILLEGAL();
1155                 break;
1156  
1157                 //
1158                 // 0xA0
1159                 //
1160              case 0xA0:
1161                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1162                 xIMMEDIATE();
1163                 xLDY();
1164                 break;
1165              case 0xA1:
1166                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1167                 xINDIRECT_X();
1168                 xLDA();
1169                 break;
1170              case 0xA2:
1171                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1172                 xIMMEDIATE();
1173                 xLDX();
1174                 break;
1175              case 0xA3:
1176                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1177                 // *** ILLEGAL ***
1178                 xILLEGAL();
1179                 break;
1180              case 0xA4:
1181                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1182                 xZEROPAGE();
1183                 xLDY();
1184                 break;
1185              case 0xA5:
1186                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1187                 xZEROPAGE();
1188                 xLDA();
1189                 break;
1190              case 0xA6:
1191                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1192                 xZEROPAGE();
1193                 xLDX();
1194                 break;
1195              case 0xA7:
1196                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1197                 // *** ILLEGAL ***
1198                 xILLEGAL();
1199                 break;
1200  
1201              case 0xA8:
1202                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1203                 // IMPLIED
1204                 xTAY();
1205                 break;
1206              case 0xA9:
1207                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1208                 xIMMEDIATE();
1209                 xLDA();
1210                 break;
1211              case 0xAA:
1212                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1213                 // IMPLIED
1214                 xTAX();
1215                 break;
1216              case 0xAB:
1217                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1218                 // *** ILLEGAL ***
1219                 xILLEGAL();
1220                 break;
1221              case 0xAC:
1222                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1223                 xABSOLUTE();
1224                 xLDY();
1225                 break;
1226              case 0xAD:
1227                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1228                 xABSOLUTE();
1229                 xLDA();
1230                 break;
1231              case 0xAE:
1232                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1233                 xABSOLUTE();
1234                 xLDX();
1235                 break;
1236              case 0xAF:
1237                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1238                 // *** ILLEGAL ***
1239                 xILLEGAL();
1240                 break;
1241  
1242                 //
1243                 // 0xB0
1244                 //
1245              case 0xB0:
1246                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1247                 // RELATIVE (IN FUNCTION)
1248                 xBCS();
1249                 break;
1250              case 0xB1:
1251                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1252                 xINDIRECT_Y();
1253                 xLDA();
1254                 break;
1255              case 0xB2:
1256                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1257                 xINDIRECT();
1258                 xLDA();
1259                 break;
1260              case 0xB3:
1261                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1262                 // *** ILLEGAL ***
1263                 xILLEGAL();
1264                 break;
1265              case 0xB4:
1266                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1267                 xZEROPAGE_X();
1268                 xLDY();
1269                 break;
1270              case 0xB5:
1271                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1272                 xZEROPAGE_X();
1273                 xLDA();
1274                 break;
1275              case 0xB6:
1276                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1277                 xZEROPAGE_Y();
1278                 xLDX();
1279                 break;
1280              case 0xB7:
1281                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1282                 // *** ILLEGAL ***
1283                 xILLEGAL();
1284                 break;
1285  
1286              case 0xB8:
1287                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1288                 // IMPLIED
1289                 xCLV();
1290                 break;
1291              case 0xB9:
1292                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1293                 xABSOLUTE_Y();
1294                 xLDA();
1295                 break;
1296              case 0xBA:
1297                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1298                 // IMPLIED
1299                 xTSX();
1300                 break;
1301              case 0xBB:
1302                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1303                 // *** ILLEGAL ***
1304                 xILLEGAL();
1305                 break;
1306              case 0xBC:
1307                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1308                 xABSOLUTE_X();
1309                 xLDY();
1310                 break;
1311              case 0xBD:
1312                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1313                 xABSOLUTE_X();
1314                 xLDA();
1315                 break;
1316              case 0xBE:
1317                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1318                 xABSOLUTE_Y();
1319                 xLDX();
1320                 break;
1321              case 0xBF:
1322                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1323                 // *** ILLEGAL ***
1324                 xILLEGAL();
1325                 break;
1326  
1327                 //
1328                 // 0xC0
1329                 //
1330              case 0xC0:
1331                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1332                 xIMMEDIATE();
1333                 xCPY();
1334                 break;
1335              case 0xC1:
1336                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1337                 xINDIRECT_X();
1338                 xCMP();
1339                 break;
1340              case 0xC2:
1341                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1342                 // *** ILLEGAL ***
1343                 xILLEGAL();
1344                 break;
1345              case 0xC3:
1346                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1347                 // *** ILLEGAL ***
1348                 xILLEGAL();
1349                 break;
1350              case 0xC4:
1351                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1352                 xZEROPAGE();
1353                 xCPY();
1354                 break;
1355              case 0xC5:
1356                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1357                 xZEROPAGE();
1358                 xCMP();
1359                 break;
1360              case 0xC6:
1361                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1362                 xZEROPAGE();
1363                 xDEC();
1364                 break;
1365              case 0xC7:
1366                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1367                 // *** ILLEGAL ***
1368                 xILLEGAL();
1369                 break;
1370  
1371              case 0xC8:
1372                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1373                 // IMPLIED
1374                 xINY();
1375                 break;
1376              case 0xC9:
1377                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1378                 xIMMEDIATE();
1379                 xCMP();
1380                 break;
1381              case 0xCA:
1382                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1383                 // IMPLIED
1384                 xDEX();
1385                 break;
1386              case 0xCB:
1387                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1388                 // IMPLIED
1389                 xWAI();
1390                 break;
1391              case 0xCC:
1392                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1393                 xABSOLUTE();
1394                 xCPY();
1395                 break;
1396              case 0xCD:
1397                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1398                 xABSOLUTE();
1399                 xCMP();
1400                 break;
1401              case 0xCE:
1402                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1403                 xABSOLUTE();
1404                 xDEC();
1405                 break;
1406              case 0xCF:
1407                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1408                 // *** ILLEGAL ***
1409                 xILLEGAL();
1410                 break;
1411  
1412                 //
1413                 // 0xD0
1414                 //
1415              case 0xD0:
1416                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1417                 // RELATIVE (IN FUNCTION)
1418                 xBNE();
1419                 break;
1420              case 0xD1:
1421                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1422                 xINDIRECT_Y();
1423                 xCMP();
1424                 break;
1425              case 0xD2:
1426                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1427                 xINDIRECT();
1428                 xCMP();
1429                 break;
1430              case 0xD3:
1431                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1432                 // *** ILLEGAL ***
1433                 xILLEGAL();
1434                 break;
1435              case 0xD4:
1436                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1437                 // *** ILLEGAL ***
1438                 xILLEGAL();
1439                 break;
1440              case 0xD5:
1441                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1442                 xZEROPAGE_X();
1443                 xCMP();
1444                 break;
1445              case 0xD6:
1446                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1447                 xZEROPAGE_X();
1448                 xDEC();
1449                 break;
1450              case 0xD7:
1451                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1452                 // *** ILLEGAL ***
1453                 xILLEGAL();
1454                 break;
1455  
1456              case 0xD8:
1457                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1458                 // IMPLIED
1459                 xCLD();
1460                 break;
1461              case 0xD9:
1462                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1463                 xABSOLUTE_Y();
1464                 xCMP();
1465                 break;
1466              case 0xDA:
1467                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1468                 // IMPLIED
1469                 xPHX();
1470                 break;
1471              case 0xDB:
1472                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1473                 // IMPLIED
1474                 xSTP();
1475                 break;
1476              case 0xDC:
1477                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1478                 // *** ILLEGAL ***
1479                 xILLEGAL();
1480                 break;
1481              case 0xDD:
1482                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1483                 xABSOLUTE_X();
1484                 xCMP();
1485                 break;
1486              case 0xDE:
1487                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
1488                 xABSOLUTE_X();
1489                 xDEC();
1490                 break;
1491              case 0xDF:
1492                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1493                 // *** ILLEGAL ***
1494                 xILLEGAL();
1495                 break;
1496  
1497                 //
1498                 // 0xE0
1499                 //
1500              case 0xE0:
1501                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1502                 xIMMEDIATE();
1503                 xCPX();
1504                 break;
1505              case 0xE1:
1506                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1507                 xINDIRECT_X();
1508                 xSBC();
1509                 break;
1510              case 0xE2:
1511                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1512                 // *** ILLEGAL ***
1513                 xILLEGAL();
1514                 break;
1515              case 0xE3:
1516                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1517                 // *** ILLEGAL ***
1518                 xILLEGAL();
1519                 break;
1520              case 0xE4:
1521                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1522                 xZEROPAGE();
1523                 xCPX();
1524                 break;
1525              case 0xE5:
1526                 gSystemCycleCount+=(1+(2*CPU_RDWR_CYC));
1527                 xZEROPAGE();
1528                 xSBC();
1529                 break;
1530              case 0xE6:
1531                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1532                 xZEROPAGE();
1533                 xINC();
1534                 break;
1535              case 0xE7:
1536                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1537                 // *** ILLEGAL ***
1538                 xILLEGAL();
1539                 break;
1540  
1541              case 0xE8:
1542                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1543                 // IMPLIED
1544                 xINX();
1545                 break;
1546              case 0xE9:
1547                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1548                 xIMMEDIATE();
1549                 xSBC();
1550                 break;
1551              case 0xEA:
1552                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1553                 // IMPLIED
1554                 xNOP();
1555                 break;
1556              case 0xEB:
1557                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1558                 // *** ILLEGAL ***
1559                 xILLEGAL();
1560                 break;
1561              case 0xEC:
1562                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1563                 xABSOLUTE();
1564                 xCPX();
1565                 break;
1566              case 0xED:
1567                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1568                 xABSOLUTE();
1569                 xSBC();
1570                 break;
1571              case 0xEE:
1572                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1573                 xABSOLUTE();
1574                 xINC();
1575                 break;
1576              case 0xEF:
1577                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1578                 // *** ILLEGAL ***
1579                 xILLEGAL();
1580                 break;
1581  
1582                 //
1583                 // 0xF0
1584                 //
1585              case 0xF0:
1586                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1587                 // RELATIVE (IN FUNCTION)
1588                 xBEQ();
1589                 break;
1590              case 0xF1:
1591                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1592                 xINDIRECT_Y();
1593                 xSBC();
1594                 break;
1595              case 0xF2:
1596                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1597                 xINDIRECT();
1598                 xSBC();
1599                 break;
1600              case 0xF3:
1601                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1602                 // *** ILLEGAL ***
1603                 xILLEGAL();
1604                 break;
1605              case 0xF4:
1606                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1607                 // *** ILLEGAL ***
1608                 xILLEGAL();
1609                 break;
1610              case 0xF5:
1611                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1612                 xZEROPAGE_X();
1613                 xSBC();
1614                 break;
1615              case 0xF6:
1616                 gSystemCycleCount+=(1+(5*CPU_RDWR_CYC));
1617                 xZEROPAGE_X();
1618                 xINC();
1619                 break;
1620              case 0xF7:
1621                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1622                 // *** ILLEGAL ***
1623                 xILLEGAL();
1624                 break;
1625  
1626              case 0xF8:
1627                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1628                 // IMPLIED
1629                 xSED();
1630                 break;
1631              case 0xF9:
1632                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1633                 xABSOLUTE_Y();
1634                 xSBC();
1635                 break;
1636              case 0xFA:
1637                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1638                 // IMPLIED
1639                 xPLX();
1640                 break;
1641              case 0xFB:
1642                 gSystemCycleCount+=(1+(1*CPU_RDWR_CYC));
1643                 // *** ILLEGAL ***
1644                 xILLEGAL();
1645                 break;
1646              case 0xFC:
1647                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1648                 // *** ILLEGAL ***
1649                 xILLEGAL();
1650                 break;
1651              case 0xFD:
1652                 gSystemCycleCount+=(1+(3*CPU_RDWR_CYC));
1653                 xABSOLUTE_X();
1654                 xSBC();
1655                 break;
1656              case 0xFE:
1657                 gSystemCycleCount+=(1+(6*CPU_RDWR_CYC));
1658                 xABSOLUTE_X();
1659                 xINC();
1660                 break;
1661              case 0xFF:
1662                 gSystemCycleCount+=(1+(4*CPU_RDWR_CYC));
1663                 // *** ILLEGAL ***
1664                 xILLEGAL();
1665                 break;
1666           }
1667  
1668  #ifdef _LYNXDBG
1669  
1670           // Trigger breakpoint if required
1671  
1672           for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++)
1673           {
1674              if(mPcBreakpoints[loop]==mPC)
1675              {
1676                 gBreakpointHit=TRUE;
1677                 mSystem.DebugTrace(0);
1678              }
1679           }
1680  
1681           // Check code level debug features
1682           // back to back CPX ($Absolute)
1683           // on the 2nd Occurance we do some debug
1684           if(mOpcode==0xec)
1685           {
1686              if(mDbgFlag)
1687              {
1688                 // We shoud do some debug now
1689                 if(!mOperand)
1690                 {
1691                    // Trigger a breakpoint
1692                    gBreakpointHit=TRUE;
1693                    // Generate a debug trail output
1694                    mSystem.DebugTrace(0);
1695                 }
1696                 else
1697                 {
1698                    // Generate a debug trail output
1699                    mSystem.DebugTrace(mOperand);
1700                 }
1701                 mDbgFlag=0;
1702              }
1703              else
1704              {
1705                 if(mOperand==0x5aa5) mDbgFlag=1; else mDbgFlag=0;
1706              }
1707           }
1708           else
1709           {
1710              mDbgFlag=0;
1711           }
1712  #endif
1713        }
1714  
1715        //		inline void SetBreakpoint(ULONG breakpoint) {mPcBreakpoint=breakpoint;};
1716  
1717        inline void SetRegs(C6502_REGS &regs)
1718        {
1719           PS(regs.PS);
1720           mA=regs.A;
1721           mX=regs.X;
1722           mY=regs.Y;
1723           mSP=regs.SP;
1724           mOpcode=regs.Opcode;
1725           mOperand=regs.Operand;
1726           mPC=regs.PC;
1727           gSystemCPUSleep=regs.WAIT;
1728  #ifdef _LYNXDBG
1729           for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++)	mPcBreakpoints[loop]=regs.cpuBreakpoints[loop];
1730  #endif
1731           gSystemNMI=regs.NMI;
1732           gSystemIRQ=regs.IRQ;
1733        }
1734  
1735        inline void GetRegs(C6502_REGS &regs)
1736        {
1737           regs.PS=PS();
1738           regs.A=mA;
1739           regs.X=mX;
1740           regs.Y=mY;
1741           regs.SP=mSP;
1742           regs.Opcode=mOpcode;
1743           regs.Operand=mOperand;
1744           regs.PC=mPC;
1745           regs.WAIT=(gSystemCPUSleep)?true:false;
1746  #ifdef _LYNXDBG
1747           for(int loop=0;loop<MAX_CPU_BREAKPOINTS;loop++)	regs.cpuBreakpoints[loop]=mPcBreakpoints[loop];
1748  #endif
1749           regs.NMI=(gSystemNMI)?true:false;
1750           regs.IRQ=(gSystemIRQ)?true:false;
1751        }
1752  
1753        inline int GetPC(void) { return mPC; }
1754  
1755        inline void xILLEGAL(void)
1756        {
1757           log_printf("CPU: Illegal opcode $%02x at PC=$%04x.\n", mOpcode, mPC);
1758        }
1759  
1760     private:
1761        CSystemBase	&mSystem;
1762  
1763        // CPU Flags & status
1764  
1765        int mA;		// Accumulator                 8 bits
1766        int mX;		// X index register            8 bits
1767        int mY;		// Y index register            8 bits
1768        int mSP;		// Stack Pointer               8 bits
1769        int mOpcode;  // Instruction opcode          8 bits
1770        int mOperand; // Intructions operand		  16 bits
1771        int mPC;		// Program Counter            16 bits
1772  
1773        int mN;		// N flag for processor status register
1774        int mV;		// V flag for processor status register
1775        int mB;		// B flag for processor status register
1776        int mD;		// D flag for processor status register
1777        int mI;		// I flag for processor status register
1778        int mZ;		// Z flag for processor status register
1779        int mC;		// C flag for processor status register
1780  
1781        int mIRQActive;
1782  
1783  #ifdef _LYNXDBG
1784        int mPcBreakpoints[MAX_CPU_BREAKPOINTS];
1785        int mDbgFlag;
1786  #endif
1787        UBYTE *mRamPointer;
1788  
1789        // Associated lookup tables
1790  
1791        // int mBCDTable[2][256];
1792  
1793        //
1794        // Opcode prototypes
1795        //
1796  
1797     private:
1798  
1799        // Answers value of the Processor Status register
1800        int PS() const
1801        {
1802           UBYTE ps = 0x20;
1803           if(mN) ps|=0x80;
1804           if(mV) ps|=0x40;
1805           if(mB) ps|=0x10;
1806           if(mD) ps|=0x08;
1807           if(mI) ps|=0x04;
1808           if(mZ) ps|=0x02;
1809           if(mC) ps|=0x01;
1810           return ps;
1811        }
1812  
1813  
1814        // Change the processor flags to correspond to the given value
1815        void PS(int ps)
1816        {
1817           mN=ps&0x80;
1818           mV=ps&0x40;
1819           mB=ps&0x10;
1820           mD=ps&0x08;
1821           mI=ps&0x04;
1822           mZ=ps&0x02;
1823           mC=ps&0x01;
1824        }
1825  
1826  };
1827  
1828  
1829  #endif
1830