NESDev and Strangulation Records messageboards
Forum Index | FAQ | New User | Login | Search

Previous ThreadView All ThreadsNext Thread*Show in Threaded Mode


SubjectAssembler Features new  
Posted byASMGuy
Posted on12/24/03 7:07 PM



I was wondering...

I've been interested in coding my own assembler recently and
think I've done a fairly good job.

I was wondering what features you all think
are good in an assembler. The more features the better, I think.

Here's the link to my assembler:
http://k2pts.home.comcast.net/gbaguy/a65_v1.77.zip

Read the readme.txt for a description of syntax and current features
and ideas for other features.

It is compiled for .NET v1.1 . C# source is included along with a test
ROM (and source). If anyone needs a .NET v1.0 version, feel free to ask.

If noone cares, that's fine too. :)

(Note: I called it a65 after A86 (just about the first x86
assembler I used. Last night, I remembered P65, and thought that
it probably would have been A65 had it not been originally written
in Perl. If Martin would like me to not use that name, he can say
so, and I'll change it back to NESbler (which this assembler is a
total rewrite of (an assembler I don't think I ever released.)))

Anyone have any ideas and/or comments?






SubjectRe: Assembler Features new  
Posted byMemblers
Posted on12/24/03 8:48 PM
From IP68.58.99.218  



Looks pretty decent. Sorry to say I might have too much time/code invested in learning ca65 to use yours, though. :P
But it looks like a good alternative. Let me know when the release version is ready, I'll add it to the site.

I really liked how x816's local labels worked. Makes code easy to read at a glance, even better than named labels at times. Consider doing it that way (if you like it), local label syntax doesn't get any better than that, IMHO.

No .dw command, yet?




SubjectRe: Assembler Features new  
Posted bytepples
Posted on12/24/03 10:37 PM
From IP68.53.188.31  



"I really liked how x816's local labels worked. Makes code easy to read at a glance, even better than named labels at times."
Anonymous local labels in ca65 and x816 get complicated when there is more than one label to skip over.

Will this assembler provide any significant advantage over CA65? CA65 is already free and multi-platform software.




SubjectRe: Assembler Features  
Posted byASMGuy
Posted on12/24/03 10:56 PM



Memblers:

I've implemented local labels using a ".scope" op.
What is the purpose of the name after ".module" in x816?
Is an error given if you give that name again?

How local labels look:

.scope
@loop:
bit $2002
bpl @loop
.scope
@loop: ; <-- that won't cause a "duplicate label" error, because it's in a new scope.
bit $2002
bpl @loop ; as you can see, local labels start with a '@'

How are local labels supposed to work? I'm not entirely sure I understand
the concept.
------------------
tepples:

Perhaps. It's just a matter of personal preference. Some people like one
assembler, others another. I don't like linking (that's one of the main
reasons I use assembly) and I'd prefer a specific assembler for the platform
that I'm working on. This assembler is NES specific (although a -raw command
line option would be simple to implement, it would just have the assembler
auto-matically switch PRG banks when the code overflows one, and then just
output all the PRG banks with no header) and outputs a ready to go binary,
which is a real plus for me.

And that free and multi-platform... Of course the assembler is free, and it
will probably run on Linux too (just c/p the EXE!), because it's written in
.NET.

There's no reason anyone would have to use this assembler or even see
any advantage of this one over any others. I just wrote it because none
of the existing ones were ideally suited to my tastes.

-----------
Everyone and Anyone:

Anyone have a copy of the UNIF spec? The page has disappeared...





SubjectRe: Assembler Features new  
Posted byblargg
Posted on12/24/03 11:35 PM
From IP199.170.89.75  



In my assembler the code is broken into independent blocks which allows local labels and for the linker to dead-strip unused code. I had one style of anonymous labels, but have recently adopted a new style based on what I saw in some NES asm source. The similarities to C should be fairly obvious :)

#include "nes.h"  ; insert text of file

extern main ; accessible to other files
static nmi ; only visible in this file
static irq

block {
main:

: lda $2002
bpl - ; previous unnamed label

; ...

nmi:
irq: rti
}

block $FFFA { ; absolute placement
dc.w nmi
dc.w main
dc.w irq
}

The dead-stripping is feature is very useful as it allows common routines to be all in one file, in separate blocks, without having unnecessary ones linked in. When I had the assembler targeted for a PIC microcontroller with flash memory, I wrote a linker which only updated the flash memory with modified blocks. This sped up reprogramming and reduced the number of erase cycles.





SubjectRe: Assembler Features new  
Posted byMemblers
Posted on12/25/03 01:33 AM
From IP68.58.99.218  



Oops, I meant unnamed/anonymous labels rather than local. But .scope seems alright. In ca65, simply using a normal label has the same effect as that .scope command. You might do that too, if you think that's a good way to do it.

