Jump to content
IGNORED

MADS macros/procedures


matosimi

Recommended Posts

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.

  • Like 1
Link to comment
Share on other sites

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 by JAC!
Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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 by flashjazzcat
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

  • 2 years later...

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?

Link to comment
Share on other sites

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 by flashjazzcat
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...