(Article by Phaze101)
The Instruction Set
I am going to try and cover as much as I can here. This article was written more than once I have to admit. I was never happy with the finish of it since I wanted a quick way of explaining it all, in a easy way. I am still not 100% happy but this is the best way I could come up with that explains the instructions set.
I came up with the idea of dividing the instruction set in categories. This was done in the past in several books. Like this I just need to explain each category instead of going through each instruction. Going through each instruction would have taken too much time and there are so many references that one can look at online to see what each instruction does.
In the next section I am listing all the 6502 CPU Instruction set. Each instruction is explained in few words what it does.
Now remember that many of the instructions support different addressing modes, what we talked about in the previous article. Now if an instruction supports addressing modes, it doesn’t mean that it supports all of the addressing modes that we coved. If various from instruction to instruction.
Another way of saying addressing modes is, each instruction can support different modes.
The below might help you remember the instructions set quicker.
Notice also that if the A register is affected most of the time the instructions ends with an A generally speaking. Same applies for X and Y.
If it is a transfer from A to Y then the instruction will end with AY and same for the rest.
Compare instructions start with a C.
Branch instructions start with a B.
When you are clearing something it starts with a CL.
When you are setting something it starts with a SE.
When you are jumping to a different address it starts with a J.
Stack operations most of the time start with a P for push and pull.
When an instructions starts with a DE is means decrement and when it starts with IN is means increment.
When it starts with LD you are loading something into something and when it starts with ST you are storing something into something else.
When it is an RT it means it is returning form something.
The 6502 instruction set
Below is a table of all the 6502 instructions and to which category they belong too.
I will be explaining in detail later each category.
The Instructions Set in Detail
Data Transfer Instructions
We have 3 type of sub categories in this section.
Instructions that start with LD are loading one of the registers with the value of a memory location.
LDA \$C000 ;load the accumulation with the 8-bit value at memory location \$C000 LDX \$C000 ;Load the X register with the 8-bit value at memory location \$C000 LDY \$C000 ;Load the Y register with the 8-bit value at memory location \$C000
Instructions that start with the ST value means that they are storing the contents of the one of the registers to a memory location.
STA \$C000 ;Store the value of the Accumulator to memory location \$C000 STX \$C000 ;Store the value of the X register to memory location \$C000 STY \$C000 ;Store the value of the Y register to memory location \$C000
The instructions TAX and TAY transfer the contents of the accumulator to either the X or Y register. The instructions TXA and TYA transfer the contents of the X or Y register to the accumulator.
Please note that there isn’t an instruction to transfer between the X and Y register. You need to use the accumulator to transfer between X and Y.
Modify Processor Status registers
In my list of categories this comes somewhere at the end but because of what I am going to cover next I thought I will discuss it before.
Not much to say here except that these instructions Clear or Set the status register Flags. Remember we covered these some time ago now.
Those that we will be using often are CLC, CLV and SEC. They are self-explanatory and no need to go in detail.
The arithmetic operations work on the accumulator. They either add or subtract memory with the accumulator.
Please note that the carry flag is used for overflow whether it is a minus or a plus. The best way to think of arithmetic operations is first to consider the number in binary.
I am not going to go into the detail of how to do binary arithmetic. It is something we will need when doing a game such as the score and hence I will cover it when we come across it.
As an overview, if in an addition the number goes beyond 255 ($FF) the carry flay is set. Before you do an addition, you clear the carry flag (CLC) and before you do a subtraction you set the carry flag (SEC).
For now, this is more than enough since Arithmetic requires an article on its own.
Logic Operations also work with the Accumulator same as Arithmetic Operations. Also, as Arithmetic operations it is better if you work out things in binary most of the time.
An AND returns 1 when both Memory and Accumulator are 1 the rest is 0
An ORA will return 1 when either the memory or the accumulator has a 1 in it
An EOR will return a 1 when either the accumulator or memory has a 1 but will always return 0 if both has got a 1 or a 0.
Shift and Modify Instructions
The instructions that start with DE which stands for decrement will decrement by 1 respectively from contents of a memory location or the registers X and Y.
The instructions that start with IN which stands for increment, will increment by 1 respectively from contents of a memory location or the registers X and Y
ROL or ROR / ASL or LSR
There will be many times when we want to shift bits around. If we shift all the bits in a byte left, we’ll effectively double the number – if we shift them right, we’ll halve it or divide by 2
You may not immediately see the need for bit shifting but as you program, you’ll come across many times you need to do it.
One very important use of ASL/LSR is for multiplication and division. The CPU has no multiply or divide commands, but it can quickly do multiply by 2 or divide by 2. You want to try to take advantage of this when designing your code!
The 6502 has 2 options.
Option1 – Shift bits within the Accumulator using ASL or LSR and this will fill any new bits with 0 and lose any bits pushed out of the accumulator,
Option 2 – Rotate bits through the carry flag’ with ROL and ROR. This puts the carry into the new bit, and any bits pushed out go into the carry flag.
These 4 instructions also form part of the arithmetic operations in a way and eventually I will do an article on arithmetic operations.
Compare and Test Instructions
Comparing to another value with CMP, CPX and CPY
Basically, with these instructions you are comparing memory or immediate number with either the A, X and Y registers respectively.
The result of the compare will set the N, Z or C flags in the status register respectively depending on whether the result is positive, null or negative. The compare is a subtraction, but the result is not stored anywhere.
The instruction BIT compares the Bits in accumulator with the contents of a memory location. In the case of the instruction BIT a logical AND is performed between A and contents of memory. The result of the comparison is indicated by the Z flag (in simple terms not to complicate things here).
Normally you do a compare before you do a branch. Based on the result of the compare your program will branch (JUMP or GOTO) to the next instruction.
The branch instructions come after the compare instructions normally, but they could appear after other instructions like DEX or DEY. The names of the branch instructions are self-explanatory. Basically, they branch according to a flag in the status register as shown in the table below.
BMI, BPL, BVC and BVS instructions are not commonly used in branches. They deal with signed arithmetic or two’s complement. None of these has been covered so far so please ignore for now.
For the other 4 instructions BCS, BCC, BEQ and BNE follow the table below when you want to decide like as some of you know in BASIC the famous IF …. Then
JMP instruction is like the BASIC command GOTO. The CPU jumps to another memory location from where it continues to execute instructions.
The JSR or Jump to Subroutine and RTS are the same as in BASIC the GOSUB and RETURN. Basically, the CPU jumps to another memory location from where it continues to execute instructions till it encounters an RTS instruction. This will make the CPU to return to where the JSR instruction was and to continue execute instructions after the JSR instruction.
Please note that before the JSR instruction happens the current Program Counter pointing is pushed (stored) onto the stack and then when the RTS instruction is encountered a pull (restore of the Program Counter) happens which restores back the Program Counter to where it was.
The RTI and BRK instructions are an advanced topic for now and we won’t be using them just yet.
Stack Operations Instructions
PHA and PLA are used to push (store) and pull (restore) the accumulator.
PHP and PLP used to push and pull the status Register Flags. We will need to keep a copy of these from time to time.
We can also modify the stack pointer by using the X register instructions TXS and TSX.
Please note that there are no instructions that store the values of the X and Y registers onto the stack. To do that you need to use TXA and TYA which transfers their respective contents to the Accumulator and then push the accumulator to the stack with their contents.
Do Nothing Instructions
NOP is an instruction that does really nothing except waste CPU time. Sometimes you need this to create delays.
That was the 6502 instructions set explained. We have skipped some instructions so as not to complicate things for you and keep things simple. Also, there are some topics as you noticed that I skip in relation to arithmetic. Eventually we will have to cover these but what we covered so far is enough to get us started.
Till now we were discussing the CPU 6502. The next series of articles will cover basic concepts related to gaming. So, with No 6 of this series you will start getting your hands dirty.
As always if you have any issues please message me. That is all for this week.
Coding is Fun 😊