All About The Status Register
Louis F. Sander
The status registers have always been a mystery to the beginning machine language programmer. This article will help clear up the mystery.
All but the simplest machine language programs make use of the 6502's seven processor status flags, and any ML programmer worth his salt masters their functions and uses. Like almost everything in ML programming, the flags operate in a straightforward and unambiguous way, but they are full of mystery for the beginner.
If you've started ML programming, but are confused by that NV-BDIZC business, this article will help you understand it. It includes a fully explained ML demo program, identically executable on a Commodore 64/PET/CBM, Apple, or Atari computer.
These explanations will assume that you have some ML knowledge and at least a beginning grasp of hexadecimal arithmetic.
Let's start by defining a register, which is a circuit inside a processor. Registers have the characteristics of memory locations, in that data can be written to them or read from them. But they often don't have addresses as such, since they are used internally by the microprocessor itself. The accumulator is the most familiar register, but there are many others in your computer.
The 6502 has an internal 8-bit register, variously called the flags register, processor status register, or P register, the bits of which are set or cleared by the results of various operations. In this context, set means equal to 1, and cleared means equal to 0. At times the bits are set and cleared, or conditioned, automatically by the 6502 chip itself; other times they are conditioned by specific program instructions. Any book on 6502 programming will show you each instruction's effect on the status bits.
Programs can check these bits and use the results of the check for whatever purpose the programmer has in mind, often to decide on a branch. The bits are sometimes called flags, and indeed, they work like the little red flags on rural mailboxes—the postal patron can raise the flag to let the mailman know there's outgoing mail, and the mailman can lower it to signal he's emptied the box. Here are the names and purposes of the eight bits in the status register, moving from left (high-order bit) to right (low-order bit):
N (bit 7)—Negative flag. (Some books call it S, for sign.) The N flag matches the high bit of the result of whatever operation the processor has just completed. If you load $FF (1111 1111) into the Y-register, for example, since the high bit of the Y-register is set, the N flag will be set, too. ML programmers make good use of the N flag. (By the way, even though this is the eighth bit, we call it bit 7, because computers start numbering things at 0.) In a computer technique called twos complement arithmetic, the high-order bit of a number is set to 1 if the number is negative, and cleared to 0 if it's positive, and that's where the N flag gets its name.
V (bit 6)—Overflow flag. This flag is important in twos complement arithmetic, but elsewhere it is rarely used. In the interest of simplicity, we'll say no more about it.
Bit 5 has no name, and is always set to 1. Since nothing can change it, it is of no use to the programmer.
B (bit 4)—Break flag, set whenever a BRK instruction is executed, clear at all other times. Rarely used by beginners.
D (bit 3)—Decimal flag. When D is set by the programmer, the 6502 does its arithmetic in BCD, binary coded decimal, which is yet another exotic type of computer math. Fortunately for nonexperts, it's seldom used, and the beginner's only concern with the D flag is to be sure it is not set unintentionally, because when it is, program behavior can be bizarre.
I (bit 2)—Interrupt mask. When this bit is set, the computer will not honor interrupts, such as those used for keyboard scanning in many computers. It is widely used, but so different from the other flags that we'll say no more about it.
Z (bit 1)—Zero flag. This one's used a great deal, and basically the computer sets it when the result of any operation is zero. Load the X-register with $00, and you set the zero flag. Subtract $32 from $32, and you do the same. Many 6502 instructions affect the Z flag, and there's always a "zero or not-zero" aspect to it, but it's not always obvious to the novice when a zero condition exists. This is probably the most important of the flags, and if you master it, mastery of the others will be easy.
C (bit 0)—Carry flag. Carry is set whenever the accumulator rolls over from $FF to $00 (just like the odometer on a car, rolling over from all nines to all zeros). It's also set by various rotation and comparison instructions. The carry flag is about as important as the Z flag, and a little more mysterious, at least to me, but its operation is really rather simple.
Next month we'll go through some practical examples to demonstrate exactly how everything works.