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.
This archive was generated by hypermail 2.1.3 : 2003-11-13 23:50:55 CET