I'm at the point where I want to start coding. I've noticed there's quite a few options as far as assemblers go, and seemingly no overall consensus as to which one is better. Though, I'm sure everyone has there personal preference, so I was hoping to find some sort of a comparison.
Is there any of the assemblers I should avoid altogether? Which one is the most commonly used in this community? Do any of the assemblers have features that make them really stand out above the rest?
I'd recommend you start with asm6; it keeps things bare-bones while offering a lot of functionality and uses a normal/"standardised" syntax.
You can "upgrade" to cc65 (ca65) when you get into more complex things.
Ah, ok. So I shouldn't have to much trouble migrating from one to the other?
No, you will have *lots* of trouble. But you're just starting out, so I wouldn't worry about it.
I started with TASM, then moved to ASM6. It was easy enough to migrate from one to the other.
I liked how ASM6 has anonymous labels (- or + as a label), and INCBIN, two feature which TASM doesn't have. The ENUM feature where you declare a bunch of variables in RAM which doesn't emit any bytes is also great.
But I didn't like how ASM6 gave you mountains of "Incorrect Address" errors for a single mistake, so I went ahead and fixed the assembler to remove some situations which caused them.
I have used ASM6 for the past couple of years and have no complaints. It's simple (i.e. easy to use for the first time) but very versatile.
Dwedit wrote:
...and INCBIN...
Yes, I could see using the incbin a lot. I am working on a tile/map editor that outputs to a binary file, I could use incbin for this right?
Dwedit wrote:
The ENUM feature where you declare a bunch of variables in RAM which doesn't emit any bytes is also great.
If I understand correctly this just enumerates a value to a certain label, like a constant?
Dwedit wrote:
But I didn't like how ASM6 gave you mountains of "Incorrect Address" errors for a single mistake, so I went ahead and fixed the assembler to remove some situations which caused them.
Now you're scaring away the n00b! :P Did you at least contact Loopy to have him incorporate the patch into the official source? (I do remember skimming the thread about the problem you describe...)
tokumaru wrote:
I have used ASM6 for the past couple of years and have no complaints. It's simple (i.e. easy to use for the first time) but very versatile.
Cool. Is it possible to use mappers with ASM6? As far as I understand I will need to use a mapper for some of the functionality I want to implement.
koitsu wrote:
...Now you're scaring away the n00b!
LOL, error messages are a part of programming life. I'd rather see too many error messages, than use a compiler that neglects to mention things
cartlemmy wrote:
I could use incbin for this right?
Yes.
Dwedit wrote:
If I understand correctly this just enumerates a value to a certain label, like a constant?
ENUM works kinda like ORG, but doesn't generate any output. It's great for defining variables.
cartlemmy wrote:
Cool. Is it possible to use mappers with ASM6?
For mappers, look into the BASE statement.
Check out the
ASM6 templates I made for a few of the simple/common/popular mappers.
tokumaru wrote:
Check out the
ASM6 templates I made for a few of the simple/common/popular mappers.
Great, thanks! This will be very helpful.
cartlemmy wrote:
I'd rather see too many error messages, than use a compiler that neglects to mention things
Good, so stay away from NESASM. That assembler is commonly used by newbies because a few tutorials use it, but it's full of nasty little problems. Generating corrupt binaries when some errors occur instead of warning you is one of them.
So, sounds like it's a safe bet to start with ASM6, I will start with that.
Thanks to everyone for their help!
Well, what happened is that us ASM6 fanboys got to answer your question first! =)
There are other favorites around these parts besides ASM6 (maybe other members will recommend them to you soon), and some of them are really good and have a lot of features, but the problem is that they require a lot of configuration before you can even assemble anything. You have to make configuration files describing the system and the cart you are using, what's ROM, what's RAM and so on. And even if you download configuration files made by others, you still have to deal with linking, which is something I'm not quite sure I understand.
For these reasons I went with ASM6, because it's as straightforward as it gets without sacrificing versatility. Just give it an ASM file and it will spit out the final binary file, no worries.
I like to use ASM6 still to test out aspects of NES programming I don't yet understand. It is definitely very easy to set up a program in ASM6, assemble and you're ready to go.
CA65 does have a bit of extra setup, but if you knew what you were doing in ASM6 prior to using CA65, it is actually the exact same thing. Instead of having .org, .base, and .pad in ASM6, you put all that stuff in a setup file and abstract that information into what are called "segments."
I've found for a large game project, the ability to use CA65's segments and memory areas has been invaluable for refactoring, and for keeping related data grouped together (even though individual chunks of data may reside in multiple PRG banks).
I think the advice already given is good, start out with ASM6 and if you eventually work on a large, complex game project you might want to check out CA65.
I use NESASM and haven't had any problems with anything close to "corruption"
Oh well, it works for me....and Sivak if I recall him mentioning.
bunnyboy also uses NESASM. Everyone craps on it but nobody knows why anymore. Almost all the problems were with much older versions that were fixed. Notice how this "corruption" problem isn't even mentioned:
http://nesdev.com/bbs/viewtopic.php?t=3726
That doesn't mean you should choose it above ASM6 just that it isn't the shit everyone claims. The most successful projects (PowerPak, Battle Kid, etc) were made with it.
Cool, thanks for the extra input I'll definitely give NESASM a look as well.
ibeenew2 wrote:
That doesn't mean you should choose it above ASM6 just that it isn't the shit everyone claims. The most successful projects (PowerPak, Battle Kid, etc) were made with it.
There is no source release for either of those projects, so that's not much help. I'm surprised Battle Kid was made with it (without much trouble), quite honestly. There also isn't any kind of documentation with the NESASM update, so it's not very easy to tell what changed. NESASM has been around since 1998 at least, last official update over 10 years ago that has been plenty of time to find problems. People advise against it only because they want to save others the time of finding the problems themselves.
NESASM, for one thing forces you to use 8kB banks, while ASM6 (or any other 6502 assembler) doesn't impose any arbitrary size limit. You can't overflow a bank (though even NROM is a flat 32kB).
As for other assemblers, CA65/CC65 is notable for being in development for a really long time (being rewritten entirely over that time I'm sure). It also includes a C compiler, but you really have to know what you're doing to use it (there aren't any usable NES-specific libraries and it's strict ANSI C).
Memblers wrote:
There is no source release for either of those projects, so that's not much help.
Theres no source for any major project, so that doesnt matter when picking an assembler. There is source for smaller complete projects like cyoa and ttxo. there are good accurate tutorials using NESASM. those tutorials should probly be writen for asm6 too.
Memblers wrote:
People advise against it only because they want to save others the time of finding the problems themselves.
Then why didn't people list those problems in the thread so they could be fixed?
Does NESASM force you to use the low-byte unary operator (is it < or >, I forget) to use zeropage instructions? I know one of the assemblers does that, and I wouldn't be able to put up with that.
Dwedit wrote:
Does NESASM force you to use the low-byte unary operator (is it < or >, I forget) to use zeropage instructions? I know one of the assemblers does that, and I wouldn't be able to put up with that.
I think it does. But AFAIK, ASM6 has a related limitation: it doesn't let you use absolute addressing to access ZP memory, so you have to .db the opcode and .dw the address if you want to do it. Unless that has changed since the last time I checked.
On the NES you can just add $800 (or $1000 or $1800) to the zero-page address if you want to access it with absolute addressing. Or use y indexing, which has no zero-page mode.
ibeenew2 wrote:
Memblers wrote:
There is no source release for either of those projects, so that's not much help.
Theres no source for any major project, so that doesnt matter when picking an assembler.
Yeah, true. There aren't many completed big projects, Neotoxin comes to mind as one that did have source posted (not sure if that was a release or a leak though).
Quote:
Memblers wrote:
People advise against it only because they want to save others the time of finding the problems themselves.
Then why didn't people list those problems in the thread so they could be fixed?
They've been listed in other threads (probably on the older forum too, for posts before 2004), but I think one important reason is that NESASM has lots of non-standard syntax. Such as not defaulting to zeropage (STA $00 coming out as STA $0000), and of course the [] vs () for indirect thing. Then too by the time someone changes the banking system, it would then be incompatible with older NESASM sources, so it may be wise to rename it to something else so people can still assemble their old stuff. Because there really are a lot of sources around that use NESASM, since it had been around for a while (same can be said of DASM as well, at least for ccovell's old stuff).
And the NESASM v3.0 is just an EXE, no docs or source, so whoever would want to fix any remaining issues/bugs will have to start back at v2.x. Maybe bunnyboy could post the modified source sometime, but I dunno, I wouldn't blame him if he doesn't want to spend much time on that.
ibeenew2 wrote:
There is source for smaller complete projects like cyoa and ttxo.
There is also source for projects such as Concentration Room and LJ65, both of which use ca65. But then they're both NROM-128, so they don't really count as "big" projects.
Memblers wrote:
And the NESASM v3.0 is just an EXE, no docs or source, so whoever would want to fix any remaining issues/bugs will have to start back at v2.x.
Source has been at
http://nespowerpak.com/nesasm/nesasmsrc.zip for at least 1.5 years. Others recompiled it for Mac etc.
tokumaru wrote:
I think it does. But AFAIK, ASM6 has a related limitation: it doesn't let you use absolute addressing to access ZP memory, so you have to .db the opcode and .dw the address if you want to do it. Unless that has changed since the last time I checked.
Are these the only times where you need ZP addresses treated as full 16-bit addresses?
* ABS,X without wraparound (into the stack page, yay)
* Timed code where you need to exact amounts of cycles and you need to burn 4 instead of 3 cycles
* Self modifying code
Dwedit wrote:
Are these the only times where you need ZP addresses treated as full 16-bit addresses?
* ABS,X without wraparound (into the stack page, yay)
* Timed code where you need to exact amounts of cycles and you need to burn 4 instead of 3 cycles
* Self modifying code
* Relocation of zero page with 'tad' instruction (see the SNESdev forum), but for this you'd be using an assembler with explicit 65816 support.
ibeenew2 wrote:
Memblers wrote:
And the NESASM v3.0 is just an EXE, no docs or source, so whoever would want to fix any remaining issues/bugs will have to start back at v2.x.
Source has been at
http://nespowerpak.com/nesasm/nesasmsrc.zip for at least 1.5 years. Others recompiled it for Mac etc.
Ah cool, so it is. And the docs even were updated. I only had grabbed the zip with the EXE (and that's what most people would link to), so it would make a lot of sense to have all that stuff together in one file. The history.txt file only shows one change in it though, regarding line length (I remember hearing about that now, but that's one bug I had never ran into myself).
Memblers wrote:
The history.txt file only shows one change in it though, regarding line length (I remember hearing about that now, but that's one bug I had never ran into myself).
Yeah, I remember someone saying this problem was fixed... but what about the others? Looking at past threads I found that at least one version of NESASM failed to report
branches out of range and
invalid addressing modes, generating corrupt binaries instead. That's awful, and will have a person pull all the hair from their heads when trying to debug a program that still assembled under these circumstances.
Personally, even if these bugs were corrected, I'd rather stay away from an assembler with a history like this. It's almost like the default option is to not report any errors and let the user think everything is alright when this obviously isn't the case.
Not sure about you guys but I have had branches out of are errors when I first started so I would think it's fixed in NESASM3.
tokumaru wrote:
Looking at past threads I found that at least one version of NESASM failed to report
branches out of range Fixed many years ago, possibly a decade. v2.51 correctly reports the error and it is at least 5 years old. People using ancient versions instead of new ones is a reflection on the people not the tool. You can't say ASM6 is incomplete because the original version didn't have incbin when it does now.
tokumaru wrote:
and
invalid addressing modes, generating corrupt binaries instead.
He was using the wrong syntax. Parenthesis are used for order of operations like 2*(label+1) so STA (tempAdd),x is
correctly assembled to STA tempAdd,x. People using it wrong does not mean bugs.
ibeenew2 wrote:
He was using the wrong syntax. Parenthesis are used for order of operations like 2*(label+1) so STA (tempAdd),x is correctly assembled to STA tempAdd,x. People using it wrong does not mean bugs.
What's weird though is that NESASM seems to be the only thing in the 6502-using world that replaces parenthesis with brackets. All other assemblers I've used also parenthesis for order of operations and they seem to do just fine. It breaks a tradition that seems to go back maybe 35 years (including lots of source code), for no real advantage. Then the brackets also are used for something else on 65c816, for long (24-bit) indirection, IIRC.
You probably know all this too, but here's an except from the history text that explains the 8kB bank size, and maybe the syntax differences:
Code:
- merged the code of the NES and the PCE assembler, now
there's only one program.
It's an HuC6280 assembler, primarily. And that system does have 8kB banks. The MagicEngine TG16/PCE emulator written by the same author was really great one (and was the only one at the time).
WLA-DX was another assembler that had syntax oddities that I complained about too when it was brought up. Basically for the same reason - it supports multiple CPUs, it's not designed around the 6502. Again I complained then, that the x816 assembler, as well as CA65, supported 6502/65C816 fully without any sort of weird pseudo-typecasting syntax being needed.
Things are a lot better when people are able to share their source code and let other use it. That's what is great about ASM6, CA65, DASM, and x816. You will have to change local labels, swap .byte for .db, easy stuff like that. Try that with NESASM, your bank is going to overflow, it might assemble and take guesses about what the parenthesis mean, it might run slower and be larger without adding stuff to specify zeropage vs absolute, and you're still going to have to change the local labels, heheh.
I was porting something to 2.51 today and found that it doesn't even warn when overwriting values:
.bank 0
.org $100
.byte $12
.bank 0
.org $100
.byte $34
The above acts as if the first .byte was never even done, without any diagnostics. That's a recipe for hard-to-find bugs.
And treating jmp ($1234) as jmp $1234 without even a warning is poor, given that (as far as I know) jmp ($1234) is the standard syntax for an indirect jump.
blargg wrote:
And treating jmp ($1234) as jmp $1234 without even a warning is poor, given that (as far as I know) jmp ($1234) is the standard syntax for an indirect jump.
Yep, I've found myself using JMP ($FFFC) quite a few times. The reset instruction, heheh.
Disclaimer: I use ca65. I've never tried nesasm, neshla, asm6 or others.
I also use revision control. Extensively. Religiously.
I've recently read the posts about people making various changes to loopy's asm6. I humbly suggest that loopy consider placing asm6 into some sort of revision control system and granting approved individuals commit access.
Loopy, if you'd like, I can host a subversion project and "trac" system for your asm6 on my own server. I maintain source trees for 20+ projects (mostly private, the largest one is 250,000+ lines of C code). I have a few public source trees (one being my own aborted attempt a a NES game). I backup to tape, a second hard-drive, a second computer (all in my house) and to a server at work (it's good to be the network security guy there). Automated regression tests upon checking are also possible (eg, compile a source file that utilizes most asm6 features and md5 the resulting .nes file). But my server is x86, so I can't automate testing of a big-endian build.
You can also get SVN, CVS, Hg, git or other hosting from a variety of places for free. Or if you have no desire to do so, you could permit the nesdev community to do the same.
The alternative is for several people to maintain their own private branches (possibly using independent rcs systems) and not benefit from a shared repository, commit histories, bug tracking and ownership, etc...
I've actually had to to use NESASM. NESASM 2.x has that bug where label names have to be shorter than a specific number of characters (which bit me when I was attempting to reassemble a public Japanese game from source -- written with NESASM!), otherwise it starts spitting out vague/bizarre errors which you won't easily determine are caused by label names being too long. NESASM 3.x would just segfault or crash in some way (I forget). Garbage. :-)
Are you running modern compter? 0_o XD
I had no idea there was a nesasm3. I just looked and the only important change is an increase of line length. The other addition seemed to be some kind of list of function addresses.
I think so?
I know I don't use it alot, but I've not really had any problems with it. Although the bank sizes differ from NES hardware is a dumb idea, indeed. If I knew more C I'd edit it but I don't, so I guess I have to suffer. Oh well.
Edited for sounding like an idiot.
I guess I didn't mention this earlier either, which somewhat explains why I'm willing to rant a lot about it, but like koitsu I use NESASM because I have to. Sometimes it's teaching people (who are already using it), there's plenty of NESASM-assembled stuff in the Garage Cart #2 compilation, even an NBASIC game (it compiles to NESASM syntax). I can certainly congratulate people who've never had trouble with it, heheh.
MCK depends on NESASM also, it has been widely used. On my original Squeedo cartridge I had a show-stopping bug that I was never able to track down (having moved on to a better rewrite), I hacked MCK to play music through my synth (IRQ'd to the NES's $4011) but there was some terrible glitching. I wouldn't be surprised at all if it was something mundane and stupid slipping through NESASM's error-checking. Wasted a lot of time debugging my PIC and NES code (which worked fine by itself), but, shit happens. And it's totally worth it that I'm making it with the PIC32 now, instead.
NESASM is inescapable, so yeah that's reason enough to discourage it's use among newbies. With ASM6 one can use those macros posted recently to create an iNES header, and that's a good basic setup that's just as convenient. At least until someone rewrites NESASM's erroring system (and banking size selectable), I can live with the syntax difference because of the ever-handy search-and-replace function.