ca65 can probably do all you want. It takes a platform configuration file which can specify where various code and data sections are to live - although the actual loading of the binary code into the target system is sometimes left as an exercise to the user.
[edit to say that I initially missed the bit about cross platform - ca65 is 6502/65816 only, sorry]
Adding a new platform into it is tricky - mostly because there isn't much documentation, but it involves changing some of the source code files. However that's really aimed at the C part of it all. For pure asm, then it's not that relevant.
cjs wrote:
- Local vs. global symbols: assemblers such as AS offer SECTION/ENDSECTION directives that seem as if they would do just as well, perhaps even better because there are more levels of scope.
- :Size-limited sections/areas: ASxxxx lets you do `.area foo (PAG)` to create an area that will give a warning/error if the size exceeds 256 bytes, which can be used for checking that, e.g., the direct page allocations of several different modules don't overflow the direct page. I'm not sure how one deals with this in whole-program assemblers, or if they even offer this kind of facility.
- Speed: probably not an issue given how fast modern systems, how fast assembling (as oposed to compiling a higher level language) is, are and that I'm unlikely to be assembling anything larger than about 10,000 lines of code, at most. It's not as if the linking/relocation stage doesn't take time anyway.
- ???: Some other things that I'm missing?
Does anybody have any experience with or thoughts on this? Am I possibly just lacking too much understanding of the whole idea of largish projects in assembly language to see if I'm worrying about the wrong issues, or missing something more important?
ca65 was designed to be the back-end assembler to the cc65 C compiler, however it's very good on it's own. I may be biased though, but I use it to build everything I do on my Ruby 6502 and 65816 systems. My OS for the '816 is split over 70+ files (.s and .h), about 13,000 lines, and uses a Makefile to build. It assembles and links in under a second on my somewhat modest i3 Linux desktop PC.
On the size limited thing - it's not automatic, but you can flag warnings with conditionals, so e.g.
Code:
commandTable:
.asciiz "LS" ; Has to be the first for histerical reasons...
...stuff omitted
.asciiz "EXIT"
.byte 0
; .byte commandTableEnd-commandTable ; un-comment to find out how big it is in the .lst
commandTableEnd:
.if commandTableEnd-commandTable > 250
.error "Command table too big"
.endif
The local/global stuff is supported - either separate files, or by using .proc/.endproc for functions. This lets you use the same label names inside each 'proc' if you like. Think of each proc like a C function. You have to export symbols to make them global and import them in other files you want to use them (again, think C extern variables)
I build my OS with the platform set to 'none' but I created a platform for C programs which does stuff like set the start/load address ($8000) and the start and end of the data segment, stack and so on, and how much zero page it can use. you don't need much of this for most asm projects though.
Start here:
https://cc65.github.io/index.htmlCheers,
-Gordon
_________________
--
Gordon Henderson.
See my
Ruby 6502 and 65816 SBC projects here:
https://projects.drogon.net/ruby/