6502 coding style.

You can talk about almost anything that you want to on this board.

Moderator: Moderators

User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

6502 coding style.

Post by GradualGames »

This seemed like a sufficiently inconsequential topic I decided it didn't really belong in the technical forum. I'm trying to come up with a better way to indent my 6502 code so it helps guide the eye and communicate more meaning. I've decided in the context of ca65 to adopt the following simple rules:

-Any time a new scope is introduced, or at least the appearance of one (such as a macro), increase the tab level by 4 spaces.

-Any time a new scope is removed, decrease the tab level by 4 spaces.

-Any code between a label and a branch is also to be indented by 4 spaces.

-The root scope is to be indented by 4 spaces (everything, directives, .res, code, data, etc.)

Here's an example of a routine from my current project formatted using these rules. I think I like this, and I'm considering writing a script to just go through my whole codebase and make it all pretty like this.

Code: Select all

    ;****************************************************************
    ;This routine kills all entities that are not the player entity.
    ;****************************************************************
    .proc entity_kill_all_but_player

        lda player_entity_index
        cmp #ENTITY_NULL
        beq :++
            ldx #(MAX_ENTITIES-1)
            next_entity:
                cpx player_entity_index
                beq :+
                    entity_clear_flag #ENTITY_FLAG_ALIVE_CLEAR
                :
                dex
            bpl next_entity
        :

        rts

    .endproc

Anyone else care to share thoughts on 6502 coding style?

*edit* It occurred to me the above rules might be tricky to iron out with a script, as there are cases I didn't address such as branching past a jmp instruction in order to achieve a longer branch.

Previously my rule was to only indent when new scopes are introduced. I might just have to settle for that alone, for simplicity's sake.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 6502 coding style.

Post by lidnariq »

GradualGames wrote:-The root scope is to be indented by 4 spaces (everything, directives, .res, code, data, etc.)
Why? Equivalently, what goes into the "no indent" group?
User avatar
gauauu
Posts: 779
Joined: Sat Jan 09, 2016 9:21 pm
Location: Central Illinois, USA
Contact:

Re: 6502 coding style.

Post by gauauu »

I tend to use a similar indenting style, but slightly less strict. (I sometimes indent sections even without a new scope or label if it helps readability, and sometimes don't indent a loop of it's already really readable)
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 6502 coding style.

Post by rainwarrior »

lidnariq wrote:
GradualGames wrote:-The root scope is to be indented by 4 spaces (everything, directives, .res, code, data, etc.)
Why? Equivalently, what goes into the "no indent" group?
I don't think I have any code in the "no indent" group, but I think I sometimes put global data or allocations without indent, constant definitions, some compile-time asserts, etc.

As for why, I think having a single indent for most code makes it easy to spot the label where they begin. Could be that I'm just used to this from C/C++ style anyway.

Some old assemblers I've used required all non-label lines to start with tab or space. The expected style there was flat, not using indents for structure, but it at least distinguishes labels from code very clearly.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: 6502 coding style.

Post by lidnariq »

Sure, I put labels, and by extension outermost .proc and .scope uses, in the "no indent" group. And blocks of documentation.

But GradualGames seems to have put nothing in the "no indent" group
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 6502 coding style.

Post by rainwarrior »

Oh, I misinterpreted where the left edge of the text was in his example.

Though I suppose that reminds me a little of Java style where everything is in a class so it's common for all the member functions to have an extra layer of indent. (Or similarly python class style where indents are mandatory.)
Garth
Posts: 246
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: 6502 coding style.

Post by Garth »

Mine is similar regarding indentation. I've seen people indent only one space for a loop or condition, and it just looks sloppy, like they did a poor job of lining things up when they meant to. Three or four works much better. I do like to put at least two spaces between words though, to make the separation stand out better when there are labels with an underscore character in them.

Apparently an assembler that's common on this forum requires labels to be on their own lines with no code on the same line. I sure don't like that requirement.

I try to use vertical alignment for maximum benefit in visual factoring. For example, even if grouped labels for EQUates or variables are of different lengths, vertically align the directives that follow them, so

Code: Select all

TIMER: DFS 4
PHI_ACCUM: DFS 2
INC_RATE: DFS 2
THRESH_INC: DFS 2
ALT_TM: DFS 2
ALT_INTERVAL: DFS 2
PORTA_REC: DFS 1
becomes:

