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 ®s) 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 ®s) 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