Next Previous Contents

10. Pseudo functions

Pseudo functions expect their arguments in parenthesis, and they have a result, either a string or an expression.

10.1 .BANKBYTE

The function returns the bank byte (that is, bits 16-23) of its argument. It works identical to the '^' operator.

See: .HIBYTE, .LOBYTE

10.2 .BLANK

Builtin function. The function evaluates its argument in braces and yields "false" if the argument is non blank (there is an argument), and "true" if there is no argument. The token list that makes up the function argument may optionally be enclosed in curly braces. This allows the inclusion of tokens that would otherwise terminate the list (the closing right parenthesis). The curly braces are not considered part of the list, a list just consisting of curly braces is considered to be empty.

As an example, the .IFBLANK statement may be replaced by

        .if     .blank({arg})
  

10.3 .CONCAT

Builtin string function. The function allows to concatenate a list of string constants separated by commas. The result is a string constant that is the concatenation of all arguments. This function is most useful in macros and when used together with the .STRING builtin function. The function may be used in any case where a string constant is expected.

Example:

        .include        .concat ("myheader", ".", "inc")
  

This is the same as the command

        .include        "myheader.inc"
  

10.4 .CONST

Builtin function. The function evaluates its argument in braces and yields "true" if the argument is a constant expression (that is, an expression that yields a constant value at assembly time) and "false" otherwise. As an example, the .IFCONST statement may be replaced by

        .if     .const(a + 3)
  

10.5 .HIBYTE

The function returns the high byte (that is, bits 8-15) of its argument. It works identical to the '>' operator.

See: .LOBYTE, .BANKBYTE

10.6 .HIWORD

The function returns the high word (that is, bits 16-31) of its argument.

See: .LOWORD

10.7 .IDENT

The function expects a string as its argument, and converts this argument into an identifier. If the string starts with the current .LOCALCHAR, it will be converted into a cheap local identifier, otherwise it will be converted into a normal identifier.

Example:

        .macro  makelabel       arg1, arg2
                .ident (.concat (arg1, arg2)):
        .endmacro

                makelabel       "foo", "bar"

                .word           foobar          ; Valid label
  

10.8 .LEFT

Builtin function. Extracts the left part of a given token list.

Syntax:

        .LEFT (<int expr>, <token list>)
  

The first integer expression gives the number of tokens to extract from the token list. The second argument is the token list itself. The token list may optionally be enclosed into curly braces. This allows the inclusion of tokens that would otherwise terminate the list (the closing right paren in the given case).

Example:

To check in a macro if the given argument has a '#' as first token (immediate addressing mode), use something like this:

        .macro  ldax    arg
                ...
                .if (.match (.left (1, {arg}), #))

                ; ldax called with immediate operand
                ...

                .endif
                ...
        .endmacro
  

See also the .MID and .RIGHT builtin functions.

10.9 .LOBYTE

The function returns the low byte (that is, bits 0-7) of its argument. It works identical to the '<' operator.

See: .HIBYTE, .BANKBYTE

10.10 .LOWORD

The function returns the low word (that is, bits 0-15) of its argument.

See: .HIWORD

10.11 .MATCH

Builtin function. Matches two token lists against each other. This is most useful within macros, since macros are not stored as strings, but as lists of tokens.

The syntax is

        .MATCH(<token list #1>, <token list #2>)
  

Both token list may contain arbitrary tokens with the exception of the terminator token (comma resp. right parenthesis) and

The token lists may optionally be enclosed into curly braces. This allows the inclusion of tokens that would otherwise terminate the list (the closing right paren in the given case). Often a macro parameter is used for any of the token lists.

Please note that the function does only compare tokens, not token attributes. So any number is equal to any other number, regardless of the actual value. The same is true for strings. If you need to compare tokens and token attributes, use the .XMATCH function.

Example:

Assume the macro ASR, that will shift right the accumulator by one, while honoring the sign bit. The builtin processor instructions will allow an optional "A" for accu addressing for instructions like ROL and ROR. We will use the .MATCH function to check for this and print and error for invalid calls.

        .macro  asr     arg

                .if (.not .blank(arg)) .and (.not .match ({arg}, a))
                .error "Syntax error"
                .endif

                cmp     #$80            ; Bit 7 into carry
                lsr     a               ; Shift carry into bit 7

        .endmacro
  

The macro will only accept no arguments, or one argument that must be the reserved keyword "A".

See: .XMATCH

10.12 .MID

Builtin function. Takes a starting index, a count and a token list as arguments. Will return part of the token list.

Syntax:

        .MID (<int expr>, <int expr>, <token list>)
  

The first integer expression gives the starting token in the list (the first token has index 0). The second integer expression gives the number of tokens to extract from the token list. The third argument is the token list itself. The token list may optionally be enclosed into curly braces. This allows the inclusion of tokens that would otherwise terminate the list (the closing right paren in the given case).

Example:

To check in a macro if the given argument has a '#' as first token (immediate addressing mode), use something like this:

        .macro  ldax    arg
                ...
                .if (.match (.mid (0, 1, {arg}), #))

                ; ldax called with immediate operand
                ...

                .endif
                ...
        .endmacro
  

See also the .LEFT and .RIGHT builtin functions.

10.13 .REF, .REFERENCED

Builtin function. The function expects an identifier as argument in braces. The argument is evaluated, and the function yields "true" if the identifier is a symbol that has already been referenced somewhere in the source file up to the current position. Otherwise the function yields false. As an example, the .IFREF statement may be replaced by

        .if     .referenced(a)
  

See: .DEFINED

10.14 .RIGHT

Builtin function. Extracts the right part of a given token list.

Syntax:

        .RIGHT (<int expr>, <token list>)
  

The first integer expression gives the number of tokens to extract from the token list. The second argument is the token list itself. The token list may optionally be enclosed into curly braces. This allows the inclusion of tokens that would otherwise terminate the list (the closing right paren in the given case).

See also the .LEFT and .MID builtin functions.

10.15 .SIZEOF

.SIZEOF is a pseudo function that returns the size of its argument. The argument can be a struct/union, a struct member, a procedure, or a label. In case of a procedure or label, its size is defined by the amount of data placed in the segment where the label is relative to. If a line of code switches segments (for example in a macro) data placed in other segments does not count for the size.

Please note that a symbol or scope must exist, before it is used together with .SIZEOF (this may get relaxed later, but will always be true for scopes). A scope has preference over a symbol with the same name, so if the last part of a name represents both, a scope and a symbol, the scope is chosen over the symbol.

After the following code:

        .struct Point                   ; Struct size = 4
                xcoord  .word
                xcoord  .word
        .endstruct

        P:      .tag    Point           ; Declare a point
        @P:     .tag    Point           ; Declare another point

        .code
        .proc   Code
                nop
                .proc   Inner
                        nop
                .endproc
                nop
        .endproc

        .proc   Data
        .data                           ; Segment switch!!!
                .res    4
        .endproc
  

.sizeof(Point)

will have the value 4, because this is the size of struct Point.

.sizeof(Point::xcoord)

will have the value 2, because this is the size of the member xcoord in struct Point.

.sizeof(P)

will have the value 4, this is the size of the data declared on the same source line as the label P, which is in the same segment that P is relative to.

.sizeof(@P)

will have the value 4, see above. The example demonstrates that .SIZEOF does also work for cheap local symbols.

.sizeof(Code)

will have the value 3, since this is amount of data emitted into the code segment, the segment that was active when Code was entered. Note that this value includes the amount of data emitted in child scopes (in this case Code::Inner).

.sizeof(Code::Inner)

will have the value 1 as expected.

.sizeof(Data)

will have the value 0. Data is emitted within the scope Data, but since the segment is switched after entry, this data is emitted into another segment.

10.16 .STRAT

Builtin function. The function accepts a string and an index as arguments and returns the value of the character at the given position as an integer value. The index is zero based.

Example:

        .macro  M       Arg
                ; Check if the argument string starts with '#'
                .if (.strat (Arg, 0) = '#')
                ...
                .endif
        .endmacro
  

10.17 .SPRINTF

Builtin function. It expects a format string as first argument. The number and type of the following arguments depend on the format string. The format string is similar to the one of the C printf function. Missing things are: Length modifiers, variable width.

The result of the function is a string.

Example:

        num     = 3

        ; Generate an identifier:
        .ident (.sprintf ("%s%03d", "label", num)):
  

10.18 .STRING

Builtin function. The function accepts an argument in braces and converts this argument into a string constant. The argument may be an identifier, or a constant numeric value.

Since you can use a string in the first place, the use of the function may not be obvious. However, it is useful in macros, or more complex setups.

Example:

        ; Emulate other assemblers:
        .macro  section name
                .segment        .string(name)
        .endmacro
  

10.19 .STRLEN

Builtin function. The function accepts a string argument in braces and evaluates to the length of the string.

Example:

The following macro encodes a string as a pascal style string with a leading length byte.

        .macro  PString Arg
                .byte   .strlen(Arg), Arg
        .endmacro
  

10.20 .TCOUNT

Builtin function. The function accepts a token list in braces. The function result is the number of tokens given as argument. The token list may optionally be enclosed into curly braces which are not considered part of the list and not counted. Enclosement in curly braces allows the inclusion of tokens that would otherwise terminate the list (the closing right paren in the given case).

Example:

The ldax macro accepts the '#' token to denote immediate addressing (as with the normal 6502 instructions). To translate it into two separate 8 bit load instructions, the '#' token has to get stripped from the argument:

        .macro  ldax    arg
                .if (.match (.mid (0, 1, {arg}), #))
                ; ldax called with immediate operand
                lda     #<(.right (.tcount ({arg})-1, {arg}))
                ldx     #>(.right (.tcount ({arg})-1, {arg}))
                .else
                ...
                .endif
        .endmacro
  

10.21 .XMATCH

Builtin function. Matches two token lists against each other. This is most useful within macros, since macros are not stored as strings, but as lists of tokens.

The syntax is

        .XMATCH(<token list #1>, <token list #2>)
  

Both token list may contain arbitrary tokens with the exception of the terminator token (comma resp. right parenthesis) and

The token lists may optionally be enclosed into curly braces. This allows the inclusion of tokens that would otherwise terminate the list (the closing right paren in the given case). Often a macro parameter is used for any of the token lists.

The function compares tokens and token values. If you need a function that just compares the type of tokens, have a look at the .MATCH function.

See: .MATCH


Next Previous Contents