Code: Select all

TIMER:         DFS  4    ; <comments>
PHI_ACCUM:     DFS  2    ; <comments>
INC_RATE:      DFS  2    ; <comments>
THRESH_INC:    DFS  2    ; <comments>
ALT_TM:        DFS  2    ; <comments>
ALT_INTERVAL:  DFS  2    ; <comments>
PORTA_REC:     DFS  1    ; <comments>
which is much more readable. ("DFS" in the C32 assembler stands for "DeFine Storage," ie, a RAM variable, allotting as many bytes to it as the number following the "DFS" says.)

An hour-long video about the oberon language has a couple of quotes I really liked (at around 36 minutes into in, give or take):
  • Programs must not be regarded as code for computers, but as literature for humans.
  • Reducing size and complexity is the triumph.
http://WilsonMinesCo.com/ lots of 6502 resources
User avatar
TOUKO
Posts: 306
Joined: Mon Mar 30, 2015 10:14 am
Location: FRANCE

Re: 6502 coding style.

Post by TOUKO »

Anyone else care to share thoughts on 6502 coding style?
I do more or less the same than you,a good indentation is for me the way to go for a really redable 6502 code .
Even better with colored syntax for differentiating for exemple opcodes and macros(and the other stuffs) .
I use notepad++ with the dina font .
https://www.dafont.com/pt/dina.font
User avatar
pubby
Posts: 583
Joined: Thu Mar 31, 2016 11:15 am

Re: 6502 coding style.

Post by pubby »

I barely indent at all and dislike seeing assembly code indented.

To separate code I use blank spaces. To clarify code I use comments.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 6502 coding style.

Post by tokumaru »

pubby wrote:I barely indent at all and dislike seeing assembly code indented.
Same here. The typical IF/ELSE/FOR/WHILE structures don't always translate well to assembly, since you have the freedom to branch/jump anywhere, and it makes little sense to write slower programs for the sole purpose of creating artificially delimited blocks of logic that look pretty.

I don't like using extra spaces or tabs to create visually aligned columns either. I see those extra characters as junk that doesn't have any meaning in the source code, and if I later decide to change a symbol's name by searching and replacing in all files, I could easily break the alignments if the new names have different lengths.

I am very obsessed about styling code though, and I think that consistency is important across all files of a project. I try to break up my code into short blocks of logic, each with its own comment describing what it does. I only add line-by-line comments to really complex code. I use one blank line to separate blocks of code. Labels also have one blank line above and below. Every file ends with a line break (this is necessary for Notepad++ to properly highlight the last line of code).
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 6502 coding style.

Post by rainwarrior »

tokumaru wrote:
pubby wrote:I barely indent at all and dislike seeing assembly code indented.
Same here. The typical IF/ELSE/FOR/WHILE structures don't always translate well to assembly, since you have the freedom to branch/jump anywhere, and it makes little sense to write slower programs for the sole purpose of creating artificially delimited blocks of logic that look pretty.
This is nothing at all to do with writing "slower" programs. You can still branch anywhere you want with indented code, you just can't express its structure with indentation. It's a visual guide to the existing structure, not the structure itself.

It's also a matter of how often you need to do something. Branching over a block of code (i.e. simple "if") is the most common case by far, and that is perfectly expressed by indents. You don't have to throw that away just because you occasionally might need something more complicated. There are alternative ways to indent things that don't have explicit nesting structure.

C/C++/etc. have things like goto and exceptions that do things that indents can't adequately designate, but there's really very little problem using them in the midst of otherwise indented code if you're careful about it. The indentation is just there to add potential redundant information, not take away possibilities.

(Python is an exception to that, though, where indents are a mandatory/functional part of the code structure. It's one of the things I dislike about it as a language, actually. In that case the indentation really does force those structures on the code... but it's also a scripting language not usually expected to be high performance.)
Last edited by rainwarrior on Tue Jan 02, 2018 3:12 pm, edited 1 time in total.
zzo38
Posts: 1096
Joined: Mon Feb 07, 2011 12:46 pm

Re: 6502 coding style.

Post by zzo38 »

I don't use indented code in assembly language, although I leave blank lines to group parts of the code, as well as adding more comments in assembly codes than I tend to use in C codes.

