Page 1 of 3
Help me pick an assembler!
Posted: Thu Mar 31, 2022 9:57 pm
by Greg816v2
I've been using ACME to write code for a 6502 board, and as the project grows I'm running into more issues with how ACME works (such as very odd behavior when separating the project into different files). I'm trying to look at all the assemblers out there but I just feel like I'm missing something.
Hoping for the following:
- Support for 65C02 and 65816
- Runs on/can be compiled on Linux
- Uses as standard syntax as possible
- Preprocessor directives like #include, #define, #ifdef, etc
- Anonymous labels (i.e. +/-). After using this in ACME I don't think I can do without it.
- The option to generate an output binary that includes a block of address space assembled to. I.e. for an EEPROM, I have code at $8000 and vectors at $FFFA..$FFFF and the output is a 32K binary.
Every assembler I come across is lacking one of these, but I'm sure they exist, so... what are y'all using

Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 6:58 am
by Proxy
I personally use ca65. It seems to have everything you're asking for.
- It has support for the NMOS 6502, 65C02, and 65816.
- It has a native linux version
- Not sure what you mean with "syntax", it uses the standard mnemonics, $ for hex, % for binary, and the assembler doesn't care about whitespace so you can place labels and instructions pretty much however you want (within reason)
- Yes it has those, check the wiki page for all directives: https://www.cc65.org/doc/ca65-11.html
- they are called unnamed labels in ca65: https://www.cc65.org/doc/ca65-6.html (seems like a horrible feature for readability though)
- that just sounds like an .ORG directive. ca65 allows you to place code/data at specific addresses.
You likely never came across this because ca65 is just one part of the whole cc65 compiler utility:
https://github.com/cc65/cc65
But it is still a fully functional standalone macro assembler, with the small detail that it generates object files that need to be linked, instead of regular binary files.
Which adds some effort in setting it up, but once set up you can just use a script to assemble and link automatically.
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 6:58 am
by drogon
I use as65 from the cc65 suite. It does all you're after and can be command-line driven if that's your thing.
-Gordon
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 7:15 am
by Proxy
That is insane, we posted our replies within the same minute and about the same assembler!
At least I assume we meant the same one, the assembler included with cc65 is called "ca65". And "as65" is a completely different assembler that only supports the 6502 and 65c02:
https://github.com/hculpan/h6502/tree/master/as65
The names are confusingly similar.
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 7:50 am
by drogon
That is insane, we posted our replies within the same minute and about the same assembler!
Great minds thinking alike
At least I assume we meant the same one, the assembler included with cc65 is called "ca65". And "as65" is a completely different assembler that only supports the 6502 and 65c02:
https://github.com/hculpan/h6502/tree/master/as65
The names are confusingly similar.
You're right - and I always confuse them. Yes.
ca65 from the
cc65 suite.
-Gordon
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 8:04 am
by GARTHWILSON
It apparently gets even worse. The one you link to seems to be totally separate from Andrew Jacobs' As65 which does support the '816. His archived material on it is available at https://web.archive.org/web/20210604074 ... /as65.html . I don't see anything about Linux support though.
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 10:13 am
by HansO
CA65 from the CC65 suite is the assembler I use for serious projects.
Does support 65(C)02 and 65C816, and the assembler/linker combinations allow a lot. And it is cross platform, in source format.
Takes some learning of course, a configuration file is more complicated and powerful than one or more .org's.
While my target is mostly 65(C)02 I often used TASM (now the 32 bit command line DOS version on Windows) for smaller/less complex projects, where a couple of .orgs are sufficient.
Cross platform: VASM also is suitable for these kind of projects. Nick gammon did his G-Pascal program in VASM, and that is quite a big project!
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 5:47 pm
by Druzyek
CA65, as everyone has mentioned here, is a very good option. You may want to try
Macroassembler AS as well to see what you think. I switched after getting frustrated with a couple of the macro features in CA65. It meets all of your requirements except being native to Linux. It runs fine for me on Ubuntu under Wine and is what I use for everything now.
EDIT: There is a
Linux port too.
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 8:06 pm
by Greg816v2
Thank you so much everybody!! Much appreciated. I knew you all would come through. Good to see there is some consensus.
I personally use ca65. It seems to have everything you're asking for.
- Not sure what you mean with "syntax", it uses the standard mnemonics, $ for hex, % for binary, and the assembler doesn't care about whitespace so you can place labels and instructions pretty much however you want (within reason)
In doing some research I see reference to some assemblers using non standard syntax requiring a lot of search/replace or hand reworking if you ever changed to another assembler. I think this is in regard to other assembler directives outside of basic mnemonics.
Ah, yeah it looks like the way they are implemented is not as clean as in ACME since the target label is not immediately apparent. I saw the same syntax in another assembler and it didn't look great to me. Either way, I'm open to doing things differently. I've become very used to doing something like this:
Without having to come up with a unique label name, leaving the code sprinkled with (to me, awkwardly named) labels. Looking at the link you send, the "cheap local labels" actually looks like it may be a better option.
[*]that just sounds like an .ORG directive. ca65 allows you to place code/data at specific addresses.
I thought so, but came across compilers that would simply assemble code as if it were located at the current address, but that's it. I.e.:
Would simply assemble a 2 byte file, where ACME would fill in the unused space (with an available directive to specify the byte value to fill with).
You likely never came across this because ca65 is just one part of the whole cc65 compiler utility:
https://github.com/cc65/cc65
But it is still a fully functional standalone macro assembler, with the small detail that it generates object files that need to be linked, instead of regular binary files.
Which adds some effort in setting it up, but once set up you can just use a script to assemble and link automatically.
Most likely! So glad I asked. I already have build scripts for my project so that's no big deal.
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 8:08 pm
by Greg816v2
CA65, as everyone has mentioned here, is a very good option. You may want to try
Macroassembler AS as well to see what you think. I switched after getting frustrated with a couple of the macro features in CA65. It meets all of your requirements except being native to Linux. It runs fine for me on Ubuntu under Wine and is what I use for everything now.
Thanks! I'll keep that in mind.
Re: Help me pick an assembler!
Posted: Fri Apr 01, 2022 9:21 pm
by GARTHWILSON
Ah, yeah it looks like the way they are implemented is not as clean as in ACME since the target label is not immediately apparent. I saw the same syntax in another assembler and it didn't look great to me. Either way, I'm open to doing things differently. I've become very used to doing something like this:
without having to come up with a unique label name, leaving the code sprinkled with (to me, awkwardly named) labels. Looking at the link you send, the "cheap local labels" actually looks like it may be a better option.
You can eliminate most of the local labels by using flow control structure macros, so the above would become something like
Code: Select all
IF_CARRY_CLEAR
STA $8000
ENDIF
RTS
and it will assemble exactly the same thing. The structures can be nested too, and the macros will figure out the right places to branch to. See my article about it, with macro source code for the C32 assembler. Andrew Jacobs built this capability into his As65 assembler so you don't even need the macros to do it. He unfortunately died Jan 8, 2021 (which was a great loss to us on 6502.org), so Bill Chatfield ("gungwald") took over development, producing DEV65 (but it assembles for other µPs also). It additionally supports relocatable code and multiple output formats. It's available for download in a pre-built binary that is easy to install and run on any system with Java 1.6 or later. Anton Treuenfels' HXA 6502 assembler also has program-structure capability built in. I don't have any experience with As65 or HXA, but they look very capable.
About the Linux part: I use the Cross-32 ("C32" for short) assembler under DOS. It can run under Windows or DOS. I keep a separate machine dedicated to DOS, but I do a few DOS things on this Linux machine too, using DOSbox. It's a teensy fraction of the speed of running real DOS, but it's not much of a problem when it's running at multi-GHz speeds when the DOS programs were intended for 16MHz. Still not as fast, but definitely tolerable for this.
You can see quite a list of assemblers in that section of my links page, most of them being free. Some of the links there are to pages with many more links to assemblers.
Re: Help me pick an assembler!
Posted: Sat Apr 02, 2022 2:45 am
by Greg816v2
Good point Garth! Definitely something I have been thinking about.
I actually scanned through your site briefly looking for links to assemblers and I missed your links page unfortunately.
Re: Help me pick an assembler!
Posted: Sat Apr 02, 2022 3:17 am
by GARTHWILSON
Good point Garth! Definitely something I have been thinking about.
I actually scanned through your site briefly looking for links to assemblers and I missed your links page unfortunately.
The links page is kind of the "second front page" of the site, and it's what my bookmark in my bookmarks toolbar is set to. The site is getting updates all the time, and if you look at the "last updated" date at the bottom of the links page, you'll see it's yesterday, and it's seldom more than a week or two back.
Re: Help me pick an assembler!
Posted: Sun Apr 03, 2022 4:33 pm
by AndersNielsen
+1 for ca65.
You can see how I setup the memory map in my sbc-project here(as well as shell scripts for assembling and linking):
https://github.com/AndersBNielsen/abn6502
Dunno if it's best practice, but it works very well.
Re: Help me pick an assembler!
Posted: Mon Apr 04, 2022 2:46 pm
by SamCoVT
Hoping for the following:
- Support for 65C02 and 65816
- Runs on/can be compiled on Linux
- Uses as standard syntax as possible
- Preprocessor directives like #include, #define, #ifdef, etc
- Anonymous labels (i.e. +/-). After using this in ACME I don't think I can do without it.
- The option to generate an output binary that includes a block of address space assembled to. I.e. for an EEPROM, I have code at $8000 and vectors at $FFFA..$FFFF and the output is a 32K binary.
ca65 is a good choice, but I'll put in a good word for
64tass (which you likely can just ask your Linux package manager for, and it's super easy to compile on systems that don't have a package). It doesn't require a configuration file like you might need to create for ca65. I haven't used it with a 65816 but 64tass lists it as supported. Here's some snippets of code (from a Forth implementation) that show several of the things you are looking for:
Anonymous labels:
There are also "local" labels - use a label that starts with an underscore and it only exists between the surrounding non-underscored labels and the same name can be reused. Here is an example that uses _done: (used 79 times in this file):
Code: Select all
abort_quote_runtime:
; """Runtime aspect of ABORT_QUOTE"""
; We arrive here with ( f addr u )
lda 4,x
ora 5,x
beq _done ; if FALSE, we're done
; We're true, so print string and ABORT. We follow Gforth
; in going to a new line after the string
jsr xt_type
jsr xt_cr
jmp xt_abort ; not JSR, so never come back
_done:
; Drop three entries from the Data Stack
txa
clc
adc #6
tax
rts
; ## ABS ( n -- u ) "Return absolute value of a number"
; ## "abs" auto ANS core
; """https://forth-standard.org/standard/core/ABS
; Return the absolute value of a number.
; """
xt_abs:
jsr underflow_1
lda 1,x
bpl _done ; positive number, easy money!
; negative: calculate 0 - n
sec
lda #0
sbc 0,x ; LSB
sta 0,x
lda #0 ; MSB
sbc 1,x
sta 1,x
_done:
z_abs: rts
This assembler doesn't quite have #ifdef, but it does have .if and named lists which is what I use for configuring optional assembly.
Code: Select all
.if "wordlist" in TALI_OPTIONAL_WORDS
; ## PREVIOUS ( -- ) "Remove the first wordlist in the search order"
; ## "previous" auto ANS search ext
; """http://forth-standard.org/standard/search/PREVIOUS"""
xt_previous:
jsr xt_get_order
jsr xt_nip
jsr xt_one_minus
jsr xt_set_order
z_previous: rts
.endif
By default the output is a .prg file (has two byte address at the beginning that say where to load it in memory), so I use the --nostart command line option to make binary ROM images.