Re: Writing my own assembler
Posted: Fri Oct 12, 2018 5:26 pm
yeah, I was confusing his assembler feature with the talk of the global jmp/label ret.
Exactly. You download the interpreter, and run your script through it, it's the same thing.zzo38 wrote:it is just another programming language and you could also use Python, Perl, or PHP).
That's what I meant by "outdated" a few posts ago. I think it's an old version of JavaScript, without little support for binary data and file manipulation.I think that Windows Script Host does not implement many ES6 features though?
Not only that, but being a popular tool that's actively maintained, there are several modules for all kinds of things you might need.If you are writing a assembler in JavaScript you will likely want byte arrays.
While square brackets for indirection makes a lot of sense in assembly (more than parentheses, I agree), there's just too much 6502 code out there using a standard that's probably as old as the CPU itself, and a change like that causes unnecessary confusion IMO.I also like the nonstandard syntax used in NESASM/MagicKit (indirect addressing uses square brackets, and zero-page addressing is explicit), but maybe you prefer the standard syntax.
I often use macros to help with this kind of thing too.I also tend to use macros to define jump tables and so on, rather than doing them manually, meaning a simple macro system might not do
Yeah, I'm considering allowing user-defined JavaScript funcions. Nothing is more versatile than a full programming language at your disposal.(although if the assembler is written in JavaScript, it would be possible to support extensions also written in JavaScript without too much difficulty)
I like that idea a lot. So many times I'm torn between trying to wrestle macros into doing something that would be easier with a full programming language, and saying "forget it" and just running my own custom pre-processor (written in perl or python or something) over my code. This could be the best of both worlds.tokumaru wrote:Yeah, I'm considering allowing user-defined JavaScript funcions. Nothing is more versatile than a full programming language at your disposal.
I've been asking Soci for 1 for a year and a half, but we didn't really come up with a nice way to do it.. that looks perfectDrakim wrote:Darn, this thread is just making me itch to take a stab at making my assembler as well. I just might give it a go.![]()
I've had some ideas floating around for a long time, so I figure I might share them here if you are interested. I'm not sure if all of these ideas are realistic, I haven't tried to implement them myself anywhere yet.
1. By far my most common label is a @Return: label in front of a nearby RTS statement. Maybe it's my style of coding, but I find that subroutines always has some branching conditions that exits early. So I realized it would be pretty nifty if I could just write a branch jump like this:
And the assembler would just treat a nearby RTS statement as a on-the-fly label destination (or throw an error if there are none within range), so you wouldn't have to put a @Return: label there. It's not really any new kind of functionality, just a sort of "auto-label" thing to make the code less verbose.Code: Select all
LDA MyVar BEQ RTS STA MyVar2
2. Sometimes as a programmer you can do things that the assembler can actually see is stupid. Like putting code in a bank, that uses a label from another bank (which is on the same page). Or if you have an absolute instruction with an Int instead of a label, which I'm guessing in 99.99% of cases is just the programmer forgetting a # symbol before the Int. It would be neat if the assembler could tell you about such mistakes.
3. Labels do a LOT of different jobs in asm code. They act as entry-points for subroutines. They act as starting offsets for data tables. And they act as holders of constant gameplay values. Sometimes I wish there was a way to mark a label as to what kind of job it does, and have the assembler throw an error at me if I'm trying to use it in a different way. So you can't JSR GHOST_ID since the label holds a constant value and not an address to a subroutine, and you can't LDA GHOST_INIT since the label holds an address to a subroutine. (Obviously sometimes you need to do tricky things like a RTS trampoline so there need to be a way to tell the assembler to not go bananas over it on specific lines).
Yeah 65816 uses [] as well so you havetokumaru wrote:While square brackets for indirection makes a lot of sense in assembly (more than parentheses, I agree), there's just too much 6502 code out there using a standard that's probably as old as the CPU itself, and a change like that causes unnecessary confusion IMO.zzo38 wrote:I also like the nonstandard syntax used in NESASM/MagicKit (indirect addressing uses square brackets, and zero-page addressing is explicit), but maybe you prefer the standard syntax.
See KickAss Assembler it is kind of a scripting language/assembler hybrid nobody really knows what it is, it kind of became a mess, but there are people who swear by it.tokumaru wrote:Yeah, I'm considering allowing user-defined JavaScript funcions. Nothing is more versatile than a full programming language at your disposal.zzo38 wrote:(although if the assembler is written in JavaScript, it would be possible to support extensions also written in JavaScript without too much difficulty)
Code: Select all
Label:
jmp Label
.org $10000Code: Select all
$fffd: jmp $fffdCode: Select all
.org $8000
;code starting at $8000 goes here
.forgetpc
;code to right-align to $10000 goes here
.org $10000Code: Select all
.scope ;starts a new scope, but we don't know what the parent label is yet
.return:
rts
Ignore45: ;oh, so this is the parent label in this scope
cmp #45
beq .return
;rest of subroutineCode: Select all
.ORG
Define origin address.
Sets the starting address of the source file. X816 will
not assemble any code until this directive is found.
This sounds pretty nice, and I could definitely see myself using it. That said, why does the simulated fixed bank need to be at the upper-end near the vectors? I just always put mine first-thing (ie left-aligned). Is there some disadvantage of how I'm doing it? (asking in good faith, not trying to pick nits and argue)tokumaru wrote:Right aligning means aligning code to an upper address, useful when you use a mapper that swaps the entire 32KB and you need to simulate a fixed bank near the CPU vectors, containing a reset stub, trampoline routines and other things.
To me personally, it makes sense to put the fixed stuff up there because of the CPU vectors, which are in the same category (i.e. thing that must be present in all banks), but what seals the deal for me is that I use the beginning of the bank for subroutines with timed code, or data that has to be aligned to memory pages for timing reasons, because it's easier align code/data to page boundaries there.gauauu wrote:That said, why does the simulated fixed bank need to be at the upper-end near the vectors? I just always put mine first-thing (ie left-aligned). Is there some disadvantage of how I'm doing it?
That might be confused with RGBDS's double colon export syntax. man 5 rgbasm says these are equivalent:tokumaru wrote:Repeated labels: I will simply allow labels to repeat if they're defined with two colons rather than one (i.e. SomeLabel:: instead of SomeLabel:).
Code: Select all
SomeLabel::
;is the same thing as this
SomeLabel:
export SomeLabel