From the other thread
The idea of using dummy strings to improve readability is a nice one. (note if you want to avoid the , issue you can switch to tass64. the .fucntion form of macros lets you do thing a,x,_and,b,y and it will work it out just fine )Garth wrote:Take a different approach. Instead of using cryptic names, make it really clear what they're doing, and use the parameters to make like a sentence. If your ADCB_W means "Do a double-precision (16-bit) add-with-carry of B and W," you could change the macro name to something like _16bit_ADC, and make the line say for example,Oziphantom wrote:Macros are nice, but they are mermaids.. they sing a sweet song and send you to your doom if you are not careful. If you make the "safe" its mostly ok. But you have to really plan to properly and understand how they work etc. I did have a lot of macros but I found they tend to make the code less readable and maintainable after a while. ADCB_W, ADCBX_W, IFBLT, IFBLTE, BAGTE etc.(Unfortunately the assembler requires separating parameters with a comma, which is why there's a comma after the _and.) The "_and" (with the underscore or other character to keep the assembler from confusing it with the mnemonic) is an equate that does not actually get used by the macro. It's only there to make things more readable to humans. The comment clarifies where the answer goes. So this would assemble the same asCode: Select all
_16bit_ADC B, _and, W ; B=B+W
The same macro can be used to add different variables which you specify in the parameters, rather than being confined to B and W. Conditional assembly in the macro definition can do optimizations if necessary. Some assemblers let you say in essence, "If there's a fourth parameter, do the following;" so you could use the same macro to add more than just two numbers, and you could invoke it something like this:Code: Select all
CLC LDA B ADC W STA B LDA B+1 ADC W+1 STA B+1
If your IFBLT means "if: branch if less than," and only assembles a BMI, it's not really clarifying or shortening anything. How about something like this instead, where a portion is skipped if the N flag is set:Code: Select all
_16bit_ADC B, W, _and, offset3 ; B=B+W+offset3
or to branch back to the beginning of a loop as long as the result is negative:Code: Select all
IF_POSITIVE ; Negative result above causes it to skip the following lines. <do_stuff> <do_stuff> <do_stuff> END_IF
Then you don't even need a label (although you can still use one if you want to).Code: Select all
BEGIN ; (Or name it "DO" if you like) <do_stuff> <do_stuff> <do_stuff> UNTIL_POSITIVE
For me the issue with _16_ADC B, W, _and, offset3 is it puts me in to a C/C++ intrinsic function mindset to which point I start to forget about # although in the example you give you then need _16_ADC_Immed B,W or if the assembler lets you determine a parameter type _16_ADC B,#W but then getting it to be able to do #<#W might be tricky...
The Mermaid part comes from the _16 ADC_8_Immed case
Code: Select all
lda B
clc
adc #W
sta B
bcc +
inc B+1
+
Code: Select all
ldx #7
- lda 2
bit 4
bpl +
_16_ADC_8_Immed 8,40
jmp _next
+ _16_ADC_8_Immed 8,20
_next
dex
bpl -
I would think that your DO/WHILE LOOP/UNTIL would have the same issue. Unless your assembler is that rare beast that lets you make unique labels? can you Loop in a Loop?
My point with
#ADCBW Add With Carry Byte to Word
#DXP Decrement X branch if Positive
was to make "instructions" and keep the Assembly look and flow.
Code: Select all
BALT - Branch A Less Than
BALT immediate/address branch_target
IF A < value THEN branch
BALT .segment
cmp \1
bcc \2
.endm
ISALT - IS Address Less Than
ISALT address immediate/address branch_target
IF (address) < value THEN branch
ISALT .segment
lda \1
cmp \2
bcc \3
.endm
As mentioned I have since abandoned this idea in favor of !!if Thing < Other then DEST and then !!Dest += #5, !!Dest &|= #$f0,#$02, !!Dest = Src + other - #40, loops and 16bit versions of the maths are the next big things to tackle though...