]> git.sur5r.net Git - cc65/blobdiff - doc/ca65.sgml
Fixed several address size issues
[cc65] / doc / ca65.sgml
index 4aaca846c705bb85130e9995850e0e4ab38cf8bf..67c7d9f66a045415e4ba583f1a213fc43651b0e2 100644 (file)
@@ -667,6 +667,278 @@ because they don't have a name which would allow to access them.
 
 
 
+<sect>Scopes<label id="scopes"><p>
+
+ca65 implements several sorts of scopes for symbols.
+
+<sect1>Global scope<p>
+
+All (non cheap local) symbols that are declared outside of any nested scopes
+are in global scope.
+
+
+<sect1>A special scope: cheap locals<p>
+
+A special scope is the scope for cheap local symbols. It lasts from one non
+local symbol to the next one, without any provisions made by the programmer.
+All other scopes differ in usage but use the same concept internally.
+
+
+<sect1>Generic nested scopes<p>
+
+A nested scoped for generic use is started with <tt/<ref id=".SCOPE"
+name=".SCOPE">/ and closed with <tt/<ref id=".ENDSCOPE" name=".ENDSCOPE">/.
+The scope can have a name, in which case it is accessible from the outside by
+using <ref id="scopesyntax" name="explicit scopes">. If the scope does not
+have a name, all symbols created within the scope are local to the scope, and
+aren't accessible from the outside.
+
+A nested scope can access symbols from the local or from enclosing scopes by
+name without using explicit scope names. In some cases there may be
+ambiguities, for example if there is a reference to a local symbol that is not
+yet defined, but a symbol with the same name exists in outer scopes:
+
+<tscreen><verb>
+        .scope  outer
+                foo     = 2
+                .scope  inner
+                        lda     #foo
+                        foo     = 3
+                .endscope
+        .endscope
+</verb></tscreen>
+
+In the example above, the <tt/lda/ instruction will load the value 3 into the
+accumulator, because <tt/foo/ is redefined in the scope. However:
+
+<tscreen><verb>
+        .scope  outer
+                foo     = $1234
+                .scope  inner
+                        lda     foo,x
+                        foo     = $12
+                .endscope
+        .endscope
+</verb></tscreen>
+
+Here, <tt/lda/ will still load from <tt/$12,x/, but since it is unknown to the
+assembler that <tt/foo/ is a zeropage symbol when translating the instruction,
+absolute mode is used instead. In fact, the assembler will not use absolute
+mode by default, but it will search through the enclosing scopes for a symbol
+with the given name. If one is found, the address size of this symbol is used.
+This may lead to errors:
+
+<tscreen><verb>
+        .scope  outer
+                foo     = $12
+                .scope  inner
+                        lda     foo,x
+                        foo     = $1234
+                .endscope
+        .endscope
+</verb></tscreen>
+
+In this case, when the assembler sees the symbol <tt/foo/ in the <tt/lda/
+instruction, it will search for an already defined symbol <tt/foo/. It will
+find <tt/foo/ in scope <tt/outer/, and a close look reveals that it is a
+zeropage symbol. So the assembler will use zeropage addressing mode. If
+<tt/foo/ is redefined later in scope <tt/inner/, the assembler tries to change
+the address in the <tt/lda/ instruction already translated, but since the new
+value needs absolute addressing mode, this fails, and an error message "Range
+error" is output.
+
+Of course the most simple solution for the problem is to move the definition
+of <tt/foo/ in scope <tt/inner/ upwards, so it preceeds its use. There may be
+rare cases when this cannot be done. In these cases, you can use one of the
+address size override operators:
+
+<tscreen><verb>
+        .scope  outer
+                foo     = $12
+                .scope  inner
+                        lda     a:foo,x
+                        foo     = $1234
+                .endscope
+        .endscope
+</verb></tscreen>
+
+This will cause the <tt/lda/ instruction to be translated using absolute
+addressing mode, which means changing the symbol reference later does not
+cause any errors.
+
+
+<sect1>Nested procedures<p>
+
+A nested procedure is created by use of <tt/<ref id=".PROC" name=".PROC">/. It
+differs from a <tt/<ref id=".SCOPE" name=".SCOPE">/ in that it must have a
+name, and a it will introduce a symbol with this name in the enclosing scope.
+So
+
+<tscreen><verb>
+        .proc   foo
+                ...
+        .endscope
+</verb></tscreen>
+
+is actually the same as
+
+<tscreen><verb>
+        foo:
+        .scope  foo
+                ...
+        .endscope
+</verb></tscreen>
+
+This is the reason why a procedure must have a name. If you want a scope
+without a name, use <tt/<ref id=".SCOPE" name=".SCOPE">/.
+
+<bf/Note:/ As you can see from the example above, scopes and symbols live in
+different namespaces. There can be a symbol named <tt/foo/ and a scope named
+<tt/foo/ without any conflicts (but see the section titled <ref
+id="scopesearch" name="&quot;Scope search order&quot;">).
+
+
+<sect1>Structs, unions and enums<p>
+
+Structs, unions and enums are explained in a <ref id="structs" name="separate
+section">, I do only cover them here, because if they are declared with a
+name, they open a nested scope, similar to <tt/<ref id=".SCOPE"
+name=".SCOPE">/. However, when no name is specified, the behaviour is
+different: In this case, no new scope will be opened, symbols declared within
+a struct, union, or enum declaration will then be added to the enclosing scope
+instead.
+
+
+<sect1>Explicit scope specification<label id="scopesyntax"><p>
+
+Accessing symbols from other scopes is possible by using an explicit scope
+specification, provided that the scope where the symbol lives in has a name.
+The namespace token (<tt/::/) is used to access other scopes:
+
+<tscreen><verb>
+        .scope  foo
+        bar:    .word   0
+        .endscope
+
+                ...
+                lda     foo::bar        ; Access foo in scope bar
+</verb></tscreen>
+
+The only way to deny access to a scope from the outside is to declare a scope
+without a name (using the <tt/<ref id=".SCOPE" name=".SCOPE">/ command).
+
+A special syntax is used to specify the global scope: If a symbol or scope is
+preceeded by the namespace token, the global scope is searched:
+
+<tscreen><verb>
+        bar     = 3
+
+        .scope  foo
+                bar     = 2
+                lda     #::bar  ; Access the global bar (which is 3)
+        .endscope
+</verb></tscreen>
+
+
+<sect1>Scope search order<label id="scopesearch"><p>
+
+The assembler searches for a scope in a similar way as for a symbol. First, it
+looks in the current scope, and then it walks up the enclosing scopes until
+the scope is found.
+
+However, one important thing to note when using explicit scope syntax is, that
+a symbol may be accessed before it is defined, but a scope may <bf/not/ be
+used without a preceeding definition. This means that in the following
+example:
+
+<tscreen><verb>
+        .scope  foo
+                bar     = 3
+        .endscope
+
+        .scope  outer
+                lda     #foo::bar  ; Will load 3, not 2!
+                .scope  foo
+                        bar     = 2
+                .endscope
+        .endscope
+</verb></tscreen>
+
+the reference to the scope <tt/foo/ will use the global scope, and not the
+local one, because the local one is not visible at the point where it is
+referenced.
+
+Things get more complex if a complete chain of scopes is specified:
+
+<tscreen><verb>
+        .scope  foo
+                .scope  outer
+                        .scope  inner
+                                bar = 1
+                        .endscope
+                .endscope
+                .scope  another
+                        .scope  nested
+                                lda     #outer::inner::bar      ; 1
+                        .endscope
+                .endscope
+        .endscope
+
+        .scope  outer
+                .scope  inner
+                        bar = 2
+                .endscope
+        .endscope
+</verb></tscreen>
+
+When <tt/outer::inner::bar/ is referenced in the <tt/lda/ instruction, the
+assembler will first search in the local scope for a scope named <tt/outer/.
+Since none is found, the enclosing scope (<tt/another/) is checked. There is
+still no scope named <tt/outer/, so scope <tt/foo/ is checked, and finally
+scope <tt/outer/ is found. Within this scope, <tt/inner/ is searched, and in
+this scope, the assembler looks for a symbol named <tt/bar/.
+
+Please note that once the anchor scope is found, all following scopes
+(<tt/inner/ in this case) are expected to be found exactly in this scope. The
+assembler will search the scope tree only for the first scope (if it is not
+anchored in the root scope). Starting from there on, there is no flexibility,
+so if the scope named <tt/outer/ found by the assembler does not contain a
+scope named <tt/inner/, this would be an error, even if such a pair does exist
+(one level up in global scope).
+
+Ambiguities that may be introduced by this search algorithm may be removed by
+anchoring the scope specification in the global scope. In the example above,
+if you want to access the "other" symbol <tt/bar/, you would have to write:
+
+<tscreen><verb>
+        .scope  foo
+                .scope  outer
+                        .scope  inner
+                                bar = 1
+                        .endscope
+                .endscope
+                .scope  another
+                        .scope  nested
+                                lda     #::outer::inner::bar    ; 2
+                        .endscope
+                .endscope
+        .endscope
+
+        .scope  outer
+                .scope  inner
+                        bar = 2
+                .endscope
+        .endscope
+</verb></tscreen>
+
+
+<sect>Address sizes<label id="address-sizes"><p>
+
+
+
+
+
+
 <sect>Control commands<label id="control-commands">
 
 <p>
