1 /* 2 * cpu_opcodes.h - 6510 CPU emulation opcode routines 3 * 4 * Frodo (C) Copyright 1994-2004 Christian Bauer 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 22 /* 23 * Routines for documented opcodes 24 */ 25 26 // Load group 27 case 0xa9: // LDA #imm 28 read_byte_imm(RA); 29 set_nz(RA); 30 break; 31 32 case 0xa5: // LDA zero 33 read_byte_zero(RA); 34 set_nz(RA); 35 break; 36 37 case 0xb5: // LDA zero,X 38 read_byte_zero_x(RA); 39 set_nz(RA); 40 break; 41 42 case 0xad: // LDA abs 43 read_byte_abs(RA); 44 set_nz(RA); 45 break; 46 47 case 0xbd: // LDA abs,X 48 read_byte_abs_x(RA); 49 set_nz(RA); 50 break; 51 52 case 0xb9: // LDA abs,Y 53 read_byte_abs_y(RA); 54 set_nz(RA); 55 break; 56 57 case 0xa1: // LDA (ind,X) 58 read_byte_ind_x(RA); 59 set_nz(RA); 60 break; 61 62 case 0xb1: // LDA (ind),Y 63 read_byte_ind_y(RA); 64 set_nz(RA); 65 break; 66 67 case 0xa2: // LDX #imm 68 read_byte_imm(RX); 69 set_nz(RX); 70 break; 71 72 case 0xa6: // LDX zero 73 read_byte_zero(RX); 74 set_nz(RX); 75 break; 76 77 case 0xb6: // LDX zero,Y 78 read_byte_zero_y(RX); 79 set_nz(RX); 80 break; 81 82 case 0xae: // LDX abs 83 read_byte_abs(RX); 84 set_nz(RX); 85 break; 86 87 case 0xbe: // LDX abs,Y 88 read_byte_abs_y(RX); 89 set_nz(RX); 90 break; 91 92 case 0xa0: // LDY #imm 93 read_byte_imm(RY); 94 set_nz(RY); 95 break; 96 97 case 0xa4: // LDY zero 98 read_byte_zero(RY); 99 set_nz(RY); 100 break; 101 102 case 0xb4: // LDY zero,X 103 read_byte_zero_x(RY); 104 set_nz(RY); 105 break; 106 107 case 0xac: // LDY abs 108 read_byte_abs(RY); 109 set_nz(RY); 110 break; 111 112 case 0xbc: // LDY abs,X 113 read_byte_abs_x(RY); 114 set_nz(RY); 115 break; 116 117 118 // Store group 119 case 0x85: // STA zero 120 read_adr_zero; 121 write_zp(ADR, RA); next_cycle; 122 break; 123 124 case 0x95: // STA zero,X 125 read_adr_zero_x; 126 write_zp(ADR, RA); next_cycle; 127 break; 128 129 case 0x8d: // STA abs 130 read_adr_abs; 131 write_byte(ADR, RA); next_cycle; 132 break; 133 134 case 0x9d: // STA abs,X 135 read_adr_abs_x; 136 write_byte(ADR, RA); next_cycle; 137 break; 138 139 case 0x99: // STA abs,Y 140 read_adr_abs_y; 141 write_byte(ADR, RA); next_cycle; 142 break; 143 144 case 0x81: // STA (ind,X) 145 read_adr_ind_x; 146 write_byte(ADR, RA); next_cycle; 147 break; 148 149 case 0x91: // STA (ind),Y 150 read_adr_ind_y; 151 write_byte(ADR, RA); next_cycle; 152 break; 153 154 case 0x86: // STX zero 155 read_adr_zero; 156 write_zp(ADR, RX); next_cycle; 157 break; 158 159 case 0x96: // STX zero,Y 160 read_adr_zero_y; 161 write_zp(ADR, RX); next_cycle; 162 break; 163 164 case 0x8e: // STX abs 165 read_adr_abs; 166 write_byte(ADR, RX); next_cycle; 167 break; 168 169 case 0x84: // STY zero 170 read_adr_zero; 171 write_zp(ADR, RY); next_cycle; 172 break; 173 174 case 0x94: // STY zero,X 175 read_adr_zero_x; 176 write_zp(ADR, RY); next_cycle; 177 break; 178 179 case 0x8c: // STY abs 180 read_adr_abs; 181 write_byte(ADR, RY); next_cycle; 182 break; 183 184 185 // Transfer group 186 case 0xaa: // TAX 187 set_nz(RX = RA); 188 read_idle_opcode; next_cycle; 189 break; 190 191 case 0x8a: // TXA 192 set_nz(RA = RX); 193 read_idle_opcode; next_cycle; 194 break; 195 196 case 0xa8: // TAY 197 set_nz(RY = RA); 198 read_idle_opcode; next_cycle; 199 break; 200 201 case 0x98: // TYA 202 set_nz(RA = RY); 203 read_idle_opcode; next_cycle; 204 break; 205 206 case 0xba: // TSX 207 set_nz(RX = RSP); 208 read_idle_opcode; next_cycle; 209 break; 210 211 case 0x9a: // TXS 212 RSP = RX; 213 read_idle_opcode; next_cycle; 214 break; 215 216 217 // Arithmetic group 218 case 0x69: {// ADC #imm 219 uint8 t; 220 read_byte_imm(t); 221 do_adc(t); 222 } 223 case 0x65: {// ADC zero 224 uint8 t; 225 read_byte_zero(t); 226 do_adc(t); 227 } 228 case 0x75: {// ADC zero,X 229 uint8 t; 230 read_byte_zero_x(t); 231 do_adc(t); 232 } 233 case 0x6d: {// ADC abs 234 uint8 t; 235 read_byte_abs(t); 236 do_adc(t); 237 } 238 case 0x7d: {// ADC abs,X 239 uint8 t; 240 read_byte_abs_x(t); 241 do_adc(t); 242 } 243 case 0x79: {// ADC abs,Y 244 uint8 t; 245 read_byte_abs_y(t); 246 do_adc(t); 247 } 248 case 0x61: {// ADC (ind,X) 249 uint8 t; 250 read_byte_ind_x(t); 251 do_adc(t); 252 } 253 case 0x71: {// ADC (ind),Y 254 uint8 t; 255 read_byte_ind_y(t); 256 do_adc(t); 257 } 258 case 0xe9: // SBC #imm 259 case 0xeb: {// Undocumented opcode 260 uint8 t; 261 read_byte_imm(t); 262 do_sbc(t); 263 } 264 case 0xe5: {// SBC zero 265 uint8 t; 266 read_byte_zero(t); 267 do_sbc(t); 268 } 269 case 0xf5: {// SBC zero,X 270 uint8 t; 271 read_byte_zero_x(t); 272 do_sbc(t); 273 } 274 case 0xed: {// SBC abs 275 uint8 t; 276 read_byte_abs(t); 277 do_sbc(t); 278 } 279 case 0xfd: {// SBC abs,X 280 uint8 t; 281 read_byte_abs_x(t); 282 do_sbc(t); 283 } 284 case 0xf9: {// SBC abs,Y 285 uint8 t; 286 read_byte_abs_y(t); 287 do_sbc(t); 288 } 289 case 0xe1: {// SBC (ind,X) 290 uint8 t; 291 read_byte_ind_x(t); 292 do_sbc(t); 293 } 294 case 0xf1: {// SBC (ind),Y 295 uint8 t; 296 read_byte_ind_y(t); 297 do_sbc(t); 298 } 299 300 301 // Increment/decrement group 302 case 0xe8: // INX 303 set_nz(++RX); 304 read_idle_opcode; next_cycle; 305 break; 306 307 case 0xca: // DEX 308 set_nz(--RX); 309 read_idle_opcode; next_cycle; 310 break; 311 312 case 0xc8: // INY 313 set_nz(++RY); 314 read_idle_opcode; next_cycle; 315 break; 316 317 case 0x88: // DEY 318 set_nz(--RY); 319 read_idle_opcode; next_cycle; 320 break; 321 322 case 0xe6: {// INC zero 323 unsigned int t; 324 read_byte_zero(t); 325 next_cycle; write_zp(ADR, set_nz(t + 1)); next_cycle; 326 break; 327 } 328 case 0xf6: {// INC zero,X 329 unsigned int t; 330 read_byte_zero_x(t); 331 next_cycle; write_zp(ADR, set_nz(t + 1)); next_cycle; 332 break; 333 } 334 case 0xee: {// INC abs 335 unsigned int t; 336 read_byte_abs(t); 337 next_cycle; write_byte_rmw(ADR, set_nz(t + 1)); next_cycle; 338 break; 339 } 340 case 0xfe: {// INC abs,X 341 read_adr_abs_x; 342 unsigned int t = read_byte(ADR); next_cycle; 343 next_cycle; write_byte_rmw(ADR, set_nz(t + 1)); next_cycle; 344 break; 345 } 346 case 0xc6: {// DEC zero 347 unsigned int t; 348 read_byte_zero(t); 349 next_cycle; write_zp(ADR, set_nz(t - 1)); next_cycle; 350 break; 351 } 352 case 0xd6: {// DEC zero,X 353 unsigned int t; 354 read_byte_zero_x(t); 355 next_cycle; write_zp(ADR, set_nz(t - 1)); next_cycle; 356 break; 357 } 358 case 0xce: {// DEC abs 359 unsigned int t; 360 read_byte_abs(t); 361 next_cycle; write_byte_rmw(ADR, set_nz(t - 1)); next_cycle; 362 break; 363 } 364 case 0xde: {// DEC abs,X 365 read_adr_abs_x; 366 unsigned int t = read_byte(ADR); next_cycle; 367 next_cycle; write_byte_rmw(ADR, set_nz(t - 1)); next_cycle; 368 break; 369 } 370 371 372 // Logic group 373 case 0x29: {// AND #imm 374 uint8 t; 375 read_byte_imm(t); 376 set_nz(RA &= t); 377 break; 378 } 379 case 0x25: {// AND zero 380 uint8 t; 381 read_byte_zero(t); 382 set_nz(RA &= t); 383 break; 384 } 385 case 0x35: {// AND zero,X 386 uint8 t; 387 read_byte_zero_x(t); 388 set_nz(RA &= t); 389 break; 390 } 391 case 0x2d: {// AND abs 392 uint8 t; 393 read_byte_abs(t); 394 set_nz(RA &= t); 395 break; 396 } 397 case 0x3d: {// AND abs,X 398 uint8 t; 399 read_byte_abs_x(t); 400 set_nz(RA &= t); 401 break; 402 } 403 case 0x39: {// AND abs,Y 404 uint8 t; 405 read_byte_abs_y(t); 406 set_nz(RA &= t); 407 break; 408 } 409 case 0x21: {// AND (ind,X) 410 uint8 t; 411 read_byte_ind_x(t); 412 set_nz(RA &= t); 413 break; 414 } 415 case 0x31: {// AND (ind),Y 416 uint8 t; 417 read_byte_ind_y(t); 418 set_nz(RA &= t); 419 break; 420 } 421 case 0x09: {// ORA #imm 422 uint8 t; 423 read_byte_imm(t); 424 set_nz(RA |= t); 425 break; 426 } 427 case 0x05: {// ORA zero 428 uint8 t; 429 read_byte_zero(t); 430 set_nz(RA |= t); 431 break; 432 } 433 case 0x15: {// ORA zero,X 434 uint8 t; 435 read_byte_zero_x(t); 436 set_nz(RA |= t); 437 break; 438 } 439 case 0x0d: {// ORA abs 440 uint8 t; 441 read_byte_abs(t); 442 set_nz(RA |= t); 443 break; 444 } 445 case 0x1d: {// ORA abs,X 446 uint8 t; 447 read_byte_abs_x(t); 448 set_nz(RA |= t); 449 break; 450 } 451 case 0x19: {// ORA abs,Y 452 uint8 t; 453 read_byte_abs_y(t); 454 set_nz(RA |= t); 455 break; 456 } 457 case 0x01: {// ORA (ind,X) 458 uint8 t; 459 read_byte_ind_x(t); 460 set_nz(RA |= t); 461 break; 462 } 463 case 0x11: {// ORA (ind),Y 464 uint8 t; 465 read_byte_ind_y(t); 466 set_nz(RA |= t); 467 break; 468 } 469 case 0x49: {// EOR #imm 470 uint8 t; 471 read_byte_imm(t); 472 set_nz(RA ^= t); 473 break; 474 } 475 case 0x45: {// EOR zero 476 uint8 t; 477 read_byte_zero(t); 478 set_nz(RA ^= t); 479 break; 480 } 481 case 0x55: {// EOR zero,X 482 uint8 t; 483 read_byte_zero_x(t); 484 set_nz(RA ^= t); 485 break; 486 } 487 case 0x4d: {// EOR abs 488 uint8 t; 489 read_byte_abs(t); 490 set_nz(RA ^= t); 491 break; 492 } 493 case 0x5d: {// EOR abs,X 494 uint8 t; 495 read_byte_abs_x(t); 496 set_nz(RA ^= t); 497 break; 498 } 499 case 0x59: {// EOR abs,Y 500 uint8 t; 501 read_byte_abs_y(t); 502 set_nz(RA ^= t); 503 break; 504 } 505 case 0x41: {// EOR (ind,X) 506 uint8 t; 507 read_byte_ind_x(t); 508 set_nz(RA ^= t); 509 break; 510 } 511 case 0x51: {// EOR (ind),Y 512 uint8 t; 513 read_byte_ind_y(t); 514 set_nz(RA ^= t); 515 break; 516 } 517 518 519 // Compare group 520 case 0xc9: {// CMP #imm 521 uint8 t; 522 read_byte_imm(t); 523 do_cmp; 524 } 525 case 0xc5: {// CMP zero 526 uint8 t; 527 read_byte_zero(t); 528 do_cmp; 529 } 530 case 0xd5: {// CMP zero,X 531 uint8 t; 532 read_byte_zero_x(t); 533 do_cmp; 534 } 535 case 0xcd: {// CMP abs 536 uint8 t; 537 read_byte_abs(t); 538 do_cmp; 539 } 540 case 0xdd: {// CMP abs,X 541 uint8 t; 542 read_byte_abs_x(t); 543 do_cmp; 544 } 545 case 0xd9: {// CMP abs,Y 546 uint8 t; 547 read_byte_abs_y(t); 548 do_cmp; 549 } 550 case 0xc1: {// CMP (ind,X) 551 uint8 t; 552 read_byte_ind_x(t); 553 do_cmp; 554 } 555 case 0xd1: {// CMP (ind),Y 556 uint8 t; 557 read_byte_ind_y(t); 558 do_cmp; 559 } 560 case 0xe0: {// CPX #imm 561 uint8 t; 562 read_byte_imm(t); 563 do_cpx; 564 } 565 case 0xe4: {// CPX zero 566 uint8 t; 567 read_byte_zero(t); 568 do_cpx; 569 } 570 case 0xec: {// CPX abs 571 uint8 t; 572 read_byte_abs(t); 573 do_cpx; 574 } 575 case 0xc0: {// CPY #imm 576 uint8 t; 577 read_byte_imm(t); 578 do_cpy; 579 } 580 case 0xc4: {// CPY zero 581 uint8 t; 582 read_byte_zero(t); 583 do_cpy; 584 } 585 case 0xcc: {// CPY abs 586 uint8 t; 587 read_byte_abs(t); 588 do_cpy; 589 } 590 591 592 // Bit-test group 593 case 0x24: {// BIT zero 594 uint8 t; 595 read_byte_zero(t); 596 do_bit; 597 } 598 case 0x2c: {// BIT abs 599 uint8 t; 600 read_byte_abs(t); 601 do_bit; 602 } 603 604 605 // Shift/rotate group 606 case 0x0a: // ASL A 607 (RA & 0x80) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 608 set_nz(RA <<= 1); 609 read_idle_opcode; next_cycle; 610 break; 611 612 case 0x06: {// ASL zero 613 unsigned int t; 614 read_byte_zero(t); 615 do_asl(write_zp); 616 } 617 case 0x16: {// ASL zero,X 618 unsigned int t; 619 read_byte_zero_x(t); 620 do_asl(write_zp); 621 } 622 case 0x0e: {// ASL abs 623 unsigned int t; 624 read_byte_abs(t); 625 do_asl(write_byte_rmw); 626 } 627 case 0x1e: {// ASL abs,X 628 read_adr_abs_x; 629 unsigned int t = read_byte(ADR); next_cycle; 630 do_asl(write_byte_rmw); 631 } 632 case 0x4a: // LSR A 633 (RA & 0x01) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 634 set_nz(RA >>= 1); 635 read_idle_opcode; next_cycle; 636 break; 637 638 case 0x46: {// LSR zero 639 unsigned int t; 640 read_byte_zero(t); 641 do_lsr(write_zp); 642 } 643 case 0x56: {// LSR zero,X 644 unsigned int t; 645 read_byte_zero_x(t); 646 do_lsr(write_zp); 647 } 648 case 0x4e: {// LSR abs 649 unsigned int t; 650 read_byte_abs(t); 651 do_lsr(write_byte_rmw); 652 } 653 case 0x5e: {// LSR abs,X 654 read_adr_abs_x; 655 unsigned int t = read_byte(ADR); next_cycle; 656 do_lsr(write_byte_rmw); 657 } 658 case 0x2a: {// ROL A 659 uint8 t = RA; 660 set_nz(RA = (RA << 1) | (PFLAGS & PFLAG_C)); 661 (t & 0x80) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 662 read_idle_opcode; next_cycle; 663 break; 664 } 665 case 0x26: {// ROL zero 666 unsigned int t; 667 read_byte_zero(t); 668 do_rol(write_zp); 669 } 670 case 0x36: {// ROL zero,X 671 unsigned int t; 672 read_byte_zero_x(t); 673 do_rol(write_zp); 674 } 675 case 0x2e: {// ROL abs 676 unsigned int t; 677 read_byte_abs(t); 678 do_rol(write_byte_rmw); 679 } 680 case 0x3e: {// ROL abs,X 681 read_adr_abs_x; 682 unsigned int t = read_byte(ADR); next_cycle; 683 do_rol(write_byte_rmw); 684 } 685 case 0x6a: {// ROR A 686 uint8 t = RA; 687 set_nz(RA = ((PFLAGS & PFLAG_C) ? ((RA >> 1) | 0x80) : (RA >> 1))); 688 (t & 0x01) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 689 read_idle_opcode; next_cycle; 690 break; 691 } 692 case 0x66: {// ROR zero 693 unsigned int t; 694 read_byte_zero(t); 695 do_ror(write_zp); 696 } 697 case 0x76: {// ROR zero,X 698 unsigned int t; 699 read_byte_zero_x(t); 700 do_ror(write_zp); 701 } 702 case 0x6e: {// ROR abs 703 unsigned int t; 704 read_byte_abs(t); 705 do_ror(write_byte_rmw); 706 } 707 case 0x7e: {// ROR abs,X 708 read_adr_abs_x; 709 unsigned int t = read_byte(ADR); next_cycle; 710 do_ror(write_byte_rmw); 711 } 712 713 714 // Stack group 715 case 0x48: // PHA 716 read_idle_opcode; next_cycle; 717 push_byte(RA); next_cycle; 718 break; 719 720 case 0x68: // PLA 721 read_idle_opcode; next_cycle; 722 read_idle_stack(RSP); next_cycle; 723 set_nz(RA = pop_byte); next_cycle; 724 break; 725 726 case 0x08: // PHP 727 read_idle_opcode; next_cycle; 728 push_flags(PFLAG_B); 729 break; 730 731 case 0x28: {// PLP 732 read_idle_opcode; next_cycle; 733 read_idle_stack(RSP); next_cycle; 734 uint8 old_pflags = PFLAGS; 735 pop_flags; 736 if (!(old_pflags & PFLAG_I) && (PFLAGS & PFLAG_I)) 737 opcode |= OPFLAG_IRQ_DISABLED; 738 else if ((old_pflags & PFLAG_I) && !(PFLAGS & PFLAG_I)) 739 opcode |= OPFLAG_IRQ_ENABLED; 740 break; 741 } 742 743 744 // Jump/branch group 745 case 0x4c: // JMP abs 746 read_adr_abs; 747 jump(ADR); 748 break; 749 750 case 0x6c: {// JMP (ind) 751 read_adr_abs; 752 uint8 t = read_byte(ADR); next_cycle; 753 jump(t | (read_byte((ADR + 1) & 0xff | ADR & 0xff00) << 8)); next_cycle; 754 break; 755 } 756 case 0x20: {// JSR abs 757 uint8 t = read_opcode; inc_pc; next_cycle; 758 read_idle_stack(RSP); next_cycle; 759 push_byte(RPC >> 8); next_cycle; 760 push_byte(RPC); next_cycle; 761 jump(t | (read_opcode << 8)); next_cycle; 762 break; 763 } 764 case 0x60: {// RTS 765 read_idle_opcode; next_cycle; 766 read_idle_stack(RSP); next_cycle; 767 uint8 t = pop_byte; next_cycle; 768 jump(t | (pop_byte << 8)); inc_pc; next_cycle; 769 read_idle_opcode; next_cycle; 770 break; 771 } 772 case 0x40: {// RTI 773 #ifdef SID_PLAYER 774 quit = true; 775 break; 776 #else 777 read_idle_opcode; next_cycle; 778 read_idle_stack(RSP); next_cycle; 779 pop_flags; 780 uint8 t = pop_byte; next_cycle; 781 jump(t | (pop_byte << 8)); next_cycle; 782 break; 783 #endif 784 } 785 case 0x00: {// BRK 786 read_idle_opcode; inc_pc; next_cycle; 787 push_byte(RPC >> 8); next_cycle; 788 push_byte(RPC); next_cycle; 789 push_flags(PFLAG_B); 790 PFLAGS |= PFLAG_I; 791 uint8 t = read_byte(0xfffe); next_cycle; 792 jump(t | (read_byte(0xffff) << 8 )); next_cycle; 793 break; 794 } 795 case 0xb0: // BCS rel 796 branch(PFLAGS & PFLAG_C); 797 798 case 0x90: // BCC rel 799 branch(!(PFLAGS & PFLAG_C)); 800 801 case 0xf0: // BEQ rel 802 branch(!Z_FLAG); 803 804 case 0xd0: // BNE rel 805 branch(Z_FLAG); 806 807 case 0x70: // BVS rel 808 #ifdef DRIVE_CPU 809 gcr_drive->Update(current_cycle); 810 if (gcr_drive->ByteReady()) 811 branch(1) 812 else 813 #endif 814 branch(PFLAGS & PFLAG_V); 815 816 case 0x50: // BVC rel 817 #ifdef DRIVE_CPU 818 gcr_drive->Update(current_cycle); 819 if (gcr_drive->ByteReady()) 820 branch(0) 821 else 822 #endif 823 branch(!(PFLAGS & PFLAG_V)); 824 825 case 0x30: // BMI rel 826 branch(N_FLAG & 0x80); 827 828 case 0x10: // BPL rel 829 branch(!(N_FLAG & 0x80)); 830 831 832 // Flags group 833 case 0x38: // SEC 834 PFLAGS |= PFLAG_C; 835 read_idle_opcode; next_cycle; 836 break; 837 838 case 0x18: // CLC 839 PFLAGS &= ~PFLAG_C; 840 read_idle_opcode; next_cycle; 841 break; 842 843 case 0xf8: // SED 844 PFLAGS |= PFLAG_D; 845 read_idle_opcode; next_cycle; 846 break; 847 848 case 0xd8: // CLD 849 PFLAGS &= ~PFLAG_D; 850 read_idle_opcode; next_cycle; 851 break; 852 853 case 0x78: // SEI 854 if (!(PFLAGS & PFLAG_I)) 855 opcode |= OPFLAG_IRQ_DISABLED; 856 PFLAGS |= PFLAG_I; 857 read_idle_opcode; next_cycle; 858 break; 859 860 case 0x58: // CLI 861 if (PFLAGS & PFLAG_I) 862 opcode |= OPFLAG_IRQ_ENABLED; 863 PFLAGS &= ~PFLAG_I; 864 read_idle_opcode; next_cycle; 865 break; 866 867 case 0xb8: // CLV 868 PFLAGS &= ~PFLAG_V; 869 read_idle_opcode; next_cycle; 870 break; 871 872 873 // NOP group 874 case 0xea: // NOP 875 read_idle_opcode; next_cycle; 876 break; 877 878 879 /* 880 * Routines for undocumented opcodes 881 */ 882 883 // Load A/X group 884 case 0xa7: // LAX zero 885 read_byte_zero(RA); 886 set_nz(RX = RA); 887 break; 888 889 case 0xb7: // LAX zero,Y 890 read_byte_zero_y(RA); 891 set_nz(RX = RA); 892 break; 893 894 case 0xaf: // LAX abs 895 read_byte_abs(RA); 896 set_nz(RX = RA); 897 break; 898 899 case 0xbf: // LAX abs,Y 900 read_byte_abs_y(RA); 901 set_nz(RX = RA); 902 break; 903 904 case 0xa3: // LAX (ind,X) 905 read_byte_ind_x(RA); 906 set_nz(RX = RA); 907 break; 908 909 case 0xb3: // LAX (ind),Y 910 read_byte_ind_y(RA); 911 set_nz(RX = RA); 912 break; 913 914 915 // Store A/X group 916 case 0x87: // SAX zero 917 read_adr_zero; 918 write_zp(ADR, RA & RX); next_cycle; 919 break; 920 921 case 0x97: // SAX zero,Y 922 read_adr_zero_y; 923 write_zp(ADR, RA & RX); next_cycle; 924 break; 925 926 case 0x8f: // SAX abs 927 read_adr_abs; 928 write_byte(ADR, RA & RX); next_cycle; 929 break; 930 931 case 0x83: // SAX (ind,X) 932 read_adr_ind_x; 933 write_byte(ADR, RA & RX); next_cycle; 934 break; 935 936 937 // ASL/ORA group 938 case 0x07: {// SLO zero 939 unsigned int t; 940 read_byte_zero(t); 941 do_slo(write_zp); 942 } 943 case 0x17: {// SLO zero,X 944 unsigned int t; 945 read_byte_zero_x(t); 946 do_slo(write_zp); 947 } 948 case 0x0f: {// SLO abs 949 unsigned int t; 950 read_byte_abs(t); 951 do_slo(write_byte_rmw); 952 } 953 case 0x1f: {// SLO abs,X 954 read_adr_abs_x; 955 unsigned int t = read_byte(ADR); next_cycle; 956 do_slo(write_byte_rmw); 957 } 958 case 0x1b: {// SLO abs,Y 959 read_adr_abs_y; 960 unsigned int t = read_byte(ADR); next_cycle; 961 do_slo(write_byte_rmw); 962 } 963 case 0x03: {// SLO (ind,X) 964 read_adr_ind_x; 965 unsigned int t = read_byte(ADR); next_cycle; 966 do_slo(write_byte_rmw); 967 } 968 case 0x13: {// SLO (ind),Y 969 read_adr_ind_y; 970 unsigned int t = read_byte(ADR); next_cycle; 971 do_slo(write_byte_rmw); 972 } 973 974 975 // ROL/AND group 976 case 0x27: {// RLA zero 977 unsigned int t; 978 read_byte_zero(t); 979 do_rla(write_zp); 980 } 981 case 0x37: {// RLA zero,X 982 unsigned int t; 983 read_byte_zero_x(t); 984 do_rla(write_zp); 985 } 986 case 0x2f: {// RLA abs 987 unsigned int t; 988 read_byte_abs(t); 989 do_rla(write_byte_rmw); 990 } 991 case 0x3f: {// RLA abs,X 992 read_adr_abs_x; 993 unsigned int t = read_byte(ADR); next_cycle; 994 do_rla(write_byte_rmw); 995 } 996 case 0x3b: {// RLA abs,Y 997 read_adr_abs_y; 998 unsigned int t = read_byte(ADR); next_cycle; 999 do_rla(write_byte_rmw); 1000 } 1001 case 0x23: {// RLA (ind,X) 1002 read_adr_ind_x; 1003 unsigned int t = read_byte(ADR); next_cycle; 1004 do_rla(write_byte_rmw); 1005 } 1006 case 0x33: {// RLA (ind),Y 1007 read_adr_ind_y; 1008 unsigned int t = read_byte(ADR); next_cycle; 1009 do_rla(write_byte_rmw); 1010 } 1011 1012 1013 // LSR/EOR group 1014 case 0x47: {// SRE zero 1015 unsigned int t; 1016 read_byte_zero(t); 1017 do_sre(write_zp); 1018 } 1019 case 0x57: {// SRE zero,X 1020 unsigned int t; 1021 read_byte_zero_x(t); 1022 do_sre(write_zp); 1023 } 1024 case 0x4f: {// SRE abs 1025 unsigned int t; 1026 read_byte_abs(t); 1027 do_sre(write_byte_rmw); 1028 } 1029 case 0x5f: {// SRE abs,X 1030 read_adr_abs_x; 1031 unsigned int t = read_byte(ADR); next_cycle; 1032 do_sre(write_byte_rmw); 1033 } 1034 case 0x5b: {// SRE abs,Y 1035 read_adr_abs_y; 1036 unsigned int t = read_byte(ADR); next_cycle; 1037 do_sre(write_byte_rmw); 1038 } 1039 case 0x43: {// SRE (ind,X) 1040 read_adr_ind_x; 1041 unsigned int t = read_byte(ADR); next_cycle; 1042 do_sre(write_byte_rmw); 1043 } 1044 case 0x53: {// SRE (ind),Y 1045 read_adr_ind_y; 1046 unsigned int t = read_byte(ADR); next_cycle; 1047 do_sre(write_byte_rmw); 1048 } 1049 1050 1051 // ROR/ADC group 1052 case 0x67: {// RRA zero 1053 unsigned int t; 1054 read_byte_zero(t); 1055 do_rra(write_zp); 1056 } 1057 case 0x77: {// RRA zero,X 1058 unsigned int t; 1059 read_byte_zero_x(t); 1060 do_rra(write_zp); 1061 } 1062 case 0x6f: {// RRA abs 1063 unsigned int t; 1064 read_byte_abs(t); 1065 do_rra(write_byte_rmw); 1066 } 1067 case 0x7f: {// RRA abs,X 1068 read_adr_abs_x; 1069 unsigned int t = read_byte(ADR); next_cycle; 1070 do_rra(write_byte_rmw); 1071 } 1072 case 0x7b: {// RRA abs,Y 1073 read_adr_abs_y; 1074 unsigned int t = read_byte(ADR); next_cycle; 1075 do_rra(write_byte_rmw); 1076 } 1077 case 0x63: {// RRA (ind,X) 1078 read_adr_ind_x; 1079 unsigned int t = read_byte(ADR); next_cycle; 1080 do_rra(write_byte_rmw); 1081 } 1082 case 0x73: {// RRA (ind),Y 1083 read_adr_ind_y; 1084 unsigned int t = read_byte(ADR); next_cycle; 1085 do_rra(write_byte_rmw); 1086 } 1087 1088 1089 // DEC/CMP group 1090 case 0xc7: {// DCP zero 1091 unsigned int t; 1092 read_byte_zero(t); 1093 do_dcp(write_zp); 1094 } 1095 case 0xd7: {// DCP zero,X 1096 unsigned int t; 1097 read_byte_zero_x(t); 1098 do_dcp(write_zp); 1099 } 1100 case 0xcf: {// DCP abs 1101 unsigned int t; 1102 read_byte_abs(t); 1103 do_dcp(write_byte_rmw); 1104 } 1105 case 0xdf: {// DCP abs,X 1106 read_adr_abs_x; 1107 unsigned int t = read_byte(ADR); next_cycle; 1108 do_dcp(write_byte_rmw); 1109 } 1110 case 0xdb: {// DCP abs,Y 1111 read_adr_abs_y; 1112 unsigned int t = read_byte(ADR); next_cycle; 1113 do_dcp(write_byte_rmw); 1114 } 1115 case 0xc3: {// DCP (ind,X) 1116 read_adr_ind_x; 1117 unsigned int t = read_byte(ADR); next_cycle; 1118 do_dcp(write_byte_rmw); 1119 } 1120 case 0xd3: {// DCP (ind),Y 1121 read_adr_ind_y; 1122 unsigned int t = read_byte(ADR); next_cycle; 1123 do_dcp(write_byte_rmw); 1124 } 1125 1126 1127 // INC/SBC group 1128 case 0xe7: {// ISB zero 1129 unsigned int t; 1130 read_byte_zero(t); 1131 do_isb(write_zp); 1132 } 1133 case 0xf7: {// ISB zero,X 1134 unsigned int t; 1135 read_byte_zero_x(t); 1136 do_isb(write_zp); 1137 } 1138 case 0xef: {// ISB abs 1139 unsigned int t; 1140 read_byte_abs(t); 1141 do_isb(write_byte_rmw); 1142 } 1143 case 0xff: {// ISB abs,X 1144 read_adr_abs_x; 1145 unsigned int t = read_byte(ADR); next_cycle; 1146 do_isb(write_byte_rmw); 1147 } 1148 case 0xfb: {// ISB abs,Y 1149 read_adr_abs_y; 1150 unsigned int t = read_byte(ADR); next_cycle; 1151 do_isb(write_byte_rmw); 1152 } 1153 case 0xe3: {// ISB (ind,X) 1154 read_adr_ind_x; 1155 unsigned int t = read_byte(ADR); next_cycle; 1156 do_isb(write_byte_rmw); 1157 } 1158 case 0xf3: {// ISB (ind),Y 1159 read_adr_ind_y; 1160 unsigned int t = read_byte(ADR); next_cycle; 1161 do_isb(write_byte_rmw); 1162 } 1163 1164 1165 // Complex functions 1166 case 0x0b: // ANC #imm 1167 case 0x2b: { 1168 uint8 t; 1169 read_byte_imm(t); 1170 set_nz(RA &= t); 1171 (N_FLAG & 0x80) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 1172 break; 1173 } 1174 case 0x4b: {// ASR #imm 1175 uint8 t; 1176 read_byte_imm(t); 1177 RA &= t; 1178 (RA & 0x01) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 1179 set_nz(RA >>= 1); 1180 break; 1181 } 1182 case 0x6b: {// ARR #imm 1183 unsigned int t; 1184 read_byte_imm(t); 1185 t &= RA; 1186 RA = ((PFLAGS & PFLAG_C) ? (t >> 1) | 0x80 : (t >> 1)); 1187 if (PFLAGS & PFLAG_D) { 1188 N_FLAG = (PFLAGS & PFLAG_C) << 7; 1189 Z_FLAG = RA; 1190 ((t ^ RA) & 0x40) ? (PFLAGS |= PFLAG_V) : (PFLAGS &= ~PFLAG_V); 1191 if ((t & 0x0f) + (t & 0x01) > 5) 1192 RA = RA & 0xf0 | (RA + 6) & 0x0f; 1193 (((t + (t & 0x10)) & 0x1f0) > 0x50) ? (PFLAGS |= PFLAG_C, RA += 0x60) : (PFLAGS &= ~PFLAG_C); 1194 } else { 1195 set_nz(RA); 1196 (RA & 0x40) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 1197 ((RA & 0x40) ^ ((RA & 0x20) << 1)) ? (PFLAGS |= PFLAG_V) : (PFLAGS &= ~PFLAG_V); 1198 } 1199 break; 1200 } 1201 case 0x8b: {// ANE #imm 1202 uint8 t; 1203 read_byte_imm(t); 1204 set_nz(RA = (RA | 0xee) & RX & t); 1205 break; 1206 } 1207 case 0x93: {// SHA (ind),Y 1208 read_adr_ind_y; 1209 write_byte(ADR, RA & RX & (((ADR - RY) >> 8) + 1)); next_cycle; 1210 break; 1211 } 1212 case 0x9b: {// SHS abs,Y 1213 read_adr_abs_y; 1214 write_byte(ADR, (RSP = RA & RX) & (((ADR - RY) >> 8) + 1)); next_cycle; 1215 break; 1216 } 1217 case 0x9c: {// SHY abs,X 1218 read_adr_abs_x; 1219 write_byte(ADR, RY & (((ADR - RX) >> 8) + 1)); next_cycle; 1220 break; 1221 } 1222 case 0x9e: {// SHX abs,Y 1223 read_adr_abs_y; 1224 write_byte(ADR, RX & (((ADR - RY) >> 8) + 1)); next_cycle; 1225 break; 1226 } 1227 case 0x9f: {// SHA abs,Y 1228 read_adr_abs_y; 1229 write_byte(ADR, RA & RX & (((ADR - RY) >> 8) + 1)); next_cycle; 1230 break; 1231 } 1232 case 0xab: {// LXA #imm 1233 uint8 t; 1234 read_byte_imm(t); 1235 set_nz(RA = RX = (RA | 0xee) & t); 1236 break; 1237 } 1238 case 0xbb: {// LAS abs,Y 1239 uint8 t; 1240 read_byte_abs_y(t); 1241 set_nz(RA = RX = RSP = t & RSP); 1242 break; 1243 } 1244 case 0xcb: {// SBX #imm 1245 unsigned int t; 1246 read_byte_imm(t); 1247 set_nz(RX = t = (RA & RX) - t); 1248 (t < 0x100) ? (PFLAGS |= PFLAG_C) : (PFLAGS &= ~PFLAG_C); 1249 break; 1250 } 1251 1252 1253 // NOP group 1254 case 0x1a: // NOP 1255 case 0x3a: 1256 case 0x5a: 1257 case 0x7a: 1258 case 0xda: 1259 case 0xfa: 1260 read_idle_opcode; next_cycle; 1261 break; 1262 1263 case 0x80: // NOP #imm 1264 case 0x82: 1265 case 0x89: 1266 case 0xc2: 1267 case 0xe2: 1268 read_idle_opcode; inc_pc; next_cycle; 1269 break; 1270 1271 case 0x04: // NOP zero 1272 case 0x44: 1273 case 0x64: 1274 read_adr_zero; 1275 read_idle_zp(ADR); next_cycle; 1276 break; 1277 1278 case 0x14: // NOP zero,X 1279 case 0x34: 1280 case 0x54: 1281 case 0x74: 1282 case 0xd4: 1283 case 0xf4: 1284 read_adr_zero_x; 1285 read_idle_zp(ADR); next_cycle; 1286 break; 1287 1288 case 0x0c: // NOP abs 1289 read_adr_abs; 1290 read_idle(ADR); next_cycle; 1291 break; 1292 1293 case 0x1c: // NOP abs,X 1294 case 0x3c: 1295 case 0x5c: 1296 case 0x7c: 1297 case 0xdc: 1298 case 0xfc: { 1299 uint8 t; 1300 read_byte_abs_x(t); 1301 break; 1302 } 1303 1304 1305 // Jam group 1306 case 0x02: 1307 case 0x12: 1308 case 0x22: 1309 case 0x32: 1310 case 0x42: 1311 case 0x52: 1312 case 0x62: 1313 case 0x72: 1314 case 0x92: 1315 case 0xb2: 1316 case 0xd2: 1317 goto illegal_op; 1318