Status flags: Difference between revisions
(→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 | 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
- ↑ Article: The Overflow (V) Flag Explained
- ↑ Article: Beyond 8-bit Unsigned Comparisons, Signed Comparisons