CPU status flag behavior: Difference between revisions
(→The B flag: "byte pushed on stack" rather than "status pushed on stack") |
(i know you may think this dead horse has been thoroughly beaten, but i'm not negating what's been stated about the B flag, i'm only clarifying it.) |
||
Line 5: | Line 5: | ||
<pre> | <pre> | ||
7654 3210 | 7654 3210 | ||
|| | || | |||| | ||
|| | || | |||+- C: 1 if last addition or shift resulted in a carry, or if | ||
|| | || | ||| last subtraction resulted in no borrow | ||
|| | || | ||+-- Z: 1 if last operation resulted in a 0 value | ||
|| | || | |+--- I: Interrupt priority level | ||
|| | || | | (0: /IRQ and /NMI get through; 1: only /NMI gets through) | ||
|| | || | +---- D: 1 to make ADC and SBC use binary-coded decimal arithmetic | ||
|| | || | (ignored on second-source 6502 like that in the NES) | ||
|| +------ B: see note below | |||
|+-------- V: 1 if last ADC or SBC resulted in signed overflow, | |+-------- V: 1 if last ADC or SBC resulted in signed overflow, | ||
| or D6 from last BIT | | or D6 from last BIT | ||
Line 19: | Line 20: | ||
== The B flag == | == The B flag == | ||
There are six and only six flags in the processor status register. | There are six and only six flags in the processor status register within the CPU. | ||
Despite what some 6502 references might appear to claim on a first reading, there is no "B flag" in the | Despite what some 6502 references might appear to claim on a first reading, there is no "B flag" stored within the CPU's status register. | ||
Two interrupts (/[[IRQ]] and /[[NMI]]) and two instructions (PHP and BRK) push the flags to the stack. In the byte pushed, bit 5 is always set to 1, and bit 4 is 1 if from an instruction (PHP or BRK) or 0 if from an interrupt line being pulled low (/IRQ or /NMI). This is the only time and place where the B flag actually exists: not in the status register itself, but in bit 4 of the copy that is written to the stack. | |||
{| class="tabular" | {| class="tabular" | ||
|- | |- |
Revision as of 08:32, 2 September 2013
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 (see Status flags); 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:
7654 3210 || | |||| || | |||+- C: 1 if last addition or shift resulted in a carry, or if || | ||| last subtraction resulted in no borrow || | ||+-- Z: 1 if last operation resulted in a 0 value || | |+--- I: Interrupt priority level || | | (0: /IRQ and /NMI get through; 1: only /NMI gets through) || | +---- D: 1 to make ADC and SBC use binary-coded decimal arithmetic || | (ignored on second-source 6502 like that in the NES) || +------ B: see note below |+-------- V: 1 if last ADC or SBC resulted in signed overflow, | or D6 from last BIT +--------- N: Set to bit 7 of the last operation
The B flag
There are six and only six flags in the processor status register within the CPU. Despite what some 6502 references might appear to claim on a first reading, there is no "B flag" stored within the CPU's status register.
Two interrupts (/IRQ and /NMI) and two instructions (PHP and BRK) push the flags to the stack. In the byte pushed, bit 5 is always set to 1, and bit 4 is 1 if from an instruction (PHP or BRK) or 0 if from an interrupt line being pulled low (/IRQ or /NMI). This is the only time and place where the B flag actually exists: not in the status register itself, but in bit 4 of the copy that is written to the stack.
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 |
Two instructions (PLP and RTI) pull a byte from the stack and set all the flags. They ignore bits 5 and 4.
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.