CPU status flag behavior: Difference between revisions
m (→The B flag: no syscall) |
(→The B flag: in http://nesdev.parodius.com/bbs/viewtopic.php?p=64224#64224 koitsu said this page was "highly convoluted") |
||
Line 18: | Line 18: | ||
== The B flag == | == The B flag == | ||
There is no "B flag" | There are six and only six flags in the processor status register. | ||
Despite what some 6502 references might appear to claim on a first reading, there is no "B flag" in the CPU. | |||
Two | Two interrupts (/[[IRQ]] and /[[NMI]]) and two instructions (PHP and BRK) push the flags to the stack. 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 (/IRQ or /NMI). | ||
{| class="tabular" | {| class="tabular" | ||
|- | |- | ||
Line 33: | Line 34: | ||
| /[[NMI]] || 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 flags | Two instructions (PLP and RTI) pull a byte from the stack and set flags. They ignore bits 5 and 4. | ||
The only way for an IRQ handler to distinguish /IRQ from BRK is to read the flags from the stack and test bit 4. | The only way for an IRQ handler to distinguish /IRQ from BRK is to read the flags from the stack and test bit 4. | ||
The slowness of this is one reason why BRK wasn't used as a syscall mechanism. | 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. | |||
== External links == | |||
*[http://nesdev.parodius.com/bbs/viewtopic.php?p=64224#64224 koitsu's explanation] |
Revision as of 00:14, 15 July 2010
The flags register, also called processor status or just P, is one of the six architectural registers on the 6502 family CPU.
There are six bits in P:
7654 3210 || |||| || |||+- C: 1 if last addition or shift resulted in a carry, or if || ||| last subtraction resulted in || ||+-- 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) |+-------- V: 1 if last ADC or SBC resulted in signed overflow, or | D6 from last BIT read as 0 +--------- N: Set to bit 7 of the last operation
The B flag
There are six and only six flags in the processor status register. Despite what some 6502 references might appear to claim on a first reading, there is no "B flag" in the CPU.
Two interrupts (/IRQ and /NMI) and two instructions (PHP and BRK) push the flags to the stack. 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 (/IRQ or /NMI).
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 flags. They ignore bits 5 and 4.
The only way for an IRQ handler to distinguish /IRQ from BRK is to read the flags 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.