I don't know what the .module command does in x816. Never used it much.

tepples:

"Anonymous local labels in ca65 and x816 get complicated when there is more than one label to skip over."

In ca65 it does, it becomes hard to tell which label is branched to. But in x816 if you skip over one anonymous label you'd use ++ as the branch target and as the label name. So you can visually trace as well as a normal label. ca65's method allows you to use several branches to the same anonymous label, but that's a rare case.




SubjectRe: Assembler Features new  
Posted byMemblers
Posted on12/25/03 01:40 AM
From IP68.58.99.218  



Dead-stripping, heh. Yeah, I recently found a way to do that with ca65 also. It's great to have, it cut down the size of some of my programs instantly (since I was using a big library thingy in one .asm file).

You use the .ifref (insert_label_name_here) command, followed by the code/rom data with an .endif at the end. The only catch is that you need have those .ifref commands processed in the source after the label has been used. I'm guessing that's because ca65 is a one-pass assembler.




SubjectRe: Assembler Features new  
Posted bytepples
Posted on12/25/03 02:24 AM
From IP68.53.188.31  



CA65 has dead code stripping as well, through the .ifref directive.




SubjectRe: Assembler Features new  
Posted bytepples
Posted on12/25/03 02:25 AM
From IP68.53.188.31  



...darn lag...




SubjectRe: Assembler Features new  
Posted byRoboNes
Posted on12/25/03 12:36 PM
From IP81.77.157.149  



i have the unif spec somewhere on a cd, i'll see if i can find it




SubjectRe: Assembler Features new  
Posted bymcmartin
Posted on12/27/03 02:02 AM
From IP216.120.118.82  



You mentioned concern about the name "A65"; I don't mind, and even if I did, I don't think I'd have a right to. =)

DASM is also a popular assembler, especially amongst the Atari 2600 crowd, though I think Solar Wars was written with it too.

Moving right along:

- Macros and conditional compilation are things that are really the most necessary for targets like the Atari 2600. They're nice, but they aren't terribly important. If you want one chunk of code to work with multiple targets, conditional compilation is probably more important.
- The traditional name for that other vector is "IRQ", not "BRK". (Besides, that way you don't have to worry about disambiguating between BRK the label and BRK the reserved word).
- Anonymous labels work like P65's, which is what I consider natural =) I probably shouldn't comment past that, other than to say that using * for the label instead of naming them - or ++ makes doing anonymous double-nested loops a bit more feasible.
- I didn't see anything that lets you refer to the location of a memory label (the equivalent of "load the high byte of the address for label 'foo' into the accumulator, what P65 would do with 'lda #>foo')
- Actually, I didn't see anything about expressions *at all*. You really need to be able to do "foo+3" to handle structures or multibyte values conveniently. Otherwise your number of labels bloats pretty dramatically. (label+i*j is probably sufficient for most HLL-y features.) This would probably also fit in well with your RAM map mode, associating sizes with the labels.
- Strings in .db is a very good thing, I use it all the time (It's more useful when you have something resembling ASCII, of course... it's absolutely critical for doing fancy text rendering on a C64)
- .dw is important (again, for naming memory locations). If you want to target things outside of the NES, having .dw.be for bigendian order is also important (I needed that to do SIDs conveniently).
- A version of .org that *does* spit out filler to reach the specified memory location is nice, too, especially if you're building a CHR-ROM by hand. (I called it ".advance", but the standard version seems to be an .org with two arguments.)




SubjectRe: Assembler Features new  
Posted byASMGuy
Posted on12/27/03 03:29 AM




"You mentioned concern about the name "A65"; I don't mind, and even if I did, I don't think I'd have a right to. =)"

Thanks :). Note that this is a NES specific assembler. (Support for non-NES
systems would be "feature", not something standard. This was another reason
for my question regarding the name...)

(Each of my bullet (dash) points will correspond to yours. I was originally
c/p'ing 2 points at a time to here, putting them in quotes and replying, but
that would have made the post unnecessarily large(r).)

