This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

nameless label styles: x816 vs. ca65

nameless label styles: x816 vs. ca65
by on (#29925)
x816 does nameless labels with + and - as label names, then jumps to them with "BNE +" or "BNE -". Example:

Code:
- NOP
  LDA somewhere
  BEQ +
    DEC something
    BNE -
+ RTS



ca65 uses : for all nameless lables, and jumps to them with "BNE :+" or "BNE :-". Example (would assemble to same as above, but ca65 style):

Code:
: NOP
  LDA somewhere
  BEQ :+
    DEC something
    BNE :-
: RTS


ca65's system just makes so much more sense to me personally... yet I seem to see x816's style more often. Which method is generally more preferred by the users here?

I ask because with the recent heat surrounding nesasm and my own boredom I've started looking into making a little assembler of my own. Since the above styles' syntax are not mutually exclusive, I've considered having both of them in the assembler, which I think would be ideal. But I'm still not 100% sure how x816 style works.

can a "BNE +" jump to a "++" label? I mean like....

Code:
    LDA blah
    BNE +
    JSR routine
++   DEC somewhere
+    INC somewhereelse
    RTS


would that BNE jump to the DEC or the INC? If the DEC, then why do you need the double ++? And if the INC, then why bother with nameless labels when they're not really nameless (in a sense, the number of +'s becomes the name)?

It just confuses me. But I know a lot of people prefer it.

