6502 flags C, N, Z, V and tests

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

6502 flags C, N, Z, V and tests

Post by Symoon »

In my recent works, not being comfortable with assembler, I had to look for many information sites. One thing I never found and thought it was missing, was a summary of the flags that could be set by the user, and tested.
In the end, only the Carry flag can be fully operated and tested with specific instructions.

Code: Select all

Set instruction   Test instruction  Flag
-----------------------------------------
 SEC               BCC              C (carry)
 CLC               BCS
-----------------------------------------
 none              BPL              N (negative)
                   BMI
-----------------------------------------
 none              BEQ              Z (zero)
                   BNE
-----------------------------------------
 CLV               BVC              V (overflow)
                   BVS
-----------------------------------------
 SED               none             D (decimal)
 CLD 
christian
Pilot Officer
Posts: 96
Joined: Sun Nov 24, 2013 9:58 pm

Re: 6502 flags C, N, Z, V and tests

Post by christian »

Sometimes you can also use the BIT instruction:
"BIT sets the Z flag as though the value in the address tested were ANDed with the accumulator. The S and V flags are set to match bits 7 and 6 respectively in the value stored at the tested address."

I have often seen using this instruction to set the V bit to 1 like this:

Code: Select all

...
xxyy 60 RTS
...

SEV:
     2C yy xx BIT xxyy
or

Code: Select all

...
xxyy 40 RTI
...

SEV:
     2C yy xx BIT xxyy
ThomH
Flying Officer
Posts: 238
Joined: Thu Oct 13, 2016 9:55 pm

Re: 6502 flags C, N, Z, V and tests

Post by ThomH »

In case it helps to offer any exposition as to `CLV`, 6502s have a dedicated input pin, SO, which when asserted will set overflow. It's there in case the hardware design requires a low-latency polling input:

Code: Select all

          CLV           ; clear V in preparation to wait...
    .loop BVC loop	; repeat until V is set
That gets you to the top of whatever responds to the external hardware in at most 3 cycles, whereas an interrupt takes at least 8 and possibly as many as 15, and having the 6502 constantly poll an address in memory would cost 6 even if you put it on the zero page (and would probably mean more electronics).

That suggests that you need a cheap way to clear the overflow flag, but it doesn't really matter if you've no cheap way to set it.

An example use of this feature is the Commodore 1540 and 1541 disk drives; they have 6502s in them and V is signalled to indicate that the next byte has been assembled from the disk.
User avatar
Dbug
Site Admin
Posts: 4438
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: 6502 flags C, N, Z, V and tests

Post by Dbug »

Interesting, did not know about this overflow trick :)
User avatar
Chema
Game master
Posts: 3013
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Re: 6502 flags C, N, Z, V and tests

Post by Chema »

Same here... Did not know that either.
User avatar
NekoNoNiaow
Flight Lieutenant
Posts: 272
Joined: Sun Jan 15, 2006 10:08 pm
Location: Montreal, Canadia

Re: 6502 flags C, N, Z, V and tests

Post by NekoNoNiaow »

I presume this is already known but for completion sake, CPU status flags can be manipulated indirectly using the PLP instruction:
  • Set A to the desired flag values.
  • Push A on the stack with PHA.
  • Execute PLP, this will set the status flags to the value just stored on the stack.
If speed is not a concern, all status flags can thus be set or reset as desired using PLP.

Also, one could consider the RTI instruction similarly since it also sets the status flags to a value pulled from the stack.
User avatar
Symoon
Archivist
Posts: 2301
Joined: Sat Jan 14, 2006 12:44 am
Location: Paris, France

Re: 6502 flags C, N, Z, V and tests

Post by Symoon »

All those other options are very interesting, keep bringing them on ;)
(Initially I made this table was because I needed extremely compact and fast ways to set/test/branch; I counted bytes and cycles many, many times... But having other ways to do is very interesting and can sometimes spare a specific instruction ! ).
ThomH
Flying Officer
Posts: 238
Joined: Thu Oct 13, 2016 9:55 pm

Re: 6502 flags C, N, Z, V and tests

Post by ThomH »

Given that `LDA`, `LDX` and `LDY` all set N and Z and all work as immediate instructions, if you have a register you don't mind overwriting then you can set N that way, and if you're setting N=0 then you can also pick a value for Z. It's two cycles, so it costs the same as a `SEC`, etc.

E.g.

Code: Select all

    LDX #$80	; sets N, resets Z
    LDX #$00	; resets N and sets Z
    LDX #$01	; resets N and Z
If you can't afford the register, wrapping a `LDA` in `PHA`/`PLA` allows you to adjust those flags without losing the register contents. Compare and contrast with a more direct `LDA`/`PHA`/`PLP` which lets you be explicit about all the flags in the same number of cycles but overwrites A.
Post Reply