Jump to content
IGNORED

Your Favorite Assembler and Why?


MachineCode
 Share

Favorite NES Assembler  

15 members have voted

  1. 1. What is your favorite NES assembler?

    • NESASM3
    • CA65
    • ASM6
    • Other (please explain in comments)
      0


Recommended Posts

I want to get back into learning NES development but am curious about which assembler to use. Tutorials like Nerdy Nights are centered around NESASM3 while others I see use CA65. Then I've read people saying that NESASM3 was limited and that I should use ASM6 but found far fewer resources centered around it. I know that in the end, a solid understanding of 6502 ASM and the NES's unique aspects (memory map, parsing the controller input byte, etc.) are most important, but I'm curious to know what the members of the homebrew community here prefer and why.

Edited by MachineCode
Link to comment
Share on other sites

ASM6 for me. 

Reasons include simplicity, and a lot of the code examples I was first able to look at and learn from used it. 

The readme docs for ASM6 were very helpful to me, and if you need some jumping off points there are some NROM, UNROM, and CNROM templates on NesDev. 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I have no experience outside of NESASM3. I think the "limitations" are mostly related to older versions. If there are any, I either haven't run into them or the affect is so complicated that I have no desire to attempt it anyways. As far as I know, no other users of NESASM3 have had issues completing any of there games due to limitations. @KHAN Games has created nearly a dozen games with it!

There are some legitimate complaints for each assembler out there. It came down to that the Nerdy Nights tutorials were very simple to follow and that is what I used to learn.

  • Like 1
Link to comment
Share on other sites

I use ca65 for a few reason:

  • The config file for the linker, while really confusing at first, is really flexible and a great way to organize your rom
  • There's a lot of people on nesdev using it, so it's easy to get help/support
  • There's quite a few powerful features (of which I only use a small percentage)
  • cc65 is part of the suite of tools that come with it, and it's nice to be able to mix C and assembly fairly easily

That said, in the end, I don't think that assembler choice is THAT big of a difference. I used dasm for Atari 6502 development (because most of the Atari community uses it) before switching to ca65 for NES, and they aren't all that different. My primary suggestion is just to use an assembler that's widely used in the community, so that it it's easier to get help when needed. Any of ca65, nesasm, and asm6 will be just fine.

  • Like 2
Link to comment
Share on other sites

I use ca65 and asm6 for different reasons:

  • asm6 for small, easy-to-manage projects
  • ca65 for everything else. 


Coming in fresh at a time when both asm6 and nesasm3 were available, asm6 simply felt like it was a bit easier. Also, reading the NN tutorials but having to type it out in asm6 syntax was a great excercise i can recommend. 

ca65, in the end, because for me there's less memory management to do throughout a project; and fewer human errors when i hit assemble. The initial config setup which may seem scary at first will pay you back with interest. 

It can do a lot of stuff. I'm not even sure how to use half of its many features, but if i'd take the time to read up on something i suspect i might find useful, it has the best documentation around. Also lots of people willing to help you if you have questions. 

*If* you want to port or your game or part of its codebase to another 65xx system at some point, it helps to have all of your codebase written in the syntax of ca65 since it is suitable for several other target platforms; not least the commodore 64. 

There is a bit of ecology/history to the asm6/nesasm3 divide. If you were frequenting NintendoAge, you were encouraged to use nesasm3 many of its user had stayed and familiarized themselves with the assmebler NN was written for. If you were on NESdev people would instead recommend asm6. (or ca65). 

So i think it's fair to say the new divide is nesasm is going to be recommended if you're on VGS, and asm6 if you're on nesdev, as far as lightweight assemblers go. 



 

  • Like 2
Link to comment
Share on other sites

37 minutes ago, FrankenGraphics said:

 

I use ca65 and asm6 for different reasons...

 

Thank you for all that great info. Damn near exactly the reason I created this thread. The divide part seems spot as to where I got information on which assembler to use years ago.

The part about portability really makes ca65 and attractive choice. As far as asm6 vs NESASM, what do you find easier about to use about asm6?


