It is currently Wed Nov 14, 2018 11:14 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Macros
PostPosted: Thu Apr 19, 2018 12:01 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 621
To stop derailing the other thread I'm pealing this one off
From the other thread
Garth wrote:
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.

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,
Code:
        _16bit_ADC   B, _and, W    ; B=B+W

(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 as
Code:
        CLC
        LDA   B
        ADC   W
        STA   B
        LDA   B+1
        ADC   W+1
        STA   B+1

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:
        _16bit_ADC   B, W, _and, offset3    ; B=B+W+offset3


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:
        IF_POSITIVE    ; Negative result above causes it to skip the following lines.
           <do_stuff>
           <do_stuff>
           <do_stuff>
        END_IF

or to branch back to the beginning of a loop as long as the result is negative:
Code:
        BEGIN           ; (Or name it "DO" if you like)
           <do_stuff>
           <do_stuff>
           <do_stuff>
        UNTIL_POSITIVE

Then you don't even need a label (although you can still use one if you want to).


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 ;) )
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:
lda B
clc
adc #W
sta B
bcc +
inc B+1
+

say given
Code:
  ldx #7
- lda 2
  bit 4
  bpl +
  _16_ADC_8_Immed 8,40
  jmp _next
+ _16_ADC_8_Immed 8,20
_next
  dex
  bpl -

spot the bug ;)
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:
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
this way I don't have to remember which way 6502 does the comparasing. Does it branch if A is < CMP or if CMP is less than A - ISALT Thing,cmp,dest - however as I said this was stupid ;)
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...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group