matosimi Posted January 6, 2012 Share Posted January 6, 2012 Hi, could you clarify me how to declare and call macros and procedures in MADS? I've read documentation but I'm pretty confused. Some small examples of usage would be appreciated. Thanks Martin Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 6, 2012 Share Posted January 6, 2012 Macros are straighforward enough: add16 .macro ; 16 bit addition lda :1 clc adc :2 sta :3 lda :1+1 adc :2+1 sta :3+1 .endm ; Call this 16 bit addition macro with: add16 num1, num2, result Procedures are a bit more elusive, depending on what you want to do with them. I've gone no further than putting .PROC / .ENDP wrappers around all my subroutines to allow outlining in WUDSN. There are all kinds of elaborate facilities for parameter passing, etc, described in the documentation, but I don't yet understand that side of it. 1 Quote Link to comment Share on other sites More sharing options...
matosimi Posted January 6, 2012 Author Share Posted January 6, 2012 Thanks, this helped me a lot. I got confused with all those apostrophes, crosses and double quotes in MADS manual. -anyone knows what does it mean? Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 6, 2012 Share Posted January 6, 2012 ' usually means used the Ascii code for whatever character that follows e.g. lda #'a will be lda #65 same with " but they're usually in pairs e.g. .byte "abcdef" Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 6, 2012 Share Posted January 6, 2012 I hope a detailed English translation of the manual is forthcoming soon. I get the feeling we're missing out on a lot of goodies. Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted January 6, 2012 Share Posted January 6, 2012 we definitly miss a lot... esp when you are looking into source codes of Tebe. Quote Link to comment Share on other sites More sharing options...
+JAC! Posted January 6, 2012 Share Posted January 6, 2012 (edited) Procedure parameters canalso be passed directly into registers and/or memory locations. Something like (syntax is not 100%) Definition: .proc my_proc (x .reg) cpx #$00 ... Call: x_position = $80 ... my_proc(x_position) => ldx $80 jsr my_proc OR .proc my_proc (label+1 .var) label ldx #0 Call becomes: lda x_position sta my_proc.x+1 jsr my_proc but I've never used it up to now. Edited January 6, 2012 by JAC! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 6, 2012 Share Posted January 6, 2012 I like the look of the second version. Quote Link to comment Share on other sites More sharing options...
NRV Posted January 6, 2012 Share Posted January 6, 2012 I like macros.. You can use :0 (parameter 0) to get the number of parameters passed, and use it to check for errors or select another code path inside your macro: ;-------------------------------------------------------------------------------- ; SetColor [0..4] [0..255] ; SetColor [0..4] [0..15] [0..15] ;-------------------------------------------------------------------------------- .macro SetColor .if :0 < 2 .or :0 > 3 .error "SetColor error" .else .if :0 = 2 lda #:2 sta COLPF0+:1 .else lda #[:2 * 16 + :3] sta COLPF0+:1 .endif .endif .endm You could compare a parameter (:1, :2, :3, ...) with 256 to see if it is a byte or a word, and do another code path.. ;-------------------------------------------------------------------------------- ; SetMemory [address] [bytes] [value] ;-------------------------------------------------------------------------------- ; warning, using some page zero memory .macro SetMemory setMemPtr = 254 setMemCounter = 252 .if :0 <> 3 .error "SetMemory error" .else ldy #0 lda #<:1 sta setMemPtr lda #>:1 sta setMemPtr+1 .if :2 < 256 lda #:3 setMemLoop1 sta (setMemPtr),y iny cpy #:2 bne setMemLoop1 .else lda #<:2 sta setMemCounter lda #>:2 sta setMemCounter+1 setMemLoop2 lda #:3 sta (setMemPtr),y iny bne setMemB1 inc setMemPtr+1 setMemB1 lda setMemCounter bne setMemB2 dec setMemCounter+1 setMemB2 dec setMemCounter lda setMemCounter ora setMemCounter+1 bne setMemLoop2 .endif .endif .endm You can use "string" parameters with %%1, %%2, %%3, ... like in: .macro ClearLine_ESC_M2_3bytes lda %%1+256*?zoneNum+32*:3+0,x sta %%2+256*?zoneNum+32*:3+0,x lda %%1+256*?zoneNum+32*:3+1,x sta %%2+256*?zoneNum+32*:3+1,x lda %%1+256*?zoneNum+32*:3+2,x sta %%2+256*?zoneNum+32*:3+2,x .endm StartESC_M2_3Bytes_SCR1 ?zoneNum = 0 .rept ZONES_OF_256_BYTES ; for the graphic mode ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 0 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 1 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 2 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 3 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 4 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 5 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 6 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 7 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 8 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 9 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 10 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 11 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 12 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 13 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 14 ClearLine_ESC_M2_3bytes Background_01, DL1_memory, 15 rts ?zoneNum ++ .endr .. this is and old macro from a software sprite experiment, that also use a local var inside the macro (?zoneNUm) Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 6, 2012 Share Posted January 6, 2012 (edited) Very nice! I love macros too, but I tend to be a little wary of them because of the tendency of macro generated code to be gain weight. But they can make for great readability: putobb .macro ; put byte to object ; putobb index,var ldy #:1 lda :2 sta (object),y .endm putobw .macro ; put word to object ; putobw index,var ldy #:1 lda :2 ldx :2+1 jsr o_putw .endm .proc o_putw ; store word in object sta (object),y iny txa sta (object),y rts .endp .proc store_object_xy putobw obj.x,cx putobb obj.y,cy putobw obj.width,width putobb obj.height,height rts .endp Edited January 6, 2012 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
tebe Posted January 12, 2012 Share Posted January 12, 2012 new mads, macros with labeled parameters SetColor .macro val,reg lda :val sta :reg .endm .macro SetColor val,reg lda %%val sta %%reg .endm .macro macro_name [par1,par2,...] ['separator']|["separator"] 'separator' - '' default mode "separator" - "" extended mode extended mode, all parameters split: type and argument test #20 .macro test "" .print :1,'|',:2 .endm Result: #|$0014 # - absolute mode $0014 argument more details -> KickAssembler page 35 mads_12.01.2012.zip KickAssembler_Manual.zip 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 12, 2012 Share Posted January 12, 2012 Whoa - great! Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted January 13, 2012 Share Posted January 13, 2012 Can someone compile an OS X Version? Quote Link to comment Share on other sites More sharing options...
tebe Posted January 13, 2012 Share Posted January 13, 2012 mads 1.9.4 build 113 mads_build113.zip Quote Link to comment Share on other sites More sharing options...
matosimi Posted January 16, 2014 Author Share Posted January 16, 2014 Hi, i have another macro issue. is it possible to use indexed tables as macro parameters? i'm trying to build macro which jumps to label when accumulator does not belong to given interval: .macro a_out a_lt :1 :3 a_ge :2 :3 .endm .macro a_lt cmp :1 bcc :2 .endm .macro a_ge cmp :1 bcs :2 .endm calling it like this works just fine: a_out #104 #104+16 label1 but i would like to call it this way: ldx #3 a_out tab1,x tab2,x label1 tab1 dta 10,20,30 tab2 dta 15,25,35 ...compiler takes tab1 as parameter1, x as parameter2, tab2 as parameter3 and so on which is ofc not correct. is it possible to do such thing in current version of MADS? Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 16, 2014 Share Posted January 16, 2014 (edited) is it possible to do such thing in current version of MADS? You can use single quotes to define the separator character thus: a_out .macro ' ' a_lt :1 :3 a_ge :2 :3 .endm a_lt .macro ' ' cmp :1 bcc :2 .endm a_ge .macro ' ' cmp :1 bcs :2 .endm org $2000 ldx #3 a_out tab1,x tab2,x label1 label1 tab1 dta 10,20,30 tab2 dta 15,25,35 This appears to compile the way you want. Edited January 16, 2014 by flashjazzcat Quote Link to comment Share on other sites More sharing options...
matosimi Posted January 16, 2014 Author Share Posted January 16, 2014 wow, unbelievable! thanks i could not understand mads manual, but now it is clear. Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted January 16, 2014 Share Posted January 16, 2014 Yeah, it took me a while to decypher it too. As you'll have realized, using double-quotes instead enables you to extract the addressing mode: ldax .macro " " ; load a,x pair .if :1 = '#' lda #< :2 ldx #> :2 .else lda :2 ldx :2+1 .endif .endm ; Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.