-Once I get to macros (There's bound to be more quirks in the basic workings
that I haven't found yet.), the question is whether to have macros as part of
the "pre-processor"-thing (currently, the pre-processor just does one level of
.include), or require macros to be defined before they are used.
-OK, I've implemented IRQ:, seems that no games use BRK (FCEU doesn't even
emulate them (I tried creating one of those software interrupt interfaces
using the padding byte..)), not that I know anything about it, but does sound
use the IRQ vector or something (seen things I don't understand in docs...
the usual :))?
-Anonymous labels are currently just a variable that contains the address
of the last one and any references to '-' are resolved using a specially
rewritten version of the "label apply'er" routine, So each * can only be used
by -'s past it, and only until another * is found. A '>-' (forward reference
to the next one) probably would be too hard, and if I decide to do it, would
be the extent of any anonymous label functionality.
-#< and #> have been implemented.
-Didn't think of that, good idea. Not sure what you mean by "also fit in well
with your RAM map mode". .RAM is essentially so that it can be known ahead of
time whether a label is zero page or not, so I choose zero page or absolute on
the spot. Being able to do things like make a label for (example) $2001, is a
plus.
-Yep strings, wanted my .db to be like almost all other assemblers.
-I have a .dw in my latest version, from the current readme:
.DW - Like .DB except with words (16-bit value) and no strings in .DW. Note
that the values are inserted as you put them (i.e. $2002 is not changed to
$02,$20).
I constantly thinking of changing that to what you'd expect it to do on a
6502 assembler, and then adding that .dw.be...
-I have a .pad, which adds a certain number of bytes onto the internal
address counter. I will have a ".advance"-like item implemented soon; I
agree that it is a necessary addition.

I will package the lastest verion (v1.95), so that the readme can be
looked at.

I'm eager to see if Robo finds the UNIF spec, as I got pretty far figuring
it out from looking at a simple UNIF demo in a hex editor. But it doesn't run
yet (FCEU doesn't give any errors about the header anymore though.).

Thanks for the thoughts and ideas and comments! :)
(I feel like I forgot something, but I always feel like that, so I'll post
again if I realize later that I actually did...)







SubjectRe: Assembler Features new  
Posted byASMGuy
Posted on12/27/03 03:34 AM



Uploaded latest version:

http://k2pts.home.comcast.net/gbaguy/a65_v1.95.zip

Changes:
- Alot of bug fixes, of course.
- Added several things (.dw,.pad,.scope,.ascii)
- IRQ: special label implemented.




SubjectDoing +; conditional instructions; I found the UNIF spec new  
Posted bytepples
Posted on12/27/03 04:09 AM
From IP68.53.188.31  



" the "pre-processor"-thing (currently, the pre-processor just does one level of .include"

I'd suggest unlimited depth of .include nesting, like C's preprocessor does with #include, or at least eight levels. It wouldn't be hard to implement with a stack data structure.

"does sound use the IRQ vector or something"
DMC can be set to trigger an IRQ after fetching the last byte of the sample. Some mapper hardware can trigger an IRQ based on a given number of cycles or (in MMC3's case) a given number of nametable fetches.

"A '>-' (forward reference to the next one) probably would be too hard"

References to '+' labels aren't hard to do. For a reference to a + label, store a fixup request, and when that + label is finally encountered, perform the fixup for all of that label's requests. It could even be done at the preprocessor level, where each reference to a + turns into e.g. _PLUS03 and then, once you find that label, the counter for the + increments to _PLUS04.

I'm almost willing to believe that local labels (labels with the @-sign, which are valid only between "real" labels, as in CA65) would be a cleaner idea than anonymous labels. But here's another interesting feature that might reduce the need for forward anonymous labels: ARM style conditional instructions, where an opcode is postfixed with the condition under which to execute it. To assemble this, write a branch with the opposite condition and then write the instruction. Thus:

CPX #50
LDXCS #50

would be assembled like x816's

CPX #50
BCC +
LDX #50
+

".RAM is essentially so that it can be known ahead of time whether a label is zero page or not"
Require all zero-page labels to be declared before they are used. If C can get away with requiring this...

" .DW - Like .DB except with words (16-bit value)"

I'd suggest .dwm and .dwi, .dwm big endian (stands for define word Motorola), .dwi little endian (define word Intel), with .dw being a synonym for .dwi.

And would there be a way to specify the character encoding or "table" to use for character and string constants? CA65 assumes ASCII, and I have to adapt my output routines and CHR tables accordingly.

"I will have a ".advance"-like item implemented soon; I
agree that it is a necessary addition."

"I'm eager to see if Robo finds the UNIF spec"
I found this in the Wayback Machine:
http://web.archive.org/web/20030214150733/www.parodius.com/~veilleux/UNIF_current.txt
and I've mirrored it:
http://pinocchio.jk0.org/UNIF_current.txt




SubjectRe: Doing +; conditional instructions; I found the UNIF spec new  
Posted byRoboNes
Posted on12/27/03 11:05 AM
From IP81.77.136.219  



http://web.archive.org/web/20030214150733/www.parodius.com/~veilleux/
without the UNIF_current.txt part it shows the entire stuth (the board names and cart lists) just as original did, great link




Previous ThreadView All ThreadsNext Thread*Show in Threaded Mode
Jump to

Memblers' homepage             Contact Me

Forums powered by WWWThreads Demo