@@ -1131,6 +1403,11 @@ Here's a list of all control commands and a description, what they do:
   is read from an include file.
 
 
+<sect1><tt>.ENDENUM</tt><label id=".ENDENUM"><p>
+
+  End a <tt><ref id=".ENUM" name=".ENUM"></tt> declaration.
+
+
 <sect1><tt>.ENDIF</tt><label id=".ENDIF"><p>
 
   Conditional assembly: Close a <tt><ref id=".IF" name=".IF..."></tt> or
@@ -1152,6 +1429,77 @@ Here's a list of all control commands and a description, what they do:
   End a <tt><ref id=".REPEAT" name=".REPEAT"></tt> block.
 
 
+<sect1><tt>.ENDSCOPE</tt><label id=".ENDSCOPE"><p>
+
+  End of local lexical level (see <tt/<ref id=".SCOPE" name=".SCOPE">/).
+
+
+<sect1><tt>.ENDSTRUCT</tt><label id=".ENDSTRUCT"><p>
+
+  Ends a struct definition. See the section named <ref id="structs"
+  name="Structs and unions">.
+
+
+<sect1><tt>.ENUM</tt><label id=".ENUM"><p>
+
+  Start an enumeration. This directive is very similar to the C <tt/enum/
+  keyword. If a name is given, a new scope is created for the enumeration,
+  otherwise the enumeration members are placed in the enclosing scope.
+
+  In the enumeration body, symbols are declared. The first symbol has a value
+  of zero, and each following symbol will get the value of the preceeding plus
+  one. This behaviour may be overriden by an explicit assignment. Two symbols
+  may have the same value.
+
+  Example:
+
+  <tscreen><verb>
+        .enum   errorcodes
+                no_error
+                file_error
+                parse_error
+        .endenum
+  </verb></tscreen>
+
+  Above example will create a new scope named <tt/errorcodes/ with three
+  symbols in it that get the values 0, 1 and 2 respectively. Another way
+  to write this would have been:
+
+  <tscreen><verb>
+        .scope  errorcodes
+                no_error        = 0
+                file_error      = 1
+                parse_error     = 2
+        .endscope
+  </verb></tscreen>
+
+  Please note that explicit scoping must be used to access the identifiers:
+
+  <tscreen><verb>
+        .word   errorcodes::no_error
+  </verb></tscreen>
+
+  A more complex example:
+
+  <tscreen><verb>
+        .enum
+                EUNKNOWN        = -1
+                EOK
+                EFILE
+                EBUSY
+                EAGAIN
+                EWOULDBLOCK     = EAGAIN
+        .endenum
+  </verb></tscreen>
+
+  In this example, the enumeration does not have a name, which means that the
+  members will be visible in the enclosing scope and can be used in this scope
+  without explicit scoping. The first member (<tt/EUNKNOWN/) has the value -1.
+  The value for the following members is incremented by one, so <tt/EOK/ would
+  be zero and so on. <tt/EWOULDBLOCK/ is an alias for <tt/EGAIN/, so it has an
+  override for the value using an already defined symbol.
+
+
 <sect1><tt>.ERROR</tt><label id=".ERROR"><p>
 
   Force an assembly error. The assembler will output an error message
@@ -2009,17 +2357,16 @@ Here's a list of all control commands and a description, what they do:
 
 <sect1><tt>.PROC</tt><label id=".PROC"><p>
 
-  Start a nested lexical level. All new symbols from now on are in the local
-  lexical level and are not accessible from outside. Symbols defined outside
-  this local level may be accessed as long as their names are not used for new
-  symbols inside the level. Symbols names in other lexical levels do not
-  clash, so you may use the same names for identifiers. The lexical level ends
-  when the <tt><ref id=".ENDPROC" name=".ENDPROC"></tt> command is read.
-  Lexical levels may be nested up to a depth of 16.
-
-  The command may be followed by an identifier, in this case the
-  identifier is declared in the outer level as a label having the value of
-  the program counter at the start of the lexical level.
+  Start a nested lexical level with the given name and adds a symbol with this
+  name to the enclosing scope. All new symbols from now on are in the local
+  lexical level and are accessible from outside only via <ref id="scopesyntax"
+  name="explicit scope specification">. Symbols defined outside this local
+  level may be accessed as long as their names are not used for new symbols
+  inside the level. Symbols names in other lexical levels do not clash, so you
+  may use the same names for identifiers. The lexical level ends when the
+  <tt><ref id=".ENDPROC" name=".ENDPROC"></tt> command is read. Lexical levels
+  may be nested up to a depth of 16 (this is an artificial limit to protect
+  against errors in the source).
 
   Note: Macro names are always in the global level and in a separate name
   space. There is no special reason for this, it's just that I've never
@@ -2039,7 +2386,8 @@ Here's a list of all control commands and a description, what they do:
        .endproc                ; Leave lexical level
   </verb></tscreen>
 
-  See: <tt><ref id=".ENDPROC" name=".ENDPROC"></tt>
+  See: <tt/<ref id=".ENDPROC" name=".ENDPROC">/ and <tt/<ref id=".SCOPE"
+  name=".SCOPE">/
 
 
 <sect1><tt>.PSC02</tt><label id=".PSC02"><p>
@@ -2131,7 +2479,7 @@ Here's a list of all control commands and a description, what they do:
 
   <tscreen><verb>
        ; Reserve 12 bytes of memory with value $AA
-       .res    12, $AA
+       .res    12, $AA
   </verb></tscreen>
 
 
@@ -2167,6 +2515,39 @@ Here's a list of all control commands and a description, what they do:
   See also the <tt><ref id=".SEGMENT" name=".SEGMENT"></tt> command.
 
 
+<sect1><tt>.SCOPE</tt><label id=".SCOPE"><p>
+
+  Start a nested lexical level with the given name. All new symbols from now
+  on are in the local lexical level and are accessible from outside only via
+  <ref id="scopesyntax" name="explicit scope specification">. Symbols defined
+  outside this local level may be accessed as long as their names are not used
+  for new symbols inside the level. Symbols names in other lexical levels do
+  not clash, so you may use the same names for identifiers. The lexical level
+  ends when the <tt><ref id=".ENDSCOPE" name=".ENDSCOPE"></tt> command is
+  read. Lexical levels may be nested up to a depth of 16 (this is an
+  artificial limit to protect against errors in the source).
+
+  Note: Macro names are always in the global level and in a separate name
+  space. There is no special reason for this, it's just that I've never
+  had any need for local macro definitions.
+
+  Example:
+
+  <tscreen><verb>
+               .scope  Error                   ; Start new scope named Error
+                None = 0                ; No error
+                File = 1                ; File error
+                Parse = 2               ; Parse error
+       .endproc                        ; Close lexical level
+
+                ...
+                lda #Error::File        ; Use symbol from scope Error
+  </verb></tscreen>
+
+  See: <tt/<ref id=".ENDSCOPE" name=".ENDSCOPE">/ and <tt/<ref id=".PROC"
+  name=".PROC">/
+
+
 <sect1><tt>.SEGMENT</tt><label id=".SEGMENT"><p>
 
   Switch to another segment. Code and data is always emitted into a
@@ -2229,6 +2610,80 @@ Here's a list of all control commands and a description, what they do:
        <tt><ref id=".PSC02" name=".PSC02"></tt>
 
 
+<sect1><tt>.SIZEOF</tt><label id=".SIZEOF"><p>
+
+  <tt/.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
+  <tt/.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 choosen over the
+  symbol.
+
+  After the following code:
+
+  <tscreen><verb>
+        .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
+  </verb></tscreen>
+
+  <descrip>
+    <tag><tt/.sizeof(Point)/</tag>
+    will have the value 4, because this is the size of struct <tt/Point/.
+
+    <tag><tt/.sizeof(Point::xcoord)/</tag>
+    will have the value 2, because this is the size of the member <tt/xcoord/
+    in struct <tt/Point/.
+
+    <tag><tt/.sizeof(P)/</tag>
+    will have the value 4, this is the size of the data declared on the same
+    source line as the label <tt/P/, which is in the same segment that <tt/P/
+    is relative to.
+
+    <tag><tt/.sizeof(@P)/</tag>
+    will have the value 4, see above. The example demonstrates that <tt/.SIZEOF/
+    does also work for cheap local symbols.
+
+    <tag><tt/.sizeof(Code)/</tag>
+    will have the value 3, since this is amount of data emitted into the code
+    segment, the segment that was active when <tt/Code/ was entered. Note that
+    this value includes the amount of data emitted in child scopes (in this
+    case <tt/Code::Inner/).
+
+    <tag><tt/.sizeof(Code::Inner)/</tag>
+    will have the value 1 as expected.
+
+    <tag><tt/.sizeof(Data)/</tag>
+    will have the value 0. Data is emitted within the scope <tt/Data/, but since
+    the segment is switched after entry, this data is emitted into another
+    segment.
+  </descrip>
+
+
 <sect1><tt>.SMART</tt><label id=".SMART"><p>
 
   Switch on or off smart mode. The command must be followed by a '+' or