by on (#29928)
I think BNE ++ can only jump to ++. The point is just to not have to come up with names, not to be flexible.

I like this notation that AFAIK, no assembler uses:

Code:
: something else
: NOP
  LDA somewhere
  BEQ +1
    DEC something
    BNE -1
  LDA somewhere
  CMP something
  BEQ +2
  BNE -2
: RTS
: something else


I really don't like the idea of "BEQ ++++++" and generally the less I have to type the better for me.
Re: nameless label styles: x816 vs. ca65
by on (#29929)

by on (#29931)
That's interesting. I may adopt that as well.


Another thing that was a minor beef with nesasm for me was it's use of brackets for indirection instead of traditional parenthesis. Instead it used parenthesis for expresson evaluation. I can see how this would become an issue if you used parenthesis for both:

Code:
LDA (zing+5),Y


Is that Absolute Y with parenthesis to enclose the expression? Or is it Indirect Y?

I thought about having a set of rules to dictate whether or not the parenthesis were in fact part of an expression or whether they were used to indicate indirection... but I think that's a bit overkill. Considering the complexity it would involve and that it would ultimately confuse people and cause hard to find assembly errors... I think I'm going to take the nesasm approach and simply use brackets for one and parenthesis for the other.

Though I'll do it reverse from nesasm (parenthesis should be for indirection since that's how they're used virtually everywhere else). So brackets would be used for expressions. Plus using indirecton (from my experience) is much more common than complex expressions that require parenthesis

Thoughts/opinions?

by on (#29932)
WLA-DX does the nameless lables like x816 seems to do. I am really used to this method because I use WLA-DX, but it seems that ca65's method would be alot better, because every lable is the same.

In WLA, all the assembler does is it finds the nearest "++" lable and uses that as the destination. It doesn't matter if there's not a "+" lable before it. I actually like that. But I think the :+/:- would be better, since you wouldn't have to actually name the lables "+" or "-".

by on (#29933)

by on (#29936)
Disch wrote:
Though I'll do it reverse from nesasm (parenthesis should be for indirection since that's how they're used virtually everywhere else). So brackets would be used for expressions. Plus using indirecton (from my experience) is much more common than complex expressions that require parenthesis

Thoughts/opinions?


This is a good idea. Parenthesis are good for real 6502 instructions, and brackets are good for expressions. This would be good to seperate them like that so you could have an easier time debugging.

As for nameless lables, and lack of readability, that's what comments are for. I personally like to write comments as if I'm talking to someone who's never looked at the code. I describe what the code is doing, how it translates into understandable concepts, and how the routine will have effect on the grand scheme of things. And it's also best to describe by the definition of the nameless lable why the code will jump to that point, and where it will have come from. Like so:

Code:
RoutineA:
lda $xx
beq +
bmi ++
             ;we will be here if bit seven is not set, and the number is not equal to 0.
+           ;This lable defines what will happen if the variable tested in RoutineA ends up being equal to zero
 blah code
++
              ;This lable defines the location what will happen if bit 7 of the variable tested in RoutineA is set.
 blah code

by on (#29939)
loopy wrote:
(edit) Here, "nameless" is a misnomer, maybe "reusable" is more appropriate..

"Reusable" is a good word for discussing the underlying concept here. I don't use CA65's nameless labels much in my own code now that I've discovered its two other useful layers of local labels. Here, I explain @ labels and scoped ordinary labels.

CA65's cheap local labels (also called @ labels), of the form '@here' and '@there', roughly correspond to x816's labels '+here' and '-there'. An @ label is visible only between one ordinary label and the next. Here, the two labels '@inner' are distinct because the ordinary label 'clearRAM' separates them:
Code:
clearNametable:
  lda #0
  tay
  ldx #4
  @inner:
    sta $2007
    sta $2007
    sta $2007
    sta $2007
    iny
    bne @inner
  rts

clearRAM:
  lda #0
  tax
  @inner:
    sta $00,x
    sta $300,x
    sta $400,x
    sta $500,x
    sta $600,x
    inx
    bne @inner
  rts

An ordinary label can be made visible only inside the scope of a single procedure by wrapping the procedure in a .proc block. Here, the two labels 'inner' are distinct, called 'clearNametable::inner' and 'clearRAM::inner':
Code:
.proc clearNametable
  lda #0
  tay
  inner:
    sta $2007
    sta $2007
    sta $2007
    sta $2007
    iny
    bne inner
  rts
.endproc

.proc clearRAM
  lda #0
  tax
  inner:
    sta $00,x
    sta $300,x
    sta $400,x
    sta $500,x
    sta $600,x
    inx
    bne inner
  rts
.endproc


Disch wrote:
Another thing that was a minor beef with nesasm for me was it's use of brackets for indirection instead of traditional parenthesis. Instead it used parenthesis for expresson evaluation. I can see how this would become an issue if you used parenthesis for both:
[...]
I thought about having a set of rules to dictate whether or not the parenthesis were in fact part of an expression or whether they were used to indicate indirection

I can't find anything in the CA65 manual that explains the algorithm that CA65 uses to distinguish these. But as far as I can tell, if the entire operand in a CA65 expression is one single parenthesized expression, CA65 treats it as indirection. Otherwise, CA65 treats it as absolute. Yes, this breaks C-style preprocessor macros, which employ parentheses to separate arguments and results from the precedence system, but CA65 has a richer macro syntax than C.

Celius wrote:
Parenthesis are good for real 6502 instructions, and brackets are good for expressions.

I thought parentheses vs. brackets were for distinguishing a 16-bit "near" address from a 24-bit "far" address on the 65C816. Because CA65 assembles both 6502 and 65C816 code, it has more need of such an algorithm.

Celius wrote:
And it's also best to describe by the definition of the nameless lable why the code will jump to that point

Based on the elaborate comments you give with these labels, it might be better to summarize the comment into a cheap local label, such as '@notWithinX' in CA65 or '+notWithinX' in x816.

by on (#29941)
re: brackets used as long indirection on 65816:

I brainfarted on this and totally forgot they had this use on 65816. I hadn't considered making this a 65816 assembler... but should I ever decide on that in the future it'd be good to avoid things like this that will cause headaches.

I suppose I could use some other form of encapsulation symbol for expressions. Maybe {curly braces}? That seems kind of iffy. I can't use <> because those have other meanings and can't be overloaded this way, and if brackets and parenthesis are both taken by indirection... I'm running out of options.

Maybe I'm overthinking this. Complex expressions are somewhat of a rarity -- at least from the code I've seen and written. In that event curly braces ought to do just fine.

-----------------

cheap @local labels are already something I've considered and decided to go with. .SCOPE and .PROC are something I haven't really considered. At least not initially. Personally I'd like to omit them from at least the initial version and maybe add them later. They don't seem like a high priority feature to me.

-----------------

I'm still kicking around macro ideas. I'll probably go with something similar but not quite as advanced as ca65's setup. Some of its features seem a little too extravagent... at least for a first version.



I appreciate all the input, everyone.



EDIT


Considering cheap @local labels are functionally very similar to x816 style "nameless" or "reusable" labels... perhaps I should leave x816 style labels out and just go with ca65's style?

by on (#29954)
Disch wrote:
Considering cheap @local labels are functionally very similar to x816 style "nameless" or "reusable" labels... perhaps I should leave x816 style labels out and just go with ca65's style?


If you want to make it an extremely comfortable assembler, you could do both. It would be nice to have more flexibility. But if nothing else, I'd go with ca65's type of nameless lables.