A Change of Heart

New instructions grace the 65C02

II Computing V1N1
October / November 1985

About the Author

Morgan P Caffrey is a programmer/ analyst concentrating on expert systems, databases and telecommunicatiom seftware. He was an early Apple II owner and former technical editor for Apple Orchard magazine.

Assembly Language 65C02

The heart of any computer is its Central Processing Unit (CPU). In a microcomputer this is a chip, usually referred to by its number. The revolution in personal computing was built largely on the back of a workhorse chip called the 6502, which was used in Apple II computers and in several other brands.

The 6502 chip is a capable CPU, but it could be better, and now it is. Apple Computer is currently installing a more powerful version, called the 65C02, in all new Apple Ile and Apple Ile computers. The 65C02 bestows several new options on assembly language programmers – for whom the balance of this article is written.

But don’t go away, beginners. Though technical, this article includes concepts and language you will confront again.

OPCODE: An executable instruction for the microprocessor such as add, substract, read, store, AND, OR, shift-left, shift-right, and so on.

OPERAND: The data or location being acted on by the opcode. An immediate val ue, the content of a location. MODE: A method of using an opcode that differentiates between accessing the operand from an absolute location, from a location pointed to by another location, and so on. Modes provide flexibility to the microprocessor, and it is usually nicer to have a smaller number of opcodes with a variety of modes than a large number of different opcodes. The 65C02 is a pin-compatible replacement for the 6502 in all Apple II-type computers. It is part of the “enhancement” upgrade for older He’s. It offers lower power consumption and some deft extensions to the parent processor’s instruction set.

The advantages are very real.

The improvements consist of 27 new opcodes made up of ten new instructions and two new ad-· dressing modes. (See box for explanation of terms.) Some things have become much simpler, some faster; some more elegant, requiring less code. Let’s look first at those instructions that are essentially extensions of existing instructions, but with different or augmented modes.


Was I waiting for this one? You bet! A Branch Always (BRA) instruction. It has no flags to control or predict or manipulate, no faked comparison; you need only branch relative to the present position +127 or -128. It does not change the state of any processor flag. This change adds simplicity and legibility, but I still wish for a signed, 16-bit branch for additional ease in writing relocatable code.


I sometimes need to add one or subtract one from the accumulator. Compare the sad methods I have used to the new, simpler version.

Table 1

It is nice to substitute one instruction for three, even if I don’t use the instruction often.


Similarly, there are new push instructions. Now, stacks are nice. I like stacks. The stack keeps track of subroutine calls and saves register values that must be restored. The 6502 offers a quick stack (you need to look at other processors to appreciate the speed), but restricts the programmer to 255 bytes. Let’s look at the old and new methods to save the processor status and all the registers.

Table 2

13 Instructions versus 9

This difference might seem trivial, but if you examine code that extensively uses registers, you’ll see this is frequently done. The old processor’s need to channel registers through the A-register is timeconsuining and not elegant. The newer method is better.


Zero is so useful. It clears the high-resolution screen to black. It sets my numeric arrays to naught. T he 65C02 offers the following simple saving and doesn’t bother a single flag:

Table 3

4 Instructions versus 1

In both cases the contents of the A, X and Y registers are the same after as before the operation. T his is not always necessary, but frequently it is. T he new instruction supports ABS, ZPG, ABS,X and ZPG,X modes.


A sweet feature ofthe 6502 is the indirect addressing. Ifyou use the Y-register with a single byte location in the zero page, you can reference any location in memory. It’s great for accessing and maintaining tables and also for various memory moves. Viewed this way, the 6502 has 128 16-bit memory pointers, any of which you can access with a simple two-byte instruction. The trouble is always that you have had to use the Y-register, which at times is awkward. Frequently it is easier and defter to leave Y=O and manipulate the zero-page pointer directly. The 65C02 has absolutc indirect addressing: for example, LDA (ZPG). You don’t have to be concerned with the Y-register. A single two-byte instruction can now load, store, add, subtract, compare, AND, OR, and EOR anywhere in memory.


The following instructions make a widened use of tables:

TABLEBASE EQU * ;symbolic pointer to base of table of routines
          DA DIVISION
          DA INSERT
          DA LOWERCASE

