As we are all on here for the same reason, I would like to create my own NES game, whether simple and stupid, or elaborate and fun (if I can ever find the time). I have been reading all sorts of information online, seen many examples, and tested some things I've created. With all that said, what is the most commonly used compiler for NES games? I have read post about people wanting to know the best, which usually results in people just going back and forth about why they think the one they are using is better. I just want to know what the majority of the people are using. Thoughts?
By request, I created a poll for this topic. I'm sure I am missing something, if so just leave it in a comment.
Make a poll. Most use ASM6 or C(A/C)65 AFAIK. I use NESASM because it's the least bullshit of any out there, even if you do have to work a different way when writing code.
I think NESASM is great for smaller things, esp. because you can put an entire program in a single .asm file. I learned on it because that's what bunnyboy's tutorial uses.
However, once I had learned how to use cc65's linker, there was no turning back for me. There's so much power in it, not to mention the ability to use C as well.
I started out using TASM, then switched to ASM6. ASM6 goes for simplicity all the way, so it's very easy to use.
About the options: NESICIDE uses CA65 (CC65), and MagicKit is basically the same as NESASM.
I use CA65.
I completely agree with rainwarrior. I started out with NESASM, but quickly changed to CA65. CA65 can be really difficult or confusing at first, but I got used to it very quickly. And while it seems like it is only useful for bigger projects, I never had any trouble using it for smaller ones. In fact I have only used it for smaller projects so far.
I have not used asm6 so I can't really say anything about it.
This discussion comes up a lot I think and there are always good reasons to use or not to use a certain assembler. I think what it really comes down to is preference and getting used to the negative aspects of a certain assembler and learning how to work with/around them.
I use WLA-DX. It's good and has lots of features, but I heard CA65 is even better.
I never really used CA65 so I can't tell. The problem is that apprently WLA-DX has not been updated since 2008.
Dwedit wrote:
ASM6 goes for simplicity all the way, so it's very easy to use.
Yes, I agree! ASM6!
This is where tokumaru agreed with Dwedit; they recommended ASM6 to me.
NESASM and ASM6 are equally simple IMO: both can create a ROM from nothing more than a single ASM file, without configuration files or complex command lines. If you're going for simplicity, you should pick one of these 2. I prefer ASM6 because NESASM uses non-standard 6502 syntax for some things and it has been known to fail silently in the past, producing corrupt binaries without reporting any errors (some people say these bugs have been fixed).
Even though they can assemble ROMs from single ASM files, that doesn't mean that's all they can do... you can use includes and local/temporary labels to better organize your sources, which is recommended for larger projects.
I use ASM6 and an assembler I wrote myself that is very similar.
My only reservation about ASM6 is its tendency to fail silently from time to time. If you use an invalid addressing mode, it might pick a different addressing mode, and the overly flexible syntax means that typos can be interpreted as labels (labels don't require colons). Once or twice this has caused me some very-difficult-to-track-down issues.
Code:
pha ; Interpreted as instruction
phx ; All interpreted as labels
phaa
phs
snarfblam wrote:
My only reservation about ASM6 is its tendency to fail silently from time to time. If you use an invalid addressing mode, it might pick a different addressing mode
Really? This is something we've seen NESASM do, but never happened to me with ASM6.
Quote:
[Silently failing] is something we've seen NESASM do, but never happened to me with ASM6.
...that you've
noticed, anyway, which is why silent failure is such a serious problem.
At least until the next-to-latest version (I haven't upgraded), ca65 silently assembled invalid code for the 65816:
Code:
BF 56 34 12 lda $123456,x ; OK, supports 24-bit indexed on X
B9 56 34 lda $123456,y ; Y can't be used for 24-bit indexing, so silently drops bank byte
I wouldn't be surprised if this isn't an isolated thing.
Silent failing shouldn't ever happen I think. At the very least print a warning, an error that would force the programmer to change the code is better.
As for WLA-DX, it does not requires semicolumns for labels, but anything that starts straight after a line is a label while instructions must have a whitespace before them. I think it's a convenient way to distinguish from labels to instructions, although semicolumns are just as convenient.
I'd say it's a good thing that ASM6 can assemble a complex project without configuration files, and it's probably a very good reason to use it. WLA-DX requires a memory mapping file and a link file, and while this enables me to solve things (like the iNES header) in a very elegant way, it is a source of annoynace for small NROM projects.
Another nice thing is unnamed labels. I use them all the time. The problem is that WLA-DX doesn't handle the + / - the same ways as CA65, which is what is preventing me to switch.
In WLA dx, something like
bpl ++
Will branch to the next unnamed label which is called "++", while on CA 65 it will mean to branch to the second next unnamed label (if I understand correctly).
Therefore in WLA-DX it's easy you use "+, -" for the inner loop, "++, --" for the outer loop, etc.. (I rarely use more than 2 of them).
For CC65 it'd be a complex process to count the amount of unnamed labels you want to skip, and therefore make the code more error prone, and indirectly you'd have to use named labels instead in order to avoid errors. I HAD errors with unnamed labels on WLA, of course, but quite rarely so.
Bregalad wrote:
For CC65 it'd be a complex process to count the amount of unnamed labels you want to skip, and therefore make the code more error prone, and indirectly you'd have to use named labels instead in order to avoid errors.
You'd want to use named labels anyway to make it easier to rearrange your loop later.
Yeah, you can just use named labels with local scope to get what you want there.
True, but finding good names for functions and variables is in my opinion one of the harest parts of programming (and I am very poor at this game).
Having to find a new label name every 4 line of assembly code isn't exactly fun.
Unnamed labels are of a great help, and with the WLA-DX system while it's possible to mess up (the program doesn't branch where you want) usually I can mangate to not mess up. With the CA65 system it sounds like I'd be messing up all the time, especially after being used to the WLA-DX system.
NESHLA was a good idea, but there is no point in using it when CA65 is much more advanced and there are
CA65 macros that can do more "high-level" stuff than NESHLA can.
(This can help with the problem of thinking up label names too.)
Bregalad wrote:
Having to find a new label name every 4 line of assembly code isn't exactly fun.
You don't need to make up a new name every time if you use anonymous (or even named) scopes in CA65:
Code:
.scope
loop:
dex
bne loop
.endscope
; The upper "loop" label is no longer visible at this point.
.scope
loop:
dey
bne loop
.endscope
Another option is
cheap local labels, but I don't like them too much.
And inside macros, where it might be used multiple times in a routine and thus get duplicate symbol labels:
Code:
.macro foo
loop1: ; prevents multiple uses of macro
@loop2: ; prevents multiple uses between two normal labels since this cheap one gets defined multiple times
.local loop3: ; OK, this label is local to this macro invocation
.scope
loop4: ; presumably also OK
.endscope
.encmacro
In ca65 I tend to use the
: label a lot. The documentation claims this is "messy code", when in fact it's their own chose of labelling model that results in that mess. Instead, had they actually supported labels named
+ and
- with "depth" support (I don't know what else to call it), it'd have made a lot more sense. Just look at the ca65 example, then compare it to this:
Code:
- lda (ptr1),y
cmp (ptr2),y
bne +
tax
beq +++
iny
bne -
inc ptr1+1
inc ptr2+1
bne -
+ bcs ++
ldx #$FF
rts
++ ldx #$01
+++ rts
Significantly more clear -- no more of this colon-label guessing game shit. x816 supports this syntax. Quoting the docs:
Quote:
Code:
Symbols
-------
...
Special symbols - and + can be used for reverse and forward
branches. These two symbols come in very handy as you will
see.
Examples:
- lda $4212 ; wait for vblank
and #$80 ; bit 7
beq - ; not vblank, repeat
lda number
cmp #1
bne +
jmp number_1
+ cmp #2
bne +
jmp number_2
+ cmp #3
In the first case of a continuous loop like in the first
example you don't need to create a new symbol name for the
routine. In the second case where you're comparing a
series of values and the subroutine is too far to branch.
If you want to use nested - and + symbols you can use --,
---, ++, or +++. Any symbols preceded with the - or +
symbols will be taken as the - or + symbol type. So in
fact, you could use proper symbol names if you want to get
more detailed in your naming convention.
...
I am generally against excessive use of pseudo-ops to declare scope/etc. as in my experience it results in really hard-to-read code (you spend more time wrapping your brain around all the pseudo-ops than you do looking at real code).
koitsu wrote:
I am generally against excessive use of pseudo-ops to declare scope/etc. as in my experience it results in really hard-to-read code (you spend more time wrapping your brain around all the pseudo-ops than you do looking at real code).
While I agree that
.scope and
.endscope is a bit wordy, XA65 uses
.( and
.), which I find quite natural.
@Koitsu : The code you posted looks exactly to what I have with WLA.
That is, if I use ++, it will refer to the next label named "++", without having to count instances of unnamed labels or anything in the like.
Bregalad wrote:
@Koitsu : The code you posted looks exactly to what I have with WLA.
That is, if I use ++, it will refer to the next label named "++", without having to count instances of unnamed labels or anything in the like.
Thumbs up for WLA's method then. Not that ca65 sucks or anything, just that with regards to quick/easy labels, I find its
: nonsense to result in ugly code, ditto with the whole excess focus on
.scope/
.endscope. I guess I'm just old fashioned and set in my ways. :-)