9#define loadA(v) { u8 u = (v); reg.a = u; reg.sr.n = u & 0x80; reg.sr.z = u == 0; }
10#define loadX(v) { u8 u = (v); reg.x = u; reg.sr.n = u & 0x80; reg.sr.z = u == 0; }
11#define loadY(v) { u8 u = (v); reg.y = u; reg.sr.n = u & 0x80; reg.sr.z = u == 0; }
15if (likely(rdyLine)) instr = read<C>(reg.pc++); else return;
16#define FETCH_ADDR_LO \
17if (likely(rdyLine)) reg.adl = read<C>(reg.pc++); else return;
18#define FETCH_ADDR_HI \
19if (likely(rdyLine)) reg.adh = read<C>(reg.pc++); else return;
20#define FETCH_POINTER_ADDR \
21if (likely(rdyLine)) reg.idl = read<C>(reg.pc++); else return;
22#define FETCH_ADDR_LO_INDIRECT \
23if (likely(rdyLine)) reg.adl = read<C>((u16)reg.idl++); else return;
24#define FETCH_ADDR_HI_INDIRECT \
25if (likely(rdyLine)) reg.adh = read<C>((u16)reg.idl++); else return;
27if (likely(rdyLine)) readIdle<C>(reg.pc); else return;
29#define READ_RELATIVE \
30if (likely(rdyLine)) reg.d = read<C>(reg.pc); else return;
31#define READ_IMMEDIATE \
32if (likely(rdyLine)) reg.d = read<C>(reg.pc++); else return;
34if (likely(rdyLine)) reg.d = read<C>(x); else return;
35#define READ_FROM_ADDRESS \
36if (likely(rdyLine)) reg.d = read<C>(HI_LO(reg.adh, reg.adl)); else return;
37#define READ_FROM_ZERO_PAGE \
38if (likely(rdyLine)) reg.d = readZeroPage<C>(reg.adl); else return;
39#define READ_FROM_ADDRESS_INDIRECT \
40if (likely(rdyLine)) reg.d = readZeroPage<C>(reg.dl); else return;
42#define IDLE_READ_IMPLIED \
43if (likely(rdyLine)) readIdle<C>(reg.pc); else return;
44#define IDLE_READ_IMMEDIATE \
45if (likely(rdyLine)) readIdle<C>(reg.pc++); else return;
46#define IDLE_READ_FROM(x) \
47if (likely(rdyLine)) readIdle<C>(x); else return;
48#define IDLE_READ_FROM_ADDRESS \
49if (likely(rdyLine)) readIdle<C>(HI_LO(reg.adh, reg.adl)); else return;
50#define IDLE_READ_FROM_ZERO_PAGE \
51if (likely(rdyLine)) readZeroPageIdle<C>(reg.adl); else return;
52#define IDLE_READ_FROM_ADDRESS_INDIRECT \
53if (likely(rdyLine)) readZeroPageIdle<C>(reg.idl); else return;
55#define WRITE_TO_ADDRESS \
56write<C>(HI_LO(reg.adh, reg.adl), reg.d);
57#define WRITE_TO_ADDRESS_AND_SET_FLAGS \
58write<C>(HI_LO(reg.adh, reg.adl), reg.d); setN(reg.d & 0x80); setZ(reg.d == 0);
59#define WRITE_TO_ZERO_PAGE \
60writeZeroPage<C>(reg.adl, reg.d);
61#define WRITE_TO_ZERO_PAGE_AND_SET_FLAGS \
62writeZeroPage<C>(reg.adl, reg.d); setN(reg.d & 0x80); setZ(reg.d == 0);
64#define ADD_INDEX_X reg.ovl = ((int)reg.adl + (int)reg.x > 0xFF); reg.adl += reg.x;
65#define ADD_INDEX_Y reg.ovl = ((int)reg.adl + (int)reg.y > 0xFF); reg.adl += reg.y;
66#define ADD_INDEX_X_INDIRECT reg.idl += reg.x;
67#define ADD_INDEX_Y_INDIRECT reg.idl += reg.y;
69#define SET_PCL(lo) reg.pc = (u16)((reg.pc & 0xff00) | (lo));
70#define SET_PCH(hi) reg.pc = (u16)((reg.pc & 0x00ff) | (hi) << 8);
71#define PUSH_PCL writeStack<C>(reg.sp--, LO_BYTE(reg.pc));
72#define PUSH_PCH writeStack<C>(reg.sp--, HI_BYTE(reg.pc));
73#define PUSH_P writeStack<C>(reg.sp--, getP());
74#define PUSH_P_WITH_B_SET writeStack<C>(reg.sp--, getP() | B_FLAG);
75#define PUSH_A writeStack<C>(reg.sp--, reg.a);
76#define PULL_PCL if (likely(rdyLine)) { SET_PCL(readStack<C>(reg.sp)); } else return;
77#define PULL_PCH if (likely(rdyLine)) { SET_PCH(readStack<C>(reg.sp)); } else return;
78#define PULL_P if (likely(rdyLine)) { setPWithoutB(readStack<C>(reg.sp)); } else return;
79#define PULL_A if (likely(rdyLine)) { loadA(readStack<C>(reg.sp)); } else return;
80#define IDLE_PULL if (likely(rdyLine)) { readStackIdle<C>(reg.sp); } else return;
82#define PAGE_BOUNDARY_CROSSED reg.ovl
83#define FIX_ADDR_HI reg.adh++;
85#define POLL_IRQ doIrq = (levelDetector.delayed() && !getI());
86#define POLL_NMI doNmi = edgeDetector.delayed();
87#define POLL_INT POLL_IRQ POLL_NMI
88#define POLL_INT_AGAIN doIrq |= (levelDetector.delayed() != 0 && !getI()); \
89doNmi |= (edgeDetector.delayed() != 0);
90#define CONTINUE next = (MicroInstruction)((int)next+1); return;
91#define DONE done<C>(); return;
103Peddle::adcBinary(u8 op)
105 u16 sum = reg.a + op + (getC() ? 1 : 0);
108 setV(!((reg.a ^ op) & 0x80) && ((reg.a ^ sum) & 0x80));
115 u16 sum = reg.a + op + (getC() ? 1 : 0);
116 u8 highDigit = (reg.a >> 4) + (op >> 4);
117 u8 lowDigit = (reg.a & 0x0F) + (op & 0x0F) + (getC() ? 1 : 0);
123 lowDigit = lowDigit + 6;
125 if (lowDigit > 0x0F) {
129 setZ((sum & 0xFF) == 0);
130 setN(highDigit & 0x08);
131 setV((((highDigit << 4) ^ reg.a) & 0x80) && !((reg.a ^ op) & 0x80));
134 highDigit = (highDigit + 6);
136 if (highDigit > 0x0F) {
143 reg.a = (u8)((highDigit << 4) | lowDigit);
147Peddle::cmp(u8 op1, u8 op2)
166Peddle::sbcBinary(u8 op)
168 u16 sum = reg.a - op - (getC() ? 0 : 1);
171 setV(((reg.a ^ sum) & 0x80) && ((reg.a ^ op) & 0x80));
178 u16 sum = reg.a - op - (getC() ? 0 : 1);
179 u8 highDigit = (reg.a >> 4) - (op >> 4);
180 u8 lowDigit = (reg.a & 0x0F) - (op & 0x0F) - (getC() ? 0 : 1);
185 if (lowDigit & 0x10) {
186 lowDigit = lowDigit - 6;
189 if (highDigit & 0x10) {
190 highDigit = highDigit - 6;
194 setV(((reg.a ^ sum) & 0x80) && ((reg.a ^ op) & 0x80));
195 setZ((sum & 0xFF) == 0);
198 reg.a = (u8)((highDigit << 4) | (lowDigit & 0x0f));
202Peddle::getLengthOfInstruction(u8 opcode)
const
204 switch(addressingMode[opcode]) {
207 case ADDR_ACCUMULATOR:
return 1;
210 case ADDR_ZERO_PAGE_X:
211 case ADDR_ZERO_PAGE_Y:
212 case ADDR_INDIRECT_X:
213 case ADDR_INDIRECT_Y:
214 case ADDR_RELATIVE:
return 2;
216 case ADDR_ABSOLUTE_X:
217 case ADDR_ABSOLUTE_Y:
219 case ADDR_INDIRECT:
return 3;
227Peddle::getLengthOfInstructionAt(u16 addr)
const
229 return getLengthOfInstruction(readDasm(addr));
233Peddle::getLengthOfCurrentInstruction()
const
235 return getLengthOfInstructionAt(getPC0());
239Peddle::getAddressOfNextInstruction()
const
241 return (u16)(getPC0() + getLengthOfCurrentInstruction());
249 case MOS_6502: reset<MOS_6502>();
break;
250 case MOS_6507: reset<MOS_6507>();
break;
251 case MOS_6510: reset<MOS_6510>();
break;
252 case MOS_8502: reset<MOS_8502>();
break;
259template <CPURevision C>
void
270 edgeDetector.reset(0);
271 levelDetector.reset(0);
276 reg.pport.data = 0xFF;
277 reg.pc = reg.pc0 = readResetVector();
289 case MOS_6502: execute<MOS_6502>();
break;
290 case MOS_6507: execute<MOS_6507>();
break;
291 case MOS_6510: execute<MOS_6510>();
break;
292 case MOS_8502: execute<MOS_8502>();
break;
299template <CPURevision C>
void
309 if (unlikely(doNmi)) {
313 edgeDetector.clear();
319 }
else if (unlikely(doIrq)) {
330 next = actionFunc[instr];
366 if (edgeDetector.current()) {
369 edgeDetector.clear();
377 write<C>(0x100+(reg.sp--), getPWithClearedB());
415 write<C>(0x100+(reg.sp--), getPWithClearedB());
436 case BRK: case RTI: case RTS:
445 case PHA: case PHP: case PLA: case PLP:
454 case ADC_zpg: case AND_zpg: case ASL_zpg: case BIT_zpg:
455 case CMP_zpg: case CPX_zpg: case CPY_zpg: case DEC_zpg:
456 case EOR_zpg: case INC_zpg: case LDA_zpg: case LDX_zpg:
457 case LDY_zpg: case LSR_zpg: case NOP_zpg: case ORA_zpg:
458 case ROL_zpg: case ROR_zpg: case SBC_zpg: case STA_zpg:
459 case STX_zpg: case STY_zpg: case DCP_zpg: case ISC_zpg:
460 case LAX_zpg: case RLA_zpg: case RRA_zpg: case SAX_zpg:
461 case SLO_zpg: case SRE_zpg:
466 case ASL_zpg_2: case DEC_zpg_2: case INC_zpg_2: case LSR_zpg_2:
467 case ROL_zpg_2: case ROR_zpg_2: case DCP_zpg_2: case ISC_zpg_2:
468 case RLA_zpg_2: case RRA_zpg_2: case SLO_zpg_2: case SRE_zpg_2:
477 case ADC_zpg_x: case AND_zpg_x: case ASL_zpg_x: case CMP_zpg_x:
478 case DEC_zpg_x: case EOR_zpg_x: case INC_zpg_x: case LDA_zpg_x:
479 case LDY_zpg_x: case LSR_zpg_x: case NOP_zpg_x: case ORA_zpg_x:
480 case ROL_zpg_x: case ROR_zpg_x: case SBC_zpg_x: case STA_zpg_x:
481 case STY_zpg_x: case DCP_zpg_x: case ISC_zpg_x: case RLA_zpg_x:
482 case RRA_zpg_x: case SLO_zpg_x: case SRE_zpg_x:
484 case LDX_zpg_y: case STX_zpg_y: case LAX_zpg_y: case SAX_zpg_y:
489 case ADC_zpg_x_2: case AND_zpg_x_2: case ASL_zpg_x_2: case CMP_zpg_x_2:
490 case DEC_zpg_x_2: case EOR_zpg_x_2: case INC_zpg_x_2: case LDA_zpg_x_2:
491 case LDY_zpg_x_2: case LSR_zpg_x_2: case NOP_zpg_x_2: case ORA_zpg_x_2:
492 case ROL_zpg_x_2: case ROR_zpg_x_2: case SBC_zpg_x_2: case DCP_zpg_x_2:
493 case ISC_zpg_x_2: case RLA_zpg_x_2: case RRA_zpg_x_2: case SLO_zpg_x_2:
494 case SRE_zpg_x_2: case STA_zpg_x_2: case STY_zpg_x_2:
500 case LDX_zpg_y_2: case LAX_zpg_y_2: case STX_zpg_y_2: case SAX_zpg_y_2:
506 case ASL_zpg_x_3: case DEC_zpg_x_3: case INC_zpg_x_3: case LSR_zpg_x_3:
507 case ROL_zpg_x_3: case ROR_zpg_x_3: case DCP_zpg_x_3: case ISC_zpg_x_3:
508 case RLA_zpg_x_3: case RRA_zpg_x_3: case SLO_zpg_x_3: case SRE_zpg_x_3:
518 case ADC_abs: case AND_abs: case ASL_abs: case BIT_abs:
519 case CMP_abs: case CPX_abs: case CPY_abs: case DEC_abs:
520 case EOR_abs: case INC_abs: case LDA_abs: case LDX_abs:
521 case LDY_abs: case LSR_abs: case NOP_abs: case ORA_abs:
522 case ROL_abs: case ROR_abs: case SBC_abs: case STA_abs:
523 case STX_abs: case STY_abs: case DCP_abs: case ISC_abs:
524 case LAX_abs: case RLA_abs: case RRA_abs: case SAX_abs:
525 case SLO_abs: case SRE_abs:
530 case ADC_abs_2: case AND_abs_2: case ASL_abs_2: case BIT_abs_2:
531 case CMP_abs_2: case CPX_abs_2: case CPY_abs_2: case DEC_abs_2:
532 case EOR_abs_2: case INC_abs_2: case LDA_abs_2: case LDX_abs_2:
533 case LDY_abs_2: case LSR_abs_2: case NOP_abs_2: case ORA_abs_2:
534 case ROL_abs_2: case ROR_abs_2: case SBC_abs_2: case STA_abs_2:
535 case STX_abs_2: case STY_abs_2: case DCP_abs_2: case ISC_abs_2:
536 case LAX_abs_2: case RLA_abs_2: case RRA_abs_2: case SAX_abs_2:
537 case SLO_abs_2: case SRE_abs_2:
542 case ASL_abs_3: case DEC_abs_3: case INC_abs_3: case LSR_abs_3:
543 case ROL_abs_3: case ROR_abs_3: case DCP_abs_3: case ISC_abs_3:
544 case RLA_abs_3: case RRA_abs_3: case SLO_abs_3: case SRE_abs_3:
553 case ADC_abs_x: case AND_abs_x: case ASL_abs_x: case CMP_abs_x:
554 case DEC_abs_x: case EOR_abs_x: case INC_abs_x: case LDA_abs_x:
555 case LDY_abs_x: case LSR_abs_x: case NOP_abs_x: case ORA_abs_x:
556 case ROL_abs_x: case ROR_abs_x: case SBC_abs_x: case STA_abs_x:
557 case DCP_abs_x: case ISC_abs_x: case RLA_abs_x: case RRA_abs_x:
558 case SHY_abs_x: case SLO_abs_x: case SRE_abs_x:
560 case ADC_abs_y: case AND_abs_y: case CMP_abs_y: case EOR_abs_y:
561 case LDA_abs_y: case LDX_abs_y: case LSR_abs_y: case ORA_abs_y:
562 case SBC_abs_y: case STA_abs_y: case DCP_abs_y: case ISC_abs_y:
563 case LAS_abs_y: case LAX_abs_y: case RLA_abs_y: case RRA_abs_y:
564 case SHA_abs_y: case SHX_abs_y: case SLO_abs_y: case SRE_abs_y:
570 case ADC_abs_x_2: case AND_abs_x_2: case ASL_abs_x_2: case CMP_abs_x_2:
571 case DEC_abs_x_2: case EOR_abs_x_2: case INC_abs_x_2: case LDA_abs_x_2:
572 case LDY_abs_x_2: case LSR_abs_x_2: case NOP_abs_x_2: case ORA_abs_x_2:
573 case ROL_abs_x_2: case ROR_abs_x_2: case SBC_abs_x_2: case STA_abs_x_2:
574 case DCP_abs_x_2: case ISC_abs_x_2: case RLA_abs_x_2: case RRA_abs_x_2:
575 case SHY_abs_x_2: case SLO_abs_x_2: case SRE_abs_x_2:
581 case ADC_abs_y_2: case AND_abs_y_2: case CMP_abs_y_2: case EOR_abs_y_2:
582 case LDA_abs_y_2: case LDX_abs_y_2: case LSR_abs_y_2: case ORA_abs_y_2:
583 case SBC_abs_y_2: case STA_abs_y_2: case DCP_abs_y_2: case ISC_abs_y_2:
584 case LAS_abs_y_2: case LAX_abs_y_2: case RLA_abs_y_2: case RRA_abs_y_2:
585 case SHA_abs_y_2: case SHX_abs_y_2: case SLO_abs_y_2: case SRE_abs_y_2:
592 case ASL_abs_x_3: case DEC_abs_x_3: case INC_abs_x_3: case LSR_abs_x_3:
593 case ROL_abs_x_3: case ROR_abs_x_3: case DCP_abs_x_3: case ISC_abs_x_3:
594 case RLA_abs_x_3: case RRA_abs_x_3: case STA_abs_x_3: case SLO_abs_x_3:
597 case LSR_abs_y_3: case STA_abs_y_3: case DCP_abs_y_3: case ISC_abs_y_3:
598 case RLA_abs_y_3: case RRA_abs_y_3: case SLO_abs_y_3: case SRE_abs_y_3:
601 if (PAGE_BOUNDARY_CROSSED) { FIX_ADDR_HI }
604 case ASL_abs_x_4:
case DEC_abs_x_4:
case INC_abs_x_4:
case LSR_abs_x_4:
605 case ROL_abs_x_4:
case ROR_abs_x_4:
case DCP_abs_x_4:
case ISC_abs_x_4:
606 case RLA_abs_x_4:
case RRA_abs_x_4:
case SLO_abs_x_4:
case SRE_abs_x_4:
608 case DCP_abs_y_4:
case LSR_abs_y_4:
case ISC_abs_y_4:
case RLA_abs_y_4:
609 case RRA_abs_y_4:
case SLO_abs_y_4:
case SRE_abs_y_4:
618 case ADC_ind_x:
case AND_ind_x:
case ASL_ind_x:
case CMP_ind_x:
619 case DEC_ind_x:
case EOR_ind_x:
case INC_ind_x:
case LDA_ind_x:
620 case LDX_ind_x:
case LDY_ind_x:
case LSR_ind_x:
case ORA_ind_x:
621 case ROL_ind_x:
case ROR_ind_x:
case SBC_ind_x:
case STA_ind_x:
622 case DCP_ind_x:
case ISC_ind_x:
case LAX_ind_x:
case RLA_ind_x:
623 case RRA_ind_x:
case SAX_ind_x:
case SLO_ind_x:
case SRE_ind_x:
628 case ADC_ind_x_2:
case AND_ind_x_2:
case ASL_ind_x_2:
case CMP_ind_x_2:
629 case DEC_ind_x_2:
case EOR_ind_x_2:
case INC_ind_x_2:
case LDA_ind_x_2:
630 case LDX_ind_x_2:
case LDY_ind_x_2:
case LSR_ind_x_2:
case ORA_ind_x_2:
631 case ROL_ind_x_2:
case ROR_ind_x_2:
case SBC_ind_x_2:
case STA_ind_x_2:
632 case DCP_ind_x_2:
case ISC_ind_x_2:
case LAX_ind_x_2:
case RLA_ind_x_2:
633 case RRA_ind_x_2:
case SAX_ind_x_2:
case SLO_ind_x_2:
case SRE_ind_x_2:
635 IDLE_READ_FROM_ADDRESS_INDIRECT
639 case ADC_ind_x_3:
case AND_ind_x_3:
case ASL_ind_x_3:
case CMP_ind_x_3:
640 case DEC_ind_x_3:
case EOR_ind_x_3:
case INC_ind_x_3:
case LDA_ind_x_3:
641 case LDX_ind_x_3:
case LDY_ind_x_3:
case LSR_ind_x_3:
case ORA_ind_x_3:
642 case ROL_ind_x_3:
case ROR_ind_x_3:
case SBC_ind_x_3:
case STA_ind_x_3:
643 case DCP_ind_x_3:
case ISC_ind_x_3:
case LAX_ind_x_3:
case RLA_ind_x_3:
644 case RRA_ind_x_3:
case SAX_ind_x_3:
case SLO_ind_x_3:
case SRE_ind_x_3:
646 FETCH_ADDR_LO_INDIRECT
649 case ADC_ind_x_4:
case AND_ind_x_4:
case ASL_ind_x_4:
case CMP_ind_x_4:
650 case DEC_ind_x_4:
case EOR_ind_x_4:
case INC_ind_x_4:
case LDA_ind_x_4:
651 case LDX_ind_x_4:
case LDY_ind_x_4:
case LSR_ind_x_4:
case ORA_ind_x_4:
652 case ROL_ind_x_4:
case ROR_ind_x_4:
case SBC_ind_x_4:
case STA_ind_x_4:
653 case DCP_ind_x_4:
case ISC_ind_x_4:
case LAX_ind_x_4:
case RLA_ind_x_4:
654 case RRA_ind_x_4:
case SAX_ind_x_4:
case SLO_ind_x_4:
case SRE_ind_x_4:
656 FETCH_ADDR_HI_INDIRECT
659 case ASL_ind_x_5:
case DEC_ind_x_5:
case INC_ind_x_5:
case LSR_ind_x_5:
660 case ROL_ind_x_5:
case ROR_ind_x_5:
case DCP_ind_x_5:
case ISC_ind_x_5:
661 case RLA_ind_x_5:
case RRA_ind_x_5:
case SLO_ind_x_5:
case SRE_ind_x_5:
670 case ADC_ind_y:
case AND_ind_y:
case CMP_ind_y:
case EOR_ind_y:
671 case LDA_ind_y:
case LDX_ind_y:
case LDY_ind_y:
case LSR_ind_y:
672 case ORA_ind_y:
case SBC_ind_y:
case STA_ind_y:
case DCP_ind_y:
673 case ISC_ind_y:
case LAX_ind_y:
case RLA_ind_y:
case RRA_ind_y:
674 case SHA_ind_y:
case SLO_ind_y:
case SRE_ind_y:
679 case ADC_ind_y_2:
case AND_ind_y_2:
case CMP_ind_y_2:
case EOR_ind_y_2:
680 case LDA_ind_y_2:
case LDX_ind_y_2:
case LDY_ind_y_2:
case LSR_ind_y_2:
681 case ORA_ind_y_2:
case SBC_ind_y_2:
case STA_ind_y_2:
case DCP_ind_y_2:
682 case ISC_ind_y_2:
case LAX_ind_y_2:
case RLA_ind_y_2:
case RRA_ind_y_2:
683 case SHA_ind_y_2:
case SLO_ind_y_2:
case SRE_ind_y_2:
685 FETCH_ADDR_LO_INDIRECT
688 case ADC_ind_y_3:
case AND_ind_y_3:
case CMP_ind_y_3:
case EOR_ind_y_3:
689 case LDA_ind_y_3:
case LDX_ind_y_3:
case LDY_ind_y_3:
case LSR_ind_y_3:
690 case ORA_ind_y_3:
case SBC_ind_y_3:
case STA_ind_y_3:
case DCP_ind_y_3:
691 case ISC_ind_y_3:
case LAX_ind_y_3:
case RLA_ind_y_3:
case RRA_ind_y_3:
692 case SHA_ind_y_3:
case SLO_ind_y_3:
case SRE_ind_y_3:
694 FETCH_ADDR_HI_INDIRECT
698 case LSR_ind_y_4:
case STA_ind_y_4:
case DCP_ind_y_4:
case ISC_ind_y_4:
699 case RLA_ind_y_4:
case RRA_ind_y_4:
case SLO_ind_y_4:
case SRE_ind_y_4:
702 if (PAGE_BOUNDARY_CROSSED) { FIX_ADDR_HI }
705 case LSR_ind_y_5:
case DCP_ind_y_5:
case ISC_ind_y_5:
case RLA_ind_y_5:
706 case RRA_ind_y_5:
case SLO_ind_y_5:
case SRE_ind_y_5:
715 case BCC_rel_2:
case BCS_rel_2:
case BEQ_rel_2:
case BMI_rel_2:
716 case BNE_rel_2:
case BPL_rel_2:
case BVC_rel_2:
case BVS_rel_2:
719 u8 pc_hi = HI_BYTE(reg.pc);
722 if (unlikely(pc_hi != HI_BYTE(reg.pc))) {
723 next = (reg.d & 0x80) ? branch_3_underflow : branch_3_overflow;
729 case branch_3_underflow:
731 IDLE_READ_FROM(reg.pc + 0x100)
735 case branch_3_overflow:
737 IDLE_READ_FROM(reg.pc - 0x100)
769 if (PAGE_BOUNDARY_CROSSED) {
800 loadA(reg.a & reg.d);
808 loadA(reg.a & reg.d);
817 if (PAGE_BOUNDARY_CROSSED) {
821 loadA(reg.a & reg.d);
833 loadA(reg.a & reg.d);
845#define DO_ASL_ACC setC(reg.a & 0x80); loadA((u8)(reg.a << 1));
846#define DO_ASL setC(reg.d & 0x80); reg.d = (u8)(reg.d << 1);
873 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
881 WRITE_TO_ADDRESS_AND_SET_FLAGS
955 setZ((reg.d & reg.a) == 0);
964 setZ((reg.d & reg.a) == 0);
1045 if (edgeDetector.current()) {
1048 edgeDetector.clear();
1223 if (PAGE_BOUNDARY_CROSSED) {
1309#define DO_DEC reg.d--;
1321 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
1337 WRITE_TO_ADDRESS_AND_SET_FLAGS
1379#define DO_EOR loadA(reg.a ^ reg.d);
1401 if (PAGE_BOUNDARY_CROSSED) {
1429#define DO_INC reg.d++;
1441 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
1457 WRITE_TO_ADDRESS_AND_SET_FLAGS
1507 reg.pc = LO_HI(reg.adl, reg.adh);
1566 reg.pc = LO_HI(reg.adl, reg.adh);
1598 if (PAGE_BOUNDARY_CROSSED) {
1645 if (PAGE_BOUNDARY_CROSSED) {
1691 if (PAGE_BOUNDARY_CROSSED) {
1721 setC(reg.a & 1); loadA(reg.a >> 1);
1729 setC(reg.d & 1); reg.d = reg.d >> 1;
1735 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
1746 setC(reg.d & 1); reg.d = reg.d >> 1;
1755 WRITE_TO_ADDRESS_AND_SET_FLAGS
1782 IDLE_READ_FROM_ZERO_PAGE
1788 IDLE_READ_FROM_ADDRESS
1789 if (PAGE_BOUNDARY_CROSSED) {
1800 IDLE_READ_FROM_ADDRESS
1815 loadA(reg.a | reg.d);
1823 loadA(reg.a | reg.d);
1832 if (PAGE_BOUNDARY_CROSSED) {
1836 loadA(reg.a | reg.d);
1848 loadA(reg.a | reg.d);
1929#define DO_ROL_ACC { u8 c = !!getC(); setC(reg.a & 0x80); loadA((u8)(reg.a << 1 | c)); }
1930#define DO_ROL { u8 c = !!getC(); setC(reg.d & 0x80); reg.d = (u8)(reg.d << 1 | c); }
1949 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
1965 WRITE_TO_ADDRESS_AND_SET_FLAGS
1979#define DO_ROR_ACC { u8 c = !!getC(); setC(reg.a & 0x1); loadA((u8)(reg.a >> 1 | c << 7)); }
1980#define DO_ROR { u8 c = !!getC(); setC(reg.d & 0x1); reg.d = (u8)(reg.d >> 1 | c << 7); }
1999 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
2015 WRITE_TO_ADDRESS_AND_SET_FLAGS
2110 if (PAGE_BOUNDARY_CROSSED) {
2366 reg.a = reg.a & reg.d;
2383 loadA(reg.a & reg.d);
2400 u8 tmp2 = reg.a & reg.d;
2403 reg.a = (getC() ? (tmp2 >> 1) | 0x80 : tmp2 >> 1);
2408 setV((reg.a & 0x40) ^ ((reg.a & 0x20) << 1));
2414 setV((tmp2 ^ reg.a) & 0x40);
2415 if ((tmp2 & 0x0f) + (tmp2 & 0x01) > 5)
2416 reg.a = (reg.a & 0xf0) | ((reg.a + 6) & 0x0f);
2417 c_flag = (tmp2 + (tmp2 & 0x10)) & 0x1f0;
2418 if (c_flag > 0x50) {
2441 u8 op2 = reg.a & reg.x;
2442 u8 tmp = op2 - reg.d;
2468 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
2489 WRITE_TO_ADDRESS_AND_SET_FLAGS
2512 WRITE_TO_ZERO_PAGE_AND_SET_FLAGS
2533 WRITE_TO_ADDRESS_AND_SET_FLAGS
2549 if (PAGE_BOUNDARY_CROSSED) {
2592 if (PAGE_BOUNDARY_CROSSED) {
2632 loadA(reg.a & reg.d);
2653 loadA(reg.a & reg.d);
2711 reg.d = reg.a & reg.x;
2719 reg.d = reg.a & reg.x;
2734 IDLE_READ_FROM_ADDRESS
2741 reg.d = reg.a & reg.x & (rdyLineUp == clock ? 0xFF : reg.adh + 1);
2748 if (PAGE_BOUNDARY_CROSSED) {
2750 reg.adh = reg.a & reg.x & reg.adh;
2763 IDLE_READ_FROM_ADDRESS
2770 reg.d = reg.a & reg.x & (rdyLineUp == clock ? 0xFF : reg.adh + 1);
2777 if (PAGE_BOUNDARY_CROSSED) {
2779 reg.adh = reg.a & reg.x & reg.adh;
2800 IDLE_READ_FROM_ADDRESS
2807 reg.d = reg.x & (rdyLineUp == clock ? 0xFF : reg.adh + 1);
2814 if (PAGE_BOUNDARY_CROSSED) {
2816 reg.adh = reg.x & reg.adh;
2837 IDLE_READ_FROM_ADDRESS
2844 reg.d = reg.y & (rdyLineUp == clock ? 0xFF : reg.adh + 1);
2851 if (PAGE_BOUNDARY_CROSSED) {
2853 reg.adh = reg.y & reg.adh;
2872#define DO_SLO setC(reg.d & 128); reg.d <<= 1;
2885 loadA(reg.a | reg.d);
2906 loadA(reg.a | reg.d);
2918#define DO_SRE setC(reg.d & 1); reg.d >>= 1;
2931 loadA(reg.a ^ reg.d);
2952 loadA(reg.a ^ reg.d);
2966 IDLE_READ_FROM_ADDRESS
2968 reg.sp = reg.a & reg.x;
2975 reg.d = reg.a & reg.x & (rdyLineUp == clock ? 0xFF : reg.adh + 1);
2982 if (PAGE_BOUNDARY_CROSSED) {
2984 reg.adh = reg.a & reg.x & reg.adh;
3005 loadA(reg.x & reg.d & (reg.a | 0xEE));
3020 reg.x = reg.d & (reg.a | 0xEE);
3032Peddle::execute(
int count)
3036 case MOS_6502: execute<MOS_6502>(count);
break;
3037 case MOS_6507: execute<MOS_6507>(count);
break;
3038 case MOS_6510: execute<MOS_6510>(count);
break;
3039 case MOS_8502: execute<MOS_8502>(count);
break;
3046template <CPURevision C>
void
3047Peddle::execute(
int count)
3049 for (
int j = 0; j < count; j++) { execute<C>(); }
3053Peddle::executeInstruction()
3057 case MOS_6502: executeInstruction<MOS_6502>();
break;
3058 case MOS_6507: executeInstruction<MOS_6507>();
break;
3059 case MOS_6510: executeInstruction<MOS_6510>();
break;
3060 case MOS_8502: executeInstruction<MOS_8502>();
break;
3067template <CPURevision C>
void
3068Peddle::executeInstruction()
3074 finishInstruction<C>();
3078Peddle::executeInstruction(
int count)
3082 case MOS_6502: executeInstruction<MOS_6502>(count);
break;
3083 case MOS_6507: executeInstruction<MOS_6507>(count);
break;
3084 case MOS_6510: executeInstruction<MOS_6510>(count);
break;
3085 case MOS_8502: executeInstruction<MOS_8502>(count);
break;
3092template <CPURevision C>
void
3093Peddle::executeInstruction(
int count)
3095 for (
int j = 0; j < count; j++) { executeInstruction<C>(); }
3099Peddle::finishInstruction()
3103 case MOS_6502: finishInstruction<MOS_6502>();
break;
3104 case MOS_6507: finishInstruction<MOS_6507>();
break;
3105 case MOS_6510: finishInstruction<MOS_6510>();
break;
3106 case MOS_8502: finishInstruction<MOS_8502>();
break;
3113template <CPURevision C>
void
3114Peddle::finishInstruction()
3116 while (!inFetchPhase()) execute<C>();
3119template <CPURevision C>
void
3124 if (flags & CPU_LOG_INSTRUCTION) {
3126 debugger.logInstruction();
3127 instructionLogged();
3130 if ((flags & CPU_CHECK_BP) && debugger.breakpointMatches(reg.pc)) {
3132 breakpointReached(reg.pc);