I'm currently in the process of writing a cycle-based 2A03 CPU core. The ViCE documentation (http://www.nesdev.com/6502_cpu.txt) is quite helpful, but the information contained there about branch opcodes is not all that clear. I know that some people here (Quietust and perhaps others) have written cycle-based CPU cores, so I'd like to see whether I'm on the right track. Here's what I've got at this point (for the BPL opcode, 0x10):
Note that the first opcode cycle (fetch opcode and increment PC) was done before the switch statement for obvious reasons. Also, the (S8) cast is for a signed char. Does this code seem correct?
Code:
/***********/
/* BPL $nn */
/***********/
case 0x10: /* 2nd cycle: Fetch operand and increment PC */
Operand = CPU_Read (CPU_PC.Word++);
CPU_Cycle ();
/* Extra cycle only if branch taken */
if (~CPU_P & CPU_N_FLAG)
{
/* 3rd cycle: Dummy opcode fetch and add operand to PC(l) */
CPU_Read (CPU_PC.Word);
Address.Word = CPU_PC.Word + (S8) (Operand);
CPU_PC.Byte.Low = Address.Byte.Low;
CPU_Cycle ();
/* Extra cycle only if PC(h) is invalid at this time */
if (CPU_PC.Byte.High != Address.Byte.High)
{
/* 4th cycle: Dummy opcode fetch and fix PC(h) */
CPU_Read (CPU_PC.Word);
CPU_PC.Byte.High = Address.Byte.High;
CPU_Cycle ();
}
}
/* Done */
break;
/* BPL $nn */
/***********/
case 0x10: /* 2nd cycle: Fetch operand and increment PC */
Operand = CPU_Read (CPU_PC.Word++);
CPU_Cycle ();
/* Extra cycle only if branch taken */
if (~CPU_P & CPU_N_FLAG)
{
/* 3rd cycle: Dummy opcode fetch and add operand to PC(l) */
CPU_Read (CPU_PC.Word);
Address.Word = CPU_PC.Word + (S8) (Operand);
CPU_PC.Byte.Low = Address.Byte.Low;
CPU_Cycle ();
/* Extra cycle only if PC(h) is invalid at this time */
if (CPU_PC.Byte.High != Address.Byte.High)
{
/* 4th cycle: Dummy opcode fetch and fix PC(h) */
CPU_Read (CPU_PC.Word);
CPU_PC.Byte.High = Address.Byte.High;
CPU_Cycle ();
}
}
/* Done */
break;
Note that the first opcode cycle (fetch opcode and increment PC) was done before the switch statement for obvious reasons. Also, the (S8) cast is for a signed char. Does this code seem correct?