Page 1 of 1
Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 7:06 am
by PolarBITS
I've read everywhere and I can't seem to find proper documentation for them. I read that they're used for looping and are dependent on certain flags, but just from their descriptions I can't make out exactly which ones. Can someone help me here?
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 7:44 am
by tepples
Which "descriptions" are you looking at?
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 7:53 am
by PolarBITS
I'm using this
http://www.6502.org/tutorials/6502opcodes.html
Also I've used the nesdev wiki.
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 9:43 am
by rainwarrior
Each branch depends on one flag.
Each branch argument is a 1-byte signed value that is added to the PC if the flag condition is true; otherwise the instruction does nothing. (If the branch is taken, 1 or 2 extra cycles are spent adding to argument to the PC.)
BEQ branches if the Z (zero) flag is set.
BNE branches if the Z flag is clear.
etc.
My favourite opcode reference is here:
http://www.obelisk.me.uk/6502/reference.html
If you're looking for a cycle-by-cycle breakdown, though, it doesn't go into that kind of detail.
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 9:48 am
by tokumaru
rainwarrior wrote:If the branch is taken, 2 or 3 extra cycles are spent adding to argument to the PC.
That's not quite right. Branch instructions will always use at least 2 cycles (time taken to fetch the opcode and the argument from memory), and if the branch is taken, 1 or 2 extra cycles are spent adding to argument to the PC (1 cycle if only the low byte of the PC changes, 2 if the high byte is also affected).
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 9:50 am
by rainwarrior
I had already fixed that typo while you were quoting me. It's accurately described in both the given references, though, so I think we're OK.
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 9:52 am
by tokumaru
It's still wrong though, it's 1 or 2 extra cycles. The +1 and +2 in that documentation are not cumulative.
The obelisk reference is my favorite too, but I can see how someone could misinterpret the information about those extra cycles.
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 04, 2017 12:09 pm
by rainwarrior
tokumaru wrote:The +1 and +2 in that documentation are not cumulative.
It was just a typo, there was no "cumulative" meaning behind the mistake.
Re: Implementing BEQ and other Branch Instructions?
Posted: Thu May 11, 2017 7:53 am
by Oziphantom
If you are looking to implement a 6502 - this doc is probably useful to you
http://www.zimmers.net/anonftp/pub/cbm/ ... data/64doc
See the "6510 Instruction Timing" section, note that the 6510 is identical to NMOS 6502 for its instruction set and timings.
For example a Branch ( relative address mode it gives )
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.
It also covers how the BCD maths and how Illegal opcodes work. Although a better document on them can be found here
http://csdb.dk/release/?id=152327
Re: Implementing BEQ and other Branch Instructions?
Posted: Sat May 13, 2017 10:57 pm
by Hangin10
(quietly updates his emulator to not have taken branches to a different page take 5 cycles)
Re: Implementing BEQ and other Branch Instructions?
Posted: Sun May 14, 2017 12:43 am
by Oziphantom
Its tricky as the 5th is actually the 1st of the next opcode. So it depends on how your system is implemented but basically it only takes 4 cycles max, as the fetch opcode is the first cycle of the next opcode.
Code: Select all
bne takenNextPage - 1 load bne 1
- 2 load offset 2
- 3 add PCL 3
- 4 add PCH 4
takenNextPage
lda #$00 - 1 load lda 5
- 2 load 00
"The opcode fetch of the next instruction is included to
this diagram for illustration purposes."
Re: Implementing BEQ and other Branch Instructions?
Posted: Mon May 15, 2017 9:00 pm
by Hangin10
Oziphantom wrote:Its tricky as the 5th is actually the 1st of the next opcode. So it depends on how your system is implemented but basically it only takes 4 cycles max, as the fetch opcode is the first cycle of the next opcode.
Code: Select all
bne takenNextPage - 1 load bne 1
- 2 load offset 2
- 3 add PCL 3
- 4 add PCH 4
takenNextPage
lda #$00 - 1 load lda 5
- 2 load 00
"The opcode fetch of the next instruction is included to
this diagram for illustration purposes."
I actually used that document for most of the opcodes. I must have just thought branches were simple enough to just use the 'obelisk' reference, but ended interpreting that one as the +1/2 as cumulative. Had I looked back at this per-cycle document, I would have done it right.