khittouchh wrote:
Hi,
I'm working with the simulator of Michal Kowalski, the 6502 simulator.
My problem is the using of a macro.
I copy the code below, with this one i don't understand why the complier accept an address for the argument and not a constant value.
Code:
;Macro
SETB: .MACRO BITSET,DONNEE
LDA BITSET
TSB DONNEE
.ENDM
Call of the macro, Compile OK
SETB 1,Temp
Call of the macro, Compile NOK
SETB #$1,Temp
Error mount by the compiler:
ERROR E038: Not enough parameters in macro call. ROW 21
Thank you very much for your help.
Firs things first (pardon my pedantry). You are using an assembler, not a compiler. One *assembles* assembly language, not compiles.
Addressing your problem, macro parameters can only be literal numeric values (binary, decimal or hexadecimal), labels and symbols. Tokens such as
# are not accepted in the parameter list. Hence your first example will assemble without error, but the second example will not.
The code within the macro definition dictates how the assembler will parse the parameters. As both instructions in your macro definition are not written to use immediate addressing, the expansion of the macro will always produce instructions using absolute or zero page addressing.
Another way to write this macro would be:
Code:
SETB .MACRO .B,.D
LDA .B
TSB .D
.ENDM
Several things worth noting:
- The macro name SETB does not need a colon. That is, SETB: is not necessary. The Kowalski assembler always assumes that a field starting in the first column is a label, macro name or symbol. I recommend you do not use a colon in any label name.
- I changed the dummy operand names in the macro definition to single letters preceded with periods. Therefore, these names will not be known outside of the macro itself and thus may be reused elsewhere in your source code. Any label or symbol preceded with a period is a local definition and thus has a scope that is bounded by the nearest non-local definitions. Keep in mind that when the macro is invoked in your code the dummy operands take on the values of the parameters passed in the macro invocation. If you use global names for the dummy operands they become known outside of the macro. You will encounter an assembly error in such a case on the next invocation, as you will be trying to redefine an already defined symbol.
If you want to be able to cause conditional assembly, that is, be able to have parameters assembled as immediate or non-immediate operands, you will need to use extra parameters in the macro to tell it how to evaluate the dummy operands at assembly time. Use of various assembler pseudo-ops will be required to write the necessary logic. See the following:
Code:
;KOWALSKI SIMULATOR ASSEMBLER DIRECTIVES — BigDumbDinosaur (revised 2012/07/01)
IO_AREA ;define console I/O area address (no leading dot in IO_AREA)
.ASCII .BYTE .DB ;generate static data, such as strings, tables, etc.
.ASCIS ;generate character string w/bit 7 of last byte set
.DBYTE .DD ;assemble big-endian word
.DCB ;equivalent to * = * + N, where N is arg to .DCB,...
;w/optional initialization pattern, e.g., .DCB 10,$FF, which will
;reserve 10 bytes & fill them with $FF
.DS .RS ;equivalent to * = * + N, where N is arg to .DS or .RS
.DW .WORD ;assemble little-endian word
.ELSE ;conditional assembly directive
.END ;mark end of source file, optional
.ENDIF ;mark end of conditional assembly
.ENDM ;mark end of macro definition
.ENDR ;mark end of repeated text
.ERROR ;emit an error message & halt assembly, e.g., .ERROR "!!! operand out of range !!!"
.EXITM ;halt macro expansion
.IF ;start conditional assembly
.INCLUDE ;insert contents of named source file, e.g., .INCLUDE "include\atomic.65s"
.IO_WND ;define console I/O window size (cols, rows)
.MACRO ;mark start of macro definition, w/optional comma-separated parameters
.OPT ;set global assembly options
.ORG ;set start of assembly address, same as * = <addr>
.PARAMTYPE ;determine macro parameter type: 1 = numeric, 2 = string,...
;.IF .PARAMTYPE(.op) == 1
.REF ;determine if label/symbol was defined,...
;e.g., .IF .REF(ABC) evaluates true if ABC has been defined; logic can be reversed with !.REF (ABC)
.REPEAT .REPT ;repeat following text, e.g., .REPT 5
.ROM_AREA ;set simulator's write-protected address range
.SET ;(re)define variable value, e.g., X .SET 1 allows X to be redefined by a later .SET. .= is a synonym for .SET
.START ;set simulator start of execution address
.STR .STRING ;generate text string, 1st byte is length, 255 bytes maximum
.STRLEN ;determine macro parameter string length
.IF evaluations can use the following binary operators:
== "is equal to"
!= "is not equal to"
> "is greater than"
< "is less than"
.IF .X means "if .X is non-zero".
Pseudo-ops are not case-sensitive.