Another question for everyone: Does anyone know what assembler the commercial NES developers used during the system’s lifecycle? I would assume they just wrote their own custom assemblers or used modified versions of other 6502 assemblers of the day but I have no proof of that.

Link to comment
Share on other sites

My oversall reservation with nesasm3 is that i feel the syntax a bit messy to read and write. Also - Without having used it much, it seems to me like i could cause a lot of human errors, sometimes without it telling me there's a problem, which can be time consuming. That said, it's is probably a matter of getting used to it, and the differences between asm6 and nesasm3 are fairly small. 

But, for example, it conflates (local) symbols/labels with dotted directives, and global symbols with caps:ed directives. Not only does it make the code harder to follow, that means everything that is not identified as a directive is instead treated as a label, which seems something i would run into a lot.

example:

  • .incbin is a directive, but .mylabel is a local label. So if i make a typo, say .incbim, it is treated as a label which could potentially go unnoticed. this particular case would probably throw me an error because .incbin should be followed by whitespace and an argument (path), but you get my drift. 
  • INCBIM, another typo, would be treated as a global label. 


The .bank directive seems unintuitive to me, since banks are fixed to 8kB whereas most mappers use 16 or 32kB banking. I could probably figure it out but meh. Banking is a set and forget thing with ca65 right at the mapper config step.

a nice thing nesasm3 has got going for it is the -raw commandline option, which strips the game from its header which is kind of useful for when flashing your binary onto a cartridge. That's a step less than in asm6 or ca65 where you need to use .ifdef to achieve the same conveniently; or commenting out an .include to the header, whichever suits your taste. It's a pretty minimal thing, but still. 

I remember reading somewhere that it was pretty easy to hog two bytes of memory instead of one with an easy-to-make syntax mistake in nesasm3, but i don't remember exactly what was the cause.

EDIT: all this seems very scary but honestly, it's just like gauauu said. the difference in your workflow is going to be fairly small. It's probably best to write a few code blocks in each style and decide for yourself. 
 

Edited by FrankenGraphics
  • Like 1
Link to comment
Share on other sites

if you're just getting started, i strongly suggest checking out NESICIDE and it's included "hello world" program. 

this'll give everything you need to get started programming. it uses CA65. 

people often say that CA65 takes a bit of work to set up, but NESICIDE takes care of all of that for you (at least at a beginner's level) so you can work on learning how to program without having to jump through hoops first. 

Edited by toggle switch
Link to comment
Share on other sites

9 hours ago, MachineCode said:

Another question for everyone: Does anyone know what assembler the commercial NES developers used during the system’s lifecycle? I would assume they just wrote their own custom assemblers or used modified versions of other 6502 assemblers of the day but I have no proof of that.

From what I understand, there wasn't an official development software or hardware, licensed developers were only given some docs in Japanese.  Based on what people from Beam Software and Software Creations have said.  The only assembler that I've ever heard named as being used for NES stuff, was one called 2500AD.  And that's only because some "Hong Kong Originals" like Pocahontas, Boogerman, were known to be programmed with it.  If you want to see something crazy, look at Color Dreams' source code that has been released.  Very little of it is assembly, the games itself are mostly some kind of custom-made scripting language.

Some games actually have some of their source code in the ROM, which can be seen on The Cutting Room Floor website http://tcrf.net/ but it's usually just tiny snippets.  One that has a substantial bit of source was actually one of Nintendo's service center test carts (used to be distributed as "cart.nes").

 

My own history of NES assemblers was starting with MagicKit/NESASM, which was brand new and had awful bugs at that time, so I switched to DASM, which didn't have .incbin at the time, then to X816 because I liked the unnamed/anonymous label support, and eventually moved to CA65 once I saw that it basically has any feature one could want.  I grew into using more of its features over time.  Now I'm even using the C compiler quite a bit, it's fairly easy to mix with assembly.

I also use ASM6 for smaller projects.  It's just simple and straight-forward.  It also allows unnamed labels.

The NESASM3 limitation usually referred to is the 8kB banking requirement.  It's based on MagicKit which is a TG16/PCE assembler, which is why there are 8kB banks and the unusual syntax for writing to zeropage (you have to always type "sta <label" instead of "sta label", because $00 and $0000 are different memory locations on a TG16).  The 8kB banking, when the NES mappers are usually 16kB or 32kB, coupled with the bug (I consider it a bug) that NESASM doesn't have a warning or error when you cross a bank boundary, it just drops the data so that leads to more micromanagement (especially if you need to completely fill up the ROM without padding).  NESASM also can't assemble relocatable code, which is a common thing to do, copy code into RAM and run it there.

MagicKit/NESASM3 does have a good macro system though.

edit: Despite what's been said about me on a certain podcast, 🙂 lol, I've used the latest version of NESASM for a very long time.  What sucks is that there are multiple branches NESASM, and none of them updated the documentation to say what was fixed or added.  There is at least NESASM3, and Unofficial MagicKit by zzo38, the latter seems to have many new features, I didn't have much luck using them myself though.

Edited by Memblers
  • Thanks 1
Link to comment
Share on other sites

I was thinking of asking the same thing. I used NESASM3 with the nerdy nights tutorials and the only limitation I ran into with it was that it returns 0 on unsuccessful runs, making my build pipeline less than ideal. I don't know if that's been fixed or not, but I've always wanted to transition to CA65 especially since I'm interested in creating games for other 6502-based machines, but mainly because of the tie in with CC65. I wrote a pong game with NESASM3 and spent a few hours trying to convert it to CA65 but had trouble with the macros. I'll have to revisit it some day.

  • Like 1
Link to comment
Share on other sites

I've only used the more advanced features of ca65 macros when i tried (and failed halfway) trying to translate Garth's FORTH layer. The problem i couldn't solve had to do an assumption of direct control over the program counter, which is not how ca65 + ld65 works. This was something i just couldn't figure out how to solve in another way, so the macros aren't to blame. But it maybe speaks a bit that it can be a little intimidating to get familiar with all of the things you can do? 

But, is there a significant difference in how it handles macros at the level  asm6 or nesasm3 is able to use macros? ie, make a macro, pass some parameters, no .ifblank directives etc. 

 

Link to comment
Share on other sites

13 hours ago, Memblers said:

and the unusual syntax for writing to zeropage (you have to always type "sta <label" instead of "sta label", because $00 and $0000 are different memory locations on a TG16). 

This was the thing i was trying to remember! So yeah, if you forget <, you will accidentally write or load from normal RAM space instead of zero page. 

Done consequently, it results in slow code, because the address to fetch it is two bytes long instead of one. Occasionally forgotten, it results in bugs. Nevermind my previous blabber about taking two bytes in storage; this is not the case. 

 

Quote

  It [asm6] also allows unnamed labels


Another good reason. I like using @ (cheap local label) , -, and + (relative lables). Makes namespace conflicts and typos (esp. with upper/lowercase labels) less common.

Edited by FrankenGraphics
Link to comment
Share on other sites

5 hours ago, FrankenGraphics said:

But, is there a significant difference in how it handles macros at the level  asm6 or nesasm3 is able to use macros? ie, make a macro, pass some parameters, no .ifblank directives etc. 

For simple stuff, it's similar. For how you build symbols, how strings get turned into symbols, etc, it has a lot of features that can end up being confusing.

  • Like 1
Link to comment
Share on other sites

I didnt vote on this because only having used asm6, I can't really favor it over the other options not having ever used them.

however, after using asm6 for a year or so now, literally the only complaint I have on it thus far, is the sole fact that it compiles "STY #$04" instead of complaining that I suck. (yes I did this more than once 😛)

  • Like 2
Link to comment
Share on other sites

2 hours ago, Mugi said:

I didnt vote on this because only having used asm6, I can't really favor it over the other options not having ever used them.

however, after using asm6 for a year or so now, literally the only complaint I have on it thus far, is the sole fact that it compiles "STY #$04" instead of complaining that I suck. (yes I did this more than once 😛)

Storing the Y register to the number 4, eh? That’s actually pretty funny that it doesn’t freak out about that.

Also, if you want to vote for ASM6 it’s cool. I only put favorite vs “what do you use” to avoid messing up people who use more than one.

Link to comment
Share on other sites

1 minute ago, MachineCode said:

Storing the Y register to the number 4, eh? That’s actually pretty funny that it doesn’t freak out about that.

Also, if you want to vote for ASM6 it’s cool. I only put favorite vs “what do you use” to avoid messing up people who use more than one.

sure thing. I cast my vote.

And yeah, especially earlier on when I was less comfortable with the instuction set, I did more times than I dare to admit. ASM6 seems to generally be fairly robust about throwing compile errors and this is the one exception with it i've found so far.

As an Additional note, our development moved over to a fork called ASM6f recently, so that's my current go-to assembler, although it doesn't really differ much from the vanilla one. Adds unofficial opcode support and some minor little things.

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, MachineCode said:

Nice. I’ll have to check out the forked version.

If you intend to mess with the illegal opcodes with it, it's worth a note to look into the version FIX94 forked from the compiler, that fixes a couple of previously unusable illegal ops with it, that were breaking our game so something had to be done to the matter.

current versions of dimension shift are compiled with this assembler and it still works on hardware, so far so good 😛

the fork can be found from here: https://github.com/FIX94/asm6f

(this makes  "LAX (IND),Y", "ISC ABS,X" and "ISC ABS,Y" usable in asm6f.)

we couldn't afford to wait for it to be merged to the master so we decided to fork it instead. At the time of writing, it hasn't been merged yet.

 

  • Like 1
Link to comment
Share on other sites

7 hours ago, KHAN Games said:

Is that us? Did we say something incorrect? My memory is awful.

Yeah there was something Beau said on the tools/assemblers episode, I don't actually remember what exactly.  Not anything important, just something I got an unintended laugh out of while I was at work (wearing headphones).  I've given NESASM a lot of crap over the years, by way of directing people away from it, but it actually is a good assembler if you're OK with requiring the specific indentation and bank size.  And it's really weird that I've been doing NES stuff for so long that I'm kinda nostalgic about it, haha.  The source code to Mouser + NESASM was my version of Nerdy Nights, back when I was like 15-16.

  • Like 1
Link to comment
Share on other sites

48 minutes ago, Jfreakofkorn said:

Anyone learning about programming, this has to be the most informative thread i have read. From the basics to the advanced. Is there any links to profile for beginner to advanced you all to recommend ? ( also have to mention, will be following this thread )

So I'm not too deep into it, but I made this Pong game a few years ago: https://github.com/TomBrannan/NES-Pong

From knowing nothing about 6502 to what you see in the link above, it took me probably 50 hours. A couple hours every night for a month. I had plenty of programming experience but no assembly. The only resources I used were the Nerdy Nights (RIP the NA link) and the NES Dev wiki: http://wiki.nesdev.com/w/index.php/Nesdev_Wiki (I think that wiki has a copy of the Nerdy Nights tutorials). I spent a lot of time looking at pages on the wiki, but I found the best way for me to learn was to take the working examples from the tutorial and change them to see what would happen. I never looked on the nesdev forums but I imagine there's lots of great info on there. I used NESASM3, FCEUX, Sublime text editor with a custom syntax highlighter, and a build keybind so I could run my code with a single keypress instead of doing it all manually. If I did it now I'd use CA65 and Visual Studio Code, but that's just my preference.

I mentioned in my post above that I want to port it to CA65, but all the code is on the github page if it is at all useful. There were a few other things I never got around to doing, like moving everything out of NMI, adding sound effects and music, making my own graphics, and just improving overall gameplay. But it wasn't meant to be an actual playable game, just a canvas as I learned new things.

All this talk is tempting me to pick it back up. If I ever find the time, I'll definitely do a writeup on here of how I set things up.

Link to comment
Share on other sites

 Share

×
×
  • Create New...