]> git.sur5r.net Git - cc65/blobdiff - doc/ca65.sgml
Fixed several address size issues
[cc65] / doc / ca65.sgml
index 4cf1419161c69bcb52c76cc5cb66ca4f6965cd87..67c7d9f66a045415e4ba583f1a213fc43651b0e2 100644 (file)
@@ -800,22 +800,139 @@ id="scopesearch" name=""Scope search order"">).
 
 <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
 
-<sect1>Explicit scope specification<label id="scopesyntax"><p>
+                ...
+                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
 
-<sect>Address sizes<label id="address-sizes">
+        .scope  outer
+                lda     #foo::bar  ; Will load 3, not 2!
+                .scope  foo
+                        bar     = 2
+                .endscope
+        .endscope
+</verb></tscreen>
 
-<p>
+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>
 
 
 
@@ -2493,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
@@ -2500,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:
 
@@ -2515,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>