The structure doesn't match that of structured programming languages anyways; many kind of jumps and stuff may be used which is difference from FOR/WHILE/IF/etc, including double-returns, coroutines, RTS trick, and whatever else may be suitable for the program being written.

Assembly language programming is for programming for a specific computer (and software that emulates that computer), and optimizations can be put in which is specific for that computer and which is difference to what a C compiler would put in. C programming is for being portable to many kind of computer, and the compiler should have optimizations, to know what is suitable for whatever computer it is being compiled on.
(Free Hero Mesh - FOSS puzzle game engine)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 6502 coding style.

Post by tokumaru »

rainwarrior wrote:This is nothing at all to do with writing "slower" programs.
It is if you need extra branches and jumps to make your code conform to a completely hierarchical structure, instead of writing faster "spaghetti code".
You can still branch anywhere you want with indented code, you just can't express its structure with indentation.
Exactly. What's the point of indenting then if it won't represent the actual structure of the program? You say that "unindentable code" is only needed occasionally, but I think I do it a lot. Functions with multiple entry points, multi-purpose RTSs, program flow control through stack manipulation, and so on, are things I do pretty often. My main loops also tend to be fairly big, because inlining things is faster than making lots of function calls, and maintaining the indentation of such long routines is a pain, and large sections of code end up too far from the left edge of the document.

I like to take all sorts of little opportunities for optimization that make little sense in indented/high-level form, so instead of constantly scratching my head figuring how to align every piece of code, I use blank lines and comments to isolate independent tasks and make them easily recognizable.

Just the other day I wrote a function that needed to do something twice before returning, so instead of wasting time and space with a loop or a separate function I did this:

Code: Select all

Function:

  ;(bunch of code)

  ;load an argument and do something
  lda #01
  jsr DoSomething

  ;load another argument and do something
  lda #02

DoSomething:

  ;(bunch of code)

  rts
DoSomething is a separate function but it's also the end of Function. I don't know if I should write DoSomething as a separate function and leave Function without an end, or keep one function inside the other and increase the indentation of the inner function, even though it isn't used exclusively as a function... I'd probably leave it as part of Function without any extra indentation, but whatever I do won't correctly represent the hierarchy of this code, so I prefer not to deal with these dilemmas (which takes time and would inevitably lead to inconsistencies in my code), and make the most of the freedom that assembly provides without any guilt.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 6502 coding style.

Post by rainwarrior »

Yes, I do optimizations like that too, but I don't really consider it much of a problem to decide how to indent anything? Just a snap decision, not something I have to think hard about?

The basic rule is, if there's a loop or a conditonal thing that's cleanly encapsulated, I indent it to show this. Makes it really easy to scan visually to the end of it. If it doesnt have clear structure I probably leave it mostly flat. Like if I have a branch instruciton, the indent usually shows me immediately where the branch goes without having to read anything else.

That's most of the point of the indentation style, being able to skim past the indented stuff without reading it. A converse rule of thumb is: if this is code you have to know about / read on the way past, don't indent it. The indents are there to show you what you can skip.
Garth
Posts: 246
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: 6502 coding style.

Post by Garth »

I've written myself a set of macros to:
  • make source code more clear
  • make myself more productive
  • get fewer bugs
  • make the code more maintainable
and it would be crazy not to use indentation with it. In most cases, there is absolutely no penalty at all in the resulting machine code, and in fact looking at it, you wouldn't be able to tell if the structure macros were used in the source code or not. Here's a basic example:

Code: Select all

        CMP  #14
        IF_EQ            ; clear enough that it really needs no comments
           <actions>
           <actions>
           <actions>
        END_IF
the IF_EQ and END_IF assembles a BNE to the end of the section, two bytes, exactly the same as you would do by hand. Note the absence of labels. I have several kinds of these program structures, with explanations and source code for doing them with the C32 assembler, at http://wilsonminesco.com/StructureMacros/ .

You can of course get much more complex, and nest program structures as well. As things get more complex, the value of the structures and indenting increases. Before I did this, proofreading complex source code involved printing it on fanfold paper and laying the long strip out on the floor and drawing arrows showing where all the branches branched to. It got ridiculous. Spaghetti. That problem doesn't happen with the macros and accompanying indentation. If you still want to use a label and jump into the middle of a program structure, you can, and I do on rare occasion.
http://WilsonMinesCo.com/ lots of 6502 resources
Post Reply