6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed Jul 03, 2024 5:50 am

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Tue Jan 07, 2014 3:06 pm 
Offline

Joined: Tue Jan 07, 2014 2:40 pm
Posts: 3
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.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2014 6:08 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
Surely
Code:
BitSet .macro bit,addr
lda #1<<bit
tsb addr
.endm

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2014 6:27 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3366
Location: Ontario, Canada
At first I misunderstood what you're trying to do. I think maybe Andrew did, too.

Quote:
i don't understand why the complier accept an address for the argument and not a constant value.
Is that really what you meant? In the first example you want to fetch from memory location 1 and use that as your bitmask?

cheers (and welcome!),
Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2014 6:34 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8239
Location: Midwestern USA
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:

  1. 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.

  2. 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.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2014 8:23 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
Writing macros that rely on text substitution to supply the addressing mode as a parameter is bad practice in my book. You should have two macros, for example
Code:
BitSetImm .macro value,addr
 lda #value,
 tsb addr
 .endm

BitSetVar .macro var,addr
 lda var
 tsb addr
 .endm

Given the simplicity of the instructions in this case and the variability the original poster was after I don't think macros are appropriate at all.

I think the same criteria should be applied as are with inline functions in C, that is, there should either be a clear saving in time (e.g. programmers or execution) or space (memory or source code). For eample

A simple macro that changes the MX bits on a 65816 and configures the assembler is OK because it saves me looking it up every time I need to do it (e.g. makes code better and more consistent by encapsulating knowledge that is needed repeatedly).

A simple macro that deposits the code to do something in less cycles that it takes to put data into standard variables, call a subroutine and put the results back where they are needed by generating code that processes the data directly is OK (e.g. custom code generation for maths operations).

A macro that generates custom code for complex operations that might otherwise be represented by duplicated chunks of source code with trivial differences in the same or different projects (i.e. code to initialize an LCD module, task switching, utilities).

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2014 8:25 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8462
Location: Southern California
To say the same thing another way, the "#" is the addressing mode, not the parameter. If you want to be able to use the macro with different addressing modes and methods of specifying the mask, for example bit number (like BitWise showed) versus an immediate mask versus fetching a mask from a memory location, you could use conditional assembly inside the macro, and use an additional parameter to tell which way you want it.

I'm not familiar with Kowalski's assembler and simulator but I do like to always use a colon after a label, so if I do a search for it, it goes right to it, rather than first turning up a lot of references to the label instead of the label itself. In the case of a macro, it always has to be defined before it's used anyway, but there could be references to it in the preceding comments.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 08, 2014 2:59 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8239
Location: Midwestern USA
GARTHWILSON wrote:
I'm not familiar with Kowalski's assembler and simulator but I do like to always use a colon after a label, so if I do a search for it, it goes right to it, rather than first turning up a lot of references to the label instead of the label itself. In the case of a macro, it always has to be defined before it's used anyway, but there could be references to it in the preceding comments.

What I do is something like the following:

Code:
;===============================================================================
;
;scsicmd: EXECUTE SCSI COMMAND
;
;   ———————————————————————————————————————————————————————————————
;   Preparatory Ops : .A:  8 bits: target device SCSI ID
;                     .X: 16 bits: command descriptor block address
;                     .Y: 16 bits: buffer address (1)
...more comments follow...
;
scsicmd  rep @11111111         ;clear all SR flags

I'm so accustomed to the official MOS Technology reference assembler syntax, which did not accept a colon with a symbol or label, that I studiously avoid that syntax. So I use the colon where it naturally fits: in the subroutine's comment header.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 08, 2014 5:29 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8462
Location: Southern California
A little off-topic, and I'm anxious to hear if khittouchh got things figured out; but regarding labels, there are places where they come fast and furious and there aren't normally a lot of comments with them, like in this portion from my '816 Forth source in the normal math operations section where they're run-of-the-mill Forth words, well documented elsewhere:
Code:
 ; The next few words starting with U go faster than their non-U counterparts
 ; by avoiding M/MOD above.  Use them to speed up execution when you're using
 ; unsigned numbers or when you know the inputs will never be negative.

        HEADER "U/MOD", NOT_IMMEDIATE   ; ( u1 u2 -- rem quot )
