A65C & A65, 65C02 & 6502 cross-assemblers


Last update Mar 2 2023. Edited by Herb Johnson, (c) Herb Johnson, except for content written by others. Contact Herb at www.retrotechnology.com, an email address is on that page..

This Web page is about a 2018 adaptation of the A65C and A65 cross-assemblers to support 65C02 and 6502 assembly for various of my vintage computing projects. I restore vintage computers of the 1970's and I support S-100 computers of the 70's and 80's and some others including the Apple II computers which use the 6502 or 65C02 microprocessor . - Herb


My current version of A65 will be at this Web link and my current version of A65C will be at this Web link. The executable program runs under Windows (XP, 2000, 7) as an MS-DOS 32-bit executable, which runs under the "DOS box" commmand line. I provide the C sources with my changes clearly marked. There are docs and sample assembly code. Check the "bugs and fixes" section below for any changes.

A65[C] history

A65[C], one of a series of 8-bit cross assemblers written in C, was freely distributed by the developer William C Colley III, through the "C Users Group" library of C programs of the 1980's and later. CUG "diskette" 219 has A65C [for the 65C02 and 6502) and A65 (for the 6502 only) and other assemblers. I (Herb Johnson) obtained A65 and A65C code, and adapted the C code to compile under the lcc-win32 Windows/MS-DOS C compiler to produce an MS-DOS command-line 32-bit executable.

Check the A18 Web page for details on my previous work with Colley's assemblers and with compiling under lcc-win32 and other related work. I contacted Bill Colley some years ago, when I adapted A18, another of his assemblers. He had no objections to my use of his work. See the A18 Web page of mine for A18, his response, and more information and links to cross-assemblers for other microprocessors which I (and others) have also adapted.

Bugs & fixes, problems with running on Windows computers, more

I have a number of these old MS-DOS cross assemblers on my Web site. Running them on today's Windows computers is challenging for some people. I've gathered my notes on the subject, on the Web page on the A18 1802 cross assembler. Read that page please. A18 is the most-updated and modified version of these cross assemblers. A65C Web page may not be as updated. So look first at A18 for any features you might request for A65C.

For those who download this program, please advise me of any errors and issues. I make zero guarantees, offer zero warrenties. I am not responsible for any loss, injury or damage to person or property of any sort. Use entirely at your own risk.

Mar 2023: 6501/2 bugs The A65.DOC documentation file, includes notes about the "ROR bug" and "JMP (nnFF)" bug. ROR is incorrect in the 6501 and early 6502 processors. All 6501/2 processors fail a JMP (nnFF) instruction, when the relative address straddles an address page boundary. All are fixed in 65C02 processors. "Read the fine manual" and do Web research for details. A65 flags the jump bug, so far it does not flag the ROR instruction.

Feb 2023: A register designation optional Instructions ASL A, LSR A, ROL A, ROR A, no longer require the "A" to assemble as opcodes acting upon the accumulator. Some assemblers I found, follow that rule. MOS Technology originally required the "A" to assemble in that fashion.

Jan 2023: page_zero and absolute addressing. 6502 instructions of the form [opcode/mnemonic] followed by [operand], can be assembled to be either page-zero addressed (with a byte address) or absolute addressed (with a word address). A65, and I believe most 6502 assesmblers, assembles either 1) a page-zero opcode for operands valued from 0 to +255, followed by that byte; or 2) an absolute-address opcode for operands valued 0100H to 0FFFFH, followed by that word. A65 currently uses the value of the operand to decide - and not how the operand is represented in text, in the assembler source.

For example, A65 evaluates "$0032" not as a word value, but as a byte value, because it evaluates as less than 255. I can't count characters to make up a rule, "00101001B" would fail. But some assemblers appear (??) to consider values written like "$0032" as a word-sized value. This is hard to confirm. I'd appreciate specific responses including examples and links to assemblers on the Web.

The problem is, sometimes the programmer may want to use absolute addressing for a location in page-zero, where by definition address values are 255 or less. Why? I do not know, not the point, the point is how one makes this possible.

Some 6809 assemblers have a unary operator ">" to force a word-size evaluation. For example ">$0032". As of Feb 2023 A65 now has that feature. A ">" unary operator on the operand expression, forces an absolute addressed instruction. A value 0100H to 0FFFFH is already a word-sized value, so the > operator has no effect. The opposite unary operator "<" is inappropriate, because 1) it suggests truncating the upper address byte arbitrarily, and 2) A65 has "HIGH" and "LOW" operators to select high or low bytes of a word-sized expression. In other assemblers, I've seen "#>" and "#<" to represent HIGH and LOW operations. I welcome commments about choices of operator syntax.

Mar 2020: I learned that the 6502 has a broken JMP (REL) instruction. Jump to an address which is stored at another address, call it "REL", will fail when REL is stored across an address page boundary. That is, stored at a memory location xxFFH and of course (xx+1)00H. The 6502 fails to increment the high-order address. But the 65C02 does increment the high-order address (so it's documented). So the A65 cross assembler flags a "V" error; the A65C assembler does not.

The 6501R and 6501Q, has the same instructions as the 6502, plus four additional bit instructions: SMBm, RMBm, BBSm, BBRm; where "m" is a digit 0-7. These are memory set, reset and branch instructions on bits in page 0 memory. These instructions are supported in the 65C02 assembler but not the 6502 assembler. The 65C02 assembler has other instructions added which are not supported on the 6501R/Q.

Mar 2019: I assembled a 65C02 program recently which used "ROL" instead of "ROL A"; likewise for the other three shift instructions ROR, LSR, ASL. I checked Western Digital's 65C02 manual. It's not real explicit but it suggests "ROL A" is the preferred syntax. I won't argue about it, but A65C will insist you include the A reference. ;)

July 2018: To compile other of Calley's assemblers under Borland's MS-DOS based Turbo C, to run on an old '386 box for instance under MS-DOS, all I had to do was change a "malloc()" call to a "alloc()" call. If someone askes nicely, I'll add such a 16-bit MS-DOS executable in the Zipped package. If you don't know what I'm talking about, look for the details on my A18 1802 Web page. - Herb Johnson

- Herb Johnson

Contact information:
Herb Johnson
New Jersey, USA
To email @ me, see
see my home Web page.

This page and edited content is copyright Herb Johnson (c) 2023. Copyright of other contents beyond brief quotes, is held by those authors. Contact Herb at www.retrotechnology.com, an email address is available on that page..