; MACRO_DEMO.ASM ; ============== ; This aims to demonstrate the way Brass's more advanced macro system can be used ; to create less stupid macros. ; For example, TASM only allows you very simple macros - and only one replacement per ; macro. ; Brass allows you to have multiple macro replacements under the same macro name, with ; different signatures. ; A signature is the argument list of the macro. In TASM, it is always one wildcard per ; argument. For example: ; -- ; #define macro(var,arg,thingy) ... ; -- ; has a signature of *,*,* - three wildcards. ; Brass would allow you to do this: ; -- ; .define macro(var,arg) ... ; Signature of *,* ; .define macro(var,arg,thingy) ... ; Signature of *,*,* ; -- ; If you then called 'macro' with two arguments, Brass would use the first macro. If ; you passed three arguments, Brass would use the second. ; Brass also allows you to catch hard-coded arguments by surrounding them in {curlies}. ; For example, if your macro requires you to load something into A, and you pass A as ; the argument, you don't want it to generate ld a,a! You can then declare a special ; case, like this: ; -- ; .define macro(var,label) ld a,var \ call label ; Signature of *,* ; .define macro({a},label) call label ; Signature of a,* ; -- ; Brass works out the priority of macros for you, so you can define them in any order. ; In this case, calling macro(43,$5443) would use the first macro, but macro(a,$5443) ; would call the second macro. ; ; You cannot use expressions and expect them to work properly, unfortunately - they'll ; be caught by the general case. The reason for this is that for expressions to work ; properly, you must have all the label addresses correctly calculated. For the labels ; to work correctly and have the correct addresses, the code must be in a static state ; so that the size of code blocks can be calculated correctly. Macros change the size ; of the code. ; ; TO TEST: ; Assemble this using the command-line syntax: ; -- ; Brass macro_demo.asm -l macro_demo.txt ; -- ; Open the list file macro_demo.txt to verify that all is good :) ; Register loading bits: (normally, these would only be defined once for the entire file) .define ld_a(value)ld a,value .define ld_a({a}) .define ld_a({0})xor a .define ld_b(value)ld b,value .define ld_b({b}) .define ld_l(value)ld l,value .define ld_l({l}) .define ld_ix(value)ld ix,value .define ld_ix({ix}) ; ionPutSprite macro wrappers .define put_sprite(x, y, height, sprite) ld_a(x)\ ld_l(y)\ ld_ix(sprite)\ ld_b(height)\ call ionPutSprite .define put_sprite(x, y, sprite) ld_a(x)\ ld_l(y)\ ld_ix(sprite)\ ld_b(8)\ call ionPutSprite ; Use them! ; Put sprite at any old position: put_sprite(10,32,sprite) ; Same thing, but with a custom height: put_sprite(10,32,16,sprite) ; See what this does: (should just be xor a\ call ionPutSprite) put_sprite(0,l,b,ix) ; ...or even this! put_sprite(a,l,b,ix) sprite: ; Imagine that this is the sprite. ionPutSprite: ; Imagine that this is the Ion sprite routine.