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