Jump to content



0

Branches? how do these really breakdown


6 replies to this topic

#1 grafixbmp OFFLINE  

grafixbmp

    Dragonstomper

  • 659 posts
  • Location:South Central US

Posted Tue Sep 8, 2009 10:05 PM

THe 6502 opcode guides I have give really cryptic general info as to encase each code in a generic cookie cuter shape. But by what I am going by, it lacks something to be desired. Are there better ones? if so, which would anyone here recommend?

Attached File  6502.txt   53.19K   69 downloads

I do have a few specifics:

N Z C I D V

N = Negative numbers?
Z = Result of something is Zero
C = Carry bit
I
D = Binary coded decimal
V = o'V'erflow

BCC = Branch on carry clear "C" = 0: I guess this means the branch happens when this bit is 0

BCS = Brance on carry set "C" = 1:The opposite from above where the carry is 1

BEQ = brance on result 0 Z = 0: Result of what a compare? It says the flag is Z. I guess this means "Zero". Is this automaticaly based on Accumulator, X, or Y index or does one need to transfer the result over?

BIT = Test bits in memory with accumuloator "Z"?: ? Still trying to fully figure this out or what it is best/good for.Something about a compare. Is this about testing the status of specific bits in the accumulator and a specific memory address.

BMI = Branch on minus "N" = 1: Minus of what? Like if 2's compliment numbers are used and the number has got a 1 indicating that is is a negative number?

BNE = Brance on result not Zero: basicaly if no register is a zero then this is a 1. Does this go simultaneously for The accumulator and x and y index registers?

BPL = Branch on result plus "N" = 1: Meaning a positive number during 2's complement? Or opposite of a BMI?

BVC = Branch on overflow clear "V" Is this some kind of extention of 8 bits during an operation where it would act like a 9'th bit?

CLC = Carry clear Just sets "C" to 0?

There are a few others that are fuzzy but these branches dealing with the "Flag registers?" are the ones that I want to get strait.

#2 e1will OFFLINE  

e1will

    Moonsweeper

  • 338 posts

Posted Wed Sep 9, 2009 12:46 AM

View Postgrafixbmp, on Tue Sep 8, 2009 10:05 PM, said:

BEQ = brance on result 0 Z = 0: Result of what a compare? It says the flag is Z. I guess this means "Zero". Is this automaticaly based on Accumulator, X, or Y index or does one need to transfer the result over?

A compare, or a load, or a variety of other things. For example:

LDA #55         ; sets the Z flag to 0, since 55 is not zero
LDY #0          ; sets the Z flag to 1
LDX #33         ; sets the Z flag to 0
CPX #33         ; sets the Z flag to 1, since X=33
CPY #33         ; sets the Z flag to 0, since Y is not 33
BEQ Someplace   ; does not branch, since the Z flag is 0 (as set by the CPY immediately above.)

Hope this helps.
--Will

#3 roland p ONLINE  

roland p

    Stargunner

  • 1,413 posts
  • RLA
  • Location:The Netherlands

Posted Wed Sep 9, 2009 1:07 AM

This made it clear for me: http://www.obelisk.d.../reference.html

#4 grafixbmp OFFLINE  

grafixbmp

    Dragonstomper

  • 659 posts
  • Location:South Central US

Posted Wed Sep 9, 2009 1:05 PM

View Poste1will, on Wed Sep 9, 2009 12:46 AM, said:

View Postgrafixbmp, on Tue Sep 8, 2009 10:05 PM, said:

BEQ = brance on result 0 Z = 0: Result of what a compare? It says the flag is Z. I guess this means "Zero". Is this automaticaly based on Accumulator, X, or Y index or does one need to transfer the result over?

A compare, or a load, or a variety of other things. For example:

LDA #55         ; sets the Z flag to 0, since 55 is not zero
LDY #0          ; sets the Z flag to 1
LDX #33         ; sets the Z flag to 0
CPX #33         ; sets the Z flag to 1, since X=33
CPY #33         ; sets the Z flag to 0, since Y is not 33
BEQ Someplace   ; does not branch, since the Z flag is 0 (as set by the CPY immediately above.)

Hope this helps.
--Will

So based upojn this, The flag responds to the last immediate change? If A is a positive number, X is zero and y is 2 but you want to check for the status of y being 0, will this just trigger because x is zero istead? THis makes no sense unless it is checked imediately after a change to one on these 3 registers and reflects that specific change imediately. What can I do if I want the check to reflect a specific register but I can't change it at that time? SOL?

#5 e1will OFFLINE  

e1will

    Moonsweeper

  • 338 posts

Posted Wed Sep 9, 2009 1:14 PM

View Postgrafixbmp, on Wed Sep 9, 2009 1:05 PM, said:

What can I do if I want the check to reflect a specific register but I can't change it at that time?

