
One caution must be mentioned with regard to the use of the 6502 instruction set. Every computer language has its own syntax, the way each command must be written for the computer to understand it. Different assemblers for the ATARI require slightly different syntax, described in detail in Chapter 6.
In this Appendix, we shall learn the commands which the 6502 can execute. The complete set of commands for the 6502 is generally referred to as the 6502 instruction set. Here the instructions are described in alphabetical order for easy reference. Along with each instruction you will find:
- Examples of its use
- Descriptions of the various addressing modes available for that instruction (see Chapter 5)
- The effect of each instruction upon the various flags in the processor status register (see Chapter 3)
ADC Add with Carry
THE INSTRUCTION
As discussed in Chapter 4, each instruction for the 6502 is abbreviated into a three-letter code called a mnemonic. The first instruction, Add with Carry, is the only instruction available for carrying out addition of two numbers. Here's an example of its use:
.
;these represent
. ;some previous
. ;instructions
ADC #2 ;add 2 to the contents of the accumulator
.
.
. ;some previous
. ;instructions
ADC #2 ;add 2 to the contents of the accumulator
.
.
Let's examine what happens when we execute this instruction. The 6502 takes whatever is already contained in the accumulator and adds to it the decimal number 2. The resulting sum remains in the accumulator, awaiting further instructions. However, there is a complication. Remember, the name of this instruction is Add with Carry. What about the carry? Remember that the Carry bit is one of the flags in the processor status register. Whenever the ADC instruction is encountered, the Carry bit is added to the sum in the accumulator. Let's suppose that just before encountering this instruction, we had stored a zero in the accumulator, and the Carry bit was a zero, as well. The sum stored in the accumulator following the execution of this instruction would still be 2, as described. However, if the Carry bit had been a 1, then the sum would have been 3. Schematically, this addition is as follows:
Accumulator
Carry Bit Instruction = > Sum
Carry Bit
0 0 ADC #2 = > 2 0
0 1 ADC #2 = > 3 0
0 0 ADC #2 = > 2 0
0 1 ADC #2 = > 3 0
Note that if the Carry bit is initially 1, it is reset to zero after the ADC instruction is executed. This makes sense, since we've already used the carry. If it wasn't reset to zero by the 6502, we might use the Carry bit twice without realizing it.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The 6502 also sets the Carry bit appropriately, as in the following examples:
Accumulator
Carry Bit Instruction = > Sum
Carry Bit
253 0 ADC #6 = > 3 1
253 1 ADC #6 = > 4 1
253 0 ADC #6 = > 3 1
253 1 ADC #6 = > 4 1
In the first example, 253 + 6 = 259, but we know that the largest number the accumulator can hold is 255. The number 256 represents zero, with a carry of one, so 259 is 3 with a carry of 1. The number 3 is stored in the accumulator and the Carry bit is set.
In the second example, the Carry bit starts at 1, so when it is added into the sum, the sum is 4. Remember, after the Carry bit is used, the 6502 resets it to zero. So why does example 2 end up with the Carry bit set? The sum was greater than 255, so the Carry bit was set before execution of the instruction was completed.
We have already discussed the ability of the 6502 to operate in decimal mode. Note here that the largest number the accumulator can store in decimal mode is 99. The Carry bit is set following an ADC instruction in decimal mode if the sum exceeds 99.
Several other flags in the processor status register are also conditioned by the ADC instruction. The Overflow bit, V, is set when bit 7, the most significant bit, is changed because of the addition. The Negative flag, N, is set if the addition produces a number greater than 127; that is, when the most significant bit, bit 7, is a 1. Remember, to the 6502, any number between 128 and 255 is a negative number, because its most significant bit is a 1. Finally, the Zero flag, Z, is set if the result of the addition is zero. Some examples of these conditions are shown below:
| A N Z C V | Instruction | = > | A N Z C V | Comments |
|
|
||||
|
2 0 0 0 0 |
ADC #3 | =
> |
5 0 0 0 0 |
Straight addition |
|
2 0 0 1 0 |
ADC #3 | = > |
6 0 0 0 0 |
Remember: add the carry! |
|
2 0 0 0 0 |
ADC #254 | =
> |
0 0 0 0 0 |
C and Z flags set |
| 2 0 0 0 0 | ADC #253 | = > | 255
1 0 0 0 |
N and V flags set |
| 253
1 0 0 0 |
ADC #6 | =
> |
3 0 0 1 1 |
C and V set; N reset |
| 125
0 0 1 0 |
ADC #2 | =
> |
128
1 0 0 1 |
N and V set; C reset |
It should now be apparent that by testing the various flags, we can easily obtain a great deal of information about the results of an addition. Instructions for testing these flags are provided and are used frequently in most assembly language programs.
ADDRESSING MODES
The ADC instruction allows any of the same eight addressing modes discussed in Chapter 5 for the LDA instruction. They are illustrated below, with the number of cycles and bytes used for each instruction:
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Immediate | ADC #2 | 2 |
2 |
A+#2 |
| Absolute | ADC $3420 | 4 |
3 |
A + contents of memory $3420 |
| Zero Page | ADC $F6 | 3 |
2 |
A+contents of memory $F6 |
| Zero Page,X | ADC $F6,X | 4 |
2 |
A+contents of memory $F6 + X |
| Absolute,X | ADC $3420,X | 4 |
3 |
A+ contents of memory $3420 + X |
| Absolute,Y | ADC $3420,Y | 4 |
3 |
A+ contents of memory $3420 + Y |
| Ind. Indir. | ADC ($F6,X) | 6 |
2 |
A+contents of addr. at $F6+X |
| Indir.Ind. | ADC ($F6),Y | 5 |
2 |
A+contents
of (address at $F6) + offset Y |
For more complete explanations of these addressing modes, please see Chapter 5.
AND The Logical AND Instruction
THE INSTRUCTION
The AND instruction performs a logical AND of the accumulator and the operand. A logical AND takes two numbers and compares them bit for bit. For each bit, if both numbers being compared contain a 1, the result contains a 1 as well; if either number contains a zero, the result contains a zero in that bit. Let's look at an example in which the accumulator contains the number 5:
AND
#$0E
The easiest way to visualize the AND operation is to convert each of the two numbers being compared to binary nomenclature, as follows:
Hex.
Binary
#5 = #%00000101
#$0E = #%00001110
result = #%00000100 = #4
#5 = #%00000101
#$0E = #%00001110
result = #%00000100 = #4
We can easily see that the only bits set to 1 in the result are those in which both numbers being compared have a 1, in this example, bit 2. Let's try another example. The accumulator contains 147, and this is the instruction:
AND
#$1D
As above, we convert to binary:
#147 =
#%10010011
#$1D = #%00011101
result = #%00010001 = #17
#$1D = #%00011101
result = #%00010001 = #17
This fairly straightforward instruction is used frequently, so you should now try an exercise by yourself. We'll assume the accumulator contains the number #$BC, and this is the instruction:
AND
#234
See if you can work out the answer for yourself.
The AND instruction is used to mask a byte in a specific way. For instance, suppose you want to know the value of the low nibble of a number. To find out, you simply AND the number with #$OF Since the high nibble of this number is zero and the low nibble is all ones, the result will be equal to the low nibble of the number you started with. Similarly, to obtain the high nibble you only have to AND with #$F0. Now let's present the answer to the above problem:
#$BC = #%10111100
#234 = #%11101010
result = #$10101000 = #168
#234 = #%11101010
result = #$10101000 = #168
EFFECTS ON THE PROCESSOR STATUS REGISTER
The AND instruction sets the Zero flag if the result is equal to zero, or resets the Zero flag if the result is not equal to zero. This instruction also sets the Negative flag if the result is greater than 127, or resets this flag if the result is less than 128. Several examples of this follow:
|
A |
Z |
N |
Instruction | = > |
A |
Z |
N |
Meaning |
|
|
||||||||
| #5 | 0 |
0 |
AND #8 | = > |
0 |
1 |
0 |
Z set by result = 0 |
| #$FE | 0 |
1 |
AND #$5F | = > | #$5E |
0 |
0 |
N reset by result< 127 |
ADDRESSING MODES
The AND instruction can also be written in any of the same eight addressing modes discussed in Chapter 5 for the LDA instruction.
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Immediate | AND #2 | 2 |
2 |
A |
| Absolute | AND $3420 | 4 |
3 |
A&contents of memory $3420 |
| Zero Page | AND $F6 | 3 |
2 |
A&contents of memory $F6 |
| Zero Page,X | AND $F6,X | 4 |
2 |
A&contents of memory $F6+X |
| Absolute,X | AND $3420,X | 4 |
3 |
A&contents of memory $3420 + X |
| Absolute,Y | AND $3420,Y | 4 |
3 |
A&contents of memory $3420 + Y |
| Ind. Indir. | AND ($F6,X) | 6 |
2 |
A&contents of addr. at $F6+X |
| Indir. Ind. | AND ($F6),Y | 5 |
2 |
A&contents
of (address at $F6) + offset Y |
ASL Arithmetic Shift Left
THE INSTRUCTION
The ASL instruction utilizes the carry bit in the processor status register as a ninth bit for a number, and pushes each bit in a number one place to the left; thus, the name arithmetic shift left. A zero is pushed into the least significant bit, and the most significant bit of the original number ends up in the Carry bit. A picture is worth a thousand words here:
C
76543210
0 < = 10110101 < = 0
1 01101010
0 < = 10110101 < = 0
1 01101010
Let's look at another example:
C
76543210
0 < = 01101101 < = 0
0 11011010
0 < = 01101101 < = 0
0 11011010
"What is the purpose of this instruction?" you may ask. Well, let's look more closely at the last example. The original number, #%01101101, is #109 in decimal form; following the ASL the resulting number is #%11011010, which is #218 in decimal form. We have doubled the number with a single instruction! Since each position in a binary number is exactly twice the value of the position to its immediate right, a shift to the left doubles the value of each bit. This is an extremely easy way of multiplying numbers by powers of 2; just ASL once for each power of 2 required.
CAUTION:
Although it seems fairly easy to multiply a number by 2 using the
ASL instruction, you must be extremely careful and correct for overflow
into the Carry bit. An example of this is the first set of numbers
above. We started with #%10110101, which is the decimal number 181, and
following our ASL we had #%01101010, which is the decimal number 106.
Now we know that 106 is not 2 times 181. In fact, 2 times 181 is 362.
Note that this is exactly 106, the result we got, plus 256. Remember,
in that example, we concluded with a carry of 1, which represents 256
when using the ASL instruction for multiplication. You must take this
carry into account whenever you use the ASL instruction.
EFFECTS ON THE PROCESSOR STATUS REGISTER
As we have already seen, the Carry bit will contain the most significant bit of the original number. The Negative flag will be set equal to the most significant bit of the result (bit 6 of the original number). The Zero flag will be set if the result is equal to zero, and will be reset for any other result. In the examples shown below, we'll use the accumulator addressing mode.
|
A |
N |
C |
Z |
Instruction | = > |
A |
N |
C |
Z |
|
|
|||||||||
| #128 | 1 |
0 |
0 |
ASL A | = > |
#0 |
0 |
1 |
1 |
| #64 | 0 |
0 |
0 |
ASL A | = > | #128 |
1 |
0 |
0 |
| #192 |
1 |
0 |
0 |
ASL A | = > | #128 |
1 |
1 |
0 |
|
#8 |
0 |
0 |
0 |
ASL A | =
> |
#16 |
0 |
0 |
0 |
ADDRESSING MODES
Examples using the five addressing modes for the ASL instruction are listed below:
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Accumulator | ASL A | 2 |
1 |
ASL value in accumulator |
| Absolute | ASL $3420 | 6 |
3 |
ASL contents: memory $3420 |
| Zero Page | ASL $F6 | 5 |
2 |
ASL contents: memory $F6 |
| Zero Page,X | ASL $F6,X | 6 |
2 |
ASL contents: memory $F6+X |
| Absolute,X | ASL $3420,X | 7 |
3 |
ASL contents: memory $3420 + X |
Note that this instruction takes quite a while to execute. In fact, the Absolute,X addressing mode of the ASL instruction requires 7 machine cycles to execute, the longest of any of the instructions in the entire 6502 set. However, we need to think about speed in absolute terms. Using this instruction allows us to perform a multiplication by 2 in 3.92 microseconds, even in this slowest of modes. Still pretty fast, especially when compared with BASIC!
BCC Branch on Carry Clear
THE INSTRUCTION
In BASIC, we can distinguish between two different types of commands which both transfer the control of a program to a new line number. The first is the straight GOTO command; we know that the number of the next line to be executed will always follow the command GOTO:
45
GOTO 90
50 .
60 .
90 ? "This line follows 45."
50 .
60 .
90 ? "This line follows 45."
After line 45 is executed, line 90 is the next line under all conditions. This is called an unconditional transfer of control.
A second type of transfer in BASIC utilizes the comparison and branching abilities of the computer:
45
IF X<32 THEN 90
50 .
.
.
90 ? "This line sometimes follows 45."
50 .
.
.
90 ? "This line sometimes follows 45."
In this example, if the value of the variable X is less than 32 in line 45, then a branch in the flow of the program is taken, and line 90 is executed next. If X is equal to or greater than 32, then the branch is not taken, and line 50 is executed next. Thus, the program flow depends on certain conditions established within the program, and for this reason, this type of transfer is called conditional transfer of control. In this example, the condition is the value of the variable X.
The BCC instruction means that if the Carry bit is clear (equal to zero), then program control must branch to a specific location. As in BASIC, if the condition is not met - in this example, if the carry bit is equal to I - the line next executed is not the line specified in the instruction, but rather the next line in the program.
In virtually all cases, branches in assembly language are specified by labels. A label can be almost any name you want to give to a specific line in an assembly language program. Let's look at a short example:
BCC SKIP
LDA $0345
.
. ;other lines
. ;of the program
SKIP LDA $4582
LDA $0345
.
. ;other lines
. ;of the program
SKIP LDA $4582
We'll take this one line at a time. First, we see the instruction BCC SKIP The Carry bit can either be a one or a zero at the time this instruction is executed. Let's first assume that the Carry bit is set to 1. When this line is executed, the BCC test fails; that is, since the Carry is not clear, the branch to SKIP is not taken. The next line executed loads the accumulator from address $0345. The program then proceeds with the next line and then the next, and so on.
Now let's assume that when the BCC is executed, the Carry bit is zero. In this case, the branch is taken, since the Carry is clear, and the next line executed loads the accumulator from memory location $4582. Then the line immediately following the SKIP line will be executed.
It should be obvious by now that in addition to the actual lines of instructions in an assembly language program, the values of each of the flags in the processor status register are an important factor in understanding a program. Instructions provided in the instruction set allow us to control these bits directly.
Still another similarity between the BCC instruction and a conditional branch in BASIC is that the branch can either be forward or backward in the program. The example above is a forward branch. To see what a backward branch looks like, let's look at the following example:
SKIP
LDA $0254
.
.
BCC SKIP
.
.
BCC SKIP
In this case, if the Carry bit is equal to zero, we branch backward from the BCC to SKIP If it is equal to 1, the line following the BCC will be executed next.
There is an important limitation to such branches in assembly language. The BCC instruction can transfer control no further than 127 bytes forward or backward in the program. Only 1 byte is used to hold the value of the branch and any 1-byte number greater than 127 is recognized as a negative number, so if we try to branch ahead 130 bytes, the 6502 recognizes this as a negative branch of 255 - 130 = 125 bytes. Instead of jumping ahead in our program, we'd be back some considerable distance over ground we'd already traveled. Most assemblers will detect the error if we try to branch too far, and report it as such at the time of assembly, but this may be very time-consuming. It's a lot easier to try to avoid this problem while writing our programs.
One caution about relative branches: most assemblers will allow a branch of the form
BCC
+7
which tells the program counter to branch forward 7 bytes if the Carry is clear when this line is executed.
CAUTION:
THIS IS VERY BAD PROGRAMMING PRACTICE!!!
The problem comes when you try to read your program, or, heaven forbid, try to change it. If you insert a line shortly after this, the branch taken by this BCC will probably be wrong. The use of labels for branch target points makes your program much easier for you to read and lessens the chance of errors. Don't, under penalty of long, long, long hours of debugging, write branches like the above!
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
The only addressing mode for the BCC instruction is the Relative mode, and we have already seen how it works. Branches are either taken or not, depending on the value of the Carry bit. Branches are either forward or backward relative to the current position of the program counter, which normally points to the start of the line immediately following the BCC instruction. The BCC instruction requires 2 bytes and takes 2 machine cycles to execute.
BCS Branch on Carry Set
THE INSTRUCTION
BCS is the exact opposite of the BCC instruction. The branch is taken when the Carry bit is equal to 1 and is not taken when the Carry bit is equal to zero. In all other respects, BCS and BCC are identical. Refer to the BCC instruction for further details.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
The only addressing mode available for the BCS instruction is the Relative mode. Its use was described above for the BCC instruction. The BCS instruction uses 2 bytes and takes 2 machine cycles to execute.
BEQ Branch on Equal to Zero
THE INSTRUCTION
The BEQ instruction is similar to the BCC and BCS instructions, but differs in one important way. Instead of using the Carry bit, the BEQ instruction uses the Zero bit as the determining factor in evaluating whether or not to take a branch. If the Zero bit is equal to 1, the branch is taken. Remember, the Zero bit will be equal to 1 only if some operation resulted in an answer of zero; thus the name Branch on Equal to Zero. If the Zero bit is equal to zero, the previous result was not equal to zero, and the branch would not be taken. This may be a little confusing at first. The best way to remember it is to understand that the Zero bit is a flag, and the flag is set when a certain condition is met. In the case of the Zero flag, the condition is a result of zero, which sets the Zero flag. Remember, we're testing for the flag being set, not for the flag being equal to zero.
LDA #0
BEQ SKIP
.
.
SKIP LDA $2F
BEQ SKIP
.
.
SKIP LDA $2F
In this example, when we load the accumulator with zero, the Zero bit is set in the processor status register. Therefore, the line executed after the BCC is SKIP, not the next line in the program. If instead we load the accumulator with 1, the branch will not be taken, and the program flow will be in order.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
The only available mode for the BEQ instruction is the Relative mode, discussed in detail in the section on the BCC instruction. The BEQ instruction needs 2 bytes of storage and requires 2 machine cycles to execute.
BIT Test Bits in Memory with Accumulator
THE INSTRUCTION
The BIT instruction performs an AND between the number stored in the accumulator and the number stored in another memory location addressed in the instruction, but it is different from the usual AND instruction in one very important way. The AND instruction performs the AND operation between the number in the accumulator and a number in a memory location and stores the result in the accumulator. The BIT instruction performs the AND, but does not store the result in the accumulator. "So what good is it?" you may ask.
Remember that the AND instruction does two things. First, it performs the AND and stores the result in the accumulator. Second, it sets and resets various flags in the processor status register. The BIT instruction performs the first function without storing the number, but it also performs the second, discussed below.
EFFECTS ON THE PROCESSOR STATUS REGISTER
Three flags in the processor status register are conditioned by the BIT instruction. The Negative flag is set to the value of bit 7,
the most significant bit, of the byte stored in the memory location being tested, and the V (oVerflow) flag is set equal to the value of bit 6 of the same byte. The Zero flag is set if the result of the AND operation is equal to zero; it is reset if the result is not equal to zero. Some examples of the BIT instruction are given below, along with their effects on the processor status register flags. For the purpose of these examples, let's assume that memory location $0345 contains the value #$F3.
|
A |
N |
V |
Z |
Instruction | =
> |
A |
N |
V |
Z |
|
|
|||||||||
| #128 | 1 |
0 |
0 |
BIT $0345 | =
> |
#128 |
1 |
1 |
0 |
| #5 | 0 |
0 |
0 |
BIT $0345 | =
> |
#1 |
1 |
1 |
0 |
| #4 | 0 |
0 |
0 |
BIT $0345 | =
> |
#0 |
1 |
1 |
1 |
| #3 | 0 |
0 |
1 |
BIT $0345 | =
> |
#3 |
1 |
1 |
0 |
This instruction is used primarily when you want to learn something about a value stored somewhere in memory without disturbing the value stored in the accumulator. For instance, you can easily learn whether the number in memory is negative, because after the BIT operation, the N flag will be set if the number was negative. Similarly, you can learn whether bit 6 of the number is a one or a zero by looking at the V flag after the BIT operation. Finally, you can determine whether an AND between the accumulator and the number in memory results in a zero value by testing the Z flag. Note that an AND operation between any number and zero will produce a zero result; so any time the number addressed in memory equals zero, the result of the BIT operation will be equal to zero and the Z flag will be set. This is quite a lot of information for an instruction which at first glance appeared to do nothing!
ADDRESSING MODES
Only two addressing modes are available for the BIT instruction, Absolute and Zero Page.
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Absolute | BIT $3420 | 4 |
3 |
A&contents of memory $3420 |
| Zero Page | BIT $F6 | 3 |
2 |
A&contents of memory $F6 |
Since the BIT instruction simply compares the values stored in the accumulator and in a specific memory location, these two modes are sufficient for any use of BIT you may require. Between them they address the entire memory space of the computer.
BMI Branch on Minus
THE INSTRUCTION
BMI is another of the conditional branch instructions in the 6502 instruction set. It utilizes the Negative flag in the processor status register; the branch is taken if the Negative flag is set and is not taken if this flag is equal to zero. In all other respects, BMI is similar to the BCC instruction already discussed. Please read that discussion for details of conditional branch instructions, and read the discussion below of the BPL instruction for a caution concerning these two instructions.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
The only addressing mode for the BMI instruction is the Relative mode, discussed for the BCC instruction. The BMI instruction requires 2 bytes of memory and takes 2 machine cycles to execute.
BNE Branch on Not Equal to Zero
THE INSTRUCTION
BNE is the exact opposite of the BEQ instruction. With the BNE instruction, the branch is taken if the Zero flag is equal to zero; that is, when the previous result was not equal to zero. The branch is not taken when the Zero flag is equal to 1. Refer to the discussion of the BCC instruction for details.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
Only the Relative addressing mode, discussed under the BCC instruction, is available for the BNE instruction. The BNE instruction requires 2 bytes of memory and takes 2 machine cycles to execute.
BPL Branch on Plus
THE INSTRUCTION
This instruction is the exact opposite of BMI. The branch is taken following the BPL instruction if the Negative flag is equal to zero and is not taken if this flag is equal to 1. One caution should be mentioned for this pair of instructions: in order for the branch to be correctly determined, the Negative flag must, of course, have been correctly conditioned prior to executing either the BMI or BPL instruction. Since not all other instructions condition the Negative flag, be sure that you use one which does correctly condition this flag before utilizing either the BMI or BPL instruction.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
Only the Relative addressing mode is available for the BPL instruction. Please- see, the discussion. of the . BCC instruction for details. The BPL instruction requires 2 bytes of memory and takes 2 machine cycles to execute.
BRK Break
THE INSTRUCTION
The BRK instruction is somewhat analogous to the BASIC STOP command. We know that the STOP command causes the program being executed to stop; at that point control is returned to the BASIC cartridge, which signals that it is back in command by telling you what happened and printing READY to the screen.
The primary use of the BRK instruction is in debugging your program after it has been written, but before it's working quite the way you intended. In BASIC, we frequently go through this debugging process by inserting STOP instructions at various places in the program and then running the program to see if we get to the various STOPS. In assembly language programming, BRKs can be used in exactly the same way. You can insert a number of BRK instructions throughout your program and then try to run it. If you don't reach the BRK instructions, you know that your program is "hanging up" somewhere prior to that instruction. Most available debuggers will print out the values of the 6502 registers whenever a BRK instruction is encountered in a program; this makes the job of debugging somewhat easier. Even with such aids, debugging a long assembly language program should not be attempted by the faint of heart, at least not unless there is a big slice of time available with nothing else to do.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
Only one addressing mode is available for the BRK instruction, the Implied mode. This is a single-byte mode, and for the BRK instruction it requires 7 machine cycles to execute.
BVC Branch on Overflow Clear
THE INSTRUCTION
BVC is another of the conditional branch instructions in the 6502 instruction set; it utilizes the Overflow flag of the processor status register. If the V flag is set, the branch is not taken, but if the V flag is clear (equal to zero), the branch is taken. See the discussion of the BCC instruction for further details on conditional branch instructions.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
The BVC instruction utilizes only the one addressing mode common to all of the conditional branch instruction, the Relative mode. The instruction requires 2 bytes and takes 2 machine cycles to execute.
BVS Branch on Overflow Set
THE INSTRUCTION
The BVS instruction is the exact opposite of the BVC instruction. If the Overflow flag in the processor status register is set (equal to 1), the branch is taken, and if the V flag is clear (equal to zero), the branch is not taken. You can find the details of relative branching in the discussion of the BCC instruction.
EFFECTS ON THE PROCESSOR STATUS REGISTER
None.
ADDRESSING MODES
The BVS instruction utilizes only the Relative mode of addressing.
CLC Clear the Carry Bit
THE INSTRUCTION
The CLC instruction has a direct and constant effect on a flag in the processor status register. It clears the Carry bit - that is, sets it equal to zero, whether it was initially zero or 1. It's most commonly used prior to addition with the ADC instruction. Since the ADC instruction always adds the Carry bit into the sum, we generally need to be sure that this bit is equal to zero before addition. This is the only way to be sure that 2 plus 1 will equal 3, and not 4 at times. Almost universally, the typical set of instructions to add two numbers will be:
LDA
#2
CLC
ADC #1
CLC
ADC #1
We load the accumulator with the first number - in this case, 2. Then we clear the Carry bit, because we have no way of knowing for certain the value of this bit at any time without a lot more code. By setting the Carry bit to zero, we know we'll get an accurate sum. We complete the operation by adding with carry the number 1. Remember that the sum, 3 in this case, will be stored in the accumulator at the completion of the addition; other lines will probably do something with this sum, such as store it in memory or utilize it in some further operation.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The only effect CLC has on the processor status register is to always set the Carry bit to zero.
ADDRESSING MODES
The sole addressing mode available for the CLC instruction is the Implied mode. The instruction is only 1 byte long and requires only 2 machine cycles to execute.
CLD Clear the Decimal Flag
THE INSTRUCTION
As we have already discussed, the 6502 can operate in either the decimal mode or the binary mode. The CLD instruction clears the decimal flag in the processor status register and resets the 6502 to operate in binary rather than decimal mode. In this book, we'll use the binary mode for most examples, but we'll briefly cover the decimal mode here. In this mode, each nibble of a byte represents a single decimal digit. The coding scheme is referred to as binarycoded decimal and is given below:
Bits
Represent
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
The difference between binary and decimal coding shows up when addition or subtraction takes place. For example, let's try the following code:
LDA
$0345 ;contains #$59
CLC ;put before an add instruction
ADC $0302 ;contains #$13
CLC ;put before an add instruction
ADC $0302 ;contains #$13
What number is contained in the accumulator after execution of these lines? We would normally think that this number should be #$6C, and if the addition were done in the binary mode we'd be correct. But suppose that we had first put the 6502 into the decimal mode. In that case, the number stored in the accumulator would be 72, because the 6502 would interpret the bytes at locations $0345 and $0302 as binary-coded decimal numbers, and would add them in decimal mode: 59 + 13 = 72.
As was mentioned before, the examples in this book are all in binary form. The decimal mode may be used, however, when a result needs to be displayed to the screen quickly. Since each nibble of the number represents a decimal digit, by masking the appropriate digit using the AND instruction and then sending it to the screen, we can display a number quickly, without the need to interconvert between binary and decimal nomenclature.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The CLD instruction directly sets the Decimal flag of the processor status register to zero, thus clearing it. No other effects occur.
ADDRESSING MODES
As with all instructions operating directly on flags in the processor status register, the only addressing mode available for the CLD instruction is the Implied mode. The instruction requires only 1 byte of memory and takes 2 machine cycles to execute.
CLI Clear the Interrupt Flag
THE INSTRUCTION
The CLI instruction operates directly on the processor status register to clear the Interrupt flag; that is, to set the flag equal to zero. This presumably follows some instruction which had set this flag. Remember that when the Interrupt flag is set, maskable interrupts are disabled. This is important for ATARI programming because several different types of interrupts are used routinely in many programs, and if the I flag is set, they cannot occur. The vertical blank interrupt and the display list interrupt are included in this category. The CLI instruction allows these interrupts to occur.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The CLI instruction operates directly to clear the I flag and has no effect on any of the other flags in the processor status register.
ADDRESSING MODES
The CLI instruction utilizes only one addressing mode, the Implied mode, and takes 1 byte of memory and 2 machine cycles to execute.
CLV Clear the Overflow Flag
THE INSTRUCTION
CLV is just like the two previous instructions, CLD and CLI, which clear a flag in the processor status register. In the case of the CLV instruction, the Overflow flag is cleared.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The CLV instruction clears the Overflow flag, but has no effect on any of the other flags in the processor status register.
ADDRESSING MODES
Like the other instructions operating directly on the processor status register, CLV has only one mode of address, the Implied mode.
CMP Compare Memory and the Accumulator
THE INSTRUCTION
In BASIC, we can compare two values and determine whether they are equal, whether A is greater than B; or whether A is less than B. Generally; this is done in an IF statement of this type:
35
IF A<B THEN ...
Using the 6502 instruction set, we can also compare two numbers, although in a slightly different way. One of the numbers to be compared must be in the accumulator, and the other may be anywhere in the memory of the computer. The instruction CMP subtracts the contents of the specified memory location from the value stored in the accumulator and sets the various processor status register flags appropriately after this subtraction. Note that the value stored in the accumulator does not change following the CMP instruction. The subtraction only sets the flags; it does not change the value originally stored in the accumulator. Knowing the values of the flags in the processor status register, we can deduce the results of the comparison. Let's first discuss the changes in the processor status register, and then we'll work on some CMP examples.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The CMP instruction sets the Zero flag if the number in memory and the number stored in the accumulator are equal. If they are not equal, the Zero flag is reset to zero. The Negative flag is set following the CMP instruction if the result of the subtraction is greater than 127 (that is, the number has its most significant bit equal to one). Otherwise, the Negative flag is reset to zero. The Carry flag is set when the value stored in memory is less than or equal to the number stored in the accumulator. C is reset when the number stored in memory is less than that stored in the accumulator. Let's look at a few examples of the CMP instruction, assuming that memory location $0345 contains #26:
|
A |
Z |
N |
C |
Instruction | = > |
A |
Z |
N |
C |
Comment |
|
|
||||||||||
|
#26 |
0 |
0 |
0 |
CMP $0345 | = > | #26 |
1 |
0 |
1 |
Z,C set by A = $0345 |
|
#48 |
0 |
0 |
0 |
CMP $0345 | = > | #48 |
0 |
0 |
1 |
Z reset;C set by A > $0345 |
| #130 |
0 |
1 |
0 |
CMP $0345 | = > | #192 |
0 |
0 |
1 |
N reset by A-$0345 < 128 |
|
#8 |
0 |
0 |
0 |
CMP $0345 | = > | #8 |
0 |
1 |
0 |
N set by A-$0345 > 127 |
In the first example, the two numbers being compared were equal, causing the subtraction to produce a result of zero. This result set the Zero flag. Since the number in memory was equal to the number in the accumulator, the Carry flag was also set. In the second example, the Zero flag was not set, since the result did not equal zero; the Negative flag was not set, since the result was positive ( + 22); and the Carry bit was set, since the number in memory was less than the number in the accumulator. In the third example, the number began as a negative, with the Negative flag set. Since the result was not equal to zero, the Zero bit was reset. The result of the subtraction, 130 minus 26, was the positive number 104, so the Negative flag was reset. Finally, since the value stored in $0345 was less than the value of #130 stored in the accumulator, the Carry bit was set.
This third example demonstrates an important point about the CMP instruction. A negative number is clearly less than a positive number, but the result of this comparison made it appear as if the negative number was larger. The CMP instruction does not use signed arithmetic; it simply compares two numbers between zero and 255, treating both numbers as positive integers. If you use signed arithmetic, you'll need to correct for this when comparing two numbers.
In the fourth example, the Zero bit was not set, since the result was not equal to zero. The Negative bit was set, since #8 - #26 = #238, which is a negative number. Finally, since the number in the accumulator was smaller than the number in memory, the Carry bit was reset with zero.
We can also look at these effects to determine how to test for the various results. The table below describes several values of the accumulator and memory, along with branch instructions which will be taken following a CMP instruction. The code looks like this:
LDA
#...
CMP $....
B.. destination
CMP $....
B.. destination
Now we'll see which branches will be taken using various values for the two numbers.
A
Mem. BCS, BPL, BNE
8 8 BEQ, BCS, BPL
9 8 BCS, BPL, BNE
8 9 BMI, BCC, BNE
8 8 BEQ, BCS, BPL
9 8 BCS, BPL, BNE
8 9 BMI, BCC, BNE
Now we can see how to structure some code which will compare two numbers and take appropriate action, depending on the results obtained. Let's suppose that we want to duplicate the following BASIC code in assembly language:
25
IF R<B THEN GOTO Q
In ATARI BASIC, this means that the branch to line Q will be taken if the value of the variable R is less than the value of the variable B at the time line 25 is executed. In assembly language, the same code looks like this:
LDA
R ;load A from memory location R
CMP B ;compare to memory location B
BCC Q ;take branch if Carry reset
CMP B ;compare to memory location B
BCC Q ;take branch if Carry reset
ADDRESSING MODES
CMP uses the same eight addressing modes discussed in Chapter 5 for the LDA instruction.
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Immediate | CMP #2 | 2 |
2 |
A-#2 |
| Absolute
|
CMP $3420 | 4 |
3 |
A-contents of memory $3420 |
| Zero Page | CMP $F6 | 3 |
2 |
A-contents of memory $F6 |
| Zero Page,X | CMP $F6,X | 4 |
2 |
A-contents of memory $F6 + X |
| Absolute,X | CMP $3420,X | 4 |
3 |
A-contents of memory $3420 + X |
| Absolute,Y | CMP $3420,Y | 4 |
3 |
A-contents of memory $3420 + Y |
| Ind. Indir. | CMP ($F6,X) | 6 |
2 |
A-contents of addr. at $F6+X |
| Indir. Ind. | CMP ($F6),Y | 5 |
2 |
A-contents
of (address at
$F6) + offset Y |
CPX Compare Index Register X with Memory
THE INSTRUCTION
This instruction compares the values in the X register and a specific memory location, in contrast to the CMP instruction, which compares the values in the accumulator and a memory location. In all other respects, the CPX and CMP instructions are identical. CPX is used primarily to test the value in register X, especially when it is being used as an index, in order to determine if it has reached the final desired value. For example, when the X register is being used as a loop counter and you wish to determine when to branch out of the loop, the CPX instruction, followed by an appropriate branch instruction, will give you the answer.
EFFECTS ON THE PROCESSOR STATUS REGISTER
If the two numbers being compared are equal, the Zero flag will be set (made equal to 1); otherwise, it will be reset (made equal to zero). If the result of the subtraction is greater than 127, the Negative flag will be set; otherwise, a will be reset. Finally, if the number in memory is less than or equal to the number stored in the X register, the Carry flag will be set; otherwise, it will be reset. Please refer to the CMP instruction for more details.
ADDRESSING MODES
The CPX instruction utilizes the three addressing modes outlined below.
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Immediate | CPX #2 | 2 |
2 |
X-#2 |
| Absolute | CPX $3420 | 4 |
3 |
X-contents of memory $3420 |
| Zero Page | CPX $F6 | 3 |
2 |
X-contents of memory $F6 |
CPY Compare Index Register Y with Memory
THE INSTRUCTION
CPY is identical to CPX or CMP in all respects, except that it uses the Y instead of the X register or the accumulator. As with the CPX instruction for the X register, when you need to determine whether the index register Y has reached a certain value, use the CPY instruction. Refer to the CMP and CPX sections of this Appendix for details.
EFFECTS ON THE PROCESSOR STATUS REGISTER
Please refer to the CMP instruction for a detailed description of the effects of CPY on the processor status register.
ADDRESSING MODES
The CPX and CPY instructions are identical in their addressing modes, examples of which are shown below:
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Immediate | CPY #2 | 2 |
2 |
Y-#2 |
| Absolute | CPY $3420 | 4 |
3 |
Y-contents of memory $3420 |
| Zero Page | CPY $F6 | 3 |
2 |
Y-contents of memory $F6 |
Please refer to Chapter 5 for details of these addressing modes.
DEC Decrement Memory
THE INSTRUCTION
In order to decrement (decrease by 1) any memory location, the DEC instruction may be used. There are actually two ways to decrement a memory location. The first, and by far the easiest, is to use DEC directly. The second, and by far the more cumbersome, is to load the accumulator from that memory location, subtract 1, and then store the resulting number back into the original memory location. You can see why a DEC instruction was included in the 6502 instruction set.
EFFECTS ON THE PROCESSOR STATUS REGISTER
If the decrementing process results in a number equal to zero in the memory location addressed, the Zero flag in the processor status register will be set. If the result is any number but zero, the Zero flag will be reset. If the number resulting from the DEC instruction is negative (greater than 127), the Negative flag will be set; otherwise, it will be reset. It is therefore possible to determine when a decrementing instruction has produced either a zero or negative result without ever loading the number in question into the accumulator: simply check the status of either the Z or the N flag in the processor status register.
ADDRESSING MODES
Four addressing modes are available for the DEC instruction, as listed below:
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Absolute | DEC $3420 | 6 |
3 |
DEC Contents of memory $3420 |
| Zero Page | DEC $176 | 5 |
2 |
DEC Contents of memory $F6 |
| Zero Page,X | DEC $F6,X | 6 |
2 |
DEC Contents of memory $F6 + X |
| Absolute,X | DEC $3420,X | 7 |
3 |
DEC Contents of memory $3420 + X |
DEX Decrement the X Register
THE INSTRUCTION
DEX specifically decrements the X register and is used primarily when the X register is being used as the index of a loop. Each time through the loop you decrement the register once. When the Z flag is set following this decrementing, you can branch out of the loop, knowing it has completed the predetermined number of cycles.
EFFECTS ON THE PROCESSOR STATUS REGISTER
Like the DEC instruction, the DEX instruction will set or reset both the Negative flag and the Zero flag in the processor status register. By testing these flags, a programmer can determine the state of the X register.
ADDRESSING MODES
Only one addressing mode is available for the DEX instruction, and as you might expect, it is the Implied mode, since the addressing can be inferred by the nature of the instruction. The instruction requires only 1 byte and takes 2 machine cycles to execute.
DEY Decrement the Y Register
THE INSTRUCTION
DEY is the Y -register counterpart to the DEX instruction. It decrements the Y register by 1.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The effects of the DEY instruction are the same as those of the DEC and DEX instructions already discussed.
ADDRESSING MODES
Like the DEX instruction, the DEY instruction uses only the Implied mode, requires 1 byte of memory, and takes 2 machine cycles to execute.
EOR Exclusive Or
THE INSTRUCTION
The EOR instruction is most like the AND instruction. Remember that AND performs a bit-by-bit AND: if a bit is set in both of the numbers being compared, the bit will be set in the resulting answer. The EOR instruction performs a bit-by-bit EOR. If a bit is set in one, and only one, of the numbers addressed, it is set in the answer. If the bit is set in both or neither, there is a zero in that position of the answer. The resulting number is stored in the accumulator. An example of this is shown below:
LDA
#133
EOR #185
EOR #185
Again, the simplest way to determine the correct answer for the EOR operation is to visualize the numbers in their binary form:
Dec.
Binary
#133 = #%10000101
#186 = #%10111010
Result = #%00111111 = #63
#133 = #%10000101
#186 = #%10111010
Result = #%00111111 = #63
Bit 7, which was set in both numbers, is equal to zero in the answer. Similarly, bit 6, which is equal to zero in both numbers, is also equal to zero in the answer. Only those bits which were set in only one of the numbers are set in the answer - bits 0 through 5.
The most common use of the EOR instruction is in complementing a number. To do this, we EOR the number with #$FF, a number in which each bit is set. For instance, to complement the number 143, we EOR it with #$FF:
#143 =
#%10001111
#$FF = #%11111111
Result = #%01110000 = #112
#$FF = #%11111111
Result = #%01110000 = #112
EFFECTS ON THE PROCESSOR STATUS REGISTER
If the resulting number, residing in the accumulator, is negative (greater than 127), the Negative flag is set; otherwise, it is reset. If the result of the FOR instruction is equal to zero, the Zero flag is set; otherwise, it is reset.
ADDRESSING MODES
The EOR instruction utilizes the same 8 addressing modes as does the LDA instruction; these are detailed in Chapter 5. Brief examples are given below:
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Immediate | EOR #2 | 2 |
2 |
A EOR #2 |
| Absolute | EOR $3420 | 4 |
3 |
A EOR memory $3420 |
| Zero Page | EOR $F6 | 3 |
2 |
A EOR memory $176 |
| Zero Page,X | EOR $F6,X | 4 |
2 |
A EOR memory $F6+X |
| Absolute,X | EOR $3420,X | 4 |
3 |
A EOR memory $3420 + X |
| Absolute,Y | EOR $3420,Y | 4 |
3 |
A EOR memory $3420 + Y |
| Ind. Indir. | EOR ($F6,X) | 6 |
2 |
A EOR addr. at $F6+X |
| Indir. Ind. | EOR ($F6),Y | 5 |
2 |
A EOR (address at $F6) + offset Y |
INC Increment Memory
THE INSTRUCTION
The INC instruction is the exact opposite of the DEC instruction, causing the value stored in any addressed memory location to be increased by 1.
EFFECTS ON THE PROCESSOR STATUS REGISTER
The INC instruction sets the Negative flag if the resulting number is greater than 127; otherwise, it resets the Negative flag. It also sets the Zero flag if the resulting number is equal to zero; otherwise, it resets the Zero flag.
ADDRESSING MODES
INC utilizes the same four addressing modes utilized by the DEC instruction. Consult the examples below:
| Mode | Instruction | Cycles | Bytes | Meaning |
|
|
||||
| Absolute | INC $3420 | 6 |
3 |
INC contents of memory $3420 |
| Zero Page | INC $176 | 5 |
2 |
INC contents of memory $F6 |
| Zero Page,X | INC $F6,X | 6 |
2 |
INC contents of memory $F6 + X |
| Absolute,X | INC $3420,X | 7 |
3 |
INC contents of memory $3420 + X |
INX Increment the X Register
THE IN