nestest branch instruction address bus

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

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

nestest branch instruction address bus

Post by alphashock » Wed Mar 25, 2020 7:44 am

Hi,

I'm implementing cycle accurate 6502 CPU emulation. My emulator generates the same output as basic instruction nestest log, although I can see some differences in address/data bus output attached to viewtopic.php?t=13283

nestest bus cycles output

Code: Select all

C72F  A:00 X:00 Y:00 P:27 SP:FB CPUC:24
      READ      $C72F => $B0
      READ      $C730 => $04
      READ      $C731 => $A2
my output

Code: Select all

C72F  A:00 X:00 Y:00 P:27 SP:FB CPUC:24
      READ      $C72F => $B0
      READ      $C730 => $04
      READ      $C735 => $EA

According to "Synertek Hardware Manual" branch operations cycle breakdown look something like this

Code: Select all

		Address Bus				Data Bus
T0		PC					OPCODE
T1		PC + 1					OFFSET
T2*		PC + 2 + OFFSET				OPCODE
T3**	        PC + 2 + OFFSET + C			OPCODE

*  skip if branch not taken
** skip if branch not taken; skip if branch operation doesn't cross page boundary
The carry flag is set so the 3rd cycle - T2 is executed. There is no carry so no 4th cycle. Also the next instruction to be executed is @ C735 which makes sense that the address holds C735. What am I missing here?

6502_cpu.txt mentions that the high address might be wrong, but this is not the case here.

User avatar
Quietust
Posts: 1607
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: nestest branch instruction address bus

Post by Quietust » Wed Mar 25, 2020 9:20 am

alphashock wrote:
Wed Mar 25, 2020 7:44 am
According to "Synertek Hardware Manual" branch operations cycle breakdown look something like this

Code: Select all

		Address Bus				Data Bus
T0		PC					OPCODE
T1		PC + 1					OFFSET
T2*		PC + 2 + OFFSET				OPCODE
T3**	        PC + 2 + OFFSET + C			OPCODE

*  skip if branch not taken
** skip if branch not taken; skip if branch operation doesn't cross page boundary
That description is incorrect - state T2 fetches from PC + 2, and state T3 fetches from PC + 2 + OFFSET; it's not until T0 of the next instruction that you'd fetch from PC + 2 + OFFSET + C.

Of course, technically all of those cycles are fetching from PC, since PC gets updated in real time as they proceed:
* T0 fetches the byte at PC (opcode) and post-increments PC
* T1 fetches the byte at PC (operand) and post-increments PC
* If the branch was taken, T2 fetches the byte at PC (what would've been the next opcode) and then adds the previous operand to PCL. If not, it runs T0 for the next instruction.
* If T2 resulted in a carry, T3 fetches the byte at PC (what would've been the next opcode, but in the wrong page) and then fixes PCH. If not, it runs T0 for the next instruction.

For reference, I got the above information from "64doc":

Code: Select all

  Relative addressing (BCC, BCS, BNE, BEQ, BPL, BMI, BVC, BVS)

        #   address  R/W description
       --- --------- --- ---------------------------------------------
        1     PC      R  fetch opcode, increment PC
        2     PC      R  fetch operand, increment PC
        3     PC      R  Fetch opcode of next instruction,
                         If branch is taken, add operand to PCL.
                         Otherwise increment PC.
        4+    PC*     R  Fetch opcode of next instruction.
                         Fix PCH. If it did not change, increment PC.
        5!    PC      R  Fetch opcode of next instruction,
                         increment PC.

       Notes: The opcode fetch of the next instruction is included to
              this diagram for illustration purposes. When determining
              real execution times, remember to subtract the last
              cycle.

              * The high byte of Program Counter (PCH) may be invalid
                at this time, i.e. it may be smaller or bigger by $100.

              + If branch is taken, this cycle will be executed.

              ! If branch occurs to different page, this cycle will be
                executed.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

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

Re: nestest branch instruction address bus

Post by alphashock » Wed Mar 25, 2020 9:48 am

* If the branch was taken, T2 fetches the byte at PC (what would've been the next opcode) and then adds the previous operand to PCL. If not, it runs T0 for the next instruction.
I see. So the address bus still contains PC (original PC + 2 referring to the format above), although the PCL is modified by the end of the cycle.

Thank you.

Post Reply