branch instruction page cross timing

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
alphashock
Posts: 4
Joined: Wed Mar 25, 2020 7:02 am

branch instruction page cross timing

Post by alphashock » Mon Apr 20, 2020 10:31 am

Hi,

I encountered two branch instructions that I think should behave exactly the same with respect to individual cycles, but they are not. Outputs are from sub instruction nestest log. Both instructions test positive, so T2 cycle is executed.

Code: Select all

BNE @ $C72A

C72A  A:CB X:04 Y:4F P:6D SP:F1 CPUC:14757
      READ      $C72A => $D0 [T0]
      READ      $C72B => $E0 [T1]
      READ      $C72C => $60 [T2]
C70C
State @ T2

PC = $C72C
ADDRESS BUS = READ $C72C
DATA BUS = E0 (from T1 - instruction operand)

PC + E0 = $C72C + $E0 = $C80C

It looks like a page cross, but I'm not sure why the T4 cycle is not being executed. On the other hand...

Code: Select all

BEQ @ $F2FC

F2FC  A:52 X:02 Y:E9 P:67 SP:FB CPUC:23301
      READ      $F2FC => $F0 [T0]
      READ      $F2FD => $02 [T1]
      READ      $F2FE => $84 [T2]
      READ      $F200 => $84 [T3]
F300
State @ T2

PC = $F2FE
ADDRESS BUS = READ $F2FE
DATA BUS = $02 (from T1 - instruction operand)

PC + $02 = $F2FE + $02 = F300

I understand that T3 address bus can hold value adjusted by -0100 as per 64doc, but I'm not sure why this instruction takes 4 cycles and the previous one only 3. According to my understanding they should be both 4 cycles. How are these two different?

lidnariq
Posts: 9681
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: branch instruction page cross timing

Post by lidnariq » Mon Apr 20, 2020 10:39 am

alphashock wrote:
Mon Apr 20, 2020 10:31 am
PC + E0 = $C72C + $E0 = $C80C
BEQ takes a signed 8-bit number, not an unsigned one.

alphashock
Posts: 4
Joined: Wed Mar 25, 2020 7:02 am

Re: branch instruction page cross timing

Post by alphashock » Mon Apr 20, 2020 11:22 am

Oh wow. You are a life saver. Thank you.

I searched a little bit and actually 6502.txt gives a good RELATIVE addressing mode explanation:
This instruction will check the zero status bit. If it is set, 39 decimal will be subtracted from the program counter and execution continues from that address. If the zero status bit is not set, execution continues from the following instruction.
Are there any other instructions I should recheck to make sure surprises like that do not happen?

Post Reply