The construction above creates a table of twobyte execution addresses. You can do something similar with most assemblers; that is, if the program executes at the location pointed to by any table entry, the described function is performed. The 6502 provides a slightly awkward method to jump to any one ofthese addresses, but the 65C02 more elegantly indexes the Jump Indirect by X.

The problem with the 6502 Jump Indirect is that if, by chance, the assembler that stores the code locates the table entry such that the two-byte value crosses a page boundary (bytes 0, 256, 512, and so on, throughout memory), the low byte would be taken properly but the next byte would be taken from 256 bytes lower. You would execute code at the wrong address. A sharp programmer learns to watch for and avoid these problems. A better processor avoids the problem, and the 65C02 fixes it at the cost of just one cycle – a good trade.


When preparing the equivalent of a CASE statement in assembler, the 6502 has a slightly split personality: nice architecture, but awkward in use. The user presses a key and the code “vectors” to the right routine for the key pressed. In the 65C02, utility is about the same but the routine is simpler.


A 0,1,2,3,4 .. . 127-returned from keyboard

8 Instructions versus 3

This new construction saves both space and time.


Some of the instructions indexed by X that do both a read and a write in a single instruction have been speeded up.

ASL LOC,X- arithmetically shift left the byte
LSR LOC,X- arithmetically shift right the byte
INC LOC,X- read, increment, store
DEC LOC,X-read, decrement, store

These can be used for bit manipulation and for multiplication and division. A savings of one cycle m ay not seem like much, but if the cycle is repeatedly saved all day long, or at a critical juncture, the savings become noticeable. (In processing every bit on a high-resolution screen – 57,344 bits-you generate some time savings if the image changes frequently.)


Bit manipulation can seem like Greek even to seasoned assembly language programmers. The idea is to isolate and process a bit (in a number, on the graphic screen, in a controller device). Once again the 6502 seems a little too hard to use, although programmers have coped with and even triumphed over it in various machines.

There have been a couple of changes in the bit manipulation capabilities. I’ll start with the bad news, which isn’t very bad.

A good method for testing individual bits in a memory location, the BIT instruction has lost one rarely used ability. Ifyou perform the BIT instruction in the immediate mode (the sam e result each time the code is executed), the 6th and 7th bit are not reflected in the processor status flag. Ifthe immediate operand is a zero, the Z-flag is set, so the instruction may still be useful.

In the 6502 the bit is frequently tested by shifting the byte left or right until a processor status flag is altered, then you branch appropriately. T he 65C02 design simplifies this read-manipulate-store sequence.

The TRB (Test and Reset Bit) does an AND with the present contents of the A-register (usually the “mask”), sets the new value of the bit(s), and automatically stores the results back. TSB (Test and Set Bit) does an OR of the Aregister and the memory location contents and stores the results back.

The only processor flag affected is the zero-flag. The addressing modes are somewhat limited; only absolute and zero-page is provided (no indexing).


Notwithstanding all the wonderful upgrades, the 65C02 could be improved even more. I would like a real 16-bit register. When I increment a zeropage location, I want an increment instruction that can detect a carry and autom atically increment the next sequential location. I also want the same thing in reverse for the decrement. I don’t suppose I’ll get them soon, but there’s no harm in mentioning it. Finally, the new chip has a few drawbacks. If you use this nice extended set of instructions, the software written won’t be compatible with a lot of the existing earlier Apple II computers, unless the owners individually decide to upgrade. This makes commercial application of the processor’s features somewhat more complicated. Also, the exisitng monitor in ROM does not disassemble the new mnemonics, nor can the old mini-assembler in ROM assemble the new instructions.

Most of the existing assemblers won’t be able to compile the new instructions. I’m sure most assembler manufacturers will upgrade, and some have already. These include Merlin PRO from Roger Wagner Publishing, Lisa 2.6X from Lazerware, and Big MAC.C from Call A.P.P.L.E.


Please follow and like us:

About the Author


The A.P.P.L.E. Website is run by the Apple Pugetsound Program Library Exchange Users Group and is open to all Apple and Macintosh fans and their friends.