Not sure I follow... whichever register you want to check will have an associate 'compare' opcode: CMP for A, CPX for X, CPY for Y. You typically (but not always) will follow one of those compares immediately with a branch.

The branch condition is based on whichever compare (or load, or add/subtract operation, etc.) last set or cleared the bit you're testing.

--Will

#6 SeaGtGruff ONLINE  

SeaGtGruff

    River Patroller

  • 4,543 posts
  • Location:Georgia, USA

Posted Wed Sep 9, 2009 3:58 PM

Different status flags are updated by different instructions, and any decent listing of 6502 assembler opcodes will indicate which status flags will be affected by each instruction. I like to use the opcodes listing at the 6502.org web site (http://www.6502.org/...502opcodes.html), just because www.6502.org is an easy URL for me to remember. :) For example, it says

ADC (ADd with Carry)
Affects Flags: S V Z C
Thus, when you use an ADC instruction, it will either set or clear the S, V, Z, and C flags. (S is just another name for N-- S for Sign, N for Negative.) Most instructions will affect at least one or two flags, but there are a few instructions that don't affect any flags. For example, the branch instructions don't affect any flags (although they are affected *by* the flags); JMP and JSR don't affect any flags; NOP doesn't affect any flags; RTS doesn't affect any flags; and the store instructions don't affect any flags.

You don't necessarily have to do a branch right after a compare instruction, addition, subtraction, etc., as long as the other instructions that come between the comparison and the branch don't change the flag you're interested in. For example, consider the following bits of code from my "bitmap" program:

   LDX field                  ; 03   ; 73 ; 219 ; 151

   STY WSYNC                  ; 03   ; 00 ; 000 ; -68
   STY VBLANK                 ; 03   ; 03 ; 009 ; -59

   BNE active_lines_1         ; 02++ ; 05 ; 015 ; -53
Here, the BNE branch is taken (or not) based on the results of the LDX instruction. It would have been easier to understand the code if the LDX and BNE had been coded one after the other, but I needed the BNE to end at cycle 5, so that's why the two STY instructions were placed between the LDX and the BNE. Fortunately, the STY instruction doesn't change any flags. If field is not equal to 0, branch to active_lines_1, else (if field *is* equal to 0) fall through to the next statement.

   CPY #192                   ; 02   ; 67 ; 201 ; 133
   STY WSYNC                  ; 03   ; 00 ; 000 ; -68
   STY HMOVE                  ; 03   ; 03 ; 009 ; -59

   BNE active_lines_1         ; 02++ ; 05 ; 015 ; -53
This is similar to the preceding example, and is coded in this order for the same reason-- so the BNE will end at cycle 5. If the Y register is not equal to 192, branch to active_lines_1; else (if Y *is* equal to 192) fall through to the next statement.

   CPY #64                    ; 02   ; 08 ; 024 ; -44

   LDA (column_01),Y          ; 05+* ; 13 ; 039 ; -29
   STA GRP0                   ; 03   ; 16 ; 048 ; -20

   LDA (column_03),Y          ; 05+  ; 21 ; 063 ; -05
   STA GRP1                   ; 03   ; 24 ; 072 ; 004

   LDA (column_09),Y          ; 05+* ; 29 ; 087 ; 019
   TAX                        ; 02   ; 31 ; 093 ; 025

   LDA (column_05),Y          ; 05+* ; 36 ; 108 ; 040
   STA GRP0                   ; 03   ; 39 ; 117 ; 049

   LDA (column_07),Y          ; 05+  ; 44 ; 132 ; 064
   STA GRP1                   ; 03   ; 47 ; 141 ; 073

   STX GRP0                   ; 03   ; 50 ; 150 ; 082

   LDA (column_11),Y          ; 05+  ; 55 ; 165 ; 097
   STA GRP1                   ; 03   ; 58 ; 174 ; 106

   BCS load_data              ; 02++ ; 60 ; 180 ; 112
This one is a little more interesting. The BCS branch is taken (or not) depending on the results of the CPY instruction. The CPY instruction affects the N, Z, and C flags-- Negative, Zero, and Carry. The STA and STX instructions don't affect any of the flags, but the LDA and TAX instructions affect the N and Z flags. As it happens, I didn't care about those flags, just the C flag, so this worked out perfect for me. If Y is greater than or equal to 64, branch to load_data; else (if Y is less than 64) fall through to the next statement. The stores to the player graphics registers had to be timed just right, but it turned out I had 2 cycles free on the line, so I could have replaced the CPY with a NOP instruction, and then put the CPY right before the BCS. However, at the time I was writing the code, I didn't know I was going to end up with 2 cycles free, so that's why I arranged the code in the order I did. :)

Michael

#7 AtariLeaf OFFLINE  

AtariLeaf

    Quadrunner

  • 6,287 posts
  • Location:Ontario Canada

Posted Wed Sep 9, 2009 6:09 PM

I use a woodchipper to break down branches.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users