📄 cpu.c
字号:
remember_xpos[remember_PC_curpos] = cpu2antic_ptr[xpos] + (ypos << 8); else#endif remember_xpos[remember_PC_curpos] = xpos + (ypos << 8); remember_PC_curpos = (remember_PC_curpos + 1) % REMEMBER_PC_STEPS; if (break_addr == GET_PC() || break_ypos == ypos) { DO_BREAK; }#endif /* MONITOR_BREAK */#if defined(WRAP_64K) && !defined(PC_PTR) memory[0x10000] = memory[0];#endif insn = GET_CODE_BYTE();#ifdef MONITOR_BREAKPOINTS if (breakpoint_table_size > 0 && breakpoints_enabled) { UBYTE optype = optype6502[insn]; int i; switch (optype >> 4) { case 1: addr = PEEK_CODE_WORD(); break; case 2: addr = PEEK_CODE_BYTE(); break; case 3: addr = PEEK_CODE_WORD() + X; break; case 4: addr = PEEK_CODE_WORD() + Y; break; case 5: addr = (UBYTE) (PEEK_CODE_BYTE() + X); addr = zGetWord(addr); break; case 6: addr = PEEK_CODE_BYTE(); addr = zGetWord(addr) + Y; break; case 7: addr = (UBYTE) (PEEK_CODE_BYTE() + X); break; case 8: addr = (UBYTE) (PEEK_CODE_BYTE() + Y); break; /* XXX: case 13 */ default: addr = 0; break; } for (i = 0; i < breakpoint_table_size; i++) { int cond; int value; if (!breakpoint_table[i].enabled) continue; /* skip */ cond = breakpoint_table[i].condition; if (cond == BREAKPOINT_OR) break; /* fire */ value = breakpoint_table[i].value; if (cond == BREAKPOINT_FLAG_CLEAR) { switch (value) { case N_FLAG: if ((N & 0x80) == 0) continue; break;#ifndef NO_V_FLAG_VARIABLE case V_FLAG: if (V == 0) continue; break;#endif case Z_FLAG: if (Z != 0) continue; break; case C_FLAG: if (C == 0) continue; break; default: if ((regP & value) == 0) continue; break; } } else if (cond == BREAKPOINT_FLAG_SET) { switch (value) { case N_FLAG: if ((N & 0x80) != 0) continue; break;#ifndef NO_V_FLAG_VARIABLE case V_FLAG: if (V != 0) continue; break;#endif case Z_FLAG: if (Z == 0) continue; break; case C_FLAG: if (C != 0) continue; break; default: if ((regP & value) != 0) continue; break; } } else { int val; switch (cond >> 3) { case BREAKPOINT_PC >> 3: val = GET_PC() - 1; break; case BREAKPOINT_A >> 3: val = A; break; case BREAKPOINT_X >> 3: val = X; break; case BREAKPOINT_Y >> 3: val = Y; break; case BREAKPOINT_S >> 3: val = S; break; case BREAKPOINT_READ >> 3: if ((optype & 4) == 0) goto cond_failed; val = addr; break; case BREAKPOINT_WRITE >> 3: if ((optype & 8) == 0) goto cond_failed; val = addr; break; case BREAKPOINT_ACCESS >> 3: if ((optype & 12) == 0) goto cond_failed; val = addr; break; default: /* shouldn't happen */ continue; } if ((cond & BREAKPOINT_LESS) != 0 && val < value) continue; if ((cond & BREAKPOINT_EQUAL) != 0 && val == value) continue; if ((cond & BREAKPOINT_GREATER) != 0 && val > value) continue; cond_failed: ; } /* a condition failed */ /* quickly skip AND-connected conditions */ do { if (++i >= breakpoint_table_size) goto no_breakpoint; } while (breakpoint_table[i].condition != BREAKPOINT_OR || !breakpoint_table[i].enabled); } /* fire breakpoint */ PC--; DO_BREAK; goto breakpoint_return; no_breakpoint: ; }#endif /* MONITOR_BREAKPOINTS */#ifndef CYCLES_PER_OPCODE xpos += cycles[insn];#endif#ifdef MONITOR_PROFILE instruction_count[insn]++;#endif#ifdef PREFETCH_CODE addr = PEEK_CODE_WORD();#endif#ifdef NO_GOTO switch (insn) {#else goto *opcode[insn];#endif OPCODE(00) /* BRK */#ifdef MONITOR_BREAK if (break_brk) { DO_BREAK; } else#endif { PC++; PHPC; PHPB1; SetI; SET_PC(dGetWordAligned(0xfffe)); INC_RET_NESTING; } DONE OPCODE(01) /* ORA (ab,x) */ INDIRECT_X; ORA(GetByte(addr)); DONE OPCODE(03) /* ASO (ab,x) [unofficial - ASL then ORA with Acc] */ INDIRECT_X; aso: RMW_GetByte(data, addr); C = (data & 0x80) ? 1 : 0; data <<= 1; PutByte(addr, data); Z = N = A |= data; DONE OPCODE_ALIAS(04) /* NOP ab [unofficial - skip byte] */ OPCODE_ALIAS(44) OPCODE(64) PC++; DONE OPCODE_ALIAS(14) /* NOP ab,x [unofficial - skip byte] */ OPCODE_ALIAS(34) OPCODE_ALIAS(54) OPCODE_ALIAS(74) OPCODE_ALIAS(d4) OPCODE(f4) PC++; DONE OPCODE_ALIAS(80) /* NOP #ab [unofficial - skip byte] */ OPCODE_ALIAS(82) OPCODE_ALIAS(89) OPCODE_ALIAS(c2) OPCODE(e2) PC++; DONE OPCODE(05) /* ORA ab */ ZPAGE; ORA(dGetByte(addr)); DONE OPCODE(06) /* ASL ab */ ZPAGE; data = dGetByte(addr); C = (data & 0x80) ? 1 : 0; Z = N = data << 1; dPutByte(addr, Z); DONE OPCODE(07) /* ASO ab [unofficial - ASL then ORA with Acc] */ ZPAGE; aso_zpage: data = dGetByte(addr); C = (data & 0x80) ? 1 : 0; data <<= 1; dPutByte(addr, data); Z = N = A |= data; DONE OPCODE(08) /* PHP */ PHPB1; DONE OPCODE(09) /* ORA #ab */ ORA(IMMEDIATE); DONE OPCODE(0a) /* ASL */ C = (A & 0x80) ? 1 : 0; Z = N = A <<= 1; DONE OPCODE_ALIAS(0b) /* ANC #ab [unofficial - AND then copy N to C (Fox) */ OPCODE(2b) AND(IMMEDIATE); C = N >= 0x80; DONE OPCODE(0c) /* NOP abcd [unofficial - skip word] */ PC += 2; DONE OPCODE(0d) /* ORA abcd */ ABSOLUTE; ORA(GetByte(addr)); DONE OPCODE(0e) /* ASL abcd */ ABSOLUTE; RMW_GetByte(data, addr); C = (data & 0x80) ? 1 : 0; Z = N = data << 1; PutByte(addr, Z); DONE OPCODE(0f) /* ASO abcd [unofficial - ASL then ORA with Acc] */ ABSOLUTE; goto aso; OPCODE(10) /* BPL */ BRANCH(!(N & 0x80)) OPCODE(11) /* ORA (ab),y */ INDIRECT_Y; NCYCLES_Y; ORA(GetByte(addr)); DONE OPCODE(13) /* ASO (ab),y [unofficial - ASL then ORA with Acc] */ INDIRECT_Y; goto aso; OPCODE(15) /* ORA ab,x */ ZPAGE_X; ORA(dGetByte(addr)); DONE OPCODE(16) /* ASL ab,x */ ZPAGE_X; data = dGetByte(addr); C = (data & 0x80) ? 1 : 0; Z = N = data << 1; dPutByte(addr, Z); DONE OPCODE(17) /* ASO ab,x [unofficial - ASL then ORA with Acc] */ ZPAGE_X; goto aso_zpage; OPCODE(18) /* CLC */ C = 0; DONE OPCODE(19) /* ORA abcd,y */ ABSOLUTE_Y; NCYCLES_Y; ORA(GetByte(addr)); DONE OPCODE(1b) /* ASO abcd,y [unofficial - ASL then ORA with Acc] */ ABSOLUTE_Y; goto aso; OPCODE_ALIAS(1c) /* NOP abcd,x [unofficial - skip word] */ OPCODE_ALIAS(3c) OPCODE_ALIAS(5c) OPCODE_ALIAS(7c) OPCODE_ALIAS(dc) OPCODE(fc) if (OP_BYTE + X >= 0x100) xpos++; PC += 2; DONE OPCODE(1d) /* ORA abcd,x */ ABSOLUTE_X; NCYCLES_X; ORA(GetByte(addr)); DONE OPCODE(1e) /* ASL abcd,x */ ABSOLUTE_X; RMW_GetByte(data, addr); C = (data & 0x80) ? 1 : 0; Z = N = data << 1; PutByte(addr, Z); DONE OPCODE(1f) /* ASO abcd,x [unofficial - ASL then ORA with Acc] */ ABSOLUTE_X; goto aso; OPCODE(20) /* JSR abcd */ { UWORD retaddr = GET_PC() + 1;#ifdef MONITOR_BREAK remember_JMP[remember_jmp_curpos] = GET_PC() - 1; remember_jmp_curpos = (remember_jmp_curpos + 1) % REMEMBER_JMP_STEPS; ret_nesting++;#endif PHW(retaddr); } SET_PC(OP_WORD); DONE OPCODE(21) /* AND (ab,x) */ INDIRECT_X; AND(GetByte(addr)); DONE OPCODE(23) /* RLA (ab,x) [unofficial - ROL Mem, then AND with A] */ INDIRECT_X; rla: RMW_GetByte(data, addr); if (C) { C = (data & 0x80) ? 1 : 0; data = (data << 1) + 1; } else { C = (data & 0x80) ? 1 : 0; data = (data << 1); } PutByte(addr, data); Z = N = A &= data; DONE OPCODE(24) /* BIT ab */ ZPAGE; N = dGetByte(addr);#ifndef NO_V_FLAG_VARIABLE V = N & 0x40;#else regP = (regP & 0xbf) + (N & 0x40);#endif Z = (A & N); DONE OPCODE(25) /* AND ab */ ZPAGE; AND(dGetByte(addr)); DONE OPCODE(26) /* ROL ab */ ZPAGE; data = dGetByte(addr); Z = N = (data << 1) + C; C = (data & 0x80) ? 1 : 0; dPutByte(addr, Z); DONE OPCODE(27) /* RLA ab [unofficial - ROL Mem, then AND with A] */ ZPAGE; rla_zpage: data = dGetByte(addr); if (C) { C = (data & 0x80) ? 1 : 0; data = (data << 1) + 1; } else { C = (data & 0x80) ? 1 : 0; data = (data << 1); } dPutByte(addr, data); Z = N = A &= data; DONE OPCODE(28) /* PLP */ PLP; CPUCHECKIRQ; DONE OPCODE(29) /* AND #ab */ AND(IMMEDIATE); DONE OPCODE(2a) /* ROL */ Z = N = (A << 1) + C; C = (A & 0x80) ? 1 : 0; A = Z; DONE OPCODE(2c) /* BIT abcd */ ABSOLUTE; N = GetByte(addr);#ifndef NO_V_FLAG_VARIABLE V = N & 0x40;#else regP = (regP & 0xbf) + (N & 0x40);#endif Z = (A & N); DONE OPCODE(2d) /* AND abcd */ ABSOLUTE; AND(GetByte(addr)); DONE OPCODE(2e) /* ROL abcd */ ABSOLUTE; RMW_GetByte(data, addr); Z = N = (data << 1) + C; C = (data & 0x80) ? 1 : 0; PutByte(addr, Z); DONE OPCODE(2f) /* RLA abcd [unofficial - ROL Mem, then AND with A] */ ABSOLUTE; goto rla; OPCODE(30) /* BMI */ BRANCH(N & 0x80) OPCODE(31) /* AND (ab),y */ INDIRECT_Y; NCYCLES_Y; AND(GetByte(addr)); DONE OPCODE(33) /* RLA (ab),y [unofficial - ROL Mem, then AND with A] */ INDIRECT_Y; goto rla; OPCODE(35) /* AND ab,x */ ZPAGE_X; AND(dGetByte(addr)); DONE OPCODE(36) /* ROL ab,x */ ZPAGE_X; data = dGetByte(addr); Z = N = (data << 1) + C; C = (data & 0x80) ? 1 : 0; dPutByte(addr, Z); DONE OPCODE(37) /* RLA ab,x [unofficial - ROL Mem, then AND with A] */ ZPAGE_X; goto rla_zpage; OPCODE(38) /* SEC */ C = 1; DONE OPCODE(39) /* AND abcd,y */ ABSOLUTE_Y; NCYCLES_Y; AND(GetByte(addr)); DONE OPCODE(3b) /* RLA abcd,y [unofficial - ROL Mem, then AND with A] */ ABSOLUTE_Y; goto rla; OPCODE(3d) /* AND abcd,x */ ABSOLUTE_X; NCYCLES_X; AND(GetByte(addr)); DONE OPCODE(3e) /* ROL abcd,x */ ABSOLUTE_X; RMW_GetByte(data, addr); Z = N = (data << 1) + C; C = (data & 0x80) ? 1 : 0; PutByte(addr, Z); DONE OPCODE(3f) /* RLA abcd,x [unofficial - ROL Mem, then AND with A] */ ABSOLUTE_X; goto rla; OPCODE(40) /* RTI */ PLP; data = PL; SET_PC((PL << 8) + data); CPUCHECKIRQ;#ifdef MONITOR_BREAK if (break_ret && --ret_nesting <= 0) break_step = TRUE;#endif DONE OPCODE(41) /* EOR (ab,x) */ INDIRECT_X; EOR(GetByte(addr)); DONE OPCODE(43) /* LSE (ab,x) [unofficial - LSR then EOR result with A] */ INDIRECT_X; lse: RMW_GetByte(data, addr); C = data & 1; data >>= 1; PutByte(addr, data); Z = N = A ^= data; DONE OPCODE(45) /* EOR ab */ ZPAGE; EOR(dGetByte(addr)); DONE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -