Status flags: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(→‎The B flag: rewrite for smoothness: B flag represents a transient state)
(→‎The B flag: there is no B flag, do not imply there is a B flag, D1x1 is not the B flag, visual6502 p4 is not the B flag)
Line 66: Line 66:
The B flag is not conventionally called part of the processor status register.
The B flag is not conventionally called part of the processor status register.
This is because it represents a transient state, not a state that persists from one instruction to another.
This is because it represents a transient state, not a state that persists from one instruction to another.
The CPU clears B during an interrupt, sets B when the interrupt finishes, and disregards bits 5 and 4 when reading flags from the stack in the PLP or RTI instruction.
The CPU pushes a value with B clear during an interrupt, pushes a value with B set in response to PHP or BRK, and disregards bits 5 and 4 when reading flags from the stack in the PLP or RTI instruction.


{| class="tabular"
{| class="tabular"

Revision as of 06:46, 15 December 2022

The flags register, also called processor status or just P, is one of the six architectural registers on the 6502 family CPU. It is composed of six one-bit registers; instructions modify one or more bits and leave others unchanged.

Instructions that save or restore the flags map them to bits in the architectural 'P' register as follows:

7  bit  0
---- ----
NVss DIZC
|||| ||||
|||| |||+- Carry
|||| ||+-- Zero
|||| |+--- Interrupt Disable
|||| +---- Decimal
||++------ No CPU effect, see: the B flag
|+-------- Overflow
+--------- Negative
  • The PHP (Push Processor Status) and PLP (Pull Processor Status) instructions can be used to retrieve or set this register directly via the stack.
  • Interrupts, including the NMI and also the pseudo-interrupt BRK instruction, implicitly push the status register to the stack.
  • Interrupts returning with RTI will implicitly pull the saved status register from the stack.

C: Carry

  • After ADC, this is the carry result of the addition.
  • After SBC or CMP, this flag will be set if no borrow was the result, or alternatively a "greater than or equal" result.
  • After a shift instruction (ASL, LSR, ROL, ROR), this contains the bit that was shifted out.
  • Increment and decrement instructions do not affect the carry flag.
  • Can be set or cleared directly with SEC, CLC.

Z: Zero

  • After most instructions that have a value result, this flag will either be set or cleared based on whether or not that value is equal to zero.

I: Interrupt Disable

  • When set, all interrupts except the NMI are inhibited.
  • Can be set or cleared directly with SEI, CLI.
  • Automatically set by the CPU when an IRQ is triggered, and restored to its previous state by RTI.
  • If the /IRQ line is low (IRQ pending) when this flag is cleared, an interrupt will immediately be triggered.

D: Decimal

  • On the NES, this flag has no effect.
  • On the original 6502, this flag causes some arithmetic instructions to use binary-coded decimal representation to make base 10 calculations easier.
  • Can be set or cleared directly with SED, CLD.

V: Overflow

  • ADC and SBC will set this flag if the signed result would be invalid[1], necessary for making signed comparisons[2].
  • BIT will load bit 6 of the addressed value directly into the V flag.
  • Can be cleared directly with CLV. There is no corresponding set instruction.

N: Negative

  • After most instructions that have a value result, this flag will contain bit 7 of that result.
  • BIT will load bit 7 of the addressed value directly into the N flag.

The B flag

While there are only six flags in the processor status register within the CPU, the value pushed to the stack has two additional bits. These do not represent a register that can hold a value but can be used to distinguish how the flags were pushed. Bit 5 is always pushed as 1. Bit 4, called the "B flag", represents a signal in the CPU controlling whether or not it was processing an interrupt when the flags were pushed. Interrupts (/IRQ and /NMI) push a value with bit 4 cleared to 0; instructions (PHP and BRK) push a value with bit 4 set to 1.

The B flag is not conventionally called part of the processor status register. This is because it represents a transient state, not a state that persists from one instruction to another. The CPU pushes a value with B clear during an interrupt, pushes a value with B set in response to PHP or BRK, and disregards bits 5 and 4 when reading flags from the stack in the PLP or RTI instruction.

Instruction Bits 5 and 4 Side effects after pushing
PHP 11 None
BRK 11 I is set to 1
/IRQ 10 I is set to 1
/NMI 10 I is set to 1

The only way for an IRQ handler to distinguish /IRQ from BRK is to read the flags byte from the stack and test bit 4. The slowness of this is one reason why BRK wasn't used as a syscall mechanism. Instead, it was more often used to trigger a patching mechanism that hung off the /IRQ vector: a single byte in PROM, UVEPROM, flash, etc. would be forced to 0, and the IRQ handler would pick something to do instead based on the program counter.

Unlike bits 5 and 4, bit 3 actually exists in P, even though it doesn't affect the ALU operation on the 2A03 or 2A07 CPU the way it does in MOS Technology's own chips.

External links

References