@@ -2236,13 +2691,21 @@ Here's a list of all control commands and a description, what they do:
   is off (that is, the assembler doesn't try to be smart), but this
   default may be changed by the -s switch on the command line.
 
-  In smart mode the assembler will track usage of the <tt/REP/ and <tt/SEP/
-  instructions in 65816 mode and update the operand sizes accordingly. If
-  the operand of such an instruction cannot be evaluated by the assembler
-  (for example, because the operand is an imported symbol), a warning is
-  issued. Beware: Since the assembler cannot trace the execution flow this
-  may lead to false results in some cases. If in doubt, use the <tt/.Inn/ and
-  <tt/.Ann/ instructions to tell the assembler about the current settings.
+  In smart mode the assembler will do the following:
+
+  <itemize>
+  <item>Track usage of the <tt/REP/ and <tt/SEP/ instructions in 65816 mode
+        and update the operand sizes accordingly. If the operand of such an
+        instruction cannot be evaluated by the assembler (for example, because
+        the operand is an imported symbol), a warning is issued. Beware: Since
+        the assembler cannot trace the execution flow this may lead to false
+        results in some cases. If in doubt, use the <tt/.Inn/ and <tt/.Ann/
+        instructions to tell the assembler about the current settings.
+  <item>In 65816 mode, replace a <tt/RTS/ instruction by <tt/RTL/ if it is
+        used within a procedure declared as <tt/far/, or if the procedure has
+        no explicit address specification, but it is <tt/far/ because of the
+        memory model used.
+  </itemize>
 
   Example:
 
@@ -2251,6 +2714,11 @@ Here's a list of all control commands and a description, what they do:
        .smart  -                       ; Stop being smart
   </verb></tscreen>
 
+  See: <tt><ref id=".A16" name=".A16"></tt>,
+       <tt><ref id=".A8" name=".A8"></tt>,
+       <tt><ref id=".I16" name=".I16"></tt>,
+       <tt><ref id=".I8" name=".I8"></tt>
+
 
 <sect1><tt>.STRAT</tt><label id=".STRAT"><p>
 
@@ -2306,6 +2774,12 @@ Here's a list of all control commands and a description, what they do:
   </verb></tscreen>
 
 
+<sect1><tt>.STRUCT</tt><label id=".STRUCT"><p>
+
+  Starts a struct definition. See the section named <ref id="structs"
+  name="Structs and unions">.
+
+
 <sect1><tt>.SUNPLUS</tt><label id=".SUNPLUS"><p>
 
   Enable the SunPlus instructions set. This command will not work in the
@@ -2317,6 +2791,23 @@ Here's a list of all control commands and a description, what they do:
   <tt><ref id=".P816" name=".P816"></tt>
 
 
+<sect1><tt>.TAG</tt><label id=".TAG"><p>
+
+  Allocate space for a struct or union.
+
+  Example:
+
+  <tscreen><verb>
+        .struct Point
+                xcoord  .word
+                ycoord  .word
+        .endstruct
+
+        .bss
+                .tag    Point           ; Allocate 4 bytes
+  </verb></tscreen>
+
+
 <sect1><tt>.TCOUNT</tt><label id=".TCOUNT"><p>
 
   Builtin function. The function accepts a token list in braces. The
@@ -2588,6 +3079,42 @@ parameters:
 </verb></tscreen>
 
 
+<sect1>Detecting parameter types<p>
+
+Sometimes it is nice to write a macro that acts differently depending on the
+type of the argument supplied. An example would be a macro that loads a 16 bit
+value from either an immediate operand, or from memory. The <tt/<ref
+id=".MATCH" name=".MATCH">/ and <tt/<ref id=".XMATCH" name=".XMATCH">/
+functions will allow you to do exactly this:
+
+<tscreen><verb>
+        .macro  ldax    arg
+                .if (.match (.left (1, arg), #))
+                    ; immediate mode
+                    lda     #<(.right (.tcount (arg)-1, arg))
+                    ldx     #>(.right (.tcount (arg)-1, arg))
+                .else
+                    ; assume absolute or zero page
+                    lda     arg
+                    ldx     1+(arg)
+                .endif
+        .endmacro
+</verb></tscreen>
+
+Using the <tt/<ref id=".MATCH" name=".MATCH">/ function, the macro is able to
+check if its argument begins with a hash mark. If so, two immediate loads are
+emitted, Otherwise a load from an absolute zero page memory location is
+assumed. So this macro can be used as
+
+<tscreen><verb>
+        foo:    .word   $5678
+        ...
+                ldax    #$1234          ; X=$12, A=$34
+        ...
+                ldax    foo             ; X=$56, A=$78
+</verb></tscreen>
+
+
 <sect1>Recursive macros<p>
 
 Macros may be used recursively:
@@ -2913,6 +3440,63 @@ CPUs (the latter two are upwards compatible to the 65SC02).
 
 
 
+<sect>Structs and unions<label id="structs"><p>
+
+Structs and unions are special forms of <ref id="scopes" name="scopes">.  They
+are to some degree comparable to their C counterparts. Both have a list of
+members. Each member allocates storage and may optionally have a name, which,
+in case of a struct, is the offset from the beginning and, in case of a union
+is always zero.
+
+Here is an example for a very simple struct with two members and a total size
+of 4 bytes:
+
+<tscreen><verb>
+      .struct Point
+              xcoord  .word
+              ycoord  .word
+      .endstruct
+</verb></tscreen>
+
+A union shares the total space between all its members, its size is the same
+as that of the largest member.
+
+A struct or union must not necessarily have a name. If it is anonymous, no
+local scope is opened, the identifiers used to name the members are placed
+into the current scope instead.
+
+A struct may contain unnamed members and definitions of local structs. The
+storage allocators may contain a multiplier, as in the example below:
+
+<tscreen><verb>
+      .struct Circle
+              .struct Point
+                      .word   2         ; Allocate two words
+              .endstruct
+              Radius  .word
+      .endstruct
+</verb></tscreen>
+
+Using the <ref id=".TAG" name=".TAG"> keyword, it is possible to embedd
+already defined structs or unions in structs:
+
+<tscreen><verb>
+      .struct Point
+              xcoord  .word
+              ycoord  .word
+      .endstruct
+
+      .struct Circle
+              Origin  .tag    Point
+              Radius  .word
+      .endstruct
+</verb></tscreen>
+
+Space for a struct or union may be allocated using the <ref id=".TAG"
+name=".TAG"> directive.
+
+
+
 <sect>Module constructors/destructors<label id="condes"><p>
 
 <em>Note:</em> This section applies mostly to C programs, so the explanation
@@ -3078,7 +3662,7 @@ notice that other than the original TASS, ca65 can never move the
 programmcounter backwards - think of it as if you are assembling to disc with
 TASS.
 
-<item>Conditional assembly (<tt/.ifeq//<tt/.endif//<tt/.gogo/ etc.) must be
+<item>Conditional assembly (<tt/.ifeq//<tt/.endif//<tt/.goto/ etc.) must be
 rewritten to match ca65 syntax. Most importantly notice that due to the lack
 of <tt/.goto/, everything involving loops must be replaced by
 <tt><ref id=".REPEAT" name=".REPEAT"></tt>.
@@ -3118,7 +3702,7 @@ hear from you. Feel free to contact me by email
 
 <sect>Copyright<p>
 
-ca65 (and all cc65 binutils) are (C) Copyright 1998-2001 Ullrich von
+ca65 (and all cc65 binutils) are (C) Copyright 1998-2003 Ullrich von
 Bassewitz. For usage of the binaries and/or sources the following
 conditions do apply: