📄 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 + -