[cc65] New assembler featues

Date view Thread view Subject view

From: Ullrich von Bassewitz (uz_at_musoftware.de)
Date: 2003-11-13 23:50:19


Hi!

As some of you may have noticed, there have been several changes to the
assembler (ca65) lately. What I'm doing is still a work in progress, but part
of it is usable now, and since I will leave for the weekend, I would like to
invite you to test the new features.

New feature list:

  * There's now a '^' bank byte operator (suggested by Fabian Nunez).

  * Better support for constant expressions. The assembler does now notice
    in more cases that an expression is constant. There are still ways to
    fool the assembler, but less than before.

  * Symbols and segments have an address size, and in many cases the address
    size can be changed by the user. As a consequence, some old directives
    will get removed after a transition time. The following have been changed:

    - Segments may be followed by a colon and an address size specifier. The
      old syntax used a comma for this purpose.

        .segment "foo" : zeropage

    - Procedure names may also have an address size specifier.

        .proc bar : far

    - Same for exports, imports and global declarations:

        .import foo : zp, bar : absolute
        .export foo : zeropage
        .global bar : far

      This means that the .importzp, .exportzp and .globalzp directives are
      deprecated and will get removed in a future version.

      Exports without an address size specifier will use the actual address
      size of the symbol, so in most cases, an explicit specification is no
      longer necessary:

        .export foo     ; Is exported as zero page, see declaration

        .zeropage
        .proc   foo : zp
                ...
        .endproc

    The ultimate goal is a cleaner interface and better support for the 65816.

  * Scopes have names and may be accessed from the outside. There is a new
    .SCOPE directive that opens an optionally named scope without defining a
    symbol for the start of the scope. As a consequence, unnamed .PROC
    directives are deprecated. .PROC is a procedure and should always have a
    name.

        foo = 1
        .scope  s1
                foo = 2
                .scope  s2
                        foo = 3
                .endscope
        .endscope

        .byte   foo             ; = 1
        .byte   ::foo           ; = 1
        .byte   s1::foo         ; = 2
        .byte   ::s1::s2::foo   ; = 3

    The namespace operator is used to describe nested scopes. If the name
    starts with the namespace operator, the next identifier is searched in
    global scope, otherwise it is searched in current scope (similar to C++).

    This change does allow to introduce constants within a named scope, which
    reduces possible collisions in the global name space. This is especially
    important when working with many/complex libraries.

    A procedure defined with .PROC is available as before. In addition to
    giving the scope a name, it defines a symbol in the enclosing scope.
    Symbols within a local scope defined by .PROC may also be accessed from
    the outside as with .SCOPE:

        .proc   foo

        bar:    rts

        .endproc

        jmp     foo::bar

  * There's now a .STRUCT directive that may be used to define struct like
    scopes. Within a struct, only storage allocations are possible:

        .struct Point
                X       .word
                Y       .word
        .endstruct

    This defines a struct with a size of 4 bytes total. Each symbol within
    the struct is defined as the offset from the beginning, starting with
    zero. So in the example above

        Point::X        = 0
        Point::Y        = 2

    There may also be unnamed members:

        .struct Point
                X       .word
                        .byte, 2        ; Allocate two bytes
                Y       .word
        .endstruct

    Structs may contain other structs:

        .struct Circle
                Origin  .tag    Point
                Radius  .word
        .endstruct

    Structs may also be defined inside structs:

        .struct Circle
                .struct Point
                        X       .word
                        Y       .word
                .endstruct
                Radius  .word
        .endstruct

    When doing this, nested structs must not have a name. Embedded structs
    without a name are called anonymous structs. Their members are actually
    part of the enclosing struct. This doesn't seem to make much sense but
    works also with unions (see below) that are nested in structs, in which
    case it becomes a nice feature.

    Space for a struct may be allocated by using the new .TAG directive:

        .tag    Circle  ; Reserves space for struct Circle

  * There's a .UNION directive that works like .STRUCT with the difference
    that all members have offset zero, and the size of the union is the size
    of its biggest member (same as in C).

  * The bank.offset syntax for far addresses is gone.


Please note that a lot is missing. For example, there is no way to initialize
a struct, access a struct variable in a struct like syntax (you will have to
use variable+offs for that), there are no docs for the new features and so on.
The stuff is very new and untested, but I thought it would be nice to have
some people try it, especially since I'm off for the weekend.

As usual, any feedback is highly appreciated.

Regards


        Uz



-- 
Ullrich von Bassewitz                                  uz_at_musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo_at_musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.


Date view Thread view Subject view

This archive was generated by hypermail 2.1.3 : 2003-11-13 23:50:55 CET