UsMOD:  DWL     nest, ZERO, SWAP, UMsMOD, unnest
 ;-------------------

        HEADER "/", NOT_IMMEDIATE       ; ( n1 n2 -- quot )
SLASH:  DWL     nest, sMOD, NIP, unnest
 ;-------------------

        HEADER "U/", NOT_IMMEDIATE      ; ( u1 u2 -- quot )
Uslash: DWL     nest, UsMOD, NIP, unnest
 ;-------------------

        HEADER "MOD", NOT_IMMEDIATE     ; ( n1 n2 -- rem )
MOD:    DWL     nest, sMOD, DROP, unnest
 ;------------------

        HEADER "UMOD", NOT_IMMEDIATE    ; ( u1 u2 -- rem )
UMOD:   DWL     nest, UsMOD, DROP, unnest
 ;-------------------

        HEADER "*/MOD", NOT_IMMEDIATE   ; ( n1 n2 n3 -- rem quot )
ssMOD:  DWL     nest, TO_R, Mstar, R_FR, MsMOD, unnest
 ;-------------------

        HEADER "U*/MOD", NOT_IMMEDIATE  ; ( u1 u2 u3 -- rem quot )
UssMOD: DWL     nest, TO_R, UMstar, R_FR, UMsMOD, unnest
 ;-------------------

        HEADER "*/", NOT_IMMEDIATE      ; ( n1 n2 n3 -- n1*n2/n3 )
STARSLASH: DWL  nest, ssMOD, NIP, unnest
 ;-------------------

        HEADER "U*/", NOT_IMMEDIATE     ; ( u1 u2 u3 -- u1*u2/u3 )
USTARSLASH: DWL nest, UssMOD, NIP, unnest
 ;-------------------

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 08, 2014 8:50 pm 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 672
I'd also like to point out that not all macro assemblers have this limitation. I've certainly used this pattern in ca65, where each macro parameter effectively behaves a string substitution for these purposes.

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 09, 2014 10:10 am 
Offline

Joined: Tue Jan 07, 2014 2:40 pm
Posts: 3
Hi,
you're right BigDumbDinosaur this is an assemblage and not a compilation.
I try to rewrite my macro but there is always an error.

Code:
SETB: .MACRO .B,.D
LDA .B
TSB .D
.ENDM

Use:
SETB #bit0,Temp (with bit0= $01 (constant))

Error : ERROR E038: Not enough parameters in macro call.

I want do to that because i inherit a lot of macro and i want to use it with the 6502 simulator.

Thanks you very much for yours answers.
Great forum.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 09, 2014 4:18 pm 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
As it has been said before, the Kowalski assembler does not support passing the immediate modifier to a macro. So you must define a macro like this:
Code:
        .ORG 0
bit0    .SET 1
Temp    .DS 1

SETBi   .MACRO .B,.D
    LDA #.B
    TSB .D
        .ENDM

    SETBi bit0,Temp
The immediate modifier is part of the opcode mnemonic and like the opcode itself cannot be passed as a parameter. Parameters may only be string or value.

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 09, 2014 6:30 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8239
Location: Midwestern USA
khittouchh wrote:
Code:
SETB    #bit0,Temp (with bit0=  $01 (constant))

It would be nice to be able to write something like that, but no such luck. In macros where I need the ability to assemble something as immediate or absolute/zero page addressing I use a flag parameter to tell the assembler what to do.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 10, 2014 8:52 am 
Offline

Joined: Tue Jan 07, 2014 2:40 pm
Posts: 3
HI,
Ok thank you very much for theses informations


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 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: