FrankenGraphics wrote:
I think garths' comment on the comment (
) reflected on what is often viewed as good vs bad commenting practice
Bad practice:
Describe what the macro literally does. This adds clutter, which will make important comments harder to find.
For example, you can just aswell read the content of the macro (inx inx inx inx) aswell as the current comment and get the same info: 4x inx. Moreover, if the name reflects it, you can get that info from the code calling the macro, too, which would make such a comment reduntant both in your macro file and your main source file/s.
Good practice:
Comment what it is supposed to do, its reason for being there, what you mean to achieve.
If the goal of the block is too basic/evident, omit comment.
Best practice (IMO - sometimes a bit overkill):
Same as good, but also add a description what arguments do, what they expect, possible caveats using this macro, and what registers/flags are affected by the macro, if not evident. Mostly needed in more complex macros.
I disagree with these statements, well... wish to expand upon...
There are 3 uses for macros.
1.) Long complicated thing that I do often enough and want to tidy as its a black box and I just don't care. For example
Code:
;@name Clear Interupts
;@desc disables NMI on CIA, IRQs on CIA and VIC, sei
;@parent IRQ
ClearInterupts .macro
sei
lda #$7f
sta $dc0d ;turn off all types of cia irq/nmi.
sta $dd0d
lda $dc0d
lda $dd0d
lda #$ff
sta $D019
lda #$00
sta $D01a
sta $dc0e
sta $dc0f
sta $dd0e
sta $dd0f
lda $d01e
lda $d01f
.endm
;@end
I do it once per project, maybe twice, fire and forget. Describing what this does exactly would be silly and long and not important.
2.) Macro to replace this missing thing, which should be named as on the tin, for example
Code:
;@name STore Zero
;@param address
;@desc writes 0 to address
;@parent STA
STZ .macro
lda #0
sta \1
.endm
;@end
;@name ADd with Carry offset by X Word
;@param address
;@param address
;@desc address@w + (address@w),x will clear carry
;@parent ADC
ADC_X_W .macro
clc
lda \1
adc \2,x
sta \1
lda (\1)+1
adc (\2)+1,x
sta (\1)+1
.endm
;@end
This makes the code tighter, and stops my eyes getting lost in boiler plate, while allowing me to re target to say a 65816 latter and make use of its built in abilities, whilst keeping the code easy to read and allowing me to see what is used and trashed where. And 3.) take something that is custom to the situation and make it easier to read, and hence form a "MACRO Language", For Example
Code:
MOVE_NEXT_ENT .macro
inx
cpx #kMaxNumEnts
.if abs(*-EntLoop) < 127
bne EntLoop
.else
beq +
jmp EntLoop
+
.fi
.endm
The problem with the 3rd case is it magically requires X to be the thing it needs to be, and after you have taken a break from coding and you come back to your game, or even if you have been spending time on the Title screen logic and not touch an ent for a while, then you come back make a change and boom, bug. Why because you forgot that magic macro needs X to be Current Ent still. And after a while you will open up your macro file and find the macro and then see what went wrong. A safer way would be to make it
Code:
MOVE_NEXT_ENT .macro
inc ENT_NUM
ldx ENT_NUM
cpx #kMaxNumEnts
.if abs(*-EntLoop) < 127
bne EntLoop
.else
beq +
jmp EntLoop
+
.fi
.endm
so now it just works, less efficient, but shouldn't have any issues unless you magically hope that X is not changed after the macro is "not taken". Lets make this macro
Code:
inxCpxEq .macro
inx
cpx \1
.if abs(*-\2) < 127
bne \2
.else
beq +
jmp \2
+
.fi
So before I had
Code:
... do things
MOVE_NEXT_ENT
.. other things
Now I have
Code:
... do things
inxCpxEq #kMaxNumEnts,EntLoop
... other things
the 2nd case you can instantly see that it A.) uses X and relies upon X having a specific value, B.) see exactly what it compares against and C.) see exactly where it jumps to, without having to track down some other macro file, which you won't keep in alphabetical order, then look it up and be OH.. as you brain will see the text MOVE_NEXT_ENT and think, well that gets the next ent, so so problems with it, and gloss over it.
C has the pre-processor and it was used for much evil, all subsequent languages have done their best to clobber the #defines see C#, Java et al . Speak with an old time C programmer and they will tend to go Roy Batty on you
Macros are mermaids, they will sing to you... type less code... be more readable and you won't need to add comments.... come deeper... add more... see how nice it looks... and then when you are in the middle of the ocean, they will turn and eat you. So they are advanced, and should only be attempted by people who know what they are doing, have strong discipline and are set in their ways. The guide is if you use a MACRO language only use macros, once you start inlining normal code with the macro code